dcos-core-monalisav2-latam 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +130 -0
- package/index.js +350 -0
- package/package.json +52 -0
- package/src/auth/handler.js +3 -0
- package/src/common/MondelezCastOrder.js +449 -0
- package/src/common/utils/AuthSecurity.js +46 -0
- package/src/common/utils/account-error-handler.js +279 -0
- package/src/common/utils/account-error-helper.js +231 -0
- package/src/common/utils/account-properties-handler.js +355 -0
- package/src/common/utils/api-response.js +62 -0
- package/src/common/utils/aws-services.js +186 -0
- package/src/common/utils/constants/account-error-codes.json +801 -0
- package/src/common/utils/constants.js +37 -0
- package/src/common/utils/convert/MondelezClientsItemsCast.js +52 -0
- package/src/common/utils/convert/MondelezInventoryItemsCast.js +15 -0
- package/src/common/utils/convert/MondelezOrderStatusCast.js +34 -0
- package/src/common/utils/convert/MondelezPricesItemsCast.js +37 -0
- package/src/common/utils/cron-ftp-get.js +143 -0
- package/src/common/utils/data-tables-helper.js +213 -0
- package/src/common/utils/date-range-calculator.js +113 -0
- package/src/common/utils/delay.js +17 -0
- package/src/common/utils/ftp-sftp.js +320 -0
- package/src/common/utils/logger.js +126 -0
- package/src/common/utils/nodemailerLib.js +61 -0
- package/src/common/utils/product-unit-converter.js +168 -0
- package/src/common/utils/schemas-utils.js +101 -0
- package/src/common/utils/seller-email-sharing-service.js +441 -0
- package/src/common/utils/sftp-utils.js +202 -0
- package/src/common/utils/status.js +15 -0
- package/src/common/utils/util.js +236 -0
- package/src/common/utils/validate-state-order.js +35 -0
- package/src/common/utils/validateProviders.js +67 -0
- package/src/common/utils/validation-data.js +45 -0
- package/src/common/utils/vtex/save-hooks.js +65 -0
- package/src/common/utils/vtex/save-schemas.js +65 -0
- package/src/common/utils/vtex-hook-handler.js +71 -0
- package/src/common/validation/AccountCoordinatesValidation.js +350 -0
- package/src/common/validation/GeneralErrorValidation.js +11 -0
- package/src/common/validation/MainErrorValidation.js +8 -0
- package/src/entities/account.js +639 -0
- package/src/entities/clients.js +104 -0
- package/src/entities/controlprice.js +196 -0
- package/src/entities/controlstock.js +206 -0
- package/src/entities/cron.js +77 -0
- package/src/entities/cronjob.js +71 -0
- package/src/entities/orders.js +195 -0
- package/src/entities/sftp-inbound.js +88 -0
- package/src/entities/sku.js +220 -0
- package/src/entities/taxpromotion.js +249 -0
- package/src/functions/account/account-get.js +262 -0
- package/src/functions/account/account-handler.js +299 -0
- package/src/functions/account/clients.js +10 -0
- package/src/functions/account/index.js +208 -0
- package/src/functions/actions/save-promotions-order-history.js +324 -0
- package/src/functions/affiliates/affiliates-hook-consumer.js +87 -0
- package/src/functions/affiliates/affiliates-hook-producer.js +45 -0
- package/src/functions/clients/clients-audience.js +62 -0
- package/src/functions/clients/clients-consumer.js +648 -0
- package/src/functions/clients/clients-producer.js +362 -0
- package/src/functions/clients/clients-suggested-product-consumer.js +166 -0
- package/src/functions/clients/helpers/suggested-product-mdlz.js +233 -0
- package/src/functions/clients_peru/email.html +129 -0
- package/src/functions/clients_peru/splitfile.js +357 -0
- package/src/functions/clients_peru/updateClients.js +1334 -0
- package/src/functions/clients_peru/utils.js +243 -0
- package/src/functions/cronjobs/cron-jobs-manager.js +40 -0
- package/src/functions/cronjobs/cron-jobs.js +171 -0
- package/src/functions/crons/cron.js +39 -0
- package/src/functions/distributors/distributor-handler.js +81 -0
- package/src/functions/distributors/distributor.js +535 -0
- package/src/functions/distributors/index.js +60 -0
- package/src/functions/financialpolicy/assign-financialpolicy.js +111 -0
- package/src/functions/financialpolicy/get-financialpolicy.js +91 -0
- package/src/functions/financialpolicy/index.js +28 -0
- package/src/functions/inventory/catalog-sync-consumer.js +17 -0
- package/src/functions/inventory/catalog-sync-handler.js +311 -0
- package/src/functions/inventory/inventory-consumer.js +119 -0
- package/src/functions/inventory/inventory-producer.js +197 -0
- package/src/functions/multiPresentation/multipre-queue.js +155 -0
- package/src/functions/multiPresentation/multipres.js +459 -0
- package/src/functions/nodeflow/index.js +83 -0
- package/src/functions/nodeflow/nodeflow-cron.js +200 -0
- package/src/functions/nodeflow/nodeflow-pub.js +203 -0
- package/src/functions/nodeflow/nodeflow-pvt.js +266 -0
- package/src/functions/notifications/download-leads-handler.js +67 -0
- package/src/functions/notifications/new-leads-notification-consumer.js +17 -0
- package/src/functions/notifications/new-leads-notification-handler.js +359 -0
- package/src/functions/notifications/order-status-notification-handler.js +482 -0
- package/src/functions/notifications/promotion-notification-handler.js +193 -0
- package/src/functions/orders/index.js +32 -0
- package/src/functions/orders/orders-cancel-handler.js +74 -0
- package/src/functions/orders/orders-handler.js +280 -0
- package/src/functions/orders/orders-hook-consumer.js +137 -0
- package/src/functions/orders/orders-hook-producer.js +170 -0
- package/src/functions/orders/orders-notifications-handler.js +137 -0
- package/src/functions/orders/orders-status-consumer.js +461 -0
- package/src/functions/orders/orders-status-producer.js +443 -0
- package/src/functions/prices/index.js +75 -0
- package/src/functions/prices/prices-consumer.js +236 -0
- package/src/functions/prices/prices-producer.js +323 -0
- package/src/functions/prices/promotion-and-tax.js +1284 -0
- package/src/functions/routesflow/assign-routeflow-queue.js +77 -0
- package/src/functions/schemas/vtex/handle-schemas.js +102 -0
- package/src/functions/security/process_gas.js +221 -0
- package/src/functions/security/security-handler.js +950 -0
- package/src/functions/sftp/sftp-consumer.js +453 -0
- package/src/functions/sftpIntegrations/processes/redirectServices.js +184 -0
- package/src/functions/sftpIntegrations/processes/validateFileSchema.js +226 -0
- package/src/functions/sftpIntegrations/schemas/credential-schema.js +123 -0
- package/src/functions/sftpIntegrations/schemas/record-schema.js +131 -0
- package/src/functions/sftpIntegrations/schemas/sftp_required_fields.json +3 -0
- package/src/functions/sftpIntegrations/sftp-config-producer.js +112 -0
- package/src/functions/sftpIntegrations/sftp-consumer.js +700 -0
- package/src/functions/sftpIntegrations/test/validateFile.test.js +122 -0
- package/src/functions/sftpIntegrations/utils/connect-dynamo.js +29 -0
- package/src/functions/sftpIntegrations/utils/split-data.js +25 -0
- package/src/functions/utils/index.js +130 -0
- package/src/functions/vtex/vtex-helpers.js +694 -0
- package/src/integrations/accountErrors/AccountErrorManager.js +437 -0
- package/src/integrations/audience/Audience.js +70 -0
- package/src/integrations/financialPolicy/FinancialPolicyApi.js +377 -0
- package/src/integrations/index.js +0 -0
- package/src/integrations/mobilvendor/MobilvendorApi.js +405 -0
- package/src/integrations/productmultipresentation/ProductMultiPresentation.js +200 -0
- package/src/mdlz/auth/SecretManagerApi.js +77 -0
- package/src/mdlz/client/MdlzApi.js +70 -0
- package/src/vtex/clients/ProvidersApi.js +51 -0
- package/src/vtex/clients/VtexApi.js +511 -0
- package/src/vtex/models/VtexOrder.js +87 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
class Constants {
|
|
2
|
+
static REGISTER_CHANGE_ON_ORDER = "/oms/pvt/orders/{orderId}/changes";
|
|
3
|
+
static START_HANDLING_ORDER = "/oms/pvt/orders/{orderId}/start-handling";
|
|
4
|
+
static INVOICE_NOTIFICATION_ORDER = "/oms/pvt/orders/{orderId}/invoice";
|
|
5
|
+
static APPROVE_PAYMENT = "/payments/pvt/payments/{paymentId}/payment-notification";
|
|
6
|
+
static GET_ORDER = `/oms/pvt/orders/{orderId}`;
|
|
7
|
+
|
|
8
|
+
static SAFETY_STOCK_TYPE_PERCENTAGE = "percentage";
|
|
9
|
+
static SAFETY_STOCK_TYPE_NOMINAL = "nominal";
|
|
10
|
+
|
|
11
|
+
static SFTP_STATUS_PENDING = "pending";
|
|
12
|
+
static SFTP_STATUS_IN_PROCESS = "inProcess";
|
|
13
|
+
static SFTP_STATUS_PROCESSED = "processed";
|
|
14
|
+
static SFTP_LOG = "log";
|
|
15
|
+
static SFTP_LOG_FILE_TYPE = ".log";
|
|
16
|
+
static SFTP_TXT_FILE_TYPE = ".txt";
|
|
17
|
+
static SFTP_CSV_FILE_TYPE = ".csv";
|
|
18
|
+
static SFTP_PROCESS_PRICES = "prices";
|
|
19
|
+
static SFTP_PROCESS_CANCEL = "cancel";
|
|
20
|
+
static SFTP_PROCESS_INVENTORY = "inventory";
|
|
21
|
+
static SFTP_PROCESS_CLIENTS = "clients";
|
|
22
|
+
static SFTP_PROCESS_ORDER = "order";
|
|
23
|
+
static SFTP_PROCESS_STATUS = "status";
|
|
24
|
+
|
|
25
|
+
static SAFETY_STOCK_TYPE_PERCENTAGE = "percentage";
|
|
26
|
+
static SAFETY_STOCK_TYPE_NOMINAL = "nominal";
|
|
27
|
+
|
|
28
|
+
static SFTP_ALL_PROCESSES_CONSUMED = [
|
|
29
|
+
this.SFTP_PROCESS_PRICES,
|
|
30
|
+
this.SFTP_PROCESS_CANCEL,
|
|
31
|
+
this.SFTP_PROCESS_INVENTORY,
|
|
32
|
+
this.SFTP_PROCESS_CLIENTS,
|
|
33
|
+
this.SFTP_PROCESS_STATUS,
|
|
34
|
+
];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
module.exports = Constants;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
|
|
2
|
+
const clientsItemsCSVToJson = (dataCSV) => {
|
|
3
|
+
|
|
4
|
+
const mondelezClientsItem = {
|
|
5
|
+
email: dataCSV.email,
|
|
6
|
+
firstName: dataCSV.firstName,
|
|
7
|
+
lastName: dataCSV.lastName,
|
|
8
|
+
documentType: dataCSV.documentType,
|
|
9
|
+
document: dataCSV.document,
|
|
10
|
+
homePhone: dataCSV.homePhone,
|
|
11
|
+
phone: dataCSV.phone,
|
|
12
|
+
customerClass: dataCSV.customerClass,
|
|
13
|
+
customerClassTwo: dataCSV.customerClassTwo,
|
|
14
|
+
approved: (dataCSV.approved === "true" ? true : dataCSV.approved === "false" ? false : -1),
|
|
15
|
+
status: dataCSV.status,
|
|
16
|
+
address: {
|
|
17
|
+
receiverName: dataCSV.address_receiverName,
|
|
18
|
+
street: dataCSV.address_street,
|
|
19
|
+
number: Number(dataCSV.address_number),
|
|
20
|
+
complement: dataCSV.address_complement,
|
|
21
|
+
postalCode: dataCSV.address_postalCode,
|
|
22
|
+
neighborhood: dataCSV.address_neighborhood,
|
|
23
|
+
city: dataCSV.address_city,
|
|
24
|
+
state: dataCSV.address_state,
|
|
25
|
+
country: dataCSV.address_country,
|
|
26
|
+
reference: dataCSV.address_reference,
|
|
27
|
+
geoCoordinates: {
|
|
28
|
+
latitude: dataCSV.address_latitude,
|
|
29
|
+
longitude: dataCSV.address_longitude
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
additional_information: {
|
|
33
|
+
deliveryDay: dataCSV.info_deliveryDay,
|
|
34
|
+
visitDay: dataCSV.info_visitDay,
|
|
35
|
+
frequency: dataCSV.info_frequency,
|
|
36
|
+
salesmanName: dataCSV.info_salesmanName,
|
|
37
|
+
distributorCode: dataCSV.info_distributorCode,
|
|
38
|
+
distributorName: dataCSV.info_distributorName,
|
|
39
|
+
clientCode: dataCSV.info_clientCode,
|
|
40
|
+
priceTable: dataCSV.info_priceTable,
|
|
41
|
+
pdvname: dataCSV.info_pdvname,
|
|
42
|
+
pdv: dataCSV.info_pdv
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
return mondelezClientsItem;
|
|
46
|
+
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
module.exports = {
|
|
50
|
+
clientsItemsCSVToJson,
|
|
51
|
+
};
|
|
52
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const orderStatusItemsCSVToJson = (itemDataCSV) => {
|
|
2
|
+
let itemRemovedCustom = {};
|
|
3
|
+
let listItemsRemoved = [];
|
|
4
|
+
|
|
5
|
+
for (let itemRemoved of itemDataCSV.changesItemsRemoved) {
|
|
6
|
+
itemRemovedCustom = {
|
|
7
|
+
sku: itemRemoved.changesItemsRemovedSku,
|
|
8
|
+
price: Number(itemRemoved.changesItemsRemovedPrice),
|
|
9
|
+
quantity: Number(itemRemoved.changesItemsRemovedQuantity),
|
|
10
|
+
};
|
|
11
|
+
listItemsRemoved.push(itemRemovedCustom);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const mdlzOrderStatusItem = {
|
|
15
|
+
changes: {
|
|
16
|
+
reason: itemDataCSV.changesReason,
|
|
17
|
+
discountValue: Number(itemDataCSV.changesDiscountValue),
|
|
18
|
+
itemsRemoved: listItemsRemoved,
|
|
19
|
+
},
|
|
20
|
+
documents: {
|
|
21
|
+
type: itemDataCSV.documentsType,
|
|
22
|
+
issuanceDate: itemDataCSV.documentsIssuanceDate,
|
|
23
|
+
invoiceNumber: itemDataCSV.documentsInvoiceNumber,
|
|
24
|
+
invoiceValue: Number(itemDataCSV.documentsInvoiceValue),
|
|
25
|
+
invoiceUrl: itemDataCSV.documentsInvoiceUrl,
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
return mdlzOrderStatusItem;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
module.exports = {
|
|
33
|
+
orderStatusItemsCSVToJson,
|
|
34
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const pricesItemsCSVToJson = (itemDataCSV) => {
|
|
2
|
+
let listFixedPrices = [];
|
|
3
|
+
|
|
4
|
+
for (let itemFixedPrices of itemDataCSV.fixedPrices) {
|
|
5
|
+
let itemFixedPricesCustom = {
|
|
6
|
+
listId: itemFixedPrices.listId,
|
|
7
|
+
value: Number(itemFixedPrices.value),
|
|
8
|
+
listPrice: Number(itemFixedPrices.listPrice),
|
|
9
|
+
minQuantity: Number(itemFixedPrices.minQuantity),
|
|
10
|
+
};
|
|
11
|
+
if (
|
|
12
|
+
(itemFixedPrices.dateRangeFrom && itemFixedPrices.dateRangeFrom.length > 0) ||
|
|
13
|
+
(itemFixedPrices.dateRangeTo && itemFixedPrices.dateRangeTo.length > 0)
|
|
14
|
+
) {
|
|
15
|
+
itemFixedPrices.dateRangeFrom = itemFixedPrices.dateRangeFrom ? itemFixedPrices.dateRangeFrom : null;
|
|
16
|
+
itemFixedPrices.dateRangeTo = itemFixedPrices.dateRangeTo ? itemFixedPrices.dateRangeTo : null;
|
|
17
|
+
itemFixedPricesCustom.dateRange = {
|
|
18
|
+
from: itemFixedPrices.dateRangeFrom,
|
|
19
|
+
to: itemFixedPrices.dateRangeTo,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
listFixedPrices.push(itemFixedPricesCustom);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const mondelezPricesItem = {
|
|
26
|
+
sku: itemDataCSV.sku,
|
|
27
|
+
listPrice: Number(itemDataCSV.listPrice),
|
|
28
|
+
basePrice: Number(itemDataCSV.basePrice),
|
|
29
|
+
fixedPrices: listFixedPrices,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
return mondelezPricesItem;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
module.exports = {
|
|
36
|
+
pricesItemsCSVToJson,
|
|
37
|
+
};
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
const DynamoAWS = require("aws-sdk/clients/dynamodb");
|
|
2
|
+
const ApiResponse = require("../../common/utils/api-response");
|
|
3
|
+
const Logger = require("../../common/utils/logger");
|
|
4
|
+
|
|
5
|
+
const CRONS_TABLE = process.env.CRONS_TABLE;
|
|
6
|
+
const SFTP_CREDENTIALS_TABLE = process.env.SFTP_CREDENTIALS_TABLE;
|
|
7
|
+
|
|
8
|
+
// ==================== CRONS ====================
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* GET /crons - Obtiene TODOS los crons
|
|
12
|
+
*/
|
|
13
|
+
const getAllCrons = async (event) => {
|
|
14
|
+
try {
|
|
15
|
+
const dynamodb = new DynamoAWS.DocumentClient();
|
|
16
|
+
const params = {
|
|
17
|
+
TableName: CRONS_TABLE
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const response = await dynamodb.scan(params).promise();
|
|
21
|
+
|
|
22
|
+
return ApiResponse.response(200, {
|
|
23
|
+
message: "Crons retrieved successfully",
|
|
24
|
+
data: response.Items || [],
|
|
25
|
+
count: response.Items ? response.Items.length : 0
|
|
26
|
+
});
|
|
27
|
+
} catch (error) {
|
|
28
|
+
Logger.error("Error getting all crons:", error);
|
|
29
|
+
return ApiResponse.response(500, { error: "Internal server error" });
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* GET /crons/createorupdate/{cronId} - Obtiene UN cron específico
|
|
35
|
+
*/
|
|
36
|
+
const getCronById = async (event) => {
|
|
37
|
+
try {
|
|
38
|
+
const { cronId } = event.pathParameters || {};
|
|
39
|
+
|
|
40
|
+
if (!cronId) {
|
|
41
|
+
return ApiResponse.response(400, { error: "cronId is required" });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const dynamodb = new DynamoAWS.DocumentClient();
|
|
45
|
+
const params = {
|
|
46
|
+
TableName: CRONS_TABLE,
|
|
47
|
+
Key: { "CronId": cronId }
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const response = await dynamodb.get(params).promise();
|
|
51
|
+
|
|
52
|
+
if (!response.Item) {
|
|
53
|
+
return ApiResponse.response(404, { error: "Cron not found" });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return ApiResponse.response(200, {
|
|
57
|
+
message: "Cron retrieved successfully",
|
|
58
|
+
data: response.Item
|
|
59
|
+
});
|
|
60
|
+
} catch (error) {
|
|
61
|
+
Logger.error("Error getting cron by ID:", error);
|
|
62
|
+
return ApiResponse.response(500, { error: "Internal server error" });
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// ==================== SFTP ====================
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* GET /account/sftp - Obtiene TODAS las credenciales SFTP
|
|
70
|
+
*/
|
|
71
|
+
const getAllSftpCredentials = async (event) => {
|
|
72
|
+
try {
|
|
73
|
+
const dynamodb = new DynamoAWS.DocumentClient();
|
|
74
|
+
const params = {
|
|
75
|
+
TableName: SFTP_CREDENTIALS_TABLE,
|
|
76
|
+
// Excluir passwords por seguridad
|
|
77
|
+
ProjectionExpression: "FtpId, #type, Host, Port, #user",
|
|
78
|
+
ExpressionAttributeNames: {
|
|
79
|
+
"#type": "Type",
|
|
80
|
+
"#user": "User"
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const response = await dynamodb.scan(params).promise();
|
|
85
|
+
|
|
86
|
+
return ApiResponse.response(200, {
|
|
87
|
+
message: "SFTP credentials retrieved successfully",
|
|
88
|
+
data: response.Items || [],
|
|
89
|
+
count: response.Items ? response.Items.length : 0
|
|
90
|
+
});
|
|
91
|
+
} catch (error) {
|
|
92
|
+
Logger.error("Error getting all SFTP credentials:", error);
|
|
93
|
+
return ApiResponse.response(500, { error: "Internal server error" });
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* GET /account/sftp/{ftpId} - Obtiene UNA credencial SFTP específica
|
|
99
|
+
*/
|
|
100
|
+
const getSftpCredentialById = async (event) => {
|
|
101
|
+
try {
|
|
102
|
+
const { ftpId } = event.pathParameters || {};
|
|
103
|
+
|
|
104
|
+
if (!ftpId) {
|
|
105
|
+
return ApiResponse.response(400, { error: "ftpId is required" });
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const dynamodb = new DynamoAWS.DocumentClient();
|
|
109
|
+
const params = {
|
|
110
|
+
TableName: SFTP_CREDENTIALS_TABLE,
|
|
111
|
+
Key: { "FtpId": ftpId },
|
|
112
|
+
// Excluir password por seguridad
|
|
113
|
+
ProjectionExpression: "FtpId, #type, Host, Port, #user",
|
|
114
|
+
ExpressionAttributeNames: {
|
|
115
|
+
"#type": "Type",
|
|
116
|
+
"#user": "User"
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const response = await dynamodb.get(params).promise();
|
|
121
|
+
|
|
122
|
+
if (!response.Item) {
|
|
123
|
+
return ApiResponse.response(404, { error: "SFTP credential not found" });
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return ApiResponse.response(200, {
|
|
127
|
+
message: "SFTP credential retrieved successfully",
|
|
128
|
+
data: response.Item
|
|
129
|
+
});
|
|
130
|
+
} catch (error) {
|
|
131
|
+
Logger.error("Error getting SFTP credential by ID:", error);
|
|
132
|
+
return ApiResponse.response(500, { error: "Internal server error" });
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
module.exports = {
|
|
137
|
+
// Crons
|
|
138
|
+
getAllCrons,
|
|
139
|
+
getCronById,
|
|
140
|
+
// SFTP
|
|
141
|
+
getAllSftpCredentials,
|
|
142
|
+
getSftpCredentialById
|
|
143
|
+
};
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detecta si los parámetros vienen en formato DataTables
|
|
3
|
+
*/
|
|
4
|
+
const isDataTablesFormat = (params) => {
|
|
5
|
+
return params.hasOwnProperty('draw') &&
|
|
6
|
+
params.hasOwnProperty('start') &&
|
|
7
|
+
params.hasOwnProperty('length');
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Carga dinámicamente el schema de account desde el archivo JSON
|
|
12
|
+
*/
|
|
13
|
+
const loadAccountSchemaProperties = () => {
|
|
14
|
+
try {
|
|
15
|
+
const schema = require('../../../json/schema-valid-json-account.json');
|
|
16
|
+
|
|
17
|
+
if (schema.properties) {
|
|
18
|
+
return Object.keys(schema.properties).sort();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
throw new Error('No properties found in schema');
|
|
22
|
+
} catch (error) {
|
|
23
|
+
console.error('Error loading account schema:', error);
|
|
24
|
+
return ['AccountName', 'ParentAccountName'];
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Obtiene mapeo de columnas completamente dinámico
|
|
30
|
+
*/
|
|
31
|
+
const getColumnMapping = (dataTablesParams) => {
|
|
32
|
+
const paramsMapping = extractColumnMappingFromParams(dataTablesParams);
|
|
33
|
+
if (Object.keys(paramsMapping).length > 0) {
|
|
34
|
+
return paramsMapping;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return generateSchemaBasedMapping();
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Extrae mapeo desde parámetros DataTables (columns[N][data])
|
|
42
|
+
*/
|
|
43
|
+
const extractColumnMappingFromParams = (dataTablesParams) => {
|
|
44
|
+
const mapping = {};
|
|
45
|
+
|
|
46
|
+
Object.keys(dataTablesParams).forEach(key => {
|
|
47
|
+
const columnMatch = key.match(/^columns\[(\d+)\]\[data\]$/);
|
|
48
|
+
if (columnMatch) {
|
|
49
|
+
const columnIndex = columnMatch[1];
|
|
50
|
+
const fieldName = dataTablesParams[key];
|
|
51
|
+
if (fieldName) {
|
|
52
|
+
mapping[columnIndex] = fieldName;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return mapping;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Genera mapeo basado dinámicamente en el schema JSON
|
|
62
|
+
*/
|
|
63
|
+
const generateSchemaBasedMapping = () => {
|
|
64
|
+
const schemaProperties = loadAccountSchemaProperties();
|
|
65
|
+
const mapping = {};
|
|
66
|
+
|
|
67
|
+
schemaProperties.forEach((property, index) => {
|
|
68
|
+
mapping[index] = property;
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
return mapping;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Convierte parámetros DataTables a formato interno
|
|
76
|
+
*/
|
|
77
|
+
const parseDataTablesParams = (dataTablesParams) => {
|
|
78
|
+
const draw = parseInt(dataTablesParams.draw) || 1;
|
|
79
|
+
const start = parseInt(dataTablesParams.start) || 0;
|
|
80
|
+
const length = Math.min(parseInt(dataTablesParams.length) || 10, 100);
|
|
81
|
+
|
|
82
|
+
const columnMapping = getColumnMapping(dataTablesParams);
|
|
83
|
+
|
|
84
|
+
const orderColumnIndex = dataTablesParams["order[0][column]"] || "0";
|
|
85
|
+
const orderDir = dataTablesParams["order[0][dir]"] || "asc";
|
|
86
|
+
const orderField = columnMapping[orderColumnIndex] || "AccountName";
|
|
87
|
+
|
|
88
|
+
const globalSearch = dataTablesParams["search[value]"] || "";
|
|
89
|
+
|
|
90
|
+
const columnFilters = {};
|
|
91
|
+
Object.keys(dataTablesParams).forEach(key => {
|
|
92
|
+
const columnMatch = key.match(/^columns\[(\d+)\]\[search\]\[value\]$/);
|
|
93
|
+
if (columnMatch && dataTablesParams[key]) {
|
|
94
|
+
const columnIndex = columnMatch[1];
|
|
95
|
+
const fieldName = columnMapping[columnIndex];
|
|
96
|
+
if (fieldName) {
|
|
97
|
+
columnFilters[fieldName] = dataTablesParams[key];
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const accountNamesFilter = detectMultipleAccountNames(dataTablesParams, globalSearch);
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
draw,
|
|
106
|
+
start,
|
|
107
|
+
length,
|
|
108
|
+
orderField,
|
|
109
|
+
orderDir,
|
|
110
|
+
globalSearch,
|
|
111
|
+
columnFilters,
|
|
112
|
+
columnMapping,
|
|
113
|
+
accountNamesFilter,
|
|
114
|
+
_limit: length,
|
|
115
|
+
_sort: orderDir === "desc" ? "desc" : "asc",
|
|
116
|
+
_like: globalSearch,
|
|
117
|
+
_from: null
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Detecta si se están buscando múltiples AccountNames
|
|
123
|
+
*/
|
|
124
|
+
const detectMultipleAccountNames = (dataTablesParams, globalSearch) => {
|
|
125
|
+
const accountNameColumnFilter = Object.keys(dataTablesParams).find(key => {
|
|
126
|
+
const match = key.match(/^columns\[(\d+)\]\[search\]\[value\]$/);
|
|
127
|
+
if (match) {
|
|
128
|
+
const columnIndex = match[1];
|
|
129
|
+
const columnDataKey = `columns[${columnIndex}][data]`;
|
|
130
|
+
return dataTablesParams[columnDataKey] === 'AccountName';
|
|
131
|
+
}
|
|
132
|
+
return false;
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
let searchValue = '';
|
|
136
|
+
if (accountNameColumnFilter) {
|
|
137
|
+
searchValue = dataTablesParams[accountNameColumnFilter];
|
|
138
|
+
} else if (globalSearch) {
|
|
139
|
+
searchValue = globalSearch;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (searchValue && (searchValue.includes(',') || searchValue.includes(';'))) {
|
|
143
|
+
return searchValue
|
|
144
|
+
.split(/[,;]/)
|
|
145
|
+
.map(name => name.trim())
|
|
146
|
+
.filter(name => name.length > 0);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return null;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Convierte parámetros legacy a formato DataTables interno
|
|
154
|
+
*/
|
|
155
|
+
const parseLegacyParams = (legacyParams) => {
|
|
156
|
+
return {
|
|
157
|
+
draw: 1,
|
|
158
|
+
start: 0,
|
|
159
|
+
length: Math.min(parseInt(legacyParams._limit) || 10, 100),
|
|
160
|
+
orderField: "AccountName",
|
|
161
|
+
orderDir: legacyParams._sort || "asc",
|
|
162
|
+
globalSearch: legacyParams._like || "",
|
|
163
|
+
columnFilters: {},
|
|
164
|
+
columnMapping: generateSchemaBasedMapping(),
|
|
165
|
+
accountNamesFilter: null,
|
|
166
|
+
_limit: legacyParams._limit,
|
|
167
|
+
_sort: legacyParams._sort,
|
|
168
|
+
_like: legacyParams._like,
|
|
169
|
+
_from: legacyParams._from,
|
|
170
|
+
_moduleActive: legacyParams._moduleActive,
|
|
171
|
+
_integration: legacyParams._integration,
|
|
172
|
+
_accountPattern: legacyParams._accountPattern
|
|
173
|
+
};
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Formatea respuesta para DataTables
|
|
178
|
+
*/
|
|
179
|
+
const formatDataTablesResponse = (data, draw, recordsTotal, recordsFiltered) => {
|
|
180
|
+
return {
|
|
181
|
+
draw: parseInt(draw),
|
|
182
|
+
recordsTotal: parseInt(recordsTotal),
|
|
183
|
+
recordsFiltered: parseInt(recordsFiltered),
|
|
184
|
+
data: data
|
|
185
|
+
};
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Formatea respuesta para formato legacy
|
|
190
|
+
*/
|
|
191
|
+
const formatLegacyResponse = (data, count, nextToken) => {
|
|
192
|
+
return {
|
|
193
|
+
message: "Accounts retrieved successfully",
|
|
194
|
+
data: data,
|
|
195
|
+
count: count,
|
|
196
|
+
pagination: {
|
|
197
|
+
nextToken: nextToken,
|
|
198
|
+
hasMore: nextToken !== null,
|
|
199
|
+
limit: data.length
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
module.exports = {
|
|
205
|
+
isDataTablesFormat,
|
|
206
|
+
parseDataTablesParams,
|
|
207
|
+
parseLegacyParams,
|
|
208
|
+
formatDataTablesResponse,
|
|
209
|
+
formatLegacyResponse,
|
|
210
|
+
getColumnMapping,
|
|
211
|
+
loadAccountSchemaProperties,
|
|
212
|
+
detectMultipleAccountNames
|
|
213
|
+
};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
const calculateDateRange = (rangeQuery, rangeValue) => {
|
|
2
|
+
const now = new Date();
|
|
3
|
+
let startDate = new Date();
|
|
4
|
+
let endDate = new Date();
|
|
5
|
+
|
|
6
|
+
// Separar el tipo de consulta y el valor numérico (si existe)
|
|
7
|
+
const [queryType, queryValue] = rangeQuery.split('_');
|
|
8
|
+
const numericValue = rangeValue || parseInt(queryValue);
|
|
9
|
+
|
|
10
|
+
switch (queryType) {
|
|
11
|
+
case 'last':
|
|
12
|
+
switch (queryValue) {
|
|
13
|
+
case 'day':
|
|
14
|
+
startDate.setDate(now.getDate() - 1);
|
|
15
|
+
startDate.setHours(0, 0, 0, 0);
|
|
16
|
+
endDate = new Date(startDate);
|
|
17
|
+
endDate.setHours(23, 59, 59, 999);
|
|
18
|
+
break;
|
|
19
|
+
|
|
20
|
+
case 'week':
|
|
21
|
+
// Encontrar el lunes de la semana anterior
|
|
22
|
+
startDate = new Date(now);
|
|
23
|
+
startDate.setDate(now.getDate() - now.getDay() - 7);
|
|
24
|
+
startDate.setHours(0, 0, 0, 0);
|
|
25
|
+
endDate = new Date(startDate);
|
|
26
|
+
endDate.setDate(startDate.getDate() + 6);
|
|
27
|
+
endDate.setHours(23, 59, 59, 999);
|
|
28
|
+
break;
|
|
29
|
+
|
|
30
|
+
case 'month':
|
|
31
|
+
startDate = new Date(now.getFullYear(), now.getMonth() - 1, 1, 0, 0, 0, 0);
|
|
32
|
+
endDate = new Date(now.getFullYear(), now.getMonth(), 0, 23, 59, 59, 999);
|
|
33
|
+
break;
|
|
34
|
+
|
|
35
|
+
case 'days':
|
|
36
|
+
if (!numericValue) throw new Error('Invalid days value');
|
|
37
|
+
startDate.setDate(now.getDate() - numericValue);
|
|
38
|
+
startDate.setHours(0, 0, 0, 0);
|
|
39
|
+
endDate = new Date(now);
|
|
40
|
+
endDate.setDate(now.getDate() - 1);
|
|
41
|
+
endDate.setHours(23, 59, 59, 999);
|
|
42
|
+
break;
|
|
43
|
+
|
|
44
|
+
case 'weeks':
|
|
45
|
+
if (!numericValue) throw new Error('Invalid weeks value');
|
|
46
|
+
startDate.setDate(now.getDate() - (numericValue * 7));
|
|
47
|
+
startDate.setHours(0, 0, 0, 0);
|
|
48
|
+
endDate = new Date(now);
|
|
49
|
+
endDate.setDate(now.getDate() - now.getDay() - 1);
|
|
50
|
+
endDate.setHours(23, 59, 59, 999);
|
|
51
|
+
break;
|
|
52
|
+
|
|
53
|
+
case 'months':
|
|
54
|
+
if (!numericValue) throw new Error('Invalid months value');
|
|
55
|
+
startDate = new Date(now.getFullYear(), now.getMonth() - numericValue, 1, 0, 0, 0, 0);
|
|
56
|
+
endDate = new Date(now.getFullYear(), now.getMonth(), 0, 23, 59, 59, 999);
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
break;
|
|
60
|
+
|
|
61
|
+
case 'now':
|
|
62
|
+
switch (queryValue) {
|
|
63
|
+
case 'days':
|
|
64
|
+
if (!numericValue) throw new Error('Invalid days value');
|
|
65
|
+
startDate.setDate(now.getDate() - numericValue + 1);
|
|
66
|
+
startDate.setHours(0, 0, 0, 0);
|
|
67
|
+
endDate = new Date(now);
|
|
68
|
+
break;
|
|
69
|
+
|
|
70
|
+
case 'week':
|
|
71
|
+
startDate.setDate(now.getDate() - now.getDay());
|
|
72
|
+
startDate.setHours(0, 0, 0, 0);
|
|
73
|
+
endDate = new Date(now);
|
|
74
|
+
break;
|
|
75
|
+
|
|
76
|
+
case 'month':
|
|
77
|
+
startDate = new Date(now.getFullYear(), now.getMonth(), 1, 0, 0, 0, 0);
|
|
78
|
+
endDate = new Date(now);
|
|
79
|
+
break;
|
|
80
|
+
|
|
81
|
+
case 'weeks':
|
|
82
|
+
if (!numericValue) throw new Error('Invalid weeks value');
|
|
83
|
+
startDate.setDate(now.getDate() - (numericValue * 7));
|
|
84
|
+
startDate.setHours(0, 0, 0, 0);
|
|
85
|
+
endDate = new Date(now);
|
|
86
|
+
break;
|
|
87
|
+
|
|
88
|
+
case 'months':
|
|
89
|
+
if (!numericValue) throw new Error('Invalid months value');
|
|
90
|
+
startDate = new Date(now.getFullYear(), now.getMonth() - numericValue + 1, 1, 0, 0, 0, 0);
|
|
91
|
+
endDate = new Date(now);
|
|
92
|
+
break;
|
|
93
|
+
|
|
94
|
+
case 'days':
|
|
95
|
+
startDate = new Date(now);
|
|
96
|
+
startDate.setHours(0, 0, 0, 0);
|
|
97
|
+
endDate = new Date(now);
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
break;
|
|
101
|
+
|
|
102
|
+
default:
|
|
103
|
+
throw new Error('Invalid range query format');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
startDate: startDate.toISOString(),
|
|
108
|
+
endDate: endDate.toISOString(),
|
|
109
|
+
period: `${queryType}_${queryValue}${numericValue ? `-${numericValue}` : ''}`
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
module.exports = { calculateDateRange };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Establece un tiempo de espera
|
|
3
|
+
* @param {number} seconds Tiempo de espera en segundos
|
|
4
|
+
* @returns
|
|
5
|
+
*/
|
|
6
|
+
module.exports.delayStatusProcess = (seconds) => {
|
|
7
|
+
return new Promise((resolve, reject) => {
|
|
8
|
+
if (!seconds || seconds > 1) {
|
|
9
|
+
// Se define un TimeOut
|
|
10
|
+
setTimeout(() => {
|
|
11
|
+
resolve(true);
|
|
12
|
+
}, (seconds * 1000));
|
|
13
|
+
} else {
|
|
14
|
+
resolve(true);
|
|
15
|
+
}
|
|
16
|
+
})
|
|
17
|
+
};
|