dcos-core-monalisav2-latam 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +130 -0
- package/index.js +350 -0
- package/package.json +52 -0
- package/src/auth/handler.js +3 -0
- package/src/common/MondelezCastOrder.js +449 -0
- package/src/common/utils/AuthSecurity.js +46 -0
- package/src/common/utils/account-error-handler.js +279 -0
- package/src/common/utils/account-error-helper.js +231 -0
- package/src/common/utils/account-properties-handler.js +355 -0
- package/src/common/utils/api-response.js +62 -0
- package/src/common/utils/aws-services.js +186 -0
- package/src/common/utils/constants/account-error-codes.json +801 -0
- package/src/common/utils/constants.js +37 -0
- package/src/common/utils/convert/MondelezClientsItemsCast.js +52 -0
- package/src/common/utils/convert/MondelezInventoryItemsCast.js +15 -0
- package/src/common/utils/convert/MondelezOrderStatusCast.js +34 -0
- package/src/common/utils/convert/MondelezPricesItemsCast.js +37 -0
- package/src/common/utils/cron-ftp-get.js +143 -0
- package/src/common/utils/data-tables-helper.js +213 -0
- package/src/common/utils/date-range-calculator.js +113 -0
- package/src/common/utils/delay.js +17 -0
- package/src/common/utils/ftp-sftp.js +320 -0
- package/src/common/utils/logger.js +126 -0
- package/src/common/utils/nodemailerLib.js +61 -0
- package/src/common/utils/product-unit-converter.js +168 -0
- package/src/common/utils/schemas-utils.js +101 -0
- package/src/common/utils/seller-email-sharing-service.js +441 -0
- package/src/common/utils/sftp-utils.js +202 -0
- package/src/common/utils/status.js +15 -0
- package/src/common/utils/util.js +236 -0
- package/src/common/utils/validate-state-order.js +35 -0
- package/src/common/utils/validateProviders.js +67 -0
- package/src/common/utils/validation-data.js +45 -0
- package/src/common/utils/vtex/save-hooks.js +65 -0
- package/src/common/utils/vtex/save-schemas.js +65 -0
- package/src/common/utils/vtex-hook-handler.js +71 -0
- package/src/common/validation/AccountCoordinatesValidation.js +350 -0
- package/src/common/validation/GeneralErrorValidation.js +11 -0
- package/src/common/validation/MainErrorValidation.js +8 -0
- package/src/entities/account.js +639 -0
- package/src/entities/clients.js +104 -0
- package/src/entities/controlprice.js +196 -0
- package/src/entities/controlstock.js +206 -0
- package/src/entities/cron.js +77 -0
- package/src/entities/cronjob.js +71 -0
- package/src/entities/orders.js +195 -0
- package/src/entities/sftp-inbound.js +88 -0
- package/src/entities/sku.js +220 -0
- package/src/entities/taxpromotion.js +249 -0
- package/src/functions/account/account-get.js +262 -0
- package/src/functions/account/account-handler.js +299 -0
- package/src/functions/account/clients.js +10 -0
- package/src/functions/account/index.js +208 -0
- package/src/functions/actions/save-promotions-order-history.js +324 -0
- package/src/functions/affiliates/affiliates-hook-consumer.js +87 -0
- package/src/functions/affiliates/affiliates-hook-producer.js +45 -0
- package/src/functions/clients/clients-audience.js +62 -0
- package/src/functions/clients/clients-consumer.js +648 -0
- package/src/functions/clients/clients-producer.js +362 -0
- package/src/functions/clients/clients-suggested-product-consumer.js +166 -0
- package/src/functions/clients/helpers/suggested-product-mdlz.js +233 -0
- package/src/functions/clients_peru/email.html +129 -0
- package/src/functions/clients_peru/splitfile.js +357 -0
- package/src/functions/clients_peru/updateClients.js +1334 -0
- package/src/functions/clients_peru/utils.js +243 -0
- package/src/functions/cronjobs/cron-jobs-manager.js +40 -0
- package/src/functions/cronjobs/cron-jobs.js +171 -0
- package/src/functions/crons/cron.js +39 -0
- package/src/functions/distributors/distributor-handler.js +81 -0
- package/src/functions/distributors/distributor.js +535 -0
- package/src/functions/distributors/index.js +60 -0
- package/src/functions/financialpolicy/assign-financialpolicy.js +111 -0
- package/src/functions/financialpolicy/get-financialpolicy.js +91 -0
- package/src/functions/financialpolicy/index.js +28 -0
- package/src/functions/inventory/catalog-sync-consumer.js +17 -0
- package/src/functions/inventory/catalog-sync-handler.js +311 -0
- package/src/functions/inventory/inventory-consumer.js +119 -0
- package/src/functions/inventory/inventory-producer.js +197 -0
- package/src/functions/multiPresentation/multipre-queue.js +155 -0
- package/src/functions/multiPresentation/multipres.js +459 -0
- package/src/functions/nodeflow/index.js +83 -0
- package/src/functions/nodeflow/nodeflow-cron.js +200 -0
- package/src/functions/nodeflow/nodeflow-pub.js +203 -0
- package/src/functions/nodeflow/nodeflow-pvt.js +266 -0
- package/src/functions/notifications/download-leads-handler.js +67 -0
- package/src/functions/notifications/new-leads-notification-consumer.js +17 -0
- package/src/functions/notifications/new-leads-notification-handler.js +359 -0
- package/src/functions/notifications/order-status-notification-handler.js +482 -0
- package/src/functions/notifications/promotion-notification-handler.js +193 -0
- package/src/functions/orders/index.js +32 -0
- package/src/functions/orders/orders-cancel-handler.js +74 -0
- package/src/functions/orders/orders-handler.js +280 -0
- package/src/functions/orders/orders-hook-consumer.js +137 -0
- package/src/functions/orders/orders-hook-producer.js +170 -0
- package/src/functions/orders/orders-notifications-handler.js +137 -0
- package/src/functions/orders/orders-status-consumer.js +461 -0
- package/src/functions/orders/orders-status-producer.js +443 -0
- package/src/functions/prices/index.js +75 -0
- package/src/functions/prices/prices-consumer.js +236 -0
- package/src/functions/prices/prices-producer.js +323 -0
- package/src/functions/prices/promotion-and-tax.js +1284 -0
- package/src/functions/routesflow/assign-routeflow-queue.js +77 -0
- package/src/functions/schemas/vtex/handle-schemas.js +102 -0
- package/src/functions/security/process_gas.js +221 -0
- package/src/functions/security/security-handler.js +950 -0
- package/src/functions/sftp/sftp-consumer.js +453 -0
- package/src/functions/sftpIntegrations/processes/redirectServices.js +184 -0
- package/src/functions/sftpIntegrations/processes/validateFileSchema.js +226 -0
- package/src/functions/sftpIntegrations/schemas/credential-schema.js +123 -0
- package/src/functions/sftpIntegrations/schemas/record-schema.js +131 -0
- package/src/functions/sftpIntegrations/schemas/sftp_required_fields.json +3 -0
- package/src/functions/sftpIntegrations/sftp-config-producer.js +112 -0
- package/src/functions/sftpIntegrations/sftp-consumer.js +700 -0
- package/src/functions/sftpIntegrations/test/validateFile.test.js +122 -0
- package/src/functions/sftpIntegrations/utils/connect-dynamo.js +29 -0
- package/src/functions/sftpIntegrations/utils/split-data.js +25 -0
- package/src/functions/utils/index.js +130 -0
- package/src/functions/vtex/vtex-helpers.js +694 -0
- package/src/integrations/accountErrors/AccountErrorManager.js +437 -0
- package/src/integrations/audience/Audience.js +70 -0
- package/src/integrations/financialPolicy/FinancialPolicyApi.js +377 -0
- package/src/integrations/index.js +0 -0
- package/src/integrations/mobilvendor/MobilvendorApi.js +405 -0
- package/src/integrations/productmultipresentation/ProductMultiPresentation.js +200 -0
- package/src/mdlz/auth/SecretManagerApi.js +77 -0
- package/src/mdlz/client/MdlzApi.js +70 -0
- package/src/vtex/clients/ProvidersApi.js +51 -0
- package/src/vtex/clients/VtexApi.js +511 -0
- package/src/vtex/models/VtexOrder.js +87 -0
|
@@ -0,0 +1,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
|