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,405 @@
|
|
|
1
|
+
const axios = require("axios");
|
|
2
|
+
const ApiResponse = require("../../common/utils/api-response");
|
|
3
|
+
const VtexApi = require("../../vtex/clients/VtexApi");
|
|
4
|
+
const Logger = require("../../common/utils/logger");
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Class representing the MobilvendorApi.
|
|
8
|
+
*
|
|
9
|
+
* @class
|
|
10
|
+
* @classdesc This class provides methods for interacting with the Mobilvendor API.
|
|
11
|
+
*/
|
|
12
|
+
class MobilvendorApi {
|
|
13
|
+
constructor(AccountName, Key, Token, AcronymClientVtex, FinancialPolicyEcu) {
|
|
14
|
+
this.AccountName = AccountName;
|
|
15
|
+
this.Key = Key;
|
|
16
|
+
this.Token = Token;
|
|
17
|
+
this.AcronymClientVtex = AcronymClientVtex;
|
|
18
|
+
this.FinancialPolicyEcu = FinancialPolicyEcu;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* set FinancialPolicyEcu
|
|
23
|
+
* */
|
|
24
|
+
setConfig(FinancialPolicyEcu) {
|
|
25
|
+
this.FinancialPolicyEcu= FinancialPolicyEcu;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Logs in to the Mobilvendor API.
|
|
30
|
+
*
|
|
31
|
+
* @returns {Object} An object containing the context ID and session ID.
|
|
32
|
+
* - contextId: The ID of the context.
|
|
33
|
+
* - sessionId: The ID of the session.
|
|
34
|
+
* @throws {Error} If there is an error during the login process.
|
|
35
|
+
*/
|
|
36
|
+
async login() {
|
|
37
|
+
try {
|
|
38
|
+
const responseLogin = await axios.post(this.FinancialPolicyEcu.configService.url,
|
|
39
|
+
this.FinancialPolicyEcu.configService.body
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
if (!responseLogin || !responseLogin?.data?.session_id){
|
|
43
|
+
Logger.error("Login mobilvendor have problems");
|
|
44
|
+
return ApiResponse.response(404, { approved: false, message: "Login mobilvendor have problems" });
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const sessionId = responseLogin.data.session_id;
|
|
48
|
+
const responseContexts = await axios.post(this.FinancialPolicyEcu.configService.url, {
|
|
49
|
+
session_id: sessionId,
|
|
50
|
+
action: "getContexts",
|
|
51
|
+
});
|
|
52
|
+
const response = responseContexts?.data?.records;
|
|
53
|
+
let contextId = response?.find(record => record?.id === this.FinancialPolicyEcu.configService.context)?.id;
|
|
54
|
+
|
|
55
|
+
if (!contextId) {
|
|
56
|
+
contextId = this.FinancialPolicyEcu.configService.context;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return { contextId, sessionId };
|
|
60
|
+
} catch (error) {
|
|
61
|
+
Logger.error(error);
|
|
62
|
+
return ApiResponse.response(404, { approved: false, message: "Login mobilvendor have problems" });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Retrieves the client data by email.
|
|
68
|
+
*
|
|
69
|
+
* This method retrieves the client data by performing the following steps:
|
|
70
|
+
* 1. Creates an instance of the VtexApi class using the provided account name, key, and token.
|
|
71
|
+
* 2. Extracts the client ID from the email.
|
|
72
|
+
* 3. Sends a GET request to the Vtex API to retrieve the client data for the specified ID.
|
|
73
|
+
* 4. Checks the response status. If the status is between 200 and 299 (inclusive), returns the client data.
|
|
74
|
+
* 5. Returns null if the response status is outside the range of 200 to 299.
|
|
75
|
+
*
|
|
76
|
+
* @param {string} email - The email of the client.
|
|
77
|
+
* @returns {Promise<Object|null>} A promise that resolves to the client data if successful, or null in case of an error.
|
|
78
|
+
* @throws {Error} If there is an error during the retrieval process.
|
|
79
|
+
*/
|
|
80
|
+
async getClientById(email) {
|
|
81
|
+
try {
|
|
82
|
+
const vtexApi = new VtexApi(this.AccountName, this.Key, this.Token);
|
|
83
|
+
const clientId = email?.split("+")[1]?.split("@")[0];
|
|
84
|
+
const responseMasterDataCT = await vtexApi.fetch(
|
|
85
|
+
`/dataentities/${this.AcronymClientVtex}/search?_fields=_all&id=${clientId}`, { method: "GET" }
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
if (responseMasterDataCT.status >= 200 && responseMasterDataCT.status < 300) {
|
|
89
|
+
return responseMasterDataCT.data[0];
|
|
90
|
+
} else {
|
|
91
|
+
Logger.error(responseMasterDataCT);
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
} catch (error) {
|
|
95
|
+
Logger.error(error);
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Retrieves the order form data by ID.
|
|
102
|
+
*
|
|
103
|
+
* This method retrieves the order form data by performing the following steps:
|
|
104
|
+
* 1. Creates an instance of the VtexApi class using the provided account name, key, and token.
|
|
105
|
+
* 2. Sends a GET request to the Vtex API to retrieve the order form data for the specified ID.
|
|
106
|
+
* 3. Checks the response status. If the status is not 200, returns an error response.
|
|
107
|
+
* 4. Returns the order form data.
|
|
108
|
+
*
|
|
109
|
+
* @param {string} orderFormId - The ID of the order form to retrieve.
|
|
110
|
+
* @returns {Promise<Object|null>} A promise that resolves to the order form data if successful, or null in case of an error.
|
|
111
|
+
* @throws {Error} If there is an error during the retrieval process.
|
|
112
|
+
*/
|
|
113
|
+
async getOrderFormById(orderFormId) {
|
|
114
|
+
try {
|
|
115
|
+
const vtexApi = new VtexApi(this.AccountName, this.Key, this.Token);
|
|
116
|
+
const responseOrderForm = await vtexApi.fetch(`/checkout/pub/orderForm/${orderFormId}?refreshOutdatedData=true`, { method: "GET" });
|
|
117
|
+
|
|
118
|
+
if (responseOrderForm.status !== 200){
|
|
119
|
+
Logger.error(responseOrderForm);
|
|
120
|
+
ApiResponse.response(404, { approved: false, message: "orderForm is not found" });
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const { data } = responseOrderForm;
|
|
124
|
+
|
|
125
|
+
return data;
|
|
126
|
+
} catch (error) {
|
|
127
|
+
Logger.error(error);
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async deleteCustomData(orderFormId, customData) {
|
|
133
|
+
try {
|
|
134
|
+
if (!customData) {
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
const vtexApi = new VtexApi(this.AccountName, this.Key, this.Token);
|
|
138
|
+
const customApps = customData?.customApps ?? [];
|
|
139
|
+
const financialPolicy = customApps?.find(app => app.id === this.FinancialPolicyEcu.configVtex.id);
|
|
140
|
+
const fields = financialPolicy?.fields;
|
|
141
|
+
|
|
142
|
+
if(this.FinancialPolicyEcu?.attachmentCredit && this.FinancialPolicyEcu?.attachmentCredit?.name && this.FinancialPolicyEcu?.attachmentCredit?.value){
|
|
143
|
+
await vtexApi.fetchPub(`/checkout/pub/orderForm/${orderFormId}/attachments/${this.FinancialPolicyEcu?.attachmentCredit?.name}`, { method: "POST" }, {value: null});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
for (const field in fields) {
|
|
147
|
+
await vtexApi.fetchPub(`/checkout/pub/orderForm/${orderFormId}/customData/${this.FinancialPolicyEcu.configVtex.id}/${field}`, { method: "DELETE" });
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return true;
|
|
151
|
+
} catch (error) {
|
|
152
|
+
Logger.error(error);
|
|
153
|
+
return ApiResponse.response(401, { approved: false, message: "Error deleting customData orderForm" });
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Updates the custom data of an order form.
|
|
159
|
+
*
|
|
160
|
+
* This method updates the custom data of an order form by performing the following steps:
|
|
161
|
+
* 1. Creates an instance of the VtexApi class using the provided account name, key, and token.
|
|
162
|
+
* 2. Sends a PUT request to the Vtex API to update the custom data of the specified order form.
|
|
163
|
+
* 3. Checks the response status. If the status is not 200, returns an error response.
|
|
164
|
+
* 4. Returns the updated custom data.
|
|
165
|
+
*
|
|
166
|
+
* @param {string} orderFormId - The ID of the order form to update.
|
|
167
|
+
* @param {string} idConfigVtex - The ID of the custom data configuration in Vtex.
|
|
168
|
+
* @param {Object} customData - The custom data to update.
|
|
169
|
+
* @returns {Promise<Object|null>} A promise that resolves to the updated custom data if successful, or null in case of an error.
|
|
170
|
+
* @throws {Error} If there is an error during the update process.
|
|
171
|
+
*/
|
|
172
|
+
async updateOrderFormCustomData(orderFormId, idConfigVtex, customData) {
|
|
173
|
+
try {
|
|
174
|
+
const vtexApi = new VtexApi(this.AccountName, this.Key, this.Token);
|
|
175
|
+
const response = await vtexApi.fetchPub(
|
|
176
|
+
`/checkout/pub/orderForm/${orderFormId}/customData/${idConfigVtex}`,
|
|
177
|
+
{ method: "PUT" },
|
|
178
|
+
customData
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
if(this.FinancialPolicyEcu?.attachmentCredit && this.FinancialPolicyEcu?.attachmentCredit?.name && this.FinancialPolicyEcu?.attachmentCredit?.value){
|
|
182
|
+
await vtexApi.fetchPub(`/checkout/pub/orderForm/${orderFormId}/attachments/${this.FinancialPolicyEcu?.attachmentCredit?.name}`, { method: "POST" }, this.FinancialPolicyEcu?.attachmentCredit?.value);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (response.status !== 200) {
|
|
186
|
+
Logger.error(response);
|
|
187
|
+
return ApiResponse.response(401, { approved: false, message: "Error updating customData orderForm" });
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return response.data;
|
|
191
|
+
} catch (error) {
|
|
192
|
+
Logger.error(error);
|
|
193
|
+
return ApiResponse.response(401, { approved: false, message: "Error updating customData orderForm" });
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
async cleanOrderFormCustomData(orderFormId, idConfigVtex) {
|
|
198
|
+
try {
|
|
199
|
+
const vtexApi = new VtexApi(this.AccountName, this.Key, this.Token);
|
|
200
|
+
const customData = {
|
|
201
|
+
"approved": "false",
|
|
202
|
+
"withCredit": "false",
|
|
203
|
+
"paymentTerm": "-",
|
|
204
|
+
"maximumCreditAmount": "-",
|
|
205
|
+
"paymentMethodCode": "-",
|
|
206
|
+
"creditDays": "-",
|
|
207
|
+
"paymentMethodName": "-"
|
|
208
|
+
};
|
|
209
|
+
const response = await vtexApi.fetchPub(
|
|
210
|
+
`/checkout/pub/orderForm/${orderFormId}/customData/${idConfigVtex}`,
|
|
211
|
+
{ method: "PUT" },
|
|
212
|
+
customData
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
if (response.status !== 200){
|
|
216
|
+
Logger.error(response);
|
|
217
|
+
return ApiResponse.response(401, { approved: false, message: "Error deleting customData orderForm" });
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return response.data;
|
|
221
|
+
} catch (error) {
|
|
222
|
+
Logger.error(error);
|
|
223
|
+
return ApiResponse.response(401, { approved: false, message: "Error cleaning customData orderForm" });
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Retrieves the customer balance from the Mobilvendor API.
|
|
229
|
+
*
|
|
230
|
+
* This method retrieves the customer balance by performing the following steps:
|
|
231
|
+
* 1. Checks if the Financial Policy is active. If not, returns an error response.
|
|
232
|
+
* 2. Checks if the orderFormId is provided. If not, returns an error response.
|
|
233
|
+
* 3. Retrieves the order form data using the provided orderFormId.
|
|
234
|
+
* 4. Retrieves the client data using the email from the order form data.
|
|
235
|
+
* 5. Retrieves the customer balance from the Mobilvendor API using the customer code.
|
|
236
|
+
* 6. Checks if the customer is found in the Mobilvendor API. If not, throws an error response.
|
|
237
|
+
* 7. Calculates the approved status based on various conditions.
|
|
238
|
+
* 8. Constructs the response object with the customer balance information.
|
|
239
|
+
* 9. Checks if the credit is not approved. If not, returns an error response.
|
|
240
|
+
* 10. Returns the response object with the customer balance information.
|
|
241
|
+
*
|
|
242
|
+
* @param {string} orderFormId - The ID of the order form associated with the customer.
|
|
243
|
+
* @param {number} creditDays - The number of credit days to consider for the customer.
|
|
244
|
+
* @returns {Promise<Object|null>} A promise that resolves to the response object with the customer balance information if successful, or null in case of an error.
|
|
245
|
+
* @throws {Error} If there is an error during the retrieval process.
|
|
246
|
+
*/
|
|
247
|
+
async getCustomerBalance(orderForm, creditDays = null, responseMasterDataCT=null) {
|
|
248
|
+
// Verificar si la política financiera está activa
|
|
249
|
+
if (!this.FinancialPolicyEcu.isActive) {
|
|
250
|
+
Logger.error("Financial Policy is not active");
|
|
251
|
+
return ApiResponse.response(401, { approved: false, message: "Financial Policy is not active" });
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Verificar si se proporcionó el orderFormId
|
|
255
|
+
if (!orderForm) {
|
|
256
|
+
Logger.error("orderForm is Required");
|
|
257
|
+
return ApiResponse.response(400, { approved: false, message: "orderForm is Required" });
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Obtener la información del cliente
|
|
261
|
+
const email = orderForm.clientProfileData?.email;
|
|
262
|
+
if (!responseMasterDataCT) {
|
|
263
|
+
Logger.error("Client not found");
|
|
264
|
+
return ApiResponse.response(404, { approved: false, message: "Client not found" });
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Calcular el valor del pedido
|
|
268
|
+
const value = (orderForm.value || 0) / 100;
|
|
269
|
+
const customerCode = responseMasterDataCT.pdv;
|
|
270
|
+
const customerWithCredit = responseMasterDataCT.withCredit ?? false;
|
|
271
|
+
// Obtener el balance del cliente
|
|
272
|
+
const responseMobilvendor = await this.getBalanceByCode(customerCode, value, creditDays, customerWithCredit);
|
|
273
|
+
return responseMobilvendor;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Retrieves the customer balance from the Mobilvendor API based on the customer code, value, and credit days.
|
|
278
|
+
*
|
|
279
|
+
* @param {string} customerCode - The customer code.
|
|
280
|
+
* @param {number} value - The value.
|
|
281
|
+
* @param {number} creditDays - The credit days.
|
|
282
|
+
* @returns {Object} - The response from the Mobilvendor API containing the customer balance information.
|
|
283
|
+
* @throws {Error} - If there is an error retrieving the customer balance.
|
|
284
|
+
*/
|
|
285
|
+
async getBalanceByCode(customerCode, value, creditDays = null, customerWithCredit=false) {
|
|
286
|
+
const { contextId, sessionId } = await this.login();
|
|
287
|
+
const dataGetCustomerBalance = {
|
|
288
|
+
session_id: sessionId,
|
|
289
|
+
action: "getCustomerBalance",
|
|
290
|
+
context_id: contextId,
|
|
291
|
+
customer_codes: [customerCode],
|
|
292
|
+
};
|
|
293
|
+
const { data } = await axios.post(this.FinancialPolicyEcu.configService.url, dataGetCustomerBalance);
|
|
294
|
+
|
|
295
|
+
if (!data?.records || data?.records.length == 0) {
|
|
296
|
+
Logger.error("customer not found in mobilvendor", dataGetCustomerBalance);
|
|
297
|
+
return ApiResponse.response(404, { approved: false, message: "customer not found in mobilvendor" });
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const controlData = data.records[0];
|
|
301
|
+
const balanceRecord = data.records.find(
|
|
302
|
+
(record) =>
|
|
303
|
+
(record.concepts === "2" || parseFloat(record.credit_limit) > 0) &&
|
|
304
|
+
record.status === "A" &&
|
|
305
|
+
record.expired_invoices === "0" &&
|
|
306
|
+
(creditDays ? parseInt(record.payment_term_days) === parseInt(creditDays) : true)
|
|
307
|
+
);
|
|
308
|
+
|
|
309
|
+
if (!balanceRecord) {
|
|
310
|
+
Logger.error("customer not found credit", controlData);
|
|
311
|
+
return ApiResponse.response(404, { approved: false, message: "customer not found credit" });
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
const {
|
|
315
|
+
balance,
|
|
316
|
+
status,
|
|
317
|
+
credit_limit,
|
|
318
|
+
payment_term_code,
|
|
319
|
+
payment_term_days,
|
|
320
|
+
payment_term_description,
|
|
321
|
+
concepts,
|
|
322
|
+
expired_invoices,
|
|
323
|
+
} = balanceRecord;
|
|
324
|
+
|
|
325
|
+
const approved =
|
|
326
|
+
status === "A" &&
|
|
327
|
+
(concepts === "0" || concepts === "2") &&
|
|
328
|
+
value <= parseFloat(credit_limit) &&
|
|
329
|
+
expired_invoices === "0" &&
|
|
330
|
+
parseFloat(balance) === 0;
|
|
331
|
+
|
|
332
|
+
const responseMobilvendor = {
|
|
333
|
+
approved,
|
|
334
|
+
withCredit: approved,
|
|
335
|
+
paymentTerm: payment_term_days || "",
|
|
336
|
+
maximumCreditAmount: parseFloat(credit_limit) || 0,
|
|
337
|
+
creditDays: parseInt(payment_term_days) || 0,
|
|
338
|
+
paymentMethodCode: payment_term_code || "",
|
|
339
|
+
paymentMethodName: payment_term_description || "",
|
|
340
|
+
customerWithCredit: approved ?? false
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
Logger.debug({ responseMobilvendor });
|
|
344
|
+
return responseMobilvendor;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Retrieves information about a specific route from the Mobilvendor API.
|
|
349
|
+
*
|
|
350
|
+
* This method first logs in to obtain the necessary session and context IDs. It then sends a POST request to the Mobilvendor API with the route code to retrieve information about the specified route.
|
|
351
|
+
*
|
|
352
|
+
* @param {string} routeCode - The code of the route for which to retrieve information.
|
|
353
|
+
* @returns {Promise<Object|null>} A promise that resolves to the route information from the Mobilvendor API if successful, or null in case of an error.
|
|
354
|
+
*/
|
|
355
|
+
async getRoute(routeCode) {
|
|
356
|
+
try {
|
|
357
|
+
const { contextId, sessionId } = await this.login();
|
|
358
|
+
const dataGetRoute = {
|
|
359
|
+
session_id: sessionId,
|
|
360
|
+
action: "getRoute",
|
|
361
|
+
context_id: contextId,
|
|
362
|
+
route_code: routeCode,
|
|
363
|
+
};
|
|
364
|
+
const responseGetRoute = await axios.post(
|
|
365
|
+
this.FinancialPolicyEcu.configService.url,
|
|
366
|
+
dataGetRoute
|
|
367
|
+
);
|
|
368
|
+
|
|
369
|
+
return responseGetRoute.data;
|
|
370
|
+
} catch (error) {
|
|
371
|
+
Logger.error(error);
|
|
372
|
+
return null;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Retrieves information about a specific route from the Mobilvendor API.
|
|
378
|
+
*
|
|
379
|
+
* This method first logs in to obtain the necessary session and context IDs. It then sends a POST request to the Mobilvendor API with the route code to retrieve information about the specified route.
|
|
380
|
+
*
|
|
381
|
+
* @param {string} routeCode - The code of the route for which to retrieve information.
|
|
382
|
+
* @returns {Promise<Object|null>} A promise that resolves to the route information from the Mobilvendor API if successful, or null in case of an error.
|
|
383
|
+
*/
|
|
384
|
+
async getRoutes() {
|
|
385
|
+
try {
|
|
386
|
+
const { contextId, sessionId } = await this.login();
|
|
387
|
+
const dataGetRoutes = {
|
|
388
|
+
session_id: sessionId,
|
|
389
|
+
action: "getRoutes",
|
|
390
|
+
context_id: contextId,
|
|
391
|
+
};
|
|
392
|
+
const responseGetRoutes = await axios.post(
|
|
393
|
+
this.FinancialPolicyEcu.configService.url,
|
|
394
|
+
dataGetRoutes
|
|
395
|
+
);
|
|
396
|
+
|
|
397
|
+
return responseGetRoutes.data.records;
|
|
398
|
+
} catch (error) {
|
|
399
|
+
Logger.error(error);
|
|
400
|
+
return null;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
module.exports = MobilvendorApi;
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
const axios = require("axios");
|
|
2
|
+
const VtexApi = require("../../vtex/clients/VtexApi");
|
|
3
|
+
const Logger = require("../../common/utils/logger");
|
|
4
|
+
|
|
5
|
+
class ProductMultiPresentation {
|
|
6
|
+
constructor(AccountName, Key, Token, AcronymDistributorVtex, ProductMultiPresentation) {
|
|
7
|
+
this.AccountName = AccountName;
|
|
8
|
+
this.Key = Key;
|
|
9
|
+
this.Token = Token;
|
|
10
|
+
this.AcronymDistributorVtex = AcronymDistributorVtex;
|
|
11
|
+
this.ProductMultiPresentation = ProductMultiPresentation;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Function per uatentication service external
|
|
16
|
+
**/
|
|
17
|
+
async getTokenAuth() {
|
|
18
|
+
return new Promise(async (response) => {
|
|
19
|
+
if (this.ProductMultiPresentation?.ServiceAuth && this.ProductMultiPresentation?.ServiceAuth?.Url && this.ProductMultiPresentation?.ServiceAuth?.Url != "") {
|
|
20
|
+
const url = this.ProductMultiPresentation?.ServiceAuth?.Url;
|
|
21
|
+
const options = {
|
|
22
|
+
method: this.ProductMultiPresentation?.ServiceAuth?.Method ?? 'GET',
|
|
23
|
+
headers: this.ProductMultiPresentation?.ServiceAuth?.Headers ?? {},
|
|
24
|
+
data: (this.ProductMultiPresentation?.ServiceAuth?.Body ? this.ProductMultiPresentation?.ServiceAuth?.Body : {}),
|
|
25
|
+
url
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
const resp = await axios(options);
|
|
30
|
+
if (resp?.data) {
|
|
31
|
+
response(resp?.data);
|
|
32
|
+
} else {
|
|
33
|
+
response(null);
|
|
34
|
+
}
|
|
35
|
+
} catch (e) {
|
|
36
|
+
Logger.error("error auth ProductMultiPresentation", e);
|
|
37
|
+
response(null);
|
|
38
|
+
}
|
|
39
|
+
} else {
|
|
40
|
+
Logger.error("error auth ProductMultiPresentation", "ServiceAuth not found");
|
|
41
|
+
response(null);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Normalize service extenal headers and body
|
|
49
|
+
**/
|
|
50
|
+
async normalizeBodyAndHeaders(AppExternalPresentation, token=null) {
|
|
51
|
+
let { Body: body, Headers: headers } = AppExternalPresentation;
|
|
52
|
+
|
|
53
|
+
if (typeof body === 'object') {
|
|
54
|
+
for (let property in body) {
|
|
55
|
+
if (typeof body[property] === 'string') {
|
|
56
|
+
try {
|
|
57
|
+
body[property] = eval(body[property]);
|
|
58
|
+
} catch (errEval) {
|
|
59
|
+
Logger.debug("error normalizeBodyAndHeaders", errEval, token);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (typeof headers === 'object') {
|
|
65
|
+
for (let property in headers) {
|
|
66
|
+
if (typeof headers[property] === 'string') {
|
|
67
|
+
try {
|
|
68
|
+
headers[property] = eval(headers[property]);
|
|
69
|
+
} catch (errEval) {
|
|
70
|
+
Logger.debug("error normalizeBodyAndHeaders", errEval, token);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return { body, headers };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async getProductList() {
|
|
80
|
+
let productList = [];
|
|
81
|
+
try {
|
|
82
|
+
const { AppExternalPresentation } = this.ProductMultiPresentation;
|
|
83
|
+
const { Url, Method, DtoProducts, AssignListProduct } = AppExternalPresentation;
|
|
84
|
+
const token= await this.getTokenAuth();
|
|
85
|
+
const { body, headers } = await this.normalizeBodyAndHeaders(AppExternalPresentation, token);
|
|
86
|
+
const response = await axios({
|
|
87
|
+
url: Url,
|
|
88
|
+
method: Method ?? 'post',
|
|
89
|
+
headers: headers,
|
|
90
|
+
data: JSON.stringify(body)
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// Se extrae la lista de productos de Geosales obtenida de la petición
|
|
94
|
+
let products = [];
|
|
95
|
+
if (AssignListProduct && AssignListProduct !== "") {
|
|
96
|
+
eval(`products=${AssignListProduct};`);
|
|
97
|
+
} else {
|
|
98
|
+
products = response?.data;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Se recorre la lista de productos (si existen elementos)
|
|
102
|
+
if (products?.length > 0) {
|
|
103
|
+
// Como la petición puede retornar 2 o más ítems con un mismo SKU, se deben agrupar los mismos priorizando aquellos que cumplan con la condicion "activo=1"
|
|
104
|
+
let skus = {}, index = 0;
|
|
105
|
+
for (let product of products) {
|
|
106
|
+
const { sku, activo } = product;
|
|
107
|
+
if (!skus.hasOwnProperty(sku)) {
|
|
108
|
+
// Si el SKU no está en el listado se agrega la información en la lista y se define los datos del índice de array y estado
|
|
109
|
+
productList.push(product);
|
|
110
|
+
skus[sku] = { index, activo };
|
|
111
|
+
index++;
|
|
112
|
+
} else {
|
|
113
|
+
// Se verifica si el producto de la lista tiene activo=0; pero se encontró un registro con el mismo SKU pero con activo=1, para actualizar los datos del producto
|
|
114
|
+
const { index } = skus[sku];
|
|
115
|
+
if (skus[sku].activo == '0' && activo == '1') {
|
|
116
|
+
productList[index] = product;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Si la lista unificada de productos tiene elementos, y se contempla aplicar un transformado de los datos, se actualiza el contenido de la lista
|
|
123
|
+
if (productList.length && Object.keys(DtoProducts).length > 0) {
|
|
124
|
+
productList = productList.map(product => {
|
|
125
|
+
const formattedProduct = {};
|
|
126
|
+
for (const [key, value] of Object.entries(DtoProducts)) {
|
|
127
|
+
if (product.hasOwnProperty(value)) {
|
|
128
|
+
formattedProduct[key] = product[value];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return formattedProduct;
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
} catch (error) {
|
|
135
|
+
Logger.error(error);
|
|
136
|
+
}
|
|
137
|
+
return productList;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async getDistributorList() {
|
|
141
|
+
try {
|
|
142
|
+
const vtexApi = new VtexApi(this.AccountName, this.Key, this.Token);
|
|
143
|
+
const distributors = await vtexApi.fetch(`/dataentities/${this.AcronymDistributorVtex}/search?_fields=_all`, {
|
|
144
|
+
method: "GET",
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
return distributors?.data?.length > 0 ? distributors.data : [];
|
|
148
|
+
} catch (error) {
|
|
149
|
+
Logger.error(error);
|
|
150
|
+
return [];
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async getAllProductsVTEX() {
|
|
155
|
+
return new Promise(async (res, err) => {
|
|
156
|
+
let listProductSkus = [];
|
|
157
|
+
try {
|
|
158
|
+
const listTradePolicy = this.ProductMultiPresentation?.TradePolicyId?.length > 0 ? this.ProductMultiPresentation?.TradePolicyId : [1];
|
|
159
|
+
const vtexApi = new VtexApi(this.AccountName, this.Key, this.Token);
|
|
160
|
+
|
|
161
|
+
for (let i = 0; i < listTradePolicy.length; i++) {
|
|
162
|
+
let stop = false, _from = 0, _to = 49;
|
|
163
|
+
while (stop === false) {
|
|
164
|
+
try {
|
|
165
|
+
const products = await vtexApi.fetch(`/catalog_system/pub/products/search/?sc=${listTradePolicy[i]}&_to=${_to}&_from=${_from}&O=OrderByNameASC`, {
|
|
166
|
+
method: "GET",
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
if (products?.data?.length > 0) {
|
|
170
|
+
for (let j = 0; j < products.data.length; j++) {
|
|
171
|
+
for (let t = 0; t < products.data[j].items.length; t++) {
|
|
172
|
+
let prod = products.data[j].items[t];
|
|
173
|
+
prod.productId = products.data[j].productId;
|
|
174
|
+
prod.TradePolicyId = listTradePolicy[i];
|
|
175
|
+
listProductSkus.push(prod);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
} else {
|
|
179
|
+
stop = true;
|
|
180
|
+
}
|
|
181
|
+
} catch (error) {
|
|
182
|
+
Logger.error("error getAllProductsVTEX while", error);
|
|
183
|
+
stop = true;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
_from += 50;
|
|
187
|
+
_to += 50;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
} catch (error) {
|
|
192
|
+
Logger.error("error getAllProductsVTEX", error);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
res(listProductSkus);
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
module.exports = ProductMultiPresentation;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const axios = require("axios");
|
|
2
|
+
const Logger = require("../../common/utils/logger");
|
|
3
|
+
|
|
4
|
+
class SecretManagerApi {
|
|
5
|
+
constructor(authorization, baseUrl) {
|
|
6
|
+
if (!authorization || !baseUrl) {
|
|
7
|
+
throw new Error("Invalid Secret Manager API Credentials");
|
|
8
|
+
}
|
|
9
|
+
this.authorization = authorization;
|
|
10
|
+
this.baseUrl = baseUrl;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
get baseURL() {
|
|
14
|
+
return this.baseUrl;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Excute a request to Secret Manager API
|
|
19
|
+
* @param {string} path
|
|
20
|
+
* @param {import("axios").AxiosRequestConfig} options
|
|
21
|
+
* @returns {Promise<import("axios").AxiosResponse>}
|
|
22
|
+
*/
|
|
23
|
+
fetch(path, options, includeFullResponse = true) {
|
|
24
|
+
const params = {
|
|
25
|
+
url: `${this.baseURL}/${path}`.replace(/([^:]\/)\/+/g, "$1"),
|
|
26
|
+
method: options.method || "GET",
|
|
27
|
+
headers: {
|
|
28
|
+
"Content-Type": "application/json",
|
|
29
|
+
Authorization: this.authorization,
|
|
30
|
+
...options.headers,
|
|
31
|
+
},
|
|
32
|
+
data : options.data,
|
|
33
|
+
ValidateStatus: function (status) {
|
|
34
|
+
return status >= 200 && status < 300;
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
return axios.request(params).then((response) => {
|
|
39
|
+
if (includeFullResponse) {
|
|
40
|
+
return response;
|
|
41
|
+
}
|
|
42
|
+
return response.data;
|
|
43
|
+
})
|
|
44
|
+
.catch((error) => {
|
|
45
|
+
// error is handled in catch block
|
|
46
|
+
Logger.error("Error Secret Manager API response: ", params);
|
|
47
|
+
if (error.response) {
|
|
48
|
+
// status code out of the range of 2xx
|
|
49
|
+
Logger.error("Data Secret Manager API response: ", error.response.data);
|
|
50
|
+
Logger.error("Status Secret Manager API response : ", error.response.status);
|
|
51
|
+
const errorResponse = {
|
|
52
|
+
status: error.response.status,
|
|
53
|
+
data: error.response.data,
|
|
54
|
+
};
|
|
55
|
+
return errorResponse;
|
|
56
|
+
} else if (error.request) {
|
|
57
|
+
// The request was made but no response was received
|
|
58
|
+
Logger.error("Error Secret Manager API no response: ", error.request);
|
|
59
|
+
const errorResponse = {
|
|
60
|
+
status: 500,
|
|
61
|
+
data: error.request,
|
|
62
|
+
};
|
|
63
|
+
return errorResponse;
|
|
64
|
+
} else {
|
|
65
|
+
// Error on setting up the request
|
|
66
|
+
Logger.error("Error Secret Manager API response: ", error.message);
|
|
67
|
+
const errorResponse = {
|
|
68
|
+
status: 500,
|
|
69
|
+
data: error.message,
|
|
70
|
+
};
|
|
71
|
+
return errorResponse;
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
module.exports = SecretManagerApi;
|