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,459 @@
1
+ const VtexApi = require('../../vtex/clients/VtexApi');
2
+ const ApiResponse = require("../../common/utils/api-response");
3
+ const AWSServices = require("../../common/utils/aws-services");
4
+ const ClientData = require("../../entities/clients");
5
+ const Logger = require("../../common/utils/logger");
6
+ const SQS_MULTIPRE_PRODUCT_QUEUE_URL = process.env.SQS_MULTIPRE_PRODUCT_QUEUE_URL;
7
+
8
+ /**
9
+ * Método para habilitar e inhabilitar presentaciones de producto.
10
+ *
11
+ * @param {object} account - Configuraciones de la cuenta de VTEX.
12
+ * @param {string} skuIdS - ID del SKU de VTEX.
13
+ * @param {object} dataExternal - Objeto con información externa del producto.
14
+ * @param {string} TradePolicyId - ID de la política comercial (opcional).
15
+ * @returns {Promise<boolean>} - Promesa que resuelve con un booleano que indica el éxito de la operación.
16
+ **/
17
+ const setPresentationsSellers = async (account, skuIdS, dataExternal, TradePolicyId = null) => {
18
+ if (!account?.ProductMultiPresentation || !account?.ProductMultiPresentation?.isActive) {
19
+ Logger.error("El proceso de presentación de productos no está habilitado.");
20
+ return false;
21
+ }
22
+
23
+ const accountName = account.AccountName;
24
+ const ParentAccountName = account.ParentAccountName;
25
+
26
+ try {
27
+ if (account?.ProductMultiPresentation?.WhiteListProductId?.length > 0 && !account?.ProductMultiPresentation?.WhiteListProductId?.includes(dataExternal?.productId)) {
28
+ // producto restingido por lista blanca
29
+ Logger.error('producto restingido por lista blanca:', dataExternal);
30
+ return false;
31
+ }
32
+
33
+ const products = await getProductBySkuId(ParentAccountName, account.Credentials.key, account.Credentials.token, skuIdS, TradePolicyId);
34
+
35
+ if (products.length > 0) {
36
+
37
+ for (let p = 0; p < products.length; p++) {
38
+ const product = products[p];
39
+ const rejectedSkus = [];
40
+ const availablePresentations = [];
41
+
42
+ for (const skuinfo of product.items) {
43
+ const item = skuinfo;
44
+ if (item && item?.isKit === true && item?.kitItems?.length === 1 && item?.itemId == skuIdS) {
45
+ const amountItem = item?.kitItems[0]?.amount ?? 1;
46
+ // Verificar si el producto está en la lista negra (WL_BlackList)
47
+ try {
48
+ const fieldBL = account?.ProductMultiPresentation?.WL_BlackList ?? "WL_BlackList";
49
+ const WL_BlackList = product[fieldBL] && product[fieldBL].length > 0 ? product[fieldBL][0] : null;
50
+ const BlackListCharacterSeparate = account?.ProductMultiPresentation?.BlackListCharacterSeparate ?? ";";
51
+ const BlackListCharacterType = account?.ProductMultiPresentation?.BlackListCharacterType ?? "@";
52
+
53
+ if (WL_BlackList) {
54
+
55
+ const listSkuInactive = WL_BlackList.split(BlackListCharacterSeparate);
56
+ for (var i = 0; i < listSkuInactive.length; i++) {
57
+ const whiteLabelData = listSkuInactive[i].split(BlackListCharacterType);
58
+
59
+ if (whiteLabelData.length == 2) {
60
+ const whiteLabel = whiteLabelData[0];
61
+ const skuIdInactive = whiteLabelData[1];
62
+ const itemBKL = product.items.find(i => (i.itemId == skuIdInactive && i.isKit === true));
63
+
64
+ if (itemBKL && !rejectedSkus?.find(i => i.itemId == itemBKL.itemId) && whiteLabel == account?.AccountName) {
65
+ rejectedSkus.push(itemBKL);
66
+ }
67
+
68
+ } else {
69
+ Logger.error('No se encontró contenido después de @');
70
+ }
71
+ }
72
+ } else {
73
+ Logger.error('No se encontró la propiedad WL_BlackList');
74
+ }
75
+ } catch (e_bkl) {
76
+ Logger.error("error en restriccion blacklist", e_bkl)
77
+ }
78
+
79
+ // Obtener el multiplicador de unidades desde "Unidades por display"
80
+ const unitDefaultValue = account?.ProductMultiPresentation?.UnitDefaultValue ?? 1;
81
+ const unitFormat = account?.ProductMultiPresentation?.UnitFormat && product[account?.ProductMultiPresentation?.UnitFormat] ? product[account?.ProductMultiPresentation?.UnitFormat][0] : unitDefaultValue;
82
+ const unitMultiplier = account?.ProductMultiPresentation?.UnitMultiplier ? item[account?.ProductMultiPresentation?.UnitMultiplier] : item?.unitMultiplier;
83
+
84
+ const multiplierFormat = parseInt(unitMultiplier, 10) * parseInt(unitFormat, 10) * parseInt(amountItem);
85
+ const exactUnit = account?.ProductMultiPresentation?.ExactUnit ?? false;
86
+ const fomulaPresentacion = account?.ProductMultiPresentation?.Formula ?? null;;
87
+ const isValidMultiple = !rejectedSkus?.find(i => i.itemId == item.itemId) ? validateMultiple(multiplierFormat, dataExternal, exactUnit, fomulaPresentacion) : false;
88
+
89
+ const valuesConsole = {
90
+ unitDefaultValue,
91
+ unitFormat,
92
+ unitMultiplier,
93
+ multiplierFormat,
94
+ exactUnit,
95
+ fomulaPresentacion,
96
+ isValidMultiple
97
+ };
98
+
99
+ if (!isValidMultiple && !rejectedSkus?.find(i => i.itemId == item.itemId) && item.isKit === true) {
100
+ rejectedSkus.push(item);
101
+ } else if (!availablePresentations?.find(i => i.itemId == item.itemId) && item.isKit === true) {
102
+ let tmpItem = item;
103
+ tmpItem.amount = amountItem;
104
+ availablePresentations.push(tmpItem);
105
+ }
106
+ }
107
+ }
108
+
109
+ const getItemComponent = product?.items?.filter(it => (it?.isKit === true));
110
+ const SkuIdMain = getItemComponent[0] && getItemComponent[0]?.kitItems?.length === 1 ? getItemComponent[0]?.kitItems[0]?.itemId : null;
111
+
112
+ if (SkuIdMain) {
113
+ const mainPrice = await getSellerPrice(
114
+ accountName,
115
+ account.Credentials.key,
116
+ account.Credentials.token,
117
+ SkuIdMain
118
+ );
119
+
120
+ if (mainPrice) {
121
+ for (const SkuId of availablePresentations) {
122
+ await updatePriceByProduct(accountName,
123
+ account.Credentials.key,
124
+ account.Credentials.token,
125
+ SkuId.itemId,
126
+ mainPrice,
127
+ (SkuId?.amount ?? 1)
128
+ );
129
+ }
130
+ for (const skuId of rejectedSkus) {
131
+ await deletePriceByProductRejected(accountName, account.Credentials.key, account.Credentials.token, skuId.itemId);
132
+ }
133
+ }
134
+
135
+ return true;
136
+ } else {
137
+ Logger.error('skuId main not found');
138
+ return false;
139
+ }
140
+ }
141
+ } else {
142
+ Logger.error('No se encontraron items en el producto:', skuIdS);
143
+ return false;
144
+ }
145
+
146
+ } catch (error) {
147
+ Logger.error('Error al obtener el producto:', error);
148
+ throw error;
149
+ }
150
+ };
151
+
152
+ //////////////////// ALL GET FUNCTIONS ////////////////////
153
+ /**
154
+ * Obtiene la información detallada de un producto por su productId utilizando la API de VTEX.
155
+ *
156
+ * @param {string} accountName - Nombre de la cuenta de VTEX.
157
+ * @param {string} key - Clave de la aplicación.
158
+ * @param {string} token - Token de la aplicación.
159
+ * @param {string} productId - ID del producto.
160
+ * @param {string} TradePolicyId - ID de la política comercial (opcional).
161
+ * @returns {Promise<Object[]>} - Promesa que resuelve con un array de objetos que representan los productos.
162
+ * @throws {Error} - Si ocurre un error al obtener el producto.
163
+ */
164
+ async function getProductByProductId(accountName, key, token, productId, TradePolicyId = null) {
165
+ try {
166
+ const vtexApi = new VtexApi(accountName, key, token);
167
+ const url = `/catalog_system/pub/products/search/?fq=productId:${productId}${(!TradePolicyId ? "" : `&sc=${TradePolicyId}`)}`;
168
+ const result = await vtexApi.fetch(url, { method: 'GET' });
169
+ //Verificar si la respuesta fue exitosa
170
+ if (result.status >= 200 && result.status < 300) {
171
+ // La respuesta fue exitosa
172
+ if (result.data && result.data.length > 0) {
173
+ return result.data;
174
+ } else {
175
+ Logger.error(`Error al obtener el producto: , ${productId}, Status: ${result.status}`);
176
+ return [];
177
+ }
178
+ } else {
179
+ // La respuesta no fue exitosa
180
+ Logger.error(`Error al obtener el producto: , ${productId}, Status: ${result.status}`);
181
+ return [];
182
+ }
183
+ } catch (error) {
184
+ Logger.error('Error al obtener el producto');
185
+ return [];
186
+ }
187
+ }
188
+
189
+ /**
190
+ * Obtiene la información detallada de un producto por su SKU ID utilizando la API de VTEX.
191
+ *
192
+ * @param {string} accountName - Nombre de la cuenta de VTEX.
193
+ * @param {string} key - Clave de la aplicación.
194
+ * @param {string} token - Token de la aplicación.
195
+ * @param {string} skuId - ID del SKU.
196
+ * @param {string} TradePolicyId - ID de la política comercial (opcional).
197
+ * @returns {Promise<Object[]>} - Promesa que resuelve con un array de objetos que representan los productos.
198
+ * @throws {Error} - Si ocurre un error al obtener el producto.
199
+ */
200
+ async function getProductBySkuId(accountName, key, token, skuId, TradePolicyId = null) {
201
+ try {
202
+ const vtexApi = new VtexApi(accountName, key, token);
203
+ const url = `/catalog_system/pub/products/search/?fq=skuId:${skuId}${(!TradePolicyId && TradePolicyId > 1 ? "" : `&sc=${TradePolicyId}`)}`;
204
+ const result = await vtexApi.fetch(url, { method: 'GET' });
205
+ //Verificar si la respuesta fue exitosa
206
+ if (result.status >= 200 && result.status < 300) {
207
+ // La respuesta fue exitosa
208
+ if (result.data && result.data.length > 0) {
209
+ return result.data;
210
+ } else {
211
+ Logger.error(`Error al obtener el producto: , ${skuId}, Status: ${result.status}`);
212
+ return [];
213
+ }
214
+ } else {
215
+ // La respuesta no fue exitosa
216
+ Logger.error(`Error al obtener el producto: , ${skuId}, Status: ${result.status}`);
217
+ return [];
218
+ }
219
+ } catch (error) {
220
+ Logger.error('Error al obtener el producto');
221
+ return [];
222
+ }
223
+ }
224
+
225
+ /**
226
+ * Obtiene el precio del vendedor para un SKU ID utilizando la API de VTEX.
227
+ *
228
+ * @param {string} accountName - Nombre de la cuenta de VTEX.
229
+ * @param {string} key - Clave de la aplicación.
230
+ * @param {string} token - Token de la aplicación.
231
+ * @param {string} skuId - ID del SKU.
232
+ * @returns {Promise<number>} - Promesa que resuelve con el precio del vendedor.
233
+ * @throws {Error} - Si ocurre un error al obtener el precio del vendedor.
234
+ */
235
+ async function getSellerPrice(accountName, appKey, appToken, skuId) {
236
+ const url = `/pricing/prices/${skuId}`;
237
+
238
+ try {
239
+ const vtexApi = new VtexApi(accountName, appKey, appToken);
240
+ const response = await vtexApi.fetchApiURL(url, { method: 'GET' });
241
+ const priceData = response.data;
242
+ // Formatear la respuesta
243
+ const formattedPriceData = {
244
+ listPrice: priceData?.listPrice,
245
+ costPrice: priceData?.costPrice,
246
+ basePrice: priceData?.basePrice,
247
+ fixedPrices: priceData?.fixedPrices ?? []
248
+ };
249
+
250
+ return formattedPriceData;
251
+ } catch (error) {
252
+ Logger.error('Error al obtener el precio del vendedor', error);
253
+ return null;
254
+ }
255
+ }
256
+
257
+ /**
258
+ * Obtiene todos los skuIds asociados a un productId utilizando la API de VTEX.
259
+ *
260
+ * @param {string} accountName - Nombre de la cuenta de VTEX.
261
+ * @param {string} appKey - Clave de la aplicación.
262
+ * @param {string} appToken - Token de la aplicación.
263
+ * @param {string} productId - ID del producto.
264
+ * @returns {Promise<string[]>} - Promesa que resuelve con un arreglo de skuIds.
265
+ * @throws {Error} - Si ocurre un error al obtener los skuIds.
266
+ */
267
+ async function getSkuIds(accountName, appKey, appToken, productId) {
268
+ const url = `/catalog_system/pub/products/variations/${productId}`;
269
+
270
+ try {
271
+ const vtexApi = new VtexApi(accountName, appKey, appToken);
272
+ const response = await vtexApi.fetch(url, { method: 'GET' });
273
+ const product = response.data;
274
+
275
+ const skuIds = product.skus.map(sku => ({
276
+ sku: sku.sku,
277
+ skuname: sku.skuname,
278
+ sellerId: sku.sellerId,
279
+ unitMultiplier: sku.unitMultiplier
280
+ }));
281
+
282
+ return skuIds;
283
+ } catch (error) {
284
+ Logger.error('Error al obtener los skuIds');
285
+ return [];
286
+ }
287
+ }
288
+
289
+ //////////////////// UPDATE AND DELETE PRICES ////////////////////
290
+
291
+ /**
292
+ * Elimina el precio de un producto rechazado por su SKU ID utilizando la API de VTEX.
293
+ *
294
+ * @param {string} accountName - Nombre de la cuenta de VTEX.
295
+ * @param {string} key - Clave de la aplicación.
296
+ * @param {string} token - Token de la aplicación.
297
+ * @param {string} skuId - ID del SKU.
298
+ * @returns {Promise<Object>} - Promesa que resuelve con el objeto de respuesta de la API.
299
+ * @throws {Error} - Si ocurre un error al eliminar el precio.
300
+ */
301
+ async function deletePriceByProductRejected(accountName, appKey, appToken, skuId) {
302
+ try {
303
+ const vtexApi = new VtexApi(accountName, appKey, appToken);
304
+ const url = `/pricing/prices/${skuId}`;
305
+ await vtexApi.fetchApiURL(url, { method: 'DELETE' });
306
+
307
+ return true;
308
+ } catch (error) {
309
+ Logger.error('Error al eliminar el precio:', error);
310
+ return false;
311
+ }
312
+ }
313
+
314
+ /**
315
+ * Actualiza el precio de un producto por su SKU ID utilizando la API de VTEX.
316
+ *
317
+ * @param {string} accountName - Nombre de la cuenta de VTEX.
318
+ * @param {string} key - Clave de la aplicación.
319
+ * @param {string} token - Token de la aplicación.
320
+ * @param {string} skuId - ID del SKU.
321
+ * @param {number} newPrice - Nuevo precio del producto.
322
+ * @returns {Promise<Object>} - Promesa que resuelve con el objeto de respuesta de la API.
323
+ * @throws {Error} - Si ocurre un error al actualizar el precio.
324
+ */
325
+ async function updatePriceByProduct(accountName, appKey, appToken, skuId, pricesData, amount) {
326
+ try {
327
+ pricesData.listPrice = pricesData?.listPrice ? (parseFloat(pricesData?.listPrice) * parseFloat(amount)) : null;
328
+ pricesData.costPrice = pricesData?.costPrice ? (parseFloat(pricesData?.costPrice) * parseFloat(amount)) : null;
329
+ pricesData.basePrice = pricesData?.basePrice ? (parseFloat(pricesData?.basePrice) * parseFloat(amount)) : null;
330
+ pricesData.fixedPrices = pricesData?.fixedPrices?.length > 0 ? formatFixesPrice(pricesData?.fixedPrices, amount) : [];
331
+
332
+ const vtexApi = new VtexApi(accountName, appKey, appToken);
333
+ const url = `/pricing/prices/${skuId}`;
334
+ const response = await vtexApi.fetchApiURL(url, {
335
+ method: 'PUT',
336
+ data: pricesData
337
+ });
338
+
339
+ return response.data;
340
+ } catch (error) {
341
+ Logger.error('Error al actualizar el precio:', error);
342
+ return false;
343
+ }
344
+ }
345
+
346
+ /**
347
+ * Set prices fixed
348
+ **/
349
+ const formatFixesPrice = (fixedPrices, amount) => {
350
+
351
+ for (let i = 0; i < fixedPrices.length; i++) {
352
+ fixedPrices[i].value = (parseFloat(fixedPrices[i].value) * parseFloat(amount));
353
+
354
+ if (fixedPrices[i]?.listPrice) {
355
+ fixedPrices[i].listPrice = (parseFloat(fixedPrices[i].listPrice) * parseFloat(amount));
356
+ }
357
+ }
358
+
359
+ return fixedPrices;
360
+ }
361
+
362
+ /**
363
+ * Valida si un múltiplo es válido basándose en la cantidad de unidades.
364
+ *
365
+ * @param {number} multiplierFormat - Formato del múltiplo.
366
+ * @param {object} dataExternal - Información externa del producto.
367
+ * @param {boolean} exactUnit - Si se debe validar unidades exactas.
368
+ * @returns {boolean} - True si el múltiplo es válido, false en caso contrario.
369
+ */
370
+ function validateMultiple(unitMultiplier, dataExternal, exactUnit = false, fomulaPresentacion = null) {
371
+ if (dataExternal?.isActive === false || dataExternal?.isActive == 0 || dataExternal?.isActive == '0') {
372
+ return false;
373
+ } else if (exactUnit === true && dataExternal?.boxUnit) {
374
+ if (fomulaPresentacion && fomulaPresentacion != '') {
375
+ let resValid = false;
376
+ try {
377
+ // response only boolean
378
+ eval(`resValid=${fomulaPresentacion}`);
379
+ } catch (err) {
380
+ Logger.error('Error formula', err);
381
+ }
382
+ return resValid;
383
+ } else {
384
+ return parseFloat(unitMultiplier) === parseFloat(dataExternal?.boxUnit) ? true : false;
385
+ }
386
+ } else if (dataExternal?.boxUnit) {
387
+ if (fomulaPresentacion && fomulaPresentacion != '') {
388
+ let resValid = false;
389
+ try {
390
+ // response only boolean
391
+ eval(`resValid=${fomulaPresentacion}`);
392
+ } catch (err) {
393
+ Logger.error('Error formula', err);
394
+ }
395
+ return resValid;
396
+ } else {
397
+ return parseFloat(unitMultiplier) % parseFloat(dataExternal?.boxUnit) == 0;
398
+ }
399
+ } else {
400
+ return false;
401
+ }
402
+ }
403
+
404
+ const handleExecute = async (accountName) => {
405
+ await AWSServices.sendSQSMessage(SQS_MULTIPRE_PRODUCT_QUEUE_URL, { accountName: accountName });
406
+ }
407
+
408
+ /**
409
+ * Función para iniciar el proceso manual de multi presentación.
410
+ *
411
+ * @param {object} event - Evento recibido que contiene la información necesaria para procesar la solicitud.
412
+ * @param {object} event.requestContext - Contexto de la solicitud que incluye información del autor.
413
+ * @param {object} event.requestContext.authorizer - Autor de la solicitud.
414
+ * @param {object} event.requestContext.authorizer.claims - Reclamaciones del autor.
415
+ * @param {string} event.requestContext.authorizer.claims.client_id - ID del cliente.
416
+ * @param {string} event.requestContext.authorizer.claims.scope - Alcance de la solicitud.
417
+ * @param {object} event.pathParameters - Parámetros de la ruta.
418
+ * @param {string} event.pathParameters.accountName - Nombre de la cuenta.
419
+ * @returns {Promise<object>} - Promesa que resuelve con un objeto de respuesta de la API.
420
+ *
421
+ **/
422
+ const producer = async (event) => {
423
+ let statusCode = 200;
424
+ let message;
425
+
426
+ try {
427
+ const clientId = event?.requestContext?.authorizer?.claims?.client_id;
428
+ const scope = event?.requestContext?.authorizer?.claims?.scope;
429
+ const accountName = event?.pathParameters?.accountName ?? null;
430
+
431
+ if (!accountName) {
432
+ return errorResponse(404, "AccountName not found");
433
+ }
434
+ if (!scope.includes("admin")) {
435
+ const validateAccount = await ClientData.validateAccount(clientId, accountName);
436
+ if (!validateAccount) {
437
+ Logger.error("Account not found: ", accountName, ". ClientId: ", clientId);
438
+ return ApiResponse.response(404, "Account not found");
439
+ }
440
+ }
441
+
442
+ // Se ejecuta el proceso de insertar en la cola SQS los datos del proceso de Multipresentation a ejecutar
443
+ await handleExecute(accountName);
444
+
445
+ message = "Message accepted!";
446
+
447
+ } catch (error) {
448
+ Logger.error("Error clients producer: ", error);
449
+ statusCode = 500;
450
+ }
451
+
452
+ return ApiResponse.response(statusCode, message);
453
+ };
454
+
455
+ module.exports = {
456
+ setPresentationsSellers,
457
+ handleExecute,
458
+ producer
459
+ };
@@ -0,0 +1,83 @@
1
+
2
+ const ApiResponse = require("../../common/utils/api-response");
3
+ const nodeFlowPrivate = require("./nodeflow-pvt");
4
+ const nodeFlowPublic = require("./nodeflow-pub");
5
+
6
+ module.exports.handler= async (req,res)=>{
7
+ const resource= req?.resource ?? null;
8
+ const method= req?.httpMethod ? String(req?.httpMethod).toUpperCase() : null;
9
+
10
+ if(resource && method){
11
+ switch(resource){
12
+ case "/pvt/nodeflow/settings":
13
+ switch(method){
14
+ case "GET":
15
+ return await nodeFlowPrivate?.getSettings(req,res);
16
+ case "PATCH":
17
+ return await nodeFlowPrivate?.createSettings(req,res);
18
+ default:
19
+ return ApiResponse.response(400, {error: "error method!."});
20
+ }
21
+ break;
22
+ case "/pvt/nodeflow/actionstype":
23
+ switch(method){
24
+ case "GET":
25
+ return await nodeFlowPrivate?.getActionsType(req,res);
26
+ case "PATCH":
27
+ return await nodeFlowPrivate?.createActionsType(req,res);
28
+ default:
29
+ return ApiResponse.response(400, {error: "error method!."});
30
+ }
31
+ break;
32
+ case "/pvt/nodeflow/create":
33
+ switch(method){
34
+ case "PATCH":
35
+ return await nodeFlowPrivate?.createNodeFlow(req,res);
36
+ default:
37
+ return ApiResponse.response(400, {error: "error method!."});
38
+ }
39
+ break;
40
+ case "/pvt/nodeflow/tree/{sources_id}":
41
+ switch(method){
42
+ case "GET":
43
+ return await nodeFlowPrivate?.treeNodeFlow(req,res);
44
+ default:
45
+ return ApiResponse.response(400, {error: "error method!."});
46
+ }
47
+ break;
48
+ case "/pvt/nodeflow/sources":
49
+ switch(method){
50
+ case "GET":
51
+ return await nodeFlowPrivate?.getSources(req,res);
52
+ case "PATCH":
53
+ return await nodeFlowPrivate?.createSources(req,res);
54
+ case "DELETE":
55
+ return await nodeFlowPrivate?.deleteSources(req,res);
56
+ default:
57
+ return ApiResponse.response(400, {error: "error method!."});
58
+ }
59
+ break;
60
+ // routes publics
61
+ case "/pub/nodeflow/{sourceName}":
62
+ switch(method){
63
+ case "POST":
64
+ return await nodeFlowPublic?.handler(req,res);
65
+ default:
66
+ return ApiResponse.response(400, {error: "error method!."});
67
+ }
68
+ break;
69
+ case "/pub/sqs/nodeflow/{sourceName}":
70
+ switch(method){
71
+ case "POST":
72
+ return await nodeFlowPublic?.handlerSqs(req,res);
73
+ default:
74
+ return ApiResponse.response(400, {error: "error method!."});
75
+ }
76
+ break;
77
+ default:
78
+ return ApiResponse.response(400, {error: "error resource!."});
79
+ }
80
+ }else{
81
+ return ApiResponse.response(400, {error: "error resource!."});
82
+ }
83
+ }