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,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const ClientData = require("../../entities/clients");
|
|
3
|
+
const AccountData = require("../../entities/account");
|
|
4
|
+
const OrderData = require("../../entities/orders");
|
|
5
|
+
const VtexApi = require("../../vtex/clients/VtexApi");
|
|
6
|
+
const ApiResponse = require("../../common/utils/api-response");
|
|
7
|
+
const Logger = require("../../common/utils/logger");
|
|
8
|
+
|
|
9
|
+
const cancel = async (event) => {
|
|
10
|
+
const orderId = event.pathParameters?.orderId;
|
|
11
|
+
const clientId = event.requestContext?.authorizer?.claims?.client_id;
|
|
12
|
+
const scope = event?.requestContext?.authorizer?.claims?.scope;
|
|
13
|
+
ApiResponse.validateRequiredParam("ClientId", clientId);
|
|
14
|
+
ApiResponse.validateRequiredParam("OrderId", orderId);
|
|
15
|
+
const dataOrder = await OrderData.getOrderDataByOrderId(orderId);
|
|
16
|
+
if (!dataOrder || dataOrder.length === 0) {
|
|
17
|
+
return ApiResponse.response(404, "Order not found");
|
|
18
|
+
}
|
|
19
|
+
for (let i = 0; i < dataOrder.length; i++) {
|
|
20
|
+
const accountNameForOrder = dataOrder[i].AccountNameForOrder;
|
|
21
|
+
const acountValid = scope.includes("admin")
|
|
22
|
+
? true
|
|
23
|
+
: await ClientData.validateAccount(clientId, accountNameForOrder);
|
|
24
|
+
if (acountValid) {
|
|
25
|
+
const accountData = await AccountData.getAccountDataByAccountName(accountNameForOrder);
|
|
26
|
+
const apiClient = new VtexApi(
|
|
27
|
+
accountData.AccountName,
|
|
28
|
+
accountData.Credentials?.key,
|
|
29
|
+
accountData.Credentials?.token
|
|
30
|
+
);
|
|
31
|
+
Logger.setAccount(accountData);
|
|
32
|
+
let reason = "Orden cancelada";
|
|
33
|
+
if(event?.body && event.body != ''){
|
|
34
|
+
try{
|
|
35
|
+
reason = JSON.parse(event.body)?.reason ?? "Orden cancelada";
|
|
36
|
+
}catch (e){
|
|
37
|
+
Logger.error(e);
|
|
38
|
+
reason = "Orden cancelada";
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
Logger.debug("VTEX API Client: ", apiClient);
|
|
42
|
+
const response = await apiClient.fetch(`/oms/pvt/orders/${orderId}/cancel`, {
|
|
43
|
+
method: "POST",
|
|
44
|
+
data: {
|
|
45
|
+
reason: reason,
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
if (response.status >= 200 || response.status < 300) {
|
|
50
|
+
const responseConfirm = await apiClient.fetch(`/oms/pvt/orders/${orderId}/cancel`, {
|
|
51
|
+
method: "POST",
|
|
52
|
+
data: {
|
|
53
|
+
reason: reason,
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
if (responseConfirm.status !== 200) {
|
|
57
|
+
return ApiResponse.response(200, "Order already cancelled");
|
|
58
|
+
}else{
|
|
59
|
+
return ApiResponse.response(response.status, "Order cancelled");
|
|
60
|
+
}
|
|
61
|
+
}else{
|
|
62
|
+
return ApiResponse.response(response.status, "Order cancelled");
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
Logger.error("Data INVALID: ", acountValid);
|
|
66
|
+
return ApiResponse.response(401, "Account not valid!");
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return ApiResponse.response(500, "Internal Server Error");
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
module.exports = {
|
|
73
|
+
cancel,
|
|
74
|
+
};
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const ClientData = require("../../entities/clients");
|
|
3
|
+
const OrderData = require("../../entities/orders");
|
|
4
|
+
const AccountData = require("../../entities/account");
|
|
5
|
+
const VtexApi = require("../../vtex/clients/VtexApi");
|
|
6
|
+
const ApiResponse = require("../../common/utils/api-response");
|
|
7
|
+
const Convert = require("../../common/MondelezCastOrder");
|
|
8
|
+
const TaxPromotionsData = require("../../entities/taxpromotion");
|
|
9
|
+
const Logger = require("../../common/utils/logger");
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* @param {import("aws-lambda").APIGatewayProxyEvent} event
|
|
13
|
+
* @returns
|
|
14
|
+
*/
|
|
15
|
+
const getOrders = async (event) => {
|
|
16
|
+
try {
|
|
17
|
+
//Modify this search data
|
|
18
|
+
|
|
19
|
+
const clientId = event?.requestContext?.authorizer?.claims?.client_id;
|
|
20
|
+
const orderId = event?.pathParameters?.orderId;
|
|
21
|
+
|
|
22
|
+
const order = await OrderData.getOrderDataByOrderId(orderId);
|
|
23
|
+
if (!order) {
|
|
24
|
+
return ApiResponse.response(404, "Order not found");
|
|
25
|
+
}
|
|
26
|
+
Logger.log("Order: ", orderId);
|
|
27
|
+
for (let i = 0; i < order.length; i++) {
|
|
28
|
+
const accountNameForOrder = order[i].AccountNameForOrder;
|
|
29
|
+
const validateAccount = await ClientData.validateAccount(clientId, accountNameForOrder);
|
|
30
|
+
if (validateAccount) {
|
|
31
|
+
const data = await AccountData.getAccountDataByAccountName(accountNameForOrder);
|
|
32
|
+
const parentAccount = await AccountData.getAccountDataByAccountName(data.ParentAccountName);
|
|
33
|
+
Logger.setAccount(parentAccount);
|
|
34
|
+
if (data && parentAccount) {
|
|
35
|
+
const apiClient = new VtexApi(data?.AccountName, data?.Credentials?.key, data?.Credentials?.token);
|
|
36
|
+
const apiClientParent = new VtexApi(
|
|
37
|
+
parentAccount?.AccountName,
|
|
38
|
+
parentAccount?.Credentials?.key,
|
|
39
|
+
parentAccount?.Credentials?.token
|
|
40
|
+
);
|
|
41
|
+
Logger.debug("VTEX API Client: ", apiClient);
|
|
42
|
+
const response = await apiClient.fetch(`/oms/pvt/orders/${orderId}`, {
|
|
43
|
+
method: "GET",
|
|
44
|
+
});
|
|
45
|
+
Logger.debug("Response order: ", response);
|
|
46
|
+
if (response.status >= 200 && response.status < 300) {
|
|
47
|
+
Logger.debug("Response: ", response.data);
|
|
48
|
+
const parentOrderId = response?.data?.marketplaceOrderId;
|
|
49
|
+
if (!parentOrderId) {
|
|
50
|
+
return ApiResponse.response(404, "Order not found. Parent Order ID not found");
|
|
51
|
+
}
|
|
52
|
+
const responseParent = await apiClientParent.fetch(`/oms/pvt/orders/${parentOrderId}`, {
|
|
53
|
+
method: "GET",
|
|
54
|
+
});
|
|
55
|
+
if (responseParent.status >= 200 && responseParent.status < 300) {
|
|
56
|
+
Logger.debug("Response Parent: ", responseParent.data);
|
|
57
|
+
const orderDataAndPromotionERP = data?.BindIdExternalPromotion === true ? await TaxPromotionsData.bindIdExternalPromotionToOrderData(responseParent.data) : responseParent.data;
|
|
58
|
+
let orderMondelez = Convert.orderToJson(response.data, orderDataAndPromotionERP, data);
|
|
59
|
+
let email = orderMondelez?.clientProfileData?.email;
|
|
60
|
+
Logger.debug("Email: ", email, typeof email);
|
|
61
|
+
if (email) {
|
|
62
|
+
try {
|
|
63
|
+
const responseMailParent = await apiClientParent.fetchOrderMail(email);
|
|
64
|
+
Logger.debug("Mail Parent: ", responseMailParent);
|
|
65
|
+
Logger.debug("Mail Parent: ", responseMailParent?.data?.email);
|
|
66
|
+
orderMondelez.clientProfileData.email = responseMailParent?.data?.email;
|
|
67
|
+
} catch (error) {
|
|
68
|
+
Logger.error(error);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//obtener cliente Masterdat VTEX
|
|
72
|
+
const idCT = (orderMondelez?.clientProfileData?.email)?.split("+")[1]?.split("@")[0].toString();
|
|
73
|
+
const responseCT = await apiClientParent.fetch(`/dataentities/${data?.AcronymClientVtex}/search?_fields=_all&id=${idCT}`, {
|
|
74
|
+
method: "GET",
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
orderMondelez.clientProfileData.customerClassTwo = null;
|
|
78
|
+
orderMondelez.clientProfileData.customerID = null;
|
|
79
|
+
orderMondelez.clientProfileData.pdv = null;
|
|
80
|
+
if (responseCT.status >= 200 && responseCT.status < 300 && responseCT.data && responseCT.data.length > 0) {
|
|
81
|
+
orderMondelez.clientProfileData.customerClassTwo = responseCT.data[0].customerClassTwo;
|
|
82
|
+
orderMondelez.clientProfileData.customerID = responseCT?.data[0]?.pdv;
|
|
83
|
+
orderMondelez.clientProfileData.pdv = responseCT?.data[0]?.pdv;
|
|
84
|
+
orderMondelez.clientProfileData.priceTables = responseCT?.data[0]?.priceTables;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
//obtener campos adicionales
|
|
88
|
+
try {
|
|
89
|
+
const fieldsAdditionalInfo = data?.AdditionalInfoOrderFromClient?.fields?.join(",");
|
|
90
|
+
const responseAdditionalInfo = fieldsAdditionalInfo && fieldsAdditionalInfo !== "" ? await apiClient.fetch(`/dataentities/${data?.AdditionalInfoOrderFromClient?.nameEntity}/documents/${orderId}?_fields=${fieldsAdditionalInfo}`, {
|
|
91
|
+
method: "GET",
|
|
92
|
+
}) : { status: 200, data: [] };
|
|
93
|
+
|
|
94
|
+
Logger.debug("responseAdditionalInfo: ", responseAdditionalInfo);
|
|
95
|
+
Logger.debug("responseCT: ", responseCT);
|
|
96
|
+
|
|
97
|
+
if (responseAdditionalInfo?.status >= 200 && responseAdditionalInfo?.status < 300 && responseAdditionalInfo?.data) {
|
|
98
|
+
const dataItems = responseAdditionalInfo?.data ?? {};
|
|
99
|
+
for (const dataItem in dataItems) {
|
|
100
|
+
Logger.debug("dataItem: ", dataItem);
|
|
101
|
+
orderMondelez.clientProfileData[dataItem] = dataItems[dataItem] ?? responseCT?.data[0]?.[dataItem] ?? null;
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
for (let j = 0; j < data?.AdditionalInfoOrderFromClient?.fields?.length; j++) {
|
|
105
|
+
let keyClient = data?.AdditionalInfoOrderFromClient?.fields[j];
|
|
106
|
+
if (keyClient && keyClient !== "") {
|
|
107
|
+
orderMondelez.clientProfileData[keyClient] = responseCT?.data[0]?.[keyClient] ?? null;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
} catch (errorSetFields) {
|
|
112
|
+
Logger.error('Error set AdditionalInfoOrderFromClient', errorSetFields);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
//obtener campos adicionales
|
|
116
|
+
|
|
117
|
+
if (data?.ObjectZeroTax === true) {
|
|
118
|
+
orderMondelez.items = setObjectZeroTax(orderMondelez.items);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (data?.ChannelWarehouse) {
|
|
122
|
+
orderMondelez.shippingAddress.logisticsInfo.deliveryIds = orderMondelez?.shippingAddress?.logisticsInfo?.deliveryIds?.map(it => {
|
|
123
|
+
it.warehouse = "";
|
|
124
|
+
for (let wr in data?.ChannelWarehouse) {
|
|
125
|
+
if (data?.ChannelWarehouse[wr] == it?.warehouseId) {
|
|
126
|
+
it.warehouse = wr;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return it;
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// adjuntar campos adicionales a las promociones de la orden
|
|
135
|
+
orderMondelez = await getAdditionalInfoPromotionsOrder(orderMondelez, data, apiClient);
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
//Additional Info Fields Sku Distributors
|
|
139
|
+
Logger.debug("Sku Distributors Management: ", data?.SkuDistributorManagementAdditionalInfo);
|
|
140
|
+
orderMondelez = await setItemsSkuDistributors(orderMondelez, data);
|
|
141
|
+
Logger.debug("Order Mondelez: ", orderMondelez);
|
|
142
|
+
} catch (error) {
|
|
143
|
+
Logger.error("GetOrder: ", error);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return ApiResponse.response(200, orderMondelez);
|
|
147
|
+
} else {
|
|
148
|
+
return ApiResponse.response(responseParent.status, responseParent.data);
|
|
149
|
+
}
|
|
150
|
+
} else {
|
|
151
|
+
return ApiResponse.response(response.status, response.data);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return ApiResponse.response(404, "Order not found");
|
|
157
|
+
} catch (error) {
|
|
158
|
+
Logger.error(error);
|
|
159
|
+
return ApiResponse.response(error?.statusCode || 500, {
|
|
160
|
+
message: error.message,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
const setObjectZeroTax = (items) => {
|
|
166
|
+
if (!items || typeof items != 'object') {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
for (var i = 0; i < items.length; i++) {
|
|
171
|
+
let exitTax = items[i]?.priceTags?.find(it => (String(it.name).indexOf("tax@price") > -1));
|
|
172
|
+
|
|
173
|
+
if (items[i]?.priceTags?.length === 0 || exitTax?.length === 0) {
|
|
174
|
+
items[i].priceTags = [...items[i]?.priceTags, {
|
|
175
|
+
"name": "tax@price",
|
|
176
|
+
"value": 0,
|
|
177
|
+
"isPercentual": true,
|
|
178
|
+
"identifier": null,
|
|
179
|
+
"rawValue": 0,
|
|
180
|
+
"valueNominal": 0,
|
|
181
|
+
"rawValueNominal": 0,
|
|
182
|
+
"rate": null,
|
|
183
|
+
"jurisCode": null,
|
|
184
|
+
"jurisType": null,
|
|
185
|
+
"jurisName": null
|
|
186
|
+
}];
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return items;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const getAdditionalInfoPromotionsOrder = async (data, account, apiClient) => {
|
|
194
|
+
if (!account
|
|
195
|
+
|| !account?.AdditionalFieldsPromotionsInOrder
|
|
196
|
+
|| !account.AdditionalFieldsPromotionsInOrder?.isActive
|
|
197
|
+
|| !account.AdditionalFieldsPromotionsInOrder?.acronymEntity
|
|
198
|
+
|| Object.keys(account.AdditionalFieldsPromotionsInOrder?.fields).length === 0) return data;
|
|
199
|
+
|
|
200
|
+
try {
|
|
201
|
+
const OrderId = data?.id;
|
|
202
|
+
const acronymEntity = account?.AdditionalFieldsPromotionsInOrder?.acronymEntity;
|
|
203
|
+
const responseAdditionalInfo = await apiClient.fetch(`/dataentities/${acronymEntity}/documents/${OrderId}?_fields=detailPromotions`, {
|
|
204
|
+
method: "GET",
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
if (responseAdditionalInfo?.status >= 200 && responseAdditionalInfo?.status < 300 && responseAdditionalInfo?.data) {
|
|
209
|
+
const promotions = responseAdditionalInfo?.data?.detailPromotions ?? [];
|
|
210
|
+
|
|
211
|
+
for (const promo of promotions) {
|
|
212
|
+
const identifiersBenefits = data?.ratesAndBenefitsData?.rateAndBenefitsIdentifiers || [];
|
|
213
|
+
for (let i = 0; i < identifiersBenefits.length; i++) {
|
|
214
|
+
const identifier = identifiersBenefits[i];
|
|
215
|
+
if (identifier?.id === promo?.id) {
|
|
216
|
+
data.ratesAndBenefitsData.rateAndBenefitsIdentifiers[i] = { ...identifier, ...promo?.fields };
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
for (let itemIndex = 0; itemIndex < data.items.length; itemIndex++) {
|
|
221
|
+
const item = data.items[itemIndex];
|
|
222
|
+
for (let priceTagIndex = 0; priceTagIndex < item.priceTags.length; priceTagIndex++) {
|
|
223
|
+
const priceTag = item.priceTags[priceTagIndex];
|
|
224
|
+
if (priceTag?.identifier === promo?.id) {
|
|
225
|
+
data.items[itemIndex].priceTags[priceTagIndex] = { ...priceTag, ...promo?.fields };
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return data;
|
|
231
|
+
} else {
|
|
232
|
+
return data;
|
|
233
|
+
}
|
|
234
|
+
} catch (errorSetFields) {
|
|
235
|
+
return data;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
//Additional Info Fields Sku Distributors
|
|
240
|
+
const setItemsSkuDistributors = async (orderMondelez, data) => {
|
|
241
|
+
if (!data || !data?.SkuDistributorManagementAdditionalInfo) {
|
|
242
|
+
return orderMondelez;
|
|
243
|
+
}
|
|
244
|
+
//TODO: Implement logic for Sku Distributors Management of Orders
|
|
245
|
+
const items = orderMondelez?.items;
|
|
246
|
+
const skuRefUsed = data?.SkuRefUsed;
|
|
247
|
+
if (typeof skuRefUsed !== "boolean") {
|
|
248
|
+
Logger.debug("Sku or ReferenceCode filter not defined, use default: ", skuRefUsed);
|
|
249
|
+
skuRefUsed = true;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (!items) {
|
|
253
|
+
Logger.error("Orders without items.");
|
|
254
|
+
return orderMondelez;
|
|
255
|
+
}
|
|
256
|
+
const apiClient = new VtexApi(data?.AccountName, data?.Credentials?.key, data?.Credentials?.token);
|
|
257
|
+
Logger.debug("VTEX API Client: ", apiClient);
|
|
258
|
+
const responseAdditionalInfo = data?.SkuDistributorManagementAdditionalInfo && data?.SkuDistributorManagementAdditionalInfo !== "" ? await apiClient.fetch(`/dataentities/${data?.SkuDistributorManagementAdditionalInfo?.entityName}/documents/${orderMondelez.id}?_fields=_all`, {
|
|
259
|
+
method: "GET",
|
|
260
|
+
}) : { status: 200, data: [] };
|
|
261
|
+
Logger.debug("responseAdditionalInfo in setItemsSkuDistributors: ", responseAdditionalInfo?.data);
|
|
262
|
+
if (responseAdditionalInfo?.status >= 200 && responseAdditionalInfo?.status < 300 && responseAdditionalInfo?.data) {
|
|
263
|
+
const dataItems = responseAdditionalInfo?.data?.items ?? [];
|
|
264
|
+
let itemsOrder = orderMondelez?.items ?? [];
|
|
265
|
+
orderMondelez.items = itemsOrder.map(itemOrder => {
|
|
266
|
+
const distributorData = dataItems.find(it => skuRefUsed ? it.refId == itemOrder.sku : it.ean == itemOrder.ean);
|
|
267
|
+
if (distributorData && distributorData.ERPCode) {
|
|
268
|
+
itemOrder.sku = distributorData.ERPCode;
|
|
269
|
+
}
|
|
270
|
+
return itemOrder;
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return orderMondelez;
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
module.exports = {
|
|
279
|
+
getOrders,
|
|
280
|
+
};
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
const OrderData = require("../../entities/orders");
|
|
2
|
+
const AccountData = require("../../entities/account");
|
|
3
|
+
const Convert = require("../../common/MondelezCastOrder");
|
|
4
|
+
const VtexApi = require("../../vtex/clients/VtexApi");
|
|
5
|
+
const TaxPromotionsData = require("../../entities/taxpromotion");
|
|
6
|
+
const Logger = require("../../common/utils/logger");
|
|
7
|
+
|
|
8
|
+
const fs = require("fs");
|
|
9
|
+
const csv = require("csv");
|
|
10
|
+
const AWS = require("aws-sdk");
|
|
11
|
+
const s3 = new AWS.S3();
|
|
12
|
+
const BUCKET_NAME = process.env.BUCKET_NAME;
|
|
13
|
+
|
|
14
|
+
const consumer = async (event) => {
|
|
15
|
+
for (const record of event.Records) {
|
|
16
|
+
Logger.debug("Message Body: ", record.body);
|
|
17
|
+
try {
|
|
18
|
+
let order = JSON.parse(record.body);
|
|
19
|
+
const dateValue = stringDateVtexToDate(order?.orderInfo?.CurrentChange);
|
|
20
|
+
const orderToUpdate = {
|
|
21
|
+
AccountNameForOrder: order?.orderInfo?.Origin?.Account,
|
|
22
|
+
OrderId: order?.orderInfo?.OrderId,
|
|
23
|
+
StatusDate: dateValue,
|
|
24
|
+
OrderState: order?.orderInfo?.State,
|
|
25
|
+
Domain: order?.orderInfo?.Domain,
|
|
26
|
+
Key: order?.orderInfo?.Origin?.Key
|
|
27
|
+
};
|
|
28
|
+
const orderSaved = await OrderData.addOrder(orderToUpdate);
|
|
29
|
+
const accountConfig = order?.accountConfig;
|
|
30
|
+
const configuredSftp = accountConfig?.SftpUsed || false;
|
|
31
|
+
const directory = accountConfig?.SftpDirectory?.orders;
|
|
32
|
+
if (accountConfig && configuredSftp && directory) {
|
|
33
|
+
const parentAccount = await AccountData.getAccountDataByAccountName(accountConfig.ParentAccountName);
|
|
34
|
+
if (parentAccount) {
|
|
35
|
+
const apiClient = new VtexApi(
|
|
36
|
+
accountConfig?.AccountName,
|
|
37
|
+
accountConfig?.Credentials?.key,
|
|
38
|
+
accountConfig?.Credentials?.token
|
|
39
|
+
);
|
|
40
|
+
const apiClientParent = new VtexApi(
|
|
41
|
+
parentAccount?.AccountName,
|
|
42
|
+
parentAccount?.Credentials?.key,
|
|
43
|
+
parentAccount?.Credentials?.token
|
|
44
|
+
);
|
|
45
|
+
const response = await apiClient.fetch(`/oms/pvt/orders/${order?.orderInfo?.OrderId}`, {
|
|
46
|
+
method: "GET",
|
|
47
|
+
});
|
|
48
|
+
if (response.status >= 200 && response.status < 300) {
|
|
49
|
+
const parentOrderId = response?.data?.marketplaceOrderId;
|
|
50
|
+
if (!parentOrderId) {
|
|
51
|
+
Logger.error("Order not found. Parent Order ID not found");
|
|
52
|
+
throw new Error("Order not found. Parent Order ID not found");
|
|
53
|
+
}
|
|
54
|
+
const responseParent = await apiClientParent.fetch(`/oms/pvt/orders/${parentOrderId}`, {
|
|
55
|
+
method: "GET",
|
|
56
|
+
});
|
|
57
|
+
if (responseParent.status >= 200 && responseParent.status < 300) {
|
|
58
|
+
const orderDataAndPromotionERP = accountConfig?.BindIdExternalPromotion === true ? await TaxPromotionsData.bindIdExternalPromotionToOrderData(responseParent.data) : responseParent.data;
|
|
59
|
+
let orderMondelez = Convert.orderToJson(response.data, orderDataAndPromotionERP);
|
|
60
|
+
let email = orderMondelez?.clientProfileData?.email;
|
|
61
|
+
if (email) {
|
|
62
|
+
try {
|
|
63
|
+
const responseMailParent = await apiClientParent.fetchOrderMail(email);
|
|
64
|
+
orderMondelez.clientProfileData.email = responseMailParent?.data?.email;
|
|
65
|
+
} catch (error) {
|
|
66
|
+
Logger.error(error);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const csvData = Convert.convertJsonOrderToCsv(orderMondelez);
|
|
70
|
+
let csvDataString = "";
|
|
71
|
+
await readStream(
|
|
72
|
+
csv.stringify(
|
|
73
|
+
csvData.csvData,
|
|
74
|
+
{ header: true, columns: csvData.csvHeaders, delimiter: ";" },
|
|
75
|
+
(err, output) => {
|
|
76
|
+
if (err) {
|
|
77
|
+
Logger.error("Error CSV: ", err);
|
|
78
|
+
}
|
|
79
|
+
csvDataString = output;
|
|
80
|
+
}
|
|
81
|
+
)
|
|
82
|
+
);
|
|
83
|
+
const fileName = orderMondelez.id + "_" + orderMondelez.status + "_" + dateValue + ".csv";
|
|
84
|
+
const params = {
|
|
85
|
+
Bucket: BUCKET_NAME,
|
|
86
|
+
Key: `${directory}${fileName}`,
|
|
87
|
+
Body: csvDataString,
|
|
88
|
+
ContentType: "text/csv",
|
|
89
|
+
ACL: "public-read",
|
|
90
|
+
};
|
|
91
|
+
await s3.putObject(params).promise();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
} catch (error) {
|
|
97
|
+
Logger.error(error);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
function readStream(stream) {
|
|
103
|
+
return new Promise((resolve, reject) => {
|
|
104
|
+
let csvString = "";
|
|
105
|
+
|
|
106
|
+
stream.on("readable", () => {
|
|
107
|
+
let chunk;
|
|
108
|
+
while ((chunk = stream.read()) !== null) {
|
|
109
|
+
csvString += chunk;
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
stream.on("end", () => {
|
|
114
|
+
resolve(csvString);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
stream.on("error", (error) => {
|
|
118
|
+
reject(error);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function stringDateVtexToDate(date) {
|
|
124
|
+
Logger.debug("Date: ", date);
|
|
125
|
+
let dateValue = date;
|
|
126
|
+
try {
|
|
127
|
+
dateValue = new Date(date).toISOString();
|
|
128
|
+
} catch (error) {
|
|
129
|
+
Logger.error(error);
|
|
130
|
+
}
|
|
131
|
+
Logger.debug("Date: ", dateValue);
|
|
132
|
+
return dateValue;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
module.exports = {
|
|
136
|
+
consumer,
|
|
137
|
+
};
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
const AWSServices = require("../../common/utils/aws-services");
|
|
2
|
+
const ApiResponse = require("../../common/utils/api-response");
|
|
3
|
+
const { isStateInNotificationProviders } = require("../../common/utils/validate-state-order");
|
|
4
|
+
const Logger = require("../../common/utils/logger");
|
|
5
|
+
const ORDER_HOOK_QUEUE_URL = process.env.ORDER_HOOK_QUEUE_URL;
|
|
6
|
+
const SQS_ROUTEFLOW_QUEUE_URL = process.env.SQS_ROUTEFLOW_QUEUE_URL;
|
|
7
|
+
const SQS_SKU_DISTRIBUTOR_QUEUE_URL = process.env.SQS_SKU_DISTRIBUTOR_QUEUE_URL;
|
|
8
|
+
// NOTIFICATIONS
|
|
9
|
+
const SQS_NOTIFICATION_ORDER_STATUS_QUEUE_URL = process.env.SQS_NOTIFICATION_ORDER_STATUS_QUEUE_URL
|
|
10
|
+
// ADDITIONAL FIELDS PROMOTIONS ORDER
|
|
11
|
+
const SQS_PROMOTIONS_ORDER_QUEUE_URL = process.env.SQS_PROMOTIONS_ORDER_QUEUE_URL;
|
|
12
|
+
|
|
13
|
+
const AccountData = require("../../entities/account");
|
|
14
|
+
|
|
15
|
+
const producer = async (event) => {
|
|
16
|
+
let statusCode = 200;
|
|
17
|
+
let message;
|
|
18
|
+
if (!event.body) {
|
|
19
|
+
return ApiResponse.response(400, "No body was found");
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
Logger.debug("all-event: ", event);
|
|
23
|
+
const appKey = event?.headers?.MDLZ_AppKey ?? event?.headers?.mdlz_appkey;
|
|
24
|
+
const appToken = event?.headers?.MDLZ_AppToken ?? event?.headers?.mdlz_apptoken;
|
|
25
|
+
|
|
26
|
+
if (!appKey || !appToken) {
|
|
27
|
+
Logger.error("Authorizer credentials is required.");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const {Domain, OrderId, CurrentChange, State, Origin} = JSON.parse(event.body);
|
|
31
|
+
if(!Domain){
|
|
32
|
+
Logger.error("Domain property is required.");
|
|
33
|
+
}
|
|
34
|
+
if(!OrderId){
|
|
35
|
+
Logger.error("OrderId property is required.");
|
|
36
|
+
}
|
|
37
|
+
if(!CurrentChange){
|
|
38
|
+
Logger.error("CurrentChange property is required.");
|
|
39
|
+
}
|
|
40
|
+
if(!State){
|
|
41
|
+
Logger.error("State property is required.");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const accountConfig = Origin?.Account ? await AccountData.getAccountDataByAccountName(Origin?.Account) : {};
|
|
45
|
+
Logger.setAccount(accountConfig);
|
|
46
|
+
Logger.debug("account-config: ", accountConfig);
|
|
47
|
+
|
|
48
|
+
if(!accountConfig){
|
|
49
|
+
Logger.error("Account config not found.");
|
|
50
|
+
}
|
|
51
|
+
if(!accountConfig?.MDLZAppKey || !accountConfig?.MDLZAppToken){
|
|
52
|
+
Logger.error("Credentials not found.");
|
|
53
|
+
}
|
|
54
|
+
if(accountConfig?.MDLZAppKey !== appKey || accountConfig?.MDLZAppToken !== appToken){
|
|
55
|
+
Logger.error("Credentials incorrect.");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if(Domain && OrderId && CurrentChange && State && accountConfig && accountConfig?.MDLZAppKey === appKey && accountConfig?.MDLZAppToken === appToken){
|
|
59
|
+
const orderInfo = JSON.parse(event.body);
|
|
60
|
+
const accountConfigParent = await AccountData.getAccountDataByAccountName(accountConfig?.ParentAccountName);
|
|
61
|
+
const orderData = {
|
|
62
|
+
orderInfo,
|
|
63
|
+
accountConfig,
|
|
64
|
+
accountConfigParent,
|
|
65
|
+
};
|
|
66
|
+
await AWSServices.sendSQSMessage(ORDER_HOOK_QUEUE_URL, orderData);
|
|
67
|
+
await sendAdditionalFields(orderData);
|
|
68
|
+
await sendAdditionalFieldsSkuDistributors(orderData);
|
|
69
|
+
|
|
70
|
+
// Send notification status order to user
|
|
71
|
+
await sendNotificationAtQueue(orderData)
|
|
72
|
+
// Save additional fields promotions in order
|
|
73
|
+
await sendAdditionalFieldsPromotionsByOrder(orderData)
|
|
74
|
+
|
|
75
|
+
message = "Message accepted!";
|
|
76
|
+
} else {
|
|
77
|
+
message = "Message no accepted!";
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
} catch (error) {
|
|
81
|
+
Logger.error(error);
|
|
82
|
+
message = error;
|
|
83
|
+
statusCode = 500;
|
|
84
|
+
}
|
|
85
|
+
return ApiResponse.response(statusCode, message);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
async function sendAdditionalFieldsPromotionsByOrder(orderData) {
|
|
89
|
+
|
|
90
|
+
if (!SQS_PROMOTIONS_ORDER_QUEUE_URL || !orderData) {
|
|
91
|
+
Logger.error('ERROR send order to promotions queue: missing queueUrl or orderData');
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const promotionsConfig = orderData?.accountConfig?.AdditionalFieldsPromotionsInOrder;
|
|
96
|
+
if (!promotionsConfig) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const { isActive, initialState } = promotionsConfig;
|
|
101
|
+
if (isActive && initialState === orderData?.orderInfo?.State) {
|
|
102
|
+
await AWSServices.sendSQSMessage(SQS_PROMOTIONS_ORDER_QUEUE_URL, orderData);
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
return false
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async function sendAdditionalFields(orderToUpdate) {
|
|
109
|
+
const additionalFields = orderToUpdate?.accountConfig?.AdditionalInfoOrderFromClient;
|
|
110
|
+
|
|
111
|
+
if(additionalFields &&
|
|
112
|
+
additionalFields?.initialState !== "" &&
|
|
113
|
+
additionalFields?.initialState !== "" &&
|
|
114
|
+
additionalFields?.initialState === orderToUpdate?.orderInfo?.State &&
|
|
115
|
+
additionalFields?.fields?.length > 0 &&
|
|
116
|
+
additionalFields?.nameEntity !== ""
|
|
117
|
+
|
|
118
|
+
){
|
|
119
|
+
await AWSServices.sendSQSMessage(SQS_ROUTEFLOW_QUEUE_URL, orderToUpdate);
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async function sendAdditionalFieldsSkuDistributors(orderToUpdate) {
|
|
127
|
+
const additionalFields = orderToUpdate?.accountConfig?.SkuDistributorManagementAdditionalInfo;
|
|
128
|
+
|
|
129
|
+
if(additionalFields &&
|
|
130
|
+
additionalFields?.initialState &&
|
|
131
|
+
additionalFields?.initialState !== "" &&
|
|
132
|
+
additionalFields?.initialState === orderToUpdate?.orderInfo?.State &&
|
|
133
|
+
additionalFields?.entityName !== "" &&
|
|
134
|
+
additionalFields?.isActive !== "" &&
|
|
135
|
+
additionalFields?.isActive === true
|
|
136
|
+
) {
|
|
137
|
+
await AWSServices.sendSQSMessage(SQS_SKU_DISTRIBUTOR_QUEUE_URL, orderToUpdate);
|
|
138
|
+
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Builder to send notifications of the status of the generated order to the users.
|
|
146
|
+
async function sendNotificationAtQueue(orderData){
|
|
147
|
+
|
|
148
|
+
if(!SQS_NOTIFICATION_ORDER_STATUS_QUEUE_URL || !orderData){
|
|
149
|
+
Logger.error('ERROR in queue')
|
|
150
|
+
return false
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const notificationOrderVTEX = orderData?.accountConfig?.NotificationsVTEX
|
|
154
|
+
const stateOrder = orderData?.orderInfo?.State
|
|
155
|
+
|
|
156
|
+
const isActiveNotifications = notificationOrderVTEX?.isActive
|
|
157
|
+
const notificationProviders = notificationOrderVTEX?.NotificationProviders ?? []
|
|
158
|
+
|
|
159
|
+
const isValidState = isStateInNotificationProviders({isActiveNotifications, notificationProviders, stateOrder})
|
|
160
|
+
|
|
161
|
+
if(isValidState){
|
|
162
|
+
await AWSServices.sendSQSMessage(SQS_NOTIFICATION_ORDER_STATUS_QUEUE_URL, orderData)
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
return false
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
module.exports = {
|
|
169
|
+
producer,
|
|
170
|
+
};
|