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,202 @@
1
+ const fs = require('fs');
2
+
3
+ const { FtpFileSystem, SftpFileSystem, FileSystem } = require('./ftp-sftp');
4
+ const Logger = require('./logger');
5
+
6
+ /**
7
+ * Permite establecer una conexión a un servidor FTP.
8
+ * @param {Object} settings Parámetros de conexión.
9
+ * @param {string} settings.type Tipo de conexión ('ftp' o 'sftp').
10
+ * @param {string} settings.host Dirección IP o dominio del servidor FTP.
11
+ * @param {string} settings.port Número de puerto.
12
+ * @param {string} settings.user Nombre del usuario FTP.
13
+ * @param {string} settings.password Contraseña del usuario FTP
14
+ * @returns {Promise<FileSystem>} Instancia de conexión al servidor FTP.
15
+ */
16
+ module.exports.connectToFtp = settings => {
17
+ return new Promise((resolve, reject) => {
18
+ let { type = 'ftp', host, port = '21', username, user = username, password } = settings;
19
+ switch (type) {
20
+ case 'ftp':
21
+ Logger.info(`Connecting to ${user}@${host} using ${type}`);
22
+ FtpFileSystem.create(host, port, user, password).then(connection => {
23
+ // Eventos al cerrar la conexión
24
+ connection.client.on('end', () => {
25
+ Logger.debug('Connection ended ' + host);
26
+ });
27
+ connection.client.on('close', () => {
28
+ Logger.debug('Connection closed ' + host);
29
+ });
30
+ resolve(connection);
31
+ }).catch(reject);
32
+ break;
33
+ case 'sftp':
34
+ Logger.info(`Connecting to ${user}@${host} using ${type}`);
35
+ SftpFileSystem.create(host, port, user, password).then(connection => {
36
+ // Eventos al cerrar la conexión
37
+ connection.client.on('end', () => {
38
+ Logger.debug('Connection ended ' + host);
39
+ });
40
+ connection.client.on('close', () => {
41
+ Logger.debug('Connection closed ' + host);
42
+ });
43
+ resolve(connection);
44
+ }).catch(reject);
45
+ break;
46
+ default:
47
+ reject(new Error(`Value type '${type || ''}' isn't valid`));
48
+ }
49
+ });
50
+ }
51
+
52
+ /**
53
+ * Obtiene la lista de archivos existentes en la carpeta.
54
+ * @param {FileSystem} clientFTP Instancia de conexión al servidor FTP.
55
+ * @param {string} filesFolderPath Carpeta donde se buscan los archivos.
56
+ * @param {function} callbackFilter Expresión regular del archivo a obtener.
57
+ * @returns Lista de archivos asociados a la consulta.
58
+ */
59
+ module.exports.getFilesInFolder = async (clientFTP, filesFolderPath, callbackFilter = null) => {
60
+ return new Promise((resolve, reject) => {
61
+ Logger.debug(`Finding files into folder: ${filesFolderPath}`);
62
+ clientFTP.list(filesFolderPath).then(list => {
63
+ if (callbackFilter) {
64
+ resolve(list.filter(callbackFilter));
65
+ } else {
66
+ resolve(list);
67
+ }
68
+ }).catch(reject);
69
+ });
70
+ };
71
+
72
+ /**
73
+ * Obtiene el contenido de un archivo del ftp.
74
+ * @param {FileSystem} clientFTP Instancia de conexión al servidor FTP.
75
+ * @param {string} filePath Ruta del archivo a leer.
76
+ * @returns Contenido del archivo.
77
+ */
78
+ module.exports.getFileContent = async (clientFTP, filePath) => {
79
+ return new Promise((resolve, reject) => {
80
+ // Obtener el contenido del archivo indicado
81
+ Logger.debug(`Reading file: ${filePath}`);
82
+ clientFTP.get(filePath).then(stream => {
83
+ // Se extrae el contenido del archivo
84
+ let content = '';
85
+ stream.on('data', function (chunk) {
86
+ content += chunk.toString();
87
+ });
88
+ stream.on('end', function () {
89
+ resolve(content);
90
+ });
91
+ }).catch(reject);
92
+ });
93
+ };
94
+
95
+ /**
96
+ * Mueve el archivo procesado a una determinada carpeta
97
+ * @param {FileSystem} clientFTP Instancia de conexión al servidor FTP.
98
+ * @param {string} filePath Directorio del archivo que se va a mover
99
+ * @param {string} targetFolder Carpeta donde se moverán los archivos procesados
100
+ * @param {string} newFileName Nombre a asignar del archivo movido a 'targetFolder'.
101
+ * @returns
102
+ */
103
+ module.exports.moveProcessedFile = (clientFTP, filePath, targetFolder, newFileName) => {
104
+ return new Promise((resolve, reject) => {
105
+ // Creación de la carpeta donde se almacenarán los archivos divididos
106
+ this.createFolder(clientFTP, targetFolder).then(() => {
107
+ newFileName = targetFolder + '/' + newFileName;
108
+ Logger.debug(`Moving file '${newFileName}' to folder '${targetFolder}'`);
109
+ clientFTP.rename(filePath, newFileName).then(() => {
110
+ resolve(newFileName);
111
+ }).catch(reject)
112
+ }).catch(reject);
113
+ });
114
+ };
115
+
116
+ /**
117
+ * Crea un nuevo directorio en el servidor FTP.
118
+ * @param {FileSystem} clientFTP Instancia de conexión al servidor FTP.
119
+ * @param {string} folderPath Ruta de la carpeta a crear
120
+ * @returns
121
+ */
122
+ module.exports.createFolder = (clientFTP, folderPath) => {
123
+ return new Promise((resolve, reject) => {
124
+ Logger.debug(`Creating folder: ${folderPath}`);
125
+ clientFTP.mkdir(folderPath, true).then(() => {
126
+ resolve(folderPath);
127
+ }).catch(ex => {
128
+ if (ex.code == 4) {
129
+ resolve(folderPath);
130
+ } else {
131
+ reject(new Error(ex?.message ?? 'Error in createFolder'));
132
+ }
133
+ });
134
+ });
135
+ }
136
+
137
+ /**
138
+ * Descarga un archivo del servidor FTP/SFTP a un directorio local.
139
+ * @param {FileSystem} clientFTP Instancia de conexión al servidor FTP.
140
+ * @param {string} remotePath Directorio del archivo del servidor FTP/SFTP a descargar.
141
+ * @param {string} localPath Directorio del archivo en local donde se descargará el archivo.
142
+ * @param {string} type Valor que indica si el servidor es 'ftp' o 'sftp'.
143
+ * @returns
144
+ */
145
+ module.exports.downloadFile = async (clientFTP, remotePath, localPath, type = 'ftp') => {
146
+ return new Promise((resolve, reject) => {
147
+ switch (type) {
148
+ case 'ftp':
149
+ clientFTP.client.get(remotePath, (err, stream) => {
150
+ if (err) {
151
+ reject(err)
152
+ } else {
153
+ stream.once('close', function () {
154
+ resolve(true);
155
+ });
156
+ stream.pipe(fs.createWriteStream(localPath));
157
+ }
158
+ });
159
+ break;
160
+ case 'sftp':
161
+ clientFTP.client.get(remotePath, localPath).then(() => {
162
+ resolve(true);
163
+ }).catch(reject);
164
+ break;
165
+ default:
166
+ reject(new Error(`Type ${type} is not valid`));
167
+ break;
168
+ }
169
+ });
170
+ }
171
+
172
+ /**
173
+ * Sube un archivo de un directorio local a un servidor FTP/SFTP.
174
+ * @param {FileSystem} clientFTP Instancia de conexión al servidor FTP.
175
+ * @param {string} localPath Directorio del archivo en local a subir.
176
+ * @param {string} remotePath Directorio del archivo del servidor FTP/SFTP a donde se subirá el archivo.
177
+ * @param {string} type Valor que indica si el servidor es 'ftp' o 'sftp'.
178
+ * @returns
179
+ */
180
+ module.exports.uploadFile = async (clientFTP, localPath, remotePath, type = 'ftp') => {
181
+ return new Promise((resolve, reject) => {
182
+ switch (type) {
183
+ case 'ftp':
184
+ clientFTP.client.put(localPath, remotePath, err => {
185
+ if (err) {
186
+ reject(err);
187
+ } else {
188
+ resolve(true);
189
+ }
190
+ });
191
+ break;
192
+ case 'sftp':
193
+ clientFTP.client.fastPut(localPath, remotePath).then(() => {
194
+ resolve(true);
195
+ }).catch(reject);
196
+ break;
197
+ default:
198
+ reject(new Error(`Type ${type} is not valid`));
199
+ break;
200
+ }
201
+ });
202
+ }
@@ -0,0 +1,15 @@
1
+ class Status {
2
+
3
+ static PAYMENT_PENDING = "payment-pending";
4
+ static PAYMENT_APPROVED = "payment-approved";
5
+ static INVOICED = "invoiced";
6
+ static HANDLING = "handling";
7
+ static READY_FOR_HANDLING = "ready-for-handling";
8
+ static WAITING_FFMTT_AUTHORIZATION = "waiting-ffmt-authorization";
9
+ static CANCEL = "cancel";
10
+ static CANCELED = "canceled";
11
+
12
+ }
13
+
14
+ module.exports = Status;
15
+
@@ -0,0 +1,236 @@
1
+ const { AxiosError } = require("axios");
2
+ const Logger = require("./logger");
3
+
4
+ /**
5
+ *
6
+ * @param {receive price product} price
7
+ * @param {receive amount round price decimal} roundUpDecimalPrice
8
+ *
9
+ * @returns
10
+ */
11
+
12
+ const roundPrice = (price, roundUpDecimalPrice) => {
13
+ const { roundUpAmountDecimal = 2, typeRounded = 'default' } = roundUpDecimalPrice;
14
+
15
+ // Factor para determinar los decimales
16
+ const factor = Math.pow(10, roundUpAmountDecimal);
17
+ const scaledPrice = price * factor;
18
+
19
+ switch (typeRounded) {
20
+ case 'up':
21
+ // Redondear siempre hacia arriba y mantener los decimales
22
+ return Math.ceil(scaledPrice) / factor;
23
+
24
+ case 'down':
25
+ // Redondear siempre hacia abajo y mantener los decimales
26
+ return Math.floor(scaledPrice) / factor;
27
+
28
+ default:
29
+ // Redondeo normal al valor más cercano y mantener los decimales
30
+ return Math.round(scaledPrice) / factor;
31
+ }
32
+ };
33
+
34
+ /**
35
+ *
36
+ * @param {Specify seconds delay time to process} time
37
+ * @returns
38
+ */
39
+ function delayToProcess(time) {
40
+ if (!time || time < 1) {
41
+ return true;
42
+ }
43
+ return new Promise((resolve, reject) => {
44
+ setTimeout(function () {
45
+ resolve(true);
46
+ }, (time * 1000));
47
+ })
48
+ };
49
+
50
+ /**
51
+ *
52
+ * @param {Specify a decimal value to rounded.} decimalValue
53
+ * @returns A value rounded to two decimals
54
+ */
55
+ function convertDecimal(decimalValue) {
56
+ const value = Math.round((parseFloat(decimalValue) + Number.EPSILON) * 100) / 100;
57
+ return value;
58
+ };
59
+
60
+ /**
61
+ *
62
+ * @param {*} str
63
+ * @param {*} quantityDecimal
64
+ * @returns
65
+ */
66
+ function transformStringToDecimal(str, quantityDecimal) {
67
+ if (str.length < quantityDecimal) {
68
+ Logger.error('Decimal format incorrect: ', str);
69
+ return '0.0';
70
+ }
71
+ let newValue = str.substring(0, str.length - 2) + '.' + str.substring(str.length - 2, str.length);
72
+ return newValue;
73
+ };
74
+
75
+ const breakString = (str, limit) => {
76
+ let brokenString = '';
77
+ for (let i = 0, count = 0; i < str.length; i++) {
78
+ if (count >= limit && str[i] === ' ') {
79
+ count = 0;
80
+ brokenString += '\n';
81
+ } else {
82
+ count++;
83
+ brokenString += str[i];
84
+ }
85
+ }
86
+ return brokenString;
87
+ }
88
+
89
+ /**
90
+ * @param {Specify date value to check}
91
+ */
92
+ function validateDate(date) {
93
+ const regex = /^\d{14}$/; // Expresión regular para validar que la cadena tenga exactamente 14 dígitos
94
+ return regex.test(date);
95
+ }
96
+
97
+ function getDateFromString(str) {
98
+ const year = parseInt(str.substring(0, 4));
99
+ const month = parseInt(str.substring(4, 6));
100
+ const day = parseInt(str.substring(6, 8));
101
+ const hora = parseInt(str.substring(8, 10));
102
+ const minute = parseInt(str.substring(10, 12));
103
+ const second = parseInt(str.substring(12, 14));
104
+ return new Date(year, month - 1, day, hora, minute, second);
105
+ }
106
+
107
+ const convertChar = (str) => {
108
+ return str.replace("<", "&lt;")
109
+ .replace(">", "&gt;")
110
+ .replace("&", "&amp;")
111
+ .replace('"', "&quot;")
112
+ .replace("'", "&apos;");
113
+ };
114
+
115
+ function stringDateVtexToDate(date) {
116
+ let dateValue = date;
117
+ try {
118
+ dateValue = new Date(date).toISOString();
119
+ } catch (error) {
120
+ Logger.error(error);
121
+ }
122
+ return dateValue;
123
+ }
124
+
125
+ const validateEmail = (email) => {
126
+ return String(email)
127
+ .toLowerCase()
128
+ .match(
129
+ /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|.(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
130
+ );
131
+ };
132
+
133
+ const validatePhone = (phone) => { // /[a-zA-Z0-9 ÑñÁÉÍÓÚáéíóú-]/
134
+ const formatPhone = /^[0-9-]+$/;
135
+ return formatPhone.test(phone)
136
+ }
137
+
138
+ const validateID = (id) => {
139
+ const formatId = /^[a-zA-Z0-9Ññ-]+$/;
140
+ return formatId.test(id)
141
+ }
142
+
143
+ const getErrorData = ex => {
144
+ let error = { message: '', status: 500, info: {} };
145
+ if (ex instanceof AxiosError) {
146
+ const { request = {}, response = {} } = ex;
147
+ const { path, method, host } = request;
148
+ const { status = 500, statusText = '', data = null } = response;
149
+
150
+ let message;
151
+ if (data?.Message) {
152
+ message = data.Message;
153
+ } else if (data) {
154
+ switch (Object.prototype.toString.call(data)) {
155
+ case '[object String]':
156
+ message = data;
157
+ break;
158
+ case '[object Object]':
159
+ message = JSON.stringify(data);
160
+ break;
161
+ }
162
+ } else if (statusText) {
163
+ message = statusText;
164
+ } else {
165
+ Logger.error(ex);
166
+ message = 'Error in Axios request';
167
+ }
168
+
169
+ error.status = status;
170
+ error.message = message;
171
+ error.info = { status, data, message, request: { path, method, host } };
172
+ } else {
173
+ const { message } = ex;
174
+ error.message = message;
175
+ error.info = { message };
176
+ }
177
+ return error;
178
+ }
179
+
180
+ /**
181
+ * Genera los valores basados en una determinada fecha para utilizarse en
182
+ * el nombre de archivos y/o carpetas.
183
+ * @param {Date} currentDate Fecha de la cual se extrae la información
184
+ * @returns Valores generados a partir de la fecha.
185
+ */
186
+ const getDateValues = (currentDate = new Date()) => {
187
+ let year = currentDate.getFullYear(),
188
+ month = String(currentDate.getMonth() + 1).padStart(2, '0'),
189
+ day = String(currentDate.getDate()).padStart(2, '0'),
190
+ hour = String(currentDate.getHours()).padStart(2, '0'),
191
+ minute = String(currentDate.getMinutes()).padStart(2, '0'),
192
+ second = String(currentDate.getSeconds()).padStart(2, '0');
193
+
194
+ return {
195
+ // Marca de tiempo de la fecha y hora actual.
196
+ 'timestamp': year + month + day + hour + minute + second,
197
+ // Marca de tiempo de la fecha actual.
198
+ 'timestampMin': year + month + day,
199
+ // Subcarpeta donde se moveran los archivos grandes que ya fueron divididos
200
+ 'processedSubfolder': `${year}/${month}`
201
+ };
202
+ };
203
+
204
+ const setQueryParams = (url, queryParams) => {
205
+ let queryText = ''
206
+ for (let key in queryParams) {
207
+ if (queryText) {
208
+ queryText += '&'
209
+ }
210
+ queryText += `${key}=${queryParams[key]}`
211
+ }
212
+
213
+ if (queryText) {
214
+ queryText = '?' + queryText
215
+ }
216
+
217
+ return url + queryText
218
+ }
219
+
220
+ module.exports = {
221
+ delayToProcess: delayToProcess,
222
+ convertDecimal: convertDecimal,
223
+ transformStringToDecimal: transformStringToDecimal,
224
+ breakString: breakString,
225
+ convertChar: convertChar,
226
+ validateDate: validateDate,
227
+ getDateFromString: getDateFromString,
228
+ stringDateVtexToDate: stringDateVtexToDate,
229
+ validateEmail: validateEmail,
230
+ validatePhone: validatePhone,
231
+ validateID: validateID,
232
+ getErrorData,
233
+ getDateValues,
234
+ setQueryParams,
235
+ roundPrice
236
+ }
@@ -0,0 +1,35 @@
1
+ const Logger = require("./logger");
2
+
3
+ const isStateInNotificationProviders = ( data = {} ) => {
4
+ const isActive = data?.isActiveNotifications === true ? true : false
5
+ if(isActive){
6
+ const isEmptyProviders = data?.notificationProviders.length === 0 ? true : false
7
+ if(isEmptyProviders){
8
+ Logger.error('NOTIFICATIONS Providers is empty')
9
+ return false
10
+ }
11
+ const isState = isStateInStatusProvider({
12
+ notificationProviders: data?.notificationProviders,
13
+ stateOrder: data?.stateOrder
14
+ })
15
+ return isState
16
+ }
17
+ return isActive
18
+ }
19
+
20
+ const isStateInStatusProvider = ( data = {} ) => {
21
+ const { notificationProviders, stateOrder } = data
22
+ let isStateFound = false;
23
+ notificationProviders.forEach(element => {
24
+ if(element.Status.hasOwnProperty(stateOrder)){
25
+ Logger.debug('STATE is Status Provider:', stateOrder)
26
+ isStateFound = true
27
+ }
28
+ });
29
+
30
+ return isStateFound
31
+ }
32
+
33
+ module.exports = {
34
+ isStateInNotificationProviders
35
+ }
@@ -0,0 +1,67 @@
1
+ const Logger = require("./logger");
2
+
3
+ /**
4
+ * Method to validate that an object contains at least one property
5
+ * @param object -- returns true if the object contains at least one property
6
+ **/
7
+ const isObjectNotEmpty = (object) => {
8
+ return Object.keys(object).length > 0
9
+ }
10
+
11
+ /**
12
+ * Method to validate a valid url
13
+ * @param url -- returns true if the url is valid or false if the url is invalid
14
+ **/
15
+ const validateURL = (url) => {
16
+ try {
17
+ new URL(url)
18
+ return url
19
+ } catch (error) {
20
+ Logger.error("URL invalid")
21
+ return false
22
+ }
23
+ }
24
+
25
+ /**
26
+ * Method to validate if the value of a property of an object is of type string and it contains an object inside the string.
27
+ * @param item -- object with assigned properties
28
+ * @param property -- name of the property to be converted or sanitized to make it a valid readable format
29
+ **/
30
+ const processStringOrObject = (item, property, order, client) => {
31
+ if (property in item) {
32
+ try {
33
+ return typeof item[property] === "string"
34
+ ? eval(`(${item[property]})`)
35
+ : item[property];
36
+ } catch (error) {
37
+ Logger.error(`Error evaluando '${property}' en '${item}':`, error);
38
+ }
39
+ }
40
+ return {};
41
+ }
42
+
43
+ /**
44
+ * Method to evaluate a condition, logic or methods, in string format as a parameter
45
+ * @param condition -- logic javascript that must be processing
46
+ * @param order --
47
+ **/
48
+
49
+ function evaluateCondition(condition, order, client) {
50
+ try {
51
+ let result = null
52
+ eval(`result=${condition}`);
53
+ return typeof result === 'boolean' ? result : false;
54
+ } catch (error) {
55
+ Logger.error('Error evaluating condition:', error.message);
56
+ return false;
57
+ }
58
+ }
59
+
60
+
61
+
62
+ module.exports = {
63
+ isObjectNotEmpty,
64
+ validateURL,
65
+ processStringOrObject,
66
+ evaluateCondition
67
+ }
@@ -0,0 +1,45 @@
1
+ const Logger = require("./logger");
2
+
3
+ const validateRequiredParam = (name, evaluate) => {
4
+ if (!evaluate) {
5
+ Logger.error(`${name} is required`);
6
+ return false;
7
+ }
8
+ };
9
+
10
+ const transformFirstKeysToUpperCaseValue = (originalObject) => {
11
+ const newObj = {};
12
+ for (const key in originalObject) {
13
+ const newKey = key.charAt(0).toUpperCase() + key.slice(1);
14
+ newObj[newKey] = originalObject[key];
15
+ }
16
+ return newObj;
17
+ };
18
+
19
+ const transformKeysToUpperCaseValue = (originalObject) => {
20
+ const newObj = {};
21
+ for (const key in originalObject) {
22
+ const newKey = key.charAt(0).toUpperCase() + key.slice(1);
23
+ newObj[newKey] =
24
+ typeof originalObject[key] === "object"
25
+ ? transformKeysToUpperCaseValue(originalObject[key])
26
+ : originalObject[key];
27
+ }
28
+ return newObj;
29
+ };
30
+
31
+ const transformFirstKeysToLowerCaseValue = (originalObject) => {
32
+ const newObj = {};
33
+ for (const key in originalObject) {
34
+ const newKey = key.charAt(0).toLowerCase() + key.slice(1);
35
+ newObj[newKey] = originalObject[key];
36
+ }
37
+ return newObj;
38
+ };
39
+
40
+ module.exports = {
41
+ validateRequiredParam,
42
+ transformKeysToUpperCaseValue,
43
+ transformFirstKeysToUpperCaseValue,
44
+ transformFirstKeysToLowerCaseValue
45
+ };
@@ -0,0 +1,65 @@
1
+ const VtexApi = require("../../../vtex/clients/VtexApi");
2
+ const Logger = require("../logger");
3
+
4
+ const handlePostOperation = async (vtexApi, url, data) => {
5
+ const options = {
6
+ method: 'POST',
7
+ data,
8
+ };
9
+ const response = await vtexApi.fetch(url, options);
10
+ if ((response?.status >= 200 && response?.status < 400) || !response) {
11
+ return {
12
+ status: 200,
13
+ message: "Record created/updated successfully",
14
+ };
15
+ }
16
+ Logger.error("Failed PUT operation", response);
17
+ throw new Error("Failed POST operation");
18
+ };
19
+
20
+ const handleDeleteOperation = async (vtexApi, url) => {
21
+ const options = {
22
+ method: 'DELETE',
23
+ };
24
+ const response = await vtexApi.fetch(url, options);
25
+
26
+ if ((response?.status >= 200 && response?.status < 400) || !response) {
27
+ return {
28
+ status: 200,
29
+ message: "Record deleted successfully",
30
+ };
31
+ }
32
+ Logger.error("Failed DELETE operation", response);
33
+ throw new Error("Failed DELETE operation");
34
+ };
35
+
36
+ const handleHookVtexMD2 = async ({ id, data, origin, httpMethod }) => {
37
+ if (!id || !origin) {
38
+ Logger.error("Missing required parameters (id or origin).");
39
+ throw new Error("Missing required parameters (id or origin).");
40
+ }
41
+ const { AccountName, AppKey, AppToken } = origin;
42
+ if (!AccountName || !AppKey || !AppToken) {
43
+ Logger.error("Incomplete 'origin' object.");
44
+ throw new Error("Incomplete 'origin' object.");
45
+ }
46
+ const vtexApi = new VtexApi(AccountName, AppKey, AppToken);
47
+ const url = `/orders/hook/config/`;
48
+ try {
49
+ switch (httpMethod) {
50
+ case 'POST':
51
+ return await handlePostOperation(vtexApi, url, data);
52
+ case 'DELETE':
53
+ return await handleDeleteOperation(vtexApi, url);
54
+ default:
55
+ return { status: 405, message: `Method ${httpMethod} not allowed to VTEX` };
56
+ }
57
+ } catch (error) {
58
+ Logger.error(`Error during operation ${httpMethod}:`, error.message);
59
+ throw error;
60
+ }
61
+ };
62
+
63
+ module.exports = {
64
+ handleHookVtexMD2,
65
+ };