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.
Files changed (129) hide show
  1. package/README.md +130 -0
  2. package/index.js +350 -0
  3. package/package.json +52 -0
  4. package/src/auth/handler.js +3 -0
  5. package/src/common/MondelezCastOrder.js +449 -0
  6. package/src/common/utils/AuthSecurity.js +46 -0
  7. package/src/common/utils/account-error-handler.js +279 -0
  8. package/src/common/utils/account-error-helper.js +231 -0
  9. package/src/common/utils/account-properties-handler.js +355 -0
  10. package/src/common/utils/api-response.js +62 -0
  11. package/src/common/utils/aws-services.js +186 -0
  12. package/src/common/utils/constants/account-error-codes.json +801 -0
  13. package/src/common/utils/constants.js +37 -0
  14. package/src/common/utils/convert/MondelezClientsItemsCast.js +52 -0
  15. package/src/common/utils/convert/MondelezInventoryItemsCast.js +15 -0
  16. package/src/common/utils/convert/MondelezOrderStatusCast.js +34 -0
  17. package/src/common/utils/convert/MondelezPricesItemsCast.js +37 -0
  18. package/src/common/utils/cron-ftp-get.js +143 -0
  19. package/src/common/utils/data-tables-helper.js +213 -0
  20. package/src/common/utils/date-range-calculator.js +113 -0
  21. package/src/common/utils/delay.js +17 -0
  22. package/src/common/utils/ftp-sftp.js +320 -0
  23. package/src/common/utils/logger.js +126 -0
  24. package/src/common/utils/nodemailerLib.js +61 -0
  25. package/src/common/utils/product-unit-converter.js +168 -0
  26. package/src/common/utils/schemas-utils.js +101 -0
  27. package/src/common/utils/seller-email-sharing-service.js +441 -0
  28. package/src/common/utils/sftp-utils.js +202 -0
  29. package/src/common/utils/status.js +15 -0
  30. package/src/common/utils/util.js +236 -0
  31. package/src/common/utils/validate-state-order.js +35 -0
  32. package/src/common/utils/validateProviders.js +67 -0
  33. package/src/common/utils/validation-data.js +45 -0
  34. package/src/common/utils/vtex/save-hooks.js +65 -0
  35. package/src/common/utils/vtex/save-schemas.js +65 -0
  36. package/src/common/utils/vtex-hook-handler.js +71 -0
  37. package/src/common/validation/AccountCoordinatesValidation.js +350 -0
  38. package/src/common/validation/GeneralErrorValidation.js +11 -0
  39. package/src/common/validation/MainErrorValidation.js +8 -0
  40. package/src/entities/account.js +639 -0
  41. package/src/entities/clients.js +104 -0
  42. package/src/entities/controlprice.js +196 -0
  43. package/src/entities/controlstock.js +206 -0
  44. package/src/entities/cron.js +77 -0
  45. package/src/entities/cronjob.js +71 -0
  46. package/src/entities/orders.js +195 -0
  47. package/src/entities/sftp-inbound.js +88 -0
  48. package/src/entities/sku.js +220 -0
  49. package/src/entities/taxpromotion.js +249 -0
  50. package/src/functions/account/account-get.js +262 -0
  51. package/src/functions/account/account-handler.js +299 -0
  52. package/src/functions/account/clients.js +10 -0
  53. package/src/functions/account/index.js +208 -0
  54. package/src/functions/actions/save-promotions-order-history.js +324 -0
  55. package/src/functions/affiliates/affiliates-hook-consumer.js +87 -0
  56. package/src/functions/affiliates/affiliates-hook-producer.js +45 -0
  57. package/src/functions/clients/clients-audience.js +62 -0
  58. package/src/functions/clients/clients-consumer.js +648 -0
  59. package/src/functions/clients/clients-producer.js +362 -0
  60. package/src/functions/clients/clients-suggested-product-consumer.js +166 -0
  61. package/src/functions/clients/helpers/suggested-product-mdlz.js +233 -0
  62. package/src/functions/clients_peru/email.html +129 -0
  63. package/src/functions/clients_peru/splitfile.js +357 -0
  64. package/src/functions/clients_peru/updateClients.js +1334 -0
  65. package/src/functions/clients_peru/utils.js +243 -0
  66. package/src/functions/cronjobs/cron-jobs-manager.js +40 -0
  67. package/src/functions/cronjobs/cron-jobs.js +171 -0
  68. package/src/functions/crons/cron.js +39 -0
  69. package/src/functions/distributors/distributor-handler.js +81 -0
  70. package/src/functions/distributors/distributor.js +535 -0
  71. package/src/functions/distributors/index.js +60 -0
  72. package/src/functions/financialpolicy/assign-financialpolicy.js +111 -0
  73. package/src/functions/financialpolicy/get-financialpolicy.js +91 -0
  74. package/src/functions/financialpolicy/index.js +28 -0
  75. package/src/functions/inventory/catalog-sync-consumer.js +17 -0
  76. package/src/functions/inventory/catalog-sync-handler.js +311 -0
  77. package/src/functions/inventory/inventory-consumer.js +119 -0
  78. package/src/functions/inventory/inventory-producer.js +197 -0
  79. package/src/functions/multiPresentation/multipre-queue.js +155 -0
  80. package/src/functions/multiPresentation/multipres.js +459 -0
  81. package/src/functions/nodeflow/index.js +83 -0
  82. package/src/functions/nodeflow/nodeflow-cron.js +200 -0
  83. package/src/functions/nodeflow/nodeflow-pub.js +203 -0
  84. package/src/functions/nodeflow/nodeflow-pvt.js +266 -0
  85. package/src/functions/notifications/download-leads-handler.js +67 -0
  86. package/src/functions/notifications/new-leads-notification-consumer.js +17 -0
  87. package/src/functions/notifications/new-leads-notification-handler.js +359 -0
  88. package/src/functions/notifications/order-status-notification-handler.js +482 -0
  89. package/src/functions/notifications/promotion-notification-handler.js +193 -0
  90. package/src/functions/orders/index.js +32 -0
  91. package/src/functions/orders/orders-cancel-handler.js +74 -0
  92. package/src/functions/orders/orders-handler.js +280 -0
  93. package/src/functions/orders/orders-hook-consumer.js +137 -0
  94. package/src/functions/orders/orders-hook-producer.js +170 -0
  95. package/src/functions/orders/orders-notifications-handler.js +137 -0
  96. package/src/functions/orders/orders-status-consumer.js +461 -0
  97. package/src/functions/orders/orders-status-producer.js +443 -0
  98. package/src/functions/prices/index.js +75 -0
  99. package/src/functions/prices/prices-consumer.js +236 -0
  100. package/src/functions/prices/prices-producer.js +323 -0
  101. package/src/functions/prices/promotion-and-tax.js +1284 -0
  102. package/src/functions/routesflow/assign-routeflow-queue.js +77 -0
  103. package/src/functions/schemas/vtex/handle-schemas.js +102 -0
  104. package/src/functions/security/process_gas.js +221 -0
  105. package/src/functions/security/security-handler.js +950 -0
  106. package/src/functions/sftp/sftp-consumer.js +453 -0
  107. package/src/functions/sftpIntegrations/processes/redirectServices.js +184 -0
  108. package/src/functions/sftpIntegrations/processes/validateFileSchema.js +226 -0
  109. package/src/functions/sftpIntegrations/schemas/credential-schema.js +123 -0
  110. package/src/functions/sftpIntegrations/schemas/record-schema.js +131 -0
  111. package/src/functions/sftpIntegrations/schemas/sftp_required_fields.json +3 -0
  112. package/src/functions/sftpIntegrations/sftp-config-producer.js +112 -0
  113. package/src/functions/sftpIntegrations/sftp-consumer.js +700 -0
  114. package/src/functions/sftpIntegrations/test/validateFile.test.js +122 -0
  115. package/src/functions/sftpIntegrations/utils/connect-dynamo.js +29 -0
  116. package/src/functions/sftpIntegrations/utils/split-data.js +25 -0
  117. package/src/functions/utils/index.js +130 -0
  118. package/src/functions/vtex/vtex-helpers.js +694 -0
  119. package/src/integrations/accountErrors/AccountErrorManager.js +437 -0
  120. package/src/integrations/audience/Audience.js +70 -0
  121. package/src/integrations/financialPolicy/FinancialPolicyApi.js +377 -0
  122. package/src/integrations/index.js +0 -0
  123. package/src/integrations/mobilvendor/MobilvendorApi.js +405 -0
  124. package/src/integrations/productmultipresentation/ProductMultiPresentation.js +200 -0
  125. package/src/mdlz/auth/SecretManagerApi.js +77 -0
  126. package/src/mdlz/client/MdlzApi.js +70 -0
  127. package/src/vtex/clients/ProvidersApi.js +51 -0
  128. package/src/vtex/clients/VtexApi.js +511 -0
  129. 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,15 @@
1
+
2
+ const inventoryItemsCSVToJson = (dataCSV) => {
3
+
4
+ const mondelezInventoryItem = {
5
+ sku: dataCSV.sku,
6
+ quantity: Number(dataCSV.quantity)
7
+ };
8
+ return mondelezInventoryItem;
9
+
10
+ };
11
+
12
+ module.exports = {
13
+ inventoryItemsCSVToJson,
14
+ };
15
+
@@ -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
+ };