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,453 @@
1
+ "use strict";
2
+ const AWS = require("aws-sdk");
3
+ const s3 = new AWS.S3();
4
+ const MdlzApi = require("../../mdlz/client/MdlzApi");
5
+ const AuthSecurity = require("../../common/utils/AuthSecurity");
6
+ const MondelezClientsItemsCast = require("../../common/utils/convert/MondelezClientsItemsCast");
7
+ const MondelezInventoryItemsCast = require("../../common/utils/convert/MondelezInventoryItemsCast");
8
+ const MondelezPricesItemsCast = require("../../common/utils/convert/MondelezPricesItemsCast");
9
+ const MondelezOrderStatusItemsCast = require("../../common/utils/convert/MondelezOrderStatusCast");
10
+ const SftpInbound = require("../../entities/sftp-inbound");
11
+ const Constants = require("../../common/utils/constants");
12
+ const AWSServices = require("../../common/utils/aws-services");
13
+ const path = require("path");
14
+ const csv = require("csv-parser");
15
+ const Logger = require("../../common/utils/logger");
16
+
17
+ const MAX_ITEMS_PROCESS_INVENTORY = process.env.MAX_ITEMS_PROCESS_INVENTORY;
18
+ const MAX_ITEMS_PROCESS_PRICES = process.env.MAX_ITEMS_PROCESS_PRICES;
19
+ const MAX_ITEMS_PROCESS_CLIENTS = process.env.MAX_ITEMS_PROCESS_CLIENTS;
20
+ let AUTHORIZATION_MANAGER_KEY = process.env.AUTHORIZATION_MANAGER_KEY;
21
+
22
+ module.exports.sftp = async (event) => {
23
+ Logger.debug("sftp-payload-request: ", event.Records);
24
+
25
+ for (const record of event.Records) {
26
+ const bucket = record.s3.bucket.name; //DO FOR EACH RECORD
27
+ const key = record.s3.object.key;
28
+ const inProcessKey = key
29
+ .replace(Constants.SFTP_STATUS_PENDING, Constants.SFTP_STATUS_IN_PROCESS)
30
+ .replace(Constants.SFTP_CSV_FILE_TYPE, Constants.SFTP_TXT_FILE_TYPE);
31
+ const newKey = key
32
+ .replace(Constants.SFTP_STATUS_PENDING, Constants.SFTP_STATUS_PROCESSED)
33
+ .replace(
34
+ Constants.SFTP_CSV_FILE_TYPE,
35
+ new Date().toISOString().slice(0, 19).replace(/-/g, "").replace("T", "").replace(/:/g, "")
36
+ )
37
+ .concat(Constants.SFTP_TXT_FILE_TYPE);
38
+ const logDirectory = newKey
39
+ .replace(Constants.SFTP_STATUS_PROCESSED, Constants.SFTP_LOG)
40
+ .replace(Constants.SFTP_TXT_FILE_TYPE, Constants.SFTP_LOG_FILE_TYPE);
41
+ var logData = [];
42
+
43
+ try {
44
+ const params = {
45
+ Bucket: bucket,
46
+ Key: key,
47
+ };
48
+
49
+ const inProcessParams = {
50
+ Bucket: bucket,
51
+ Key: `${inProcessKey}`,
52
+ CopySource: `${bucket}/${key}`,
53
+ ContentType: "application/json; charset=utf-8",
54
+ };
55
+ if (key.includes(Constants.SFTP_STATUS_PENDING)) {
56
+ const pathDirectory = path.dirname(key);
57
+ const sftpConfig = await SftpInbound.getItemsByDirectory(pathDirectory);
58
+ const data = await s3.getObject(params).promise();
59
+ await s3.copyObject(inProcessParams).promise();
60
+ await s3.deleteObject(params).promise();
61
+
62
+ if (!sftpConfig) {
63
+ const errorSftpMessage = "SFTP config not found: directory= " + key + ". ProcessExecute = not found";
64
+ Logger.error(errorSftpMessage);
65
+ logData.push(new Date().toISOString() + " - ERROR - " + errorSftpMessage);
66
+ throw new Error(errorSftpMessage);
67
+ } else if (sftpConfig.length > 1) {
68
+ const errorSftpMessage =
69
+ "SFTP config duplicated: directory= " + key + ". ProcessExecute = " + sftpConfig[0].processExecute;
70
+ Logger.error("Duplicated error: " + errorSftpMessage, ". All SFTP config: ", sftpConfig);
71
+ logData.push(new Date().toISOString() + " - ERROR - " + errorSftpMessage);
72
+ throw new Error(errorSftpMessage);
73
+ }
74
+ const csvData = data.Body.toString("utf-8");
75
+ if (!AUTHORIZATION_MANAGER_KEY) {
76
+ const errorAuthSftpMessage = "SFTP profile authorization not found";
77
+ Logger.error(errorAuthSftpMessage);
78
+ logData.push(new Date().toISOString() + " - ERROR - " + errorAuthSftpMessage);
79
+ return;
80
+ }
81
+
82
+ let authSecret = await AWSServices.getSecretValue(AUTHORIZATION_MANAGER_KEY);
83
+
84
+ authSecret = JSON.parse(authSecret);
85
+
86
+ const APP_KEY_HEADER = authSecret?.appKey;
87
+ const APP_TOKEN_HEADER = authSecret?.appSecret;
88
+ const SCOPE_ADMIN_HEADER = authSecret?.scope;
89
+ const GRANT_TYPE_HEADER = authSecret?.grantType;
90
+
91
+ if (!APP_KEY_HEADER || !APP_TOKEN_HEADER || !SCOPE_ADMIN_HEADER || !GRANT_TYPE_HEADER) {
92
+ Logger.error({
93
+ "SFTP master profile authorization params not found: appKey= ":
94
+ APP_KEY_HEADER,
95
+ ". appSecret = ":
96
+ APP_TOKEN_HEADER,
97
+ ". scope = ":
98
+ SCOPE_ADMIN_HEADER,
99
+ ". grantType = ":
100
+ GRANT_TYPE_HEADER
101
+ });
102
+ logData.push(new Date().toISOString() + " - ERROR - SFTP master profile authorization params not found.\n");
103
+ return;
104
+ }
105
+
106
+ const parsedData = await parseCSV(csvData);
107
+ const apiAuthSecurity = new AuthSecurity(
108
+ APP_KEY_HEADER,
109
+ APP_TOKEN_HEADER,
110
+ GRANT_TYPE_HEADER,
111
+ SCOPE_ADMIN_HEADER
112
+ );
113
+ const responseAuth = await apiAuthSecurity.fetchAuthToken("", {
114
+ method: "POST",
115
+ });
116
+
117
+ if (responseAuth.status >= 200 && responseAuth.status < 300) {
118
+ const { AccountName, ProcessExecute } = sftpConfig[0];
119
+ const { access_token } = responseAuth?.data;
120
+ const apiMdlzClient = new MdlzApi(`Bearer ${access_token}`, GRANT_TYPE_HEADER, SCOPE_ADMIN_HEADER);
121
+ if (ProcessExecute === Constants.SFTP_PROCESS_STATUS) {
122
+ if (parsedData) {
123
+ for (let item of parsedData) {
124
+ const orderId = item.orderId;
125
+ const dataStatusCasted = MondelezOrderStatusItemsCast.orderStatusItemsCSVToJson(item);
126
+ const responseMdlz = await apiMdlzClient.fetch(`orders/status/${orderId}`, {
127
+ method: "POST",
128
+ data: dataStatusCasted,
129
+ });
130
+ if (responseMdlz.status >= 200 && responseMdlz.status < 300) {
131
+ const successMdlzMessage =
132
+ "Process order status was successfully: " +
133
+ orderId +
134
+ ". Response: " +
135
+ JSON.stringify(responseMdlz.data);
136
+ logData.push(new Date().toISOString() + " - INFO - " + successMdlzMessage);
137
+ } else {
138
+ const errorMdlzMessage =
139
+ "Error while requesting MDLZ order status for: " +
140
+ orderId +
141
+ ". With body: " +
142
+ JSON.stringify(dataStatusCasted) +
143
+ ". Status: " +
144
+ responseMdlz.status +
145
+ ". Response: " +
146
+ JSON.stringify(responseMdlz.data);
147
+ Logger.error(errorMdlzMessage);
148
+ logData.push(new Date().toISOString() + " - ERROR - " + errorMdlzMessage);
149
+ }
150
+ }
151
+ }
152
+ } else if (ProcessExecute === Constants.SFTP_PROCESS_CANCEL) {
153
+ if (parsedData) {
154
+ for (let item of parsedData) {
155
+ const orderId = item.orderId;
156
+ const responseMdlz = await apiMdlzClient.fetch(`orders/cancel/${orderId}`, {
157
+ method: "POST",
158
+ });
159
+ if (responseMdlz.status >= 200 && responseMdlz.status < 300) {
160
+ const successMdlzMessage =
161
+ "Process order cancel was successfully: " +
162
+ orderId +
163
+ ". Response: " +
164
+ JSON.stringify(responseMdlz.data);
165
+ logData.push(new Date().toISOString() + " - INFO - " + successMdlzMessage);
166
+ } else {
167
+ const errorMdlzMessage =
168
+ "Error while requesting MDLZ order cancel for: " +
169
+ orderId +
170
+ ". Status: " +
171
+ responseMdlz.status +
172
+ ". Response: " +
173
+ JSON.stringify(responseMdlz.data);
174
+ Logger.error(errorMdlzMessage);
175
+ logData.push(new Date().toISOString() + " - ERROR - " + errorMdlzMessage);
176
+ }
177
+ }
178
+ }
179
+ } else if (ProcessExecute === Constants.SFTP_PROCESS_INVENTORY) {
180
+ if (parsedData) {
181
+ let warehouse = "";
182
+ if (sftpConfig[0]?.Warehouse) {
183
+ warehouse = sftpConfig[0].Warehouse;
184
+ }
185
+ let hasCount = parsedData.length > MAX_ITEMS_PROCESS_INVENTORY;
186
+ let count = 1;
187
+ let dataToSend = [];
188
+ let dataProcessed = [];
189
+ for (let item of parsedData) {
190
+ let itemInventoryCasted = MondelezInventoryItemsCast.inventoryItemsCSVToJson(item);
191
+ dataProcessed.push(itemInventoryCasted);
192
+ if (hasCount) {
193
+ count += 1;
194
+ }
195
+ if (hasCount && count >= MAX_ITEMS_PROCESS_INVENTORY) {
196
+ dataToSend.push(dataProcessed);
197
+ dataProcessed = [];
198
+ count = 0;
199
+ }
200
+ }
201
+ if (dataProcessed.length > 0) {
202
+ dataToSend.push(dataProcessed);
203
+ }
204
+ for (let dataInventory of dataToSend) {
205
+ const dataInventoryValues = {
206
+ an: AccountName,
207
+ warehouse: warehouse,
208
+ inventory: dataInventory,
209
+ };
210
+ const responseMdlz = await apiMdlzClient.fetch("inventory", {
211
+ method: "POST",
212
+ data: dataInventoryValues,
213
+ });
214
+ if (responseMdlz.status >= 200 && responseMdlz.status < 300) {
215
+ const successMdlzMessage =
216
+ "Process inventory was successfully. " +
217
+ ". Status: " +
218
+ responseMdlz.status +
219
+ ". Response: " +
220
+ JSON.stringify(responseMdlz.data);
221
+ logData.push(new Date().toISOString() + " - INFO - " + successMdlzMessage);
222
+ } else {
223
+ const errorMdlzMessage =
224
+ "Error while requesting MDLZ inventory for: " +
225
+ JSON.stringify(dataInventoryValues) +
226
+ ". Status: " +
227
+ responseMdlz.status +
228
+ ". Response: " +
229
+ JSON.stringify(responseMdlz.data);
230
+ Logger.error(errorMdlzMessage);
231
+ logData.push(new Date().toISOString() + " - ERROR - " + errorMdlzMessage);
232
+ }
233
+ }
234
+ }
235
+ } else if (ProcessExecute === Constants.SFTP_PROCESS_PRICES) {
236
+ if (parsedData) {
237
+ let hasCount = parsedData.length > MAX_ITEMS_PROCESS_PRICES;
238
+ let count = 1;
239
+ let dataToSend = [];
240
+ let dataProcessed = [];
241
+ for (let item of parsedData) {
242
+ let itemPricesCasted = MondelezPricesItemsCast.pricesItemsCSVToJson(item);
243
+ dataProcessed.push(itemPricesCasted);
244
+ if (hasCount) {
245
+ count += 1;
246
+ }
247
+ if (hasCount && count >= MAX_ITEMS_PROCESS_PRICES) {
248
+ dataToSend.push(dataProcessed);
249
+ dataProcessed = [];
250
+ count = 0;
251
+ }
252
+ }
253
+ if (dataProcessed.length > 0) {
254
+ dataToSend.push(dataProcessed);
255
+ }
256
+ for (let dataPrices of dataToSend) {
257
+ const dataPricesValues = {
258
+ an: AccountName,
259
+ prices: dataPrices,
260
+ };
261
+ const responseMdlz = await apiMdlzClient.fetch("prices", {
262
+ method: "POST",
263
+ data: dataPricesValues,
264
+ });
265
+ if (responseMdlz.status >= 200 && responseMdlz.status < 300) {
266
+ const successMdlzMessage =
267
+ "Process prices was successfully. " +
268
+ ". Status: " +
269
+ responseMdlz.status +
270
+ ". Response: " +
271
+ JSON.stringify(responseMdlz.data);
272
+ logData.push(new Date().toISOString() + " - INFO - " + successMdlzMessage);
273
+ } else {
274
+ const errorMdlzMessage =
275
+ "Error while requesting MDLZ prices for: " +
276
+ JSON.stringify(dataPricesValues) +
277
+ ". Status: " +
278
+ responseMdlz.status +
279
+ ". Response: " +
280
+ JSON.stringify(responseMdlz.data);
281
+ Logger.error(errorMdlzMessage);
282
+ logData.push(new Date().toISOString() + " - ERROR - " + errorMdlzMessage);
283
+ }
284
+ }
285
+ }
286
+ } else if (ProcessExecute === Constants.SFTP_PROCESS_CLIENTS) {
287
+ if (parsedData) {
288
+ let hasCount = parsedData.length > MAX_ITEMS_PROCESS_CLIENTS;
289
+ let count = 1;
290
+ let dataToSend = [];
291
+ let dataProcessed = [];
292
+ for (let item of parsedData) {
293
+ let itemClientCasted = MondelezClientsItemsCast.clientsItemsCSVToJson(item);
294
+ dataProcessed.push(itemClientCasted);
295
+ if (hasCount) {
296
+ count += 1;
297
+ }
298
+ if (hasCount && count >= MAX_ITEMS_PROCESS_CLIENTS) {
299
+ dataToSend.push(dataProcessed);
300
+ dataProcessed = [];
301
+ count = 0;
302
+ }
303
+ }
304
+ if (dataProcessed.length > 0) {
305
+ dataToSend.push(dataProcessed);
306
+ }
307
+ for (let dataClients of dataToSend) {
308
+ const dataClientsValues = {
309
+ an: AccountName,
310
+ clients: dataClients,
311
+ };
312
+ const responseMdlz = await apiMdlzClient.fetch("clients", {
313
+ method: "POST",
314
+ data: dataClientsValues,
315
+ });
316
+ if (responseMdlz.status >= 200 && responseMdlz.status < 300) {
317
+ const successMdlzMessage =
318
+ "Process clients was successfully. " +
319
+ ". Status: " +
320
+ responseMdlz.status +
321
+ ". Response: " +
322
+ JSON.stringify(responseMdlz.data);
323
+ logData.push(new Date().toISOString() + " - INFO - " + successMdlzMessage);
324
+ } else {
325
+ const errorMdlzMessage =
326
+ "Error while requesting MDLZ clients for: " +
327
+ JSON.stringify(dataClientsValues) +
328
+ ". Status: " +
329
+ responseMdlz.status +
330
+ ". Response: " +
331
+ JSON.stringify(responseMdlz.data);
332
+ Logger.error(errorMdlzMessage);
333
+ logData.push(new Date().toISOString() + " - ERROR - " + errorMdlzMessage);
334
+ }
335
+ }
336
+ }
337
+ } else {
338
+ const errorProcessMessage = "Process not found: " + ProcessExecute + ". Check the process configs.";
339
+ Logger.error(errorProcessMessage);
340
+ logData.push(new Date().toISOString() + " - ERROR - " + errorProcessMessage);
341
+ }
342
+ } else {
343
+ Logger.error("Error while requesting authorization");
344
+ logData.push(new Date().toISOString() + " - ERROR - " + "Error while requesting authorization.");
345
+ }
346
+ }
347
+ } catch (error) {
348
+ Logger.error("Error process data: ", error);
349
+ logData.push(new Date().toISOString() + " - ERROR - " + error);
350
+ } finally {
351
+ const params = {
352
+ Bucket: bucket,
353
+ Key: inProcessKey,
354
+ };
355
+ const newParams = {
356
+ Bucket: bucket,
357
+ Key: `${newKey}`,
358
+ CopySource: `${bucket}/${inProcessKey}`,
359
+ ContentType: "application/json; charset=utf-8",
360
+ };
361
+ let logAllData = "";
362
+ for (let line of logData) {
363
+ logAllData += line + "\n";
364
+ }
365
+ const logParams = {
366
+ Bucket: bucket,
367
+ Key: logDirectory,
368
+ Body: logAllData,
369
+ };
370
+ try {
371
+ await s3.copyObject(newParams).promise();
372
+ await s3.deleteObject(params).promise();
373
+ await s3.putObject(logParams).promise();
374
+ } catch (error) {
375
+ Logger.error("Error while copying and deleting object. ", error);
376
+ }
377
+ }
378
+ }
379
+ };
380
+
381
+ function parseCSV(csvData) {
382
+ let isEvalOnFirst = false;
383
+ let fixedPricesProperty = "";
384
+ let changesItemsRemovedProperty = "";
385
+ return new Promise((resolve, reject) => {
386
+ const results = [];
387
+ const stream = csv({ header: true, separator: ";" })
388
+ .on("data", (data) => {
389
+ if (data) {
390
+ if (!isEvalOnFirst) {
391
+ fixedPricesProperty = Object.keys(data).find((key) => key.startsWith("fixedPrices"));
392
+ changesItemsRemovedProperty = Object.keys(data).find((key) => key.startsWith("changesItemsRemoved"));
393
+ isEvalOnFirst = true;
394
+ }
395
+ if (fixedPricesProperty) {
396
+ // Convert the field "fixedPrices" in an array of objects
397
+ const fixedPricesValue = data[fixedPricesProperty];
398
+ const fixedPricesArray = fixedPricesValue
399
+ .split("|")
400
+ .filter(Boolean)
401
+ .map((item) => {
402
+ let [listId, value, listPrice, minQuantity, dateRangeFrom, dateRangeTo] = item.split(",");
403
+ // if some of the values listId, value, listPrice, minQuantity, dateRangeFrom, dateRangeTo are empty, set them to null
404
+ listId = listId || null;
405
+ value = value || null;
406
+ listPrice = listPrice || null;
407
+ minQuantity = minQuantity || null;
408
+ dateRangeFrom = dateRangeFrom || null;
409
+ dateRangeTo = dateRangeTo || null;
410
+ return {
411
+ listId,
412
+ value,
413
+ listPrice,
414
+ minQuantity,
415
+ dateRangeFrom,
416
+ dateRangeTo,
417
+ };
418
+ });
419
+ // Replace the field "fixedPrices" with the new array of objects
420
+ data.fixedPrices = fixedPricesArray;
421
+ delete data[fixedPricesProperty];
422
+ }
423
+ if (changesItemsRemovedProperty) {
424
+ // Convert the field "changesItemsRemoved" in an array of objects
425
+ const changesItemsRemovedValue = data[changesItemsRemovedProperty];
426
+ const changesItemsRemovedArray = changesItemsRemovedValue
427
+ .split("|")
428
+ .filter(Boolean)
429
+ .map((item) => {
430
+ let [changesItemsRemovedSku, changesItemsRemovedPrice, changesItemsRemovedQuantity] = item.split(",");
431
+ // if some of the values changesItemsRemovedSku, changesItemsRemovedPrice, changesItemsRemovedQuantity are empty, set them to null
432
+ changesItemsRemovedSku = changesItemsRemovedSku || null;
433
+ changesItemsRemovedPrice = changesItemsRemovedPrice || null;
434
+ changesItemsRemovedQuantity = changesItemsRemovedQuantity || null;
435
+ return {
436
+ changesItemsRemovedSku,
437
+ changesItemsRemovedPrice,
438
+ changesItemsRemovedQuantity,
439
+ };
440
+ });
441
+ // Replace the field "changesItemsRemoved" with the new array of objects
442
+ data.changesItemsRemoved = changesItemsRemovedArray;
443
+ delete data[changesItemsRemovedProperty];
444
+ }
445
+ results.push(data);
446
+ }
447
+ })
448
+ .on("end", () => resolve(results))
449
+ .on("error", (error) => reject(error));
450
+ stream.write(csvData);
451
+ stream.end();
452
+ });
453
+ }
@@ -0,0 +1,184 @@
1
+ const { producer: producerPrices } = require('../../prices/prices-producer.js');
2
+ const { producer: producerInventory } = require('../../inventory/inventory-producer.js');
3
+ const { producer: producerClients } = require('../../clients/clients-producer.js');
4
+ const { cancel: orderCancel } = require('../../orders/orders-cancel-handler.js');
5
+ const { splitData } = require('../utils/split-data.js')
6
+
7
+ const Logger = require("../../../common/utils/logger");
8
+
9
+ class ServicesRedirect {
10
+ constructor(accountConfig) {
11
+ this.config = accountConfig;
12
+ const { AccountName = '' } = this.config;
13
+ }
14
+
15
+ async initSendData({ typeProcess, data }) {
16
+ try {
17
+ switch (typeProcess) {
18
+ case 'clients':
19
+ return await this.sendDataClients(data)
20
+ case 'price':
21
+ return await this.sendDataPrices(data)
22
+ case 'stock':
23
+ return await this.sendDataStock(data)
24
+ case 'order-status':
25
+ return await this.sendDataOrderStatus(data)
26
+ case 'order-cancel':
27
+ return await this.sendDataOrderCancel(data)
28
+ default:
29
+ throw new Error(`Unsupported typeProcess: ${typeProcess}`)
30
+ }
31
+ } catch (error) {
32
+ Logger.error('Error in initSendData:', error.message)
33
+ throw error
34
+ }
35
+ }
36
+
37
+ async sendDataClients(data) {
38
+ if (!data) return false
39
+
40
+ try {
41
+ const event = {
42
+ internalService: true,
43
+ accountData: this.config,
44
+ body: JSON.stringify({
45
+ an: this.config?.AccountName,
46
+ clients: [data],
47
+ })
48
+ }
49
+ const response = await producerClients(event);
50
+
51
+ if (response.statusCode >= 200 && response.statusCode < 300) {
52
+ return true;
53
+ } else {
54
+ Logger.error('Failed to send data via producer:', response);
55
+ return false;
56
+ }
57
+
58
+ } catch (error) {
59
+ Logger.error('Error in sendDataPrices:', error);
60
+ return false;
61
+ }
62
+ }
63
+
64
+ async sendDataPrices(data) {
65
+ if (!data) return false
66
+
67
+ try {
68
+
69
+ const event = {
70
+ internalService: true,
71
+ accountData: this.config,
72
+ body: JSON.stringify({
73
+ an: this.config?.AccountName,
74
+ prices: [data],
75
+ })
76
+ }
77
+ const response = await producerPrices(event);
78
+
79
+ if (response.statusCode >= 200 && response.statusCode < 300) {
80
+ return true;
81
+ } else {
82
+ Logger.error('Failed to send data via producer:', response);
83
+ return false;
84
+ }
85
+
86
+ } catch (error) {
87
+ Logger.error('Error in sendDataPrices:', error);
88
+ return false;
89
+ }
90
+
91
+ }
92
+
93
+ async sendDataStock(data) {
94
+ if (!data) return false
95
+
96
+ try {
97
+ const warehouse = data?.warehouse ?? null
98
+ delete data?.warehouse
99
+
100
+ const event = {
101
+ internalService: true,
102
+ accountData: this.config,
103
+ body: JSON.stringify({
104
+ an: this.config?.AccountName,
105
+ warehouse,
106
+ inventory: [data],
107
+ })
108
+ }
109
+ const response = await producerInventory(event);
110
+
111
+ if (response.statusCode >= 200 && response.statusCode < 300) {
112
+ return true;
113
+ } else {
114
+ Logger.error('Failed to send data via producer:', response);
115
+ return false;
116
+ }
117
+
118
+ } catch (error) {
119
+ Logger.error('Error in sendDataPrices:', error);
120
+ return false;
121
+ }
122
+ }
123
+
124
+ async sendDataOrderStatus(data) {
125
+ if (!data) return false
126
+
127
+ try {
128
+
129
+ const { documents, changes } = splitData(data);
130
+
131
+ const event = {
132
+ internalService: true,
133
+ accountData: this.config,
134
+ body: JSON.stringify({
135
+ changes,
136
+ documents,
137
+ })
138
+ }
139
+ const response = await producerPrices(event);
140
+
141
+ if (response.statusCode >= 200 && response.statusCode < 300) {
142
+ return true;
143
+ } else {
144
+ Logger.error('Failed to send data via producer:', response);
145
+ return false;
146
+ }
147
+
148
+ } catch (error) {
149
+ Logger.error('Error in sendDataPrices:', error);
150
+ return false;
151
+ }
152
+ }
153
+
154
+ async sendDataOrderCancel(data) {
155
+ if (!data) return false
156
+
157
+ try {
158
+
159
+ const event = {
160
+ internalService: true,
161
+ accountData: this.config,
162
+ pathParameters: data?.orderId,
163
+ body: JSON.stringify({
164
+ reason: data?.reason,
165
+ })
166
+ }
167
+ const response = await orderCancel(event);
168
+
169
+ if (response.statusCode >= 200 && response.statusCode < 300) {
170
+ return true;
171
+ } else {
172
+ Logger.error('Failed to send data via producer:', response);
173
+ return false;
174
+ }
175
+
176
+ } catch (error) {
177
+ Logger.error('Error in sendDataPrices:', error);
178
+ return false;
179
+ }
180
+ }
181
+
182
+ }
183
+
184
+ module.exports = ServicesRedirect