dcos-core-monalisav2-latam 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/README.md +130 -0
  2. package/index.js +350 -0
  3. package/package.json +52 -0
  4. package/src/auth/handler.js +3 -0
  5. package/src/common/MondelezCastOrder.js +449 -0
  6. package/src/common/utils/AuthSecurity.js +46 -0
  7. package/src/common/utils/account-error-handler.js +279 -0
  8. package/src/common/utils/account-error-helper.js +231 -0
  9. package/src/common/utils/account-properties-handler.js +355 -0
  10. package/src/common/utils/api-response.js +62 -0
  11. package/src/common/utils/aws-services.js +186 -0
  12. package/src/common/utils/constants/account-error-codes.json +801 -0
  13. package/src/common/utils/constants.js +37 -0
  14. package/src/common/utils/convert/MondelezClientsItemsCast.js +52 -0
  15. package/src/common/utils/convert/MondelezInventoryItemsCast.js +15 -0
  16. package/src/common/utils/convert/MondelezOrderStatusCast.js +34 -0
  17. package/src/common/utils/convert/MondelezPricesItemsCast.js +37 -0
  18. package/src/common/utils/cron-ftp-get.js +143 -0
  19. package/src/common/utils/data-tables-helper.js +213 -0
  20. package/src/common/utils/date-range-calculator.js +113 -0
  21. package/src/common/utils/delay.js +17 -0
  22. package/src/common/utils/ftp-sftp.js +320 -0
  23. package/src/common/utils/logger.js +126 -0
  24. package/src/common/utils/nodemailerLib.js +61 -0
  25. package/src/common/utils/product-unit-converter.js +168 -0
  26. package/src/common/utils/schemas-utils.js +101 -0
  27. package/src/common/utils/seller-email-sharing-service.js +441 -0
  28. package/src/common/utils/sftp-utils.js +202 -0
  29. package/src/common/utils/status.js +15 -0
  30. package/src/common/utils/util.js +236 -0
  31. package/src/common/utils/validate-state-order.js +35 -0
  32. package/src/common/utils/validateProviders.js +67 -0
  33. package/src/common/utils/validation-data.js +45 -0
  34. package/src/common/utils/vtex/save-hooks.js +65 -0
  35. package/src/common/utils/vtex/save-schemas.js +65 -0
  36. package/src/common/utils/vtex-hook-handler.js +71 -0
  37. package/src/common/validation/AccountCoordinatesValidation.js +350 -0
  38. package/src/common/validation/GeneralErrorValidation.js +11 -0
  39. package/src/common/validation/MainErrorValidation.js +8 -0
  40. package/src/entities/account.js +639 -0
  41. package/src/entities/clients.js +104 -0
  42. package/src/entities/controlprice.js +196 -0
  43. package/src/entities/controlstock.js +206 -0
  44. package/src/entities/cron.js +77 -0
  45. package/src/entities/cronjob.js +71 -0
  46. package/src/entities/orders.js +195 -0
  47. package/src/entities/sftp-inbound.js +88 -0
  48. package/src/entities/sku.js +220 -0
  49. package/src/entities/taxpromotion.js +249 -0
  50. package/src/functions/account/account-get.js +262 -0
  51. package/src/functions/account/account-handler.js +299 -0
  52. package/src/functions/account/clients.js +10 -0
  53. package/src/functions/account/index.js +208 -0
  54. package/src/functions/actions/save-promotions-order-history.js +324 -0
  55. package/src/functions/affiliates/affiliates-hook-consumer.js +87 -0
  56. package/src/functions/affiliates/affiliates-hook-producer.js +45 -0
  57. package/src/functions/clients/clients-audience.js +62 -0
  58. package/src/functions/clients/clients-consumer.js +648 -0
  59. package/src/functions/clients/clients-producer.js +362 -0
  60. package/src/functions/clients/clients-suggested-product-consumer.js +166 -0
  61. package/src/functions/clients/helpers/suggested-product-mdlz.js +233 -0
  62. package/src/functions/clients_peru/email.html +129 -0
  63. package/src/functions/clients_peru/splitfile.js +357 -0
  64. package/src/functions/clients_peru/updateClients.js +1334 -0
  65. package/src/functions/clients_peru/utils.js +243 -0
  66. package/src/functions/cronjobs/cron-jobs-manager.js +40 -0
  67. package/src/functions/cronjobs/cron-jobs.js +171 -0
  68. package/src/functions/crons/cron.js +39 -0
  69. package/src/functions/distributors/distributor-handler.js +81 -0
  70. package/src/functions/distributors/distributor.js +535 -0
  71. package/src/functions/distributors/index.js +60 -0
  72. package/src/functions/financialpolicy/assign-financialpolicy.js +111 -0
  73. package/src/functions/financialpolicy/get-financialpolicy.js +91 -0
  74. package/src/functions/financialpolicy/index.js +28 -0
  75. package/src/functions/inventory/catalog-sync-consumer.js +17 -0
  76. package/src/functions/inventory/catalog-sync-handler.js +311 -0
  77. package/src/functions/inventory/inventory-consumer.js +119 -0
  78. package/src/functions/inventory/inventory-producer.js +197 -0
  79. package/src/functions/multiPresentation/multipre-queue.js +155 -0
  80. package/src/functions/multiPresentation/multipres.js +459 -0
  81. package/src/functions/nodeflow/index.js +83 -0
  82. package/src/functions/nodeflow/nodeflow-cron.js +200 -0
  83. package/src/functions/nodeflow/nodeflow-pub.js +203 -0
  84. package/src/functions/nodeflow/nodeflow-pvt.js +266 -0
  85. package/src/functions/notifications/download-leads-handler.js +67 -0
  86. package/src/functions/notifications/new-leads-notification-consumer.js +17 -0
  87. package/src/functions/notifications/new-leads-notification-handler.js +359 -0
  88. package/src/functions/notifications/order-status-notification-handler.js +482 -0
  89. package/src/functions/notifications/promotion-notification-handler.js +193 -0
  90. package/src/functions/orders/index.js +32 -0
  91. package/src/functions/orders/orders-cancel-handler.js +74 -0
  92. package/src/functions/orders/orders-handler.js +280 -0
  93. package/src/functions/orders/orders-hook-consumer.js +137 -0
  94. package/src/functions/orders/orders-hook-producer.js +170 -0
  95. package/src/functions/orders/orders-notifications-handler.js +137 -0
  96. package/src/functions/orders/orders-status-consumer.js +461 -0
  97. package/src/functions/orders/orders-status-producer.js +443 -0
  98. package/src/functions/prices/index.js +75 -0
  99. package/src/functions/prices/prices-consumer.js +236 -0
  100. package/src/functions/prices/prices-producer.js +323 -0
  101. package/src/functions/prices/promotion-and-tax.js +1284 -0
  102. package/src/functions/routesflow/assign-routeflow-queue.js +77 -0
  103. package/src/functions/schemas/vtex/handle-schemas.js +102 -0
  104. package/src/functions/security/process_gas.js +221 -0
  105. package/src/functions/security/security-handler.js +950 -0
  106. package/src/functions/sftp/sftp-consumer.js +453 -0
  107. package/src/functions/sftpIntegrations/processes/redirectServices.js +184 -0
  108. package/src/functions/sftpIntegrations/processes/validateFileSchema.js +226 -0
  109. package/src/functions/sftpIntegrations/schemas/credential-schema.js +123 -0
  110. package/src/functions/sftpIntegrations/schemas/record-schema.js +131 -0
  111. package/src/functions/sftpIntegrations/schemas/sftp_required_fields.json +3 -0
  112. package/src/functions/sftpIntegrations/sftp-config-producer.js +112 -0
  113. package/src/functions/sftpIntegrations/sftp-consumer.js +700 -0
  114. package/src/functions/sftpIntegrations/test/validateFile.test.js +122 -0
  115. package/src/functions/sftpIntegrations/utils/connect-dynamo.js +29 -0
  116. package/src/functions/sftpIntegrations/utils/split-data.js +25 -0
  117. package/src/functions/utils/index.js +130 -0
  118. package/src/functions/vtex/vtex-helpers.js +694 -0
  119. package/src/integrations/accountErrors/AccountErrorManager.js +437 -0
  120. package/src/integrations/audience/Audience.js +70 -0
  121. package/src/integrations/financialPolicy/FinancialPolicyApi.js +377 -0
  122. package/src/integrations/index.js +0 -0
  123. package/src/integrations/mobilvendor/MobilvendorApi.js +405 -0
  124. package/src/integrations/productmultipresentation/ProductMultiPresentation.js +200 -0
  125. package/src/mdlz/auth/SecretManagerApi.js +77 -0
  126. package/src/mdlz/client/MdlzApi.js +70 -0
  127. package/src/vtex/clients/ProvidersApi.js +51 -0
  128. package/src/vtex/clients/VtexApi.js +511 -0
  129. package/src/vtex/models/VtexOrder.js +87 -0
@@ -0,0 +1,1284 @@
1
+ const ProductMultiPresentation = require("../../integrations/productmultipresentation/ProductMultiPresentation");
2
+ const AWSServices = require("../../common/utils/aws-services");
3
+ const VtexApi = require("../../vtex/clients/VtexApi");
4
+ const ApiResponse = require("../../common/utils/api-response");
5
+ const TaxPromotionsData = require("../../entities/taxpromotion");
6
+ const ClientData = require("../../entities/clients");
7
+ const AccountData = require("../../entities/account");
8
+ const Logger = require("../../common/utils/logger");
9
+ const SQS_PROCESSTAX_QUEUE_URL= process?.env?.SQS_PROCESSTAX_QUEUE_URL ?? null;
10
+ const SQS_PROCESSTAX_DQL_QUEUE_URL= process?.env?.SQS_PROCESSTAX_DQL_QUEUE_URL ?? null;
11
+ const MAX_ATTEMPS= process?.env?.MAX_ATTEMPS ?? null;
12
+
13
+ const RetryCreateVTEX = process?.env?.RetryCreateVTEX ?? 5;
14
+
15
+ /**
16
+ * Servicio para procesar impuesto
17
+ * @event Parametro don la informacion de la cola recibida
18
+ **/
19
+ const consumerapp = async (event) => {
20
+ for (const record of event.Records) {
21
+ Logger.debug("Message consumerapp Body from price procucer: ", record.body, ". Type: ", typeof record.body);
22
+
23
+ let { data, dataAccount, dataAccountParent } = JSON.parse(record.body);
24
+ const attemps = JSON.parse(record.body)?.attemps || 0;
25
+ const vtexApi = new VtexApi(dataAccount?.AccountName, dataAccount?.Credentials?.key, dataAccount?.Credentials?.token);
26
+
27
+ if(attemps && MAX_ATTEMPS >= attemps){
28
+ await sendSQStax(JSON.parse(record.body), true);
29
+ return false;
30
+ }
31
+
32
+ try{
33
+ let resSavetaxapp= await setTaxes({
34
+ data:data,
35
+ vtexApi:vtexApi,
36
+ dataAccount: dataAccount,
37
+ dataAccountParent: dataAccountParent
38
+ });
39
+
40
+ const listClearPromotions= await setPromotionsClearVTEX({
41
+ vtexApi:vtexApi,
42
+ dataAccount: dataAccount
43
+ });
44
+ }catch (err){
45
+ Logger.error('Error save tax internal app.',err);
46
+ await delayStatusProcess(5);
47
+ await sendSQStax({
48
+ data:data,
49
+ dataAccount: dataAccount,
50
+ attemps: attemps ? (attemps+1) : 1
51
+ });
52
+ }
53
+
54
+ }
55
+ };
56
+
57
+ /**
58
+ * Retorna listado de promociones para generar limpieza dentro de VTEX
59
+ * @param vtexApp -- Objeto con la configuracion de servicios VTEX
60
+ * @param dataAccount -- Objeto con las configuraciones de la cuenta
61
+ **/
62
+ const setPromotionsClearVTEX= async ({vtexApi=null, dataAccount= null})=>{
63
+ if(!vtexApi || !dataAccount || !dataAccount?.AccountName){
64
+ Logger.error('tax not procesed', 'vtexApi', vtexApi, 'dataAccount', dataAccount);
65
+ return null;
66
+ }
67
+
68
+ return new Promise(async (res, err)=>{
69
+ let listTaxes= await TaxPromotionsData.getAllPromotionsOrTaxes({IdSeller:[dataAccount?.AccountName], TypeSearch: 'taxes'});
70
+ let searchTaxes= await getAllTaxes({vtexApi:vtexApi}),
71
+ listForArchive=[];
72
+
73
+ for (let i = 0; i < searchTaxes?.items.length; i++) {
74
+ let promoArchive= listTaxes.find(pr=>(pr?.idCalculatorConfiguration === searchTaxes?.items[i]?.idCalculatorConfiguration));
75
+ if(!promoArchive){
76
+ listForArchive= [...listForArchive, searchTaxes?.items[i]];
77
+ }
78
+ }
79
+
80
+ for (let i = 0; i < listForArchive?.length; i++) {
81
+ try{
82
+ let resArch= await archivePromotionOrtaxVtex({id:listForArchive[i]?.idCalculatorConfiguration, vtexApi:vtexApi});
83
+ if(!resArch){
84
+ throw "Error Archive";
85
+ }
86
+ }catch(ee){
87
+ Logger.error(ee);
88
+ err(ee);
89
+ }
90
+ }
91
+
92
+ res(listForArchive);
93
+ })
94
+ }
95
+
96
+ /**
97
+ * Obtiene todos los impuestos relacionados a un id de impuesto
98
+ **/
99
+ const getTaxesPerIdRelation= async (idInitial)=>{
100
+ let listTaxes= [];
101
+ let count= 1;
102
+ let stopApi= false;
103
+
104
+ while (stopApi === false) {
105
+ let idEnd= `${idInitial}${count}`;
106
+ count++;
107
+ try{
108
+ const dataTax= await TaxPromotionsData.getPerId(idEnd);
109
+ if(dataTax){
110
+ listTaxes= [...listTaxes, dataTax];
111
+ }else{
112
+ stopApi= true;
113
+ }
114
+ }catch(er){
115
+ Logger.error("error search promotion", idInitial, count);
116
+ stopApi= true;
117
+ }
118
+ }
119
+
120
+ return listTaxes;
121
+ };
122
+
123
+ /**
124
+ * Get all product VTEX
125
+ **/
126
+ const getAllProductVtex= async (accountConfig)=>{
127
+ const listProducts = new ProductMultiPresentation(
128
+ accountConfig.AccountName,
129
+ accountConfig.Credentials.key,
130
+ accountConfig.Credentials.token,
131
+ null,
132
+ accountConfig.ProductMultiPresentation
133
+ );
134
+
135
+ return await listProducts.getAllProductsVTEX();
136
+ };
137
+
138
+ /**
139
+ * Funcion para comvertir sku a sku vtex
140
+ **/
141
+ const convertSkuVtex= (dataTax, productsVtex)=>{
142
+ let skuVtex= [], skuNoVtex= [];
143
+ for (let i = 0; i < dataTax?.skus.length; i++) {
144
+ const skuErp= dataTax?.skus[i];
145
+ const productVtex= productsVtex?.find(it=>(it?.referenceId[0]?.Value == skuErp || it?.ean == skuErp || it?.itemId == skuErp));
146
+ if(productVtex){
147
+ skuVtex= [...skuVtex, {
148
+ id: productVtex?.itemId,
149
+ name: productVtex?.name
150
+ }];
151
+ }else{
152
+ skuNoVtex=[...skuNoVtex, skuErp];
153
+ }
154
+ }
155
+ dataTax.skus= skuVtex;
156
+ return dataTax;
157
+ };
158
+
159
+
160
+ /**
161
+ * Asignacion de impuestos dentro de VTEX
162
+ * @param data -- datos de ingreso dentro de la cola
163
+ * @param vtexApi -- configuracion para servicios de VTEX
164
+ * @param dataAccount -- datos de configuracion
165
+ **/
166
+ const setTaxes= async ({data=null, vtexApi=null, dataAccount= null, dataAccountParent=null})=>{
167
+ if(!data || !vtexApi || !dataAccount || !dataAccount?.AccountName || !dataAccountParent || !dataAccountParent?.AccountName || typeof data != 'object' || Object.keys(data).length === 0) {
168
+ Logger.error('tax not procesed','data', data, 'vtexApi', vtexApi, 'dataAccount', dataAccount, 'dataAccountParent', dataAccountParent);
169
+ return null;
170
+ }
171
+
172
+ return new Promise(async(res, error)=>{
173
+ try{
174
+ const allProducts= await getAllProductVtex(dataAccountParent);
175
+ let responseObjSave=[], listTaxesNofifications=[];
176
+
177
+ for (const tax in data) {
178
+ const dataTax= convertSkuVtex(data[tax], allProducts);
179
+ listTaxesNofifications= [...listTaxesNofifications, {id: tax, data:dataTax}];
180
+ const listTaxes= await getTaxesPerIdRelation(tax);
181
+
182
+ let dataTaxesSave= await getDataSaveTax({listTaxes:listTaxes, dataTax: dataTax, idExternalPromotion:tax});
183
+ if(dataTaxesSave && dataTaxesSave?.length > 0){
184
+ for (let i = 0; i < dataTaxesSave.length; i++) {
185
+ responseObjSave= [...responseObjSave, dataTaxesSave[i]];
186
+ }
187
+ }
188
+ }
189
+
190
+ const listUpdate= await getListTaxesUpdate({listTaxesNofifications: listTaxesNofifications, AccountName: dataAccount?.AccountName });
191
+ if(listUpdate?.length > 0){
192
+ for (let u = 0; u < listUpdate.length; u++) {
193
+ responseObjSave= [...responseObjSave, listUpdate[u]];
194
+ }
195
+ }
196
+
197
+ let listTaxUpdated=[];
198
+ for (let i = 0; i < responseObjSave?.length; i++) {
199
+ let responseSaveTaxApp= await saveTaxOrPromotionApp({data: responseObjSave[i]});
200
+ if(responseSaveTaxApp){
201
+ listTaxUpdated= [...listTaxUpdated, responseSaveTaxApp];
202
+ }
203
+ }
204
+
205
+ await delayStatusProcess(3);
206
+ let responsesSavesVTEX= [];
207
+ for (let x= 0; x < listTaxUpdated.length; x++) {
208
+ let responseSaveVTEX= await saveTaxVTEX({dataTax: listTaxUpdated[x], dataAccount:dataAccount, returnCatch: true});
209
+ responsesSavesVTEX= [...responsesSavesVTEX, responseSaveVTEX];
210
+ }
211
+
212
+ res(listTaxUpdated);
213
+ } catch (errr){
214
+ error(errr);
215
+ }
216
+ });
217
+ }
218
+
219
+ /**
220
+ * Crear o actualizar promociones o impuestos VTEX
221
+ **/
222
+ const saveTaxVTEX= async ({dataTax=null, dataAccount=null, returnCatch=false})=>{
223
+
224
+ if (!dataTax || !dataAccount) {
225
+ return null;
226
+ }
227
+
228
+ try{
229
+ const idEnd= dataTax?.idExternalPromotion ?? null;
230
+ let dataTaxExist= await TaxPromotionsData.getPerId(idEnd);
231
+ try{
232
+ if(dataTaxExist){
233
+ delete dataTaxExist.idSeller;
234
+
235
+ try{
236
+ const { an, key, token } = {
237
+ an: dataAccount?.AccountName,
238
+ key: dataAccount?.Credentials?.key,
239
+ token: dataAccount?.Credentials?.token
240
+ };
241
+
242
+ const vtexApi = new VtexApi(an, key, token);
243
+ const dataSaveVtex= await saveTaxOrPromotion({data:dataTaxExist, vtexApi:vtexApi, returnCatch:returnCatch});
244
+ if(dataSaveVtex){
245
+ dataTaxExist.idCalculatorConfiguration= dataSaveVtex?.idCalculatorConfiguration;
246
+ dataTaxExist.lastModified= dataSaveVtex?.lastModified;
247
+ let responseSave2= await TaxPromotionsData.createOrUpdate(dataTaxExist);
248
+
249
+ }else{
250
+ // enviar a cola
251
+ throw "error save VTEX";
252
+ }
253
+ }catch (e){
254
+ Logger.error('error save VTEX', e);
255
+ // enviar a cola
256
+ throw "error save VTEX or save app.";
257
+ }
258
+ }
259
+ }catch (err){
260
+ Logger.error('error save VTEX', err);
261
+ throw "error save TAX";
262
+ }
263
+
264
+ return dataTaxExist;
265
+ }catch (e){
266
+ Logger.error(e);
267
+ throw "not save TAX";
268
+ return null;
269
+ }
270
+ }
271
+
272
+ /**
273
+ * Crear o actualizar promociones o impuestos API
274
+ **/
275
+ const saveTaxOrPromotionApp= async ({data=null})=>{
276
+
277
+ if (!data || (!data?.idExternalPromotion && !data?.idCalculatorConfiguration)) {
278
+ return null;
279
+ }
280
+
281
+ if(data?.idCalculatorConfiguration && !data?.idExternalPromotion){
282
+ const registerPerIdVTEX= await TaxPromotionsData.getPerIdVtex(data?.idCalculatorConfiguration);
283
+
284
+ if(registerPerIdVTEX && registerPerIdVTEX?.idExternalPromotion){
285
+ data.idExternalPromotion= registerPerIdVTEX?.idExternalPromotion;
286
+ }
287
+ }
288
+
289
+ const dataCompleteSave= data;
290
+ const idPromotionTax= dataCompleteSave?.idExternalPromotion ?? null;
291
+
292
+ if(dataCompleteSave && idPromotionTax){
293
+ try{
294
+ const responseSave= await TaxPromotionsData.createOrUpdate(dataCompleteSave);
295
+ return responseSave;
296
+ }catch (e){
297
+ Logger.error('error create promo app internal',e);
298
+ throw 'error create promo app internal';
299
+ return null;
300
+ }
301
+ }else{
302
+ Logger.error('error create promo app internal idPromotionTax or dataCompleteSave incomplete',dataCompleteSave, idPromotionTax);
303
+ return null;
304
+ }
305
+ }
306
+
307
+ /**
308
+ * Crear o actualizar promociones o impuestos VTEX
309
+ **/
310
+ const saveTaxOrPromotionVTEX= async ({idPromotionTax=null, dataAccount=null, isTax=false, returnCatch=false})=>{
311
+
312
+ if (!idPromotionTax || !dataAccount) {
313
+ return null;
314
+ }
315
+
316
+ try{
317
+ let dataPromotionSave= await TaxPromotionsData.getPerId(idPromotionTax);
318
+ let responseSave= dataPromotionSave;
319
+
320
+ try{
321
+ if(dataPromotionSave){
322
+ if(isTax===true){
323
+ delete dataPromotionSave.idSeller;
324
+ }
325
+ try{
326
+ const { an, key, token } = {
327
+ an: dataAccount?.AccountName,
328
+ key: dataAccount?.Credentials?.key,
329
+ token: dataAccount?.Credentials?.token
330
+ };
331
+
332
+ const vtexApi = new VtexApi(an, key, token);
333
+ const dataSaveVtex= await saveTaxOrPromotion({data:dataPromotionSave, vtexApi:vtexApi, returnCatch:returnCatch});
334
+ if(dataSaveVtex){
335
+ responseSave.idCalculatorConfiguration= dataSaveVtex?.idCalculatorConfiguration;
336
+ responseSave.lastModified= dataSaveVtex?.lastModified;
337
+ responseSave.idExternalPromotion= idPromotionTax;
338
+ let responseSave2= await TaxPromotionsData.createOrUpdate(responseSave);
339
+
340
+ }else{
341
+ // enviar a cola
342
+ throw "error save VTEX response null";
343
+ }
344
+ }catch (e){
345
+ Logger.error('error save VTEX', e);
346
+ // enviar a cola
347
+ throw "error save VTEX or save app.";
348
+ }
349
+ }
350
+ }catch (err){
351
+ Logger.error('error save VTEX', err);
352
+ throw "error save TAX";
353
+ }
354
+
355
+ return responseSave;
356
+ }catch (e){
357
+ Logger.error(e);
358
+ throw "not save TAX";
359
+ return null;
360
+ }
361
+ }
362
+
363
+ /**
364
+ * Obtiene listas de impuestos para validar que el sku no exista en impuestos que no aplica
365
+ **/
366
+ const getListTaxesUpdate= async ({listTaxesNofifications= null, AccountName=null})=>{
367
+ if(!listTaxesNofifications || !AccountName){
368
+ return [];
369
+ }
370
+
371
+ let listTaxes= await TaxPromotionsData.getAllPromotionsOrTaxes({IdSeller:[AccountName], TypeSearch: 'taxes'});
372
+ let listTaxesValid=[];
373
+ let listUpdate=[];
374
+
375
+ for (let i = 0; i < listTaxes.length; i++) {
376
+ let exit= false;
377
+ for (let j = 0; j < listTaxesNofifications.length; j++) {
378
+ if(listTaxes[i]?.idExternalPromotion?.indexOf(listTaxesNofifications[j]?.id) > -1 ){
379
+ exit= true;
380
+ }
381
+ }
382
+
383
+ if(!exit){
384
+ listTaxesValid=[...listTaxesValid, listTaxes[i]];
385
+ }
386
+ }
387
+
388
+ for (let i = 0; i < listTaxesValid?.length; i++) {
389
+ let update=false;
390
+ let listSkusUpdate= [];
391
+ for (let j = 0; j < listTaxesValid[i]?.skus?.length; j++) {
392
+ let foundSku= false;
393
+ let skuSearch= listTaxesValid[i]?.skus[j]?.id;
394
+ for (let vs = 0; vs < listTaxesNofifications.length; vs++) {
395
+ let skus=listTaxesNofifications[vs]?.data?.skus ?? [];
396
+ let skufind= skus.find(is=>(is?.id === skuSearch));
397
+ if(skufind){
398
+ foundSku=true;
399
+ }
400
+ }
401
+ if( foundSku === true){
402
+ update=true;
403
+ }else{
404
+ listSkusUpdate= [...listSkusUpdate, {
405
+ id: listTaxesValid[i]?.skus[j]?.id,
406
+ name: listTaxesValid[i]?.skus[j]?.name
407
+ }]
408
+ }
409
+ }
410
+
411
+ if(update === true){
412
+ listTaxesValid[i].skus= listSkusUpdate;
413
+ if(listTaxesValid[i]?.skus?.length === 0){
414
+ listTaxesValid[i].isActive= false;
415
+ }
416
+ listUpdate= [...listUpdate, listTaxesValid[i]];
417
+ }
418
+ }
419
+
420
+ return listUpdate;
421
+ };
422
+
423
+ /**
424
+ * Se obtiene json inicial para lamacenamiento
425
+ **/
426
+ const getJsonDataTaxInitial= (tax=null, idExternalPromotion=null)=>{
427
+ const idSeller= tax?.an;
428
+ const yearNow= (new Date()).getFullYear();
429
+ let objectTax= {
430
+ idExternalPromotion: idExternalPromotion,
431
+ name: String(`${idExternalPromotion}`).replace(/ /g, '').toLocaleUpperCase(),
432
+ isActive: true,
433
+ origin: "Fulfillment",
434
+ description: tax?.description ? tax?.description : idExternalPromotion,
435
+ beginDateUtc: `${yearNow}-01-01T00:00:00Z`,
436
+ endDateUtc: `${(parseInt(yearNow)+2)}-01-30T23:59:00Z`,
437
+ skusAreInclusive: true,
438
+ nominalDiscountType: "cart",
439
+ clusterExpressions: [],
440
+ clusterOperator: "all",
441
+ type: "tax",
442
+ idSeller: idSeller
443
+ };
444
+
445
+ if(tax?.type === 'percentual'){
446
+ objectTax.percentualTax = tax?.value;
447
+ }else if(tax?.type === 'nominal') {
448
+ objectTax.nominalTax = tax?.value;
449
+ }
450
+
451
+ return objectTax;
452
+ };
453
+
454
+ /**
455
+ * Dividir skus en grupos de 100
456
+ **/
457
+ const getSkusPerCien= (skus)=>{
458
+ let group= [], c=0, countP=0, skusS=[];
459
+ for (let i = 0; i < skus.length; i++) {
460
+
461
+ if(countP >= 100){
462
+ skusS= [];
463
+ c++;
464
+ countP=0;
465
+ }
466
+ countP++;
467
+ skusS= [...skusS, skus[i]];
468
+ group[c]= skusS;
469
+ }
470
+
471
+ return group;
472
+ };
473
+
474
+ /**
475
+ * Funcion para obtener los objetos a salvar
476
+ **/
477
+ const getObjectFinish= (tax, idExternalPromotion, count=0, idsTaxesVtex=null)=>{
478
+ let divCien= getSkusPerCien(tax?.skus);
479
+ let objectTaxes= [];
480
+ for (let c = 0; c < divCien.length; c++) {
481
+ count++;
482
+ let idTax= `${idExternalPromotion}${count}`;
483
+ let objectTax= getJsonDataTaxInitial(tax, idTax);
484
+ objectTax.idCalculatorConfiguration= idsTaxesVtex && idsTaxesVtex[idTax] ? idsTaxesVtex[idTax] : null;
485
+ objectTax.skus= divCien[c] ?? [];
486
+ let objectTaxSv= getDataCompleteTaxPromotions({data: objectTax, idPromotionTax: `${idExternalPromotion}${count}`});
487
+ objectTaxes= [...objectTaxes, objectTaxSv];
488
+ }
489
+ return objectTaxes;
490
+ };
491
+
492
+ /**
493
+ * Unir skus de promiciones relacionadas
494
+ **/
495
+ const getMergeSkusListTaxes = (listTaxesMerge=[])=>{
496
+ let skusMg= [], skusMgInclude=[];
497
+ let rListTax= [], listIdTaxesVtex={};
498
+
499
+ for (let i = 0; i < listTaxesMerge.length; i++) {
500
+ let skusFor= listTaxesMerge[i]?.skus;
501
+ let idTax= listTaxesMerge[i]?.idExternalPromotion;
502
+ listIdTaxesVtex[idTax]= listTaxesMerge[i]?.idCalculatorConfiguration ?? null;
503
+ for (let j = 0; j < skusFor.length; j++) {
504
+ if(!skusMgInclude.includes(skusFor[j].id)){
505
+ skusMg= [...skusMg, skusFor[j]];
506
+ skusMgInclude= [...skusMgInclude, skusFor[j].id];
507
+ }
508
+ }
509
+ }
510
+ if(listTaxesMerge[0]){
511
+ listTaxesMerge[0].skus= skusMg;
512
+ rListTax= [...rListTax, listTaxesMerge[0]];
513
+ }
514
+ return {listTaxesMerge: rListTax, listIdTaxesVtex: listIdTaxesVtex };
515
+ };
516
+
517
+ /**
518
+ * Traer lista de skus gerenar para almacenar
519
+ *
520
+ **/
521
+ const getListSkusFinish= (listSkusCreate, listTaxesMerge)=>{
522
+ let skusReturn= [];
523
+ for (let i = 0; i < listTaxesMerge.length; i++) {
524
+ for (let j = 0; j < listTaxesMerge[i].skus.length; j++) {
525
+ let skusave= listTaxesMerge[i].skus[j];
526
+ skusReturn=[...skusReturn, skusave];
527
+ }
528
+ }
529
+
530
+ for (let i = 0; i < listSkusCreate?.length; i++) {
531
+ let skusavec= listSkusCreate[i];
532
+ skusReturn=[...skusReturn, skusavec];
533
+ }
534
+
535
+ return skusReturn;
536
+ };
537
+
538
+ /**
539
+ * Obtener lista de impuestos salvar por items
540
+ * @param listTaxes -- liata de impuestos vtex
541
+ * @param tax -- impuesto de un item especifico
542
+ * @param skuId -- id de sku VTEX
543
+ * @param vtexApi -- objeto con lcases de VTEX
544
+ **/
545
+ const getDataSaveTax= ({listTaxes=null, dataTax=null, idExternalPromotion= null})=>{
546
+ if(!listTaxes || !dataTax || !idExternalPromotion){
547
+ return null;
548
+ }
549
+
550
+ let listTaxesUpdate= [];
551
+ const tax= dataTax;
552
+
553
+ let objectTaxes=[];
554
+ if(listTaxes?.length === 0){
555
+ return getObjectFinish(tax, idExternalPromotion, 0, null);
556
+ }else{
557
+ let listSkusCreate= [];
558
+ const listSkus= tax?.skus ?? [];
559
+ const listTaxesAndIdVtex = getMergeSkusListTaxes(listTaxes);
560
+ const listTaxesMerge = listTaxesAndIdVtex?.listTaxesMerge ?? [];
561
+ const listIdTaxesVtex = listTaxesAndIdVtex?.listIdTaxesVtex ?? {};
562
+
563
+ for (let j = 0; j < listSkus.length; j++) {
564
+ let existSku= false;
565
+ for (let i = 0; i < listTaxesMerge?.length; i++) {
566
+ let findSku= listTaxesMerge[i]?.skus?.find(it=> (it?.id==listSkus[j]?.id));
567
+ if(findSku){
568
+ existSku=true;
569
+ }
570
+ }
571
+
572
+ if(existSku===false){
573
+ listSkusCreate= [...listSkusCreate, listSkus[j]];
574
+ }
575
+ }
576
+
577
+ let createnw= listSkusCreate?.length > 0 ? true : false;
578
+ if(createnw===true){
579
+ tax.skus= getListSkusFinish(listSkusCreate, listTaxesMerge);
580
+ objectTaxes= getObjectFinish(tax, idExternalPromotion, 0, listIdTaxesVtex);
581
+ }
582
+
583
+ return objectTaxes;
584
+ }
585
+ };
586
+
587
+ /**
588
+ * Obtener lista promociones por name VTEX
589
+ * @param name -- Nombre de la promoiciom
590
+ * */
591
+ const getAllTaxes= async ({vtexApi=null})=>{
592
+ if(!vtexApi){
593
+ return null;
594
+ }
595
+ return new Promise(async(res, error)=>{
596
+
597
+ const resTaxes = await vtexApi.fetch(`/rnb/pvt/taxes/calculatorconfiguration`, {
598
+ method: "GET"
599
+ });
600
+
601
+ if(resTaxes?.data){
602
+ res(resTaxes?.data);
603
+ }else{
604
+ res([]);
605
+ }
606
+ });
607
+ }
608
+
609
+ /**
610
+ * Obtener lista promociones por name VTEX
611
+ * @param name -- Nombre de la promoiciom
612
+ * */
613
+ const getAllPromotions= async ({vtexApi=null})=>{
614
+ if(!vtexApi){
615
+ return null;
616
+ }
617
+ return new Promise(async(res, error)=>{
618
+
619
+ const resPromotions = await vtexApi.fetch(`/rnb/pvt/benefits/calculatorconfiguration`, {
620
+ method: "GET"
621
+ });
622
+
623
+ if(resPromotions?.data){
624
+ res(resPromotions?.data);
625
+ }else{
626
+ res([]);
627
+ }
628
+ });
629
+ }
630
+
631
+ /**
632
+ * Obtener datos de la promocion VTEX
633
+ * @param id -- id del impuesto
634
+ * @param vtexApi -- vtexApi objeto servicios VTEX
635
+ * */
636
+ const getDataTax= async ({id=null, vtexApi=null})=>{
637
+ if(!vtexApi || !id){
638
+ return null;
639
+ }
640
+ return new Promise(async(res, error)=>{
641
+
642
+ const resTaxes = await vtexApi.fetch(`/rnb/pvt/calculatorconfiguration/${id}`, {
643
+ method: "GET"
644
+ });
645
+
646
+ if(resTaxes?.data){
647
+ res(resTaxes?.data);
648
+ }else{
649
+ res(null);
650
+ }
651
+ });
652
+ }
653
+
654
+ /**
655
+ * Obtener lista promociones por name
656
+ * @param name -- Nombre de la promoiciom
657
+ * */
658
+ const getDataSkuPerId= async ({skuId=null, vtexApi=null})=>{
659
+ if(!skuId || !vtexApi){
660
+ return null;
661
+ }
662
+ return new Promise(async(res, error)=>{
663
+
664
+ const resSku = await vtexApi.fetch(`/catalog_system/pvt/sku/stockkeepingunitbyid/${skuId}`, {
665
+ method: "GET"
666
+ });
667
+
668
+ if(resSku?.data){
669
+ res(resSku?.data);
670
+ }else{
671
+ res(null);
672
+ }
673
+ });
674
+ }
675
+
676
+ /**
677
+ * Guardar impuesto dentro de VTEX
678
+ * @param data -- Datos del impuesto
679
+ * @param vtexApi -- Objeto con propieadades VTEX
680
+ * */
681
+ const saveTaxOrPromotion= async ({data=null, vtexApi=null, returnCatch=false})=>{
682
+ if(typeof data !== 'object' || !data || !vtexApi){
683
+ return null;
684
+ }
685
+ return new Promise(async(res, error)=>{
686
+
687
+ if(data?.type === 'tax'){
688
+ if(data?.percentualTax === 0 && data?.nominalTax === 0){
689
+ res(null);
690
+ return;
691
+ }
692
+
693
+ try{
694
+ let searchTaxes=await vtexApi.fetch(`/rnb/pvt/taxes/calculatorconfiguration`, {
695
+ method: "GET"
696
+ });
697
+
698
+ let listItems= searchTaxes?.data?.items ?? [];
699
+ let findPerName= listItems?.find(tx=>(tx?.name === data?.name));
700
+ if(findPerName?.idCalculatorConfiguration){
701
+ data.idCalculatorConfiguration= findPerName.idCalculatorConfiguration;
702
+ }
703
+ }catch(errsvtex){
704
+ Logger.error('Error search tax in vtex.');
705
+ if(returnCatch === true){
706
+ error(errsvtex);
707
+ }
708
+ }
709
+ }
710
+
711
+ if(!data?.idCalculatorConfiguration){
712
+ delete data.idCalculatorConfiguration;
713
+ }
714
+ let response= {status:200, data:null};
715
+ try{
716
+ response = await vtexApi.fetch(`/rnb/pvt/calculatorconfiguration/`, {
717
+ method: "POST",
718
+ data: data
719
+ });
720
+ }catch(errsvtex){
721
+ Logger.error('Error save tax in vtex.', errsvtex, JSON.stringify(data));
722
+ if(returnCatch === true){
723
+ error(errsvtex);
724
+ }
725
+ }
726
+
727
+ if(response?.status >= 200 && response?.status < 300){
728
+ res(response?.data);
729
+ }else{
730
+ res(null);
731
+ }
732
+ });
733
+ }
734
+
735
+ /**
736
+ * Crear o actualizar promociones o impuestos API
737
+ **/
738
+ const createorupdate= async (event)=>{
739
+
740
+ let data = JSON.parse(event.body);
741
+ const clientId = event?.requestContext?.authorizer?.claims?.client_id;
742
+ const accountName= data?.idSeller;
743
+
744
+ const validateAccount = await ClientData.validateAccount(clientId, accountName);
745
+
746
+ if(validateAccount===false){
747
+ return ApiResponse.response(404, 'idSeller not authorizer!');
748
+ }
749
+
750
+ let dataAccount = await AccountData.getAccountDataByAccountName(accountName);
751
+ if (!dataAccount) {
752
+ Logger.error("Account not found: ", accountName, ". ClientId: ", clientId);
753
+ return ApiResponse.response(404, "Account not found");
754
+ }
755
+ const accountNameParent= dataAccount?.ParentAccountName;
756
+ if(dataAccount?.PromotionsPerParentAccount && dataAccount?.PromotionsPerParentAccount === true){
757
+ dataAccount = await AccountData.getAccountDataByAccountName(accountNameParent);
758
+ }
759
+
760
+ if (!dataAccount) {
761
+ Logger.error("AccountParent not found: ", accountNameParent, ". ClientId: ", clientId);
762
+ return ApiResponse.response(404, "Account Parent not found");
763
+ }
764
+
765
+ let idPromotionTax= getIdPromotionTax({data:data});
766
+ if(data?.idCalculatorConfiguration && !data?.idExternalPromotion){
767
+ const registerPerIdVTEX= await TaxPromotionsData.getPerIdVtex(data?.idCalculatorConfiguration);
768
+
769
+ if(registerPerIdVTEX && registerPerIdVTEX?.idExternalPromotion){
770
+ idPromotionTax= registerPerIdVTEX?.idExternalPromotion;
771
+ }
772
+ }
773
+
774
+ const dataCompleteSave= getDataCompleteTaxPromotions({data: data, idPromotionTax: idPromotionTax});
775
+
776
+ if(dataCompleteSave){
777
+ try{
778
+ let responseSave= await TaxPromotionsData.createOrUpdate(dataCompleteSave);
779
+ try{
780
+ const dataPromotionSave= await TaxPromotionsData.getPerId(idPromotionTax);
781
+
782
+ if(dataPromotionSave){
783
+ try{
784
+ const { an, key, token } = {
785
+ an: dataAccount?.AccountName,
786
+ key: dataAccount?.Credentials?.key,
787
+ token: dataAccount?.Credentials?.token
788
+ };
789
+
790
+ const vtexApi = new VtexApi(an, key, token);
791
+ const dataSaveVtex= await saveTaxOrPromotion({data:dataPromotionSave, vtexApi:vtexApi});
792
+ if(dataSaveVtex){
793
+ responseSave.idCalculatorConfiguration= dataSaveVtex?.idCalculatorConfiguration;
794
+ responseSave.lastModified= dataSaveVtex?.lastModified;
795
+ await TaxPromotionsData.createOrUpdate(responseSave);
796
+ }else{
797
+ // enviar a cola
798
+ await sendSQSMessageTaxOrPromotion(responseSave, dataAccount);
799
+ return ApiResponse.response(401, 'error create tax or promotion!');
800
+ }
801
+ }catch (e){
802
+ Logger.error('error save VTEX');
803
+ // enviar a cola
804
+ await sendSQSMessageTaxOrPromotion(responseSave, dataAccount);
805
+ return ApiResponse.response(401, 'error create tax or promotion!');
806
+ }
807
+ }
808
+ }catch (err){
809
+ Logger.error('error save VTEX', err);
810
+ // enviar a cola
811
+ await sendSQSMessageTaxOrPromotion(responseSave, dataAccount);
812
+ }
813
+
814
+ return ApiResponse.response(200, responseSave);
815
+ }catch (e){
816
+ Logger.error(e);
817
+ return ApiResponse.response(401, 'error create tax or promotion!');
818
+ }
819
+ }else{
820
+ return ApiResponse.response(401, 'error request!');
821
+ }
822
+ }
823
+
824
+ /**
825
+ * Metodo para enviar a cola cuando para algun error dentro del proceso de creacion de una promo en VTEX
826
+ * */
827
+ const sendSQSMessageTaxOrPromotion= async (data, dataAccount)=>{
828
+ if(!data || !dataAccount){
829
+ return null;
830
+ }
831
+
832
+ // codigo para logica cola
833
+ // if(attemps < RetryCreateVTEX){}
834
+
835
+ return true
836
+ }
837
+
838
+ /**
839
+ * Crear o actualizar promociones o impuestos proceso cola
840
+ **/
841
+ const createorupdatequeue= async (event)=>{
842
+
843
+ }
844
+
845
+ /**
846
+ * Completa todas las propiedades del json de promociones o impuestos
847
+ * @param data -- datos de json enviados para creacion
848
+ * @param idPromotionTax -- es le id interno de la promocion o impuesto
849
+ **/
850
+ const getDataCompleteTaxPromotions= ({data=null, idPromotionTax=null})=>{
851
+ if(!data || !idPromotionTax ){
852
+ return null;
853
+ }
854
+
855
+ return {
856
+ "idExternalPromotion": idPromotionTax ?? null,
857
+ "idCalculatorConfiguration": data?.idCalculatorConfiguration ?? null,
858
+ "name": data?.name ?? "",
859
+ "description": data?.description ?? "",
860
+ "generalValues": data?.generalValues ?? null,
861
+ "beginDateUtc": data?.beginDateUtc ?? "",
862
+ "endDateUtc": data?.endDateUtc ?? "",
863
+ "daysAgoOfPurchases": data?.daysAgoOfPurchases ?? 0,
864
+ "isActive": data?.isActive ?? true,
865
+ "isArchived": data?.isArchived ?? false,
866
+ "isFeatured": data?.isFeatured ?? false,
867
+ "disableDeal": data?.disableDeal ?? false,
868
+ "activeDaysOfWeek": data?.activeDaysOfWeek ?? [],
869
+ "offset": data?.offset ?? -3,
870
+ "activateGiftsMultiplier": data?.activateGiftsMultiplier ?? false,
871
+ "newOffset": data?.newOffset ?? -3,
872
+ "maxPricesPerItems": data?.maxPricesPerItems ?? [],
873
+ "cumulative": data?.cumulative ?? false,
874
+ "nominalShippingDiscountValue": data?.nominalShippingDiscountValue ?? 0,
875
+ "absoluteShippingDiscountValue": data?.absoluteShippingDiscountValue ?? 0,
876
+ "nominalDiscountValue": data?.nominalDiscountValue ?? 0,
877
+ "nominalDiscountType": data?.nominalDiscountType ?? "cart",
878
+ "maximumUnitPriceDiscount": data?.maximumUnitPriceDiscount ?? 0,
879
+ "percentualDiscountValue": data?.percentualDiscountValue ?? 0,
880
+ "rebatePercentualDiscountValue": data?.rebatePercentualDiscountValue ?? 0,
881
+ "percentualShippingDiscountValue": data?.percentualShippingDiscountValue ?? 0,
882
+ "percentualTax": data?.percentualTax ?? 0,
883
+ "shippingPercentualTax": data?.shippingPercentualTax ?? 0,
884
+ "percentualDiscountValueList1": data?.percentualDiscountValueList1 ?? 0,
885
+ "percentualDiscountValueList2": data?.percentualDiscountValueList2 ?? 0,
886
+ "skusGift": {
887
+ "quantitySelectable": data?.skusGift?.quantitySelectable ?? 0,
888
+ "gifts": data?.skusGift?.gifts ?? []
889
+ },
890
+ "nominalRewardValue": data?.nominalRewardValue ?? 0,
891
+ "percentualRewardValue": data?.percentualRewardValue ?? 0,
892
+ "orderStatusRewardValue": data?.orderStatusRewardValue ?? "invoiced",
893
+ "maxNumberOfAffectedItems": data?.maxNumberOfAffectedItems ?? 0,
894
+ "maxNumberOfAffectedItemsGroupKey": data?.maxNumberOfAffectedItemsGroupKey ?? "perCart",
895
+ "applyToAllShippings": data?.applyToAllShippings ?? false,
896
+ "nominalTax": data?.nominalTax ?? 0,
897
+ "maxPackValue": data?.maxPackValue ?? 0,
898
+ "origin": data?.origin ?? "Marketplace",
899
+ "idSeller": data?.idSeller ?? "",
900
+ "idSellerIsInclusive": data?.idSellerIsInclusive ?? true,
901
+ "idsSalesChannel": data?.idsSalesChannel ?? [],
902
+ "areSalesChannelIdsExclusive": data?.areSalesChannelIdsExclusive ?? false,
903
+ "marketingTags": data?.marketingTags ?? [],
904
+ "marketingTagsAreNotInclusive": data?.marketingTagsAreNotInclusive ?? false,
905
+ "paymentsMethods": data?.paymentsMethods ?? [],
906
+ "stores": data?.stores ?? [],
907
+ "campaigns": data?.campaigns ?? [],
908
+ "storesAreInclusive": data?.storesAreInclusive ?? false,
909
+ "categories": data?.categories ?? [],
910
+ "categoriesAreInclusive": data?.categoriesAreInclusive ?? false,
911
+ "brands": data?.brands ?? [],
912
+ "brandsAreInclusive": data?.brandsAreInclusive ?? false,
913
+ "products": data?.products ?? [],
914
+ "productsAreInclusive": data?.productsAreInclusive ?? false,
915
+ "skus": data?.skus ?? [],
916
+ "skusAreInclusive": data?.skusAreInclusive ?? true,
917
+ "collections1BuyTogether": data?.collections1BuyTogether ?? [],
918
+ "collections2BuyTogether": data?.collections2BuyTogether ?? [],
919
+ "minimumQuantityBuyTogether": data?.minimumQuantityBuyTogether ?? 0,
920
+ "quantityToAffectBuyTogether": data?.quantityToAffectBuyTogether ?? 0,
921
+ "enableBuyTogetherPerSku": data?.enableBuyTogetherPerSku ?? true,
922
+ "listSku1BuyTogether": data?.listSku1BuyTogether ?? [],
923
+ "listSku2BuyTogether": data?.listSku2BuyTogether ?? [],
924
+ "coupon": data?.coupon ?? [],
925
+ "totalValueFloor": data?.totalValueFloor ?? 0,
926
+ "totalValueCeling": data?.totalValueCeling ?? 0,
927
+ "totalValueIncludeAllItems": data?.totalValueIncludeAllItems ?? false,
928
+ "totalValueMode": data?.totalValueMode ?? "IncludeMatchedItems",
929
+ "collections": data?.collections ?? [],
930
+ "collectionsIsInclusive": data?.collectionsIsInclusive ?? false,
931
+ "restrictionsBins": data?.restrictionsBins ?? [],
932
+ "cardIssuers": data?.cardIssuers ?? [],
933
+ "totalValuePurchase": data?.totalValuePurchase ?? 0,
934
+ "slasIds": data?.slasIds ?? [],
935
+ "isSlaSelected": data?.isSlaSelected ?? false,
936
+ "isFirstBuy": data?.isFirstBuy ?? false,
937
+ "firstBuyIsProfileOptimistic": data?.firstBuyIsProfileOptimistic ?? false,
938
+ "compareListPriceAndPrice": data?.compareListPriceAndPrice ?? false,
939
+ "isDifferentListPriceAndPrice": data?.isDifferentListPriceAndPrice ?? false,
940
+ "zipCodeRanges": data?.zipCodeRanges ?? [],
941
+ "itemMaxPrice": data?.itemMaxPrice ?? 0,
942
+ "itemMinPrice": data?.itemMinPrice ?? 0,
943
+ "installment": data?.installment ?? 0,
944
+ "isMinMaxInstallments": data?.isMinMaxInstallments ?? false,
945
+ "minInstallment": data?.minInstallment ?? 0,
946
+ "maxInstallment": data?.maxInstallment ?? 0,
947
+ "merchants": data?.merchants ?? [],
948
+ "clusterExpressions": data?.clusterExpressions ?? [],
949
+ "piiClusterExpressions": data?.piiClusterExpressions ?? [],
950
+ "clusterOperator": data?.clusterOperator ?? "all",
951
+ "paymentsRules": data?.paymentsRules ?? [],
952
+ "giftListTypes": data?.giftListTypes ?? [],
953
+ "productsSpecifications": data?.productsSpecifications ?? [],
954
+ "affiliates": data?.affiliates ??[],
955
+ "maxUsage": data?.maxUsage ?? 0,
956
+ "maxUsagePerClient": data?.maxUsagePerClient ?? 0,
957
+ "shouldDistributeDiscountAmongMatchedItems": data?.shouldDistributeDiscountAmongMatchedItems ?? false,
958
+ "multipleUsePerClient": data?.multipleUsePerClient ?? false,
959
+ "type": data?.type ?? "regular",
960
+ "useNewProgressiveAlgorithm": data?.useNewProgressiveAlgorithm ?? false,
961
+ "percentualDiscountValueList": data?.percentualDiscountValueList ?? [],
962
+ "packSize": data?.packSize ?? 0
963
+ };
964
+ };
965
+
966
+ /**
967
+ * Obtener listado de promociones o impuestos
968
+ **/
969
+ const gettaxesorpromotions= async (event)=>{
970
+ // benefits | taxes
971
+ const clientId = event?.requestContext?.authorizer?.claims?.client_id;
972
+ const typeSearch= event?.pathParameters?.type ?? 'benefits';
973
+
974
+ const listAccounts = await ClientData.getClient(clientId);
975
+
976
+ let listAccountsSearch= listAccounts?.AccountNames?.values;
977
+ let listAll= [];
978
+ let listPromotionsOrTax= [];
979
+
980
+ if(listAccountsSearch?.length > 0){
981
+ if(event?.queryStringParameters?.idSeller){
982
+ listAccountsSearch= listAccountsSearch.filter(it=>(it===event?.queryStringParameters?.idSeller));
983
+ }
984
+
985
+ listAll= await TaxPromotionsData.getAllPromotionsOrTaxes({
986
+ IdSeller: listAccountsSearch,
987
+ TypeSearch: typeSearch
988
+ });
989
+
990
+ const accountName= listAccountsSearch[0];
991
+ let dataAccount = await AccountData.getAccountDataByAccountName(accountName);
992
+ if (!dataAccount) {
993
+ Logger.error("Account not found: ", accountName, ". ClientId: ", clientId);
994
+ return ApiResponse.response(404, "Account not found");
995
+ }
996
+
997
+ if(dataAccount?.PromotionsPerParentAccount && dataAccount?.PromotionsPerParentAccount === true){
998
+ const accountNameParent= dataAccount?.ParentAccountName;
999
+ dataAccount = await AccountData.getAccountDataByAccountName(accountNameParent);
1000
+ }
1001
+
1002
+ if (!dataAccount) {
1003
+ Logger.error("Account not found: ", accountName, ". ClientId: ", clientId);
1004
+ return ApiResponse.response(404, "Account not found");
1005
+ }
1006
+
1007
+ try{
1008
+ const { an, key, token } = {
1009
+ an: dataAccount?.AccountName,
1010
+ key: dataAccount?.Credentials?.key,
1011
+ token: dataAccount?.Credentials?.token
1012
+ };
1013
+ const vtexApi = new VtexApi(an, key, token);
1014
+
1015
+ if(typeSearch==='benefits'){
1016
+ listPromotionsOrTax= await getAllPromotions({
1017
+ vtexApi: vtexApi
1018
+ });
1019
+ }else{
1020
+ listPromotionsOrTax= await getAllTaxes({
1021
+ vtexApi: vtexApi
1022
+ });
1023
+ }
1024
+
1025
+ } catch (error){
1026
+ Logger.error('error list VTEX', error);
1027
+ }
1028
+ }
1029
+
1030
+ const dataListPromotionFix= getJsonListPromotion(listAll,listPromotionsOrTax);
1031
+
1032
+ return ApiResponse.response(200, dataListPromotionFix);
1033
+ }
1034
+
1035
+ const getJsonListPromotion= (items, itemsVtex)=>{
1036
+ let listPromotionInMarketplace=[];
1037
+
1038
+ for (var i = 0; i < items.length; i++) {
1039
+ let exitPromotionInVtex= false;
1040
+ for (var j = 0; j < itemsVtex?.items?.length; j++) {
1041
+ if(items[i]?.idCalculatorConfiguration === itemsVtex?.items[j]?.idCalculatorConfiguration){
1042
+ exitPromotionInVtex=true;
1043
+ }
1044
+ }
1045
+
1046
+ if(exitPromotionInVtex===true){
1047
+ listPromotionInMarketplace=[...listPromotionInMarketplace, items[i]];
1048
+ }
1049
+ }
1050
+
1051
+ return {
1052
+ "limitConfigurationMaxPrice": itemsVtex?.limitConfigurationMaxPrice,
1053
+ "limitConfiguration": itemsVtex?.limitConfiguration,
1054
+ "items": listPromotionInMarketplace ?? [],
1055
+ "disabledItems": itemsVtex?.disabledItems,
1056
+ "archivedItems": itemsVtex?.archivedItems
1057
+ };
1058
+ }
1059
+
1060
+ /**
1061
+ * Obtener promocion o impuesto por id de vtex o id externo
1062
+ **/
1063
+ const gettaxorpromotion= async (event)=>{
1064
+ let data = JSON.parse(event.body);
1065
+ const clientId = event?.requestContext?.authorizer?.claims?.client_id;
1066
+ const idPromotionOrTax= event?.pathParameters?.idCalculatorConfiguration ?? null;
1067
+
1068
+ if(!idPromotionOrTax){
1069
+ return ApiResponse.response(401, "Error request!");
1070
+ }
1071
+ const listAccounts = await ClientData.getClient(clientId);
1072
+ const listAccountsSearch= listAccounts?.AccountNames?.values;
1073
+
1074
+ // Obtener por id vtex
1075
+ let dataPT= await TaxPromotionsData.getPerId(idPromotionOrTax);
1076
+ if(!dataPT){
1077
+ dataPT= await TaxPromotionsData.getPerIdVtex(idPromotionOrTax);
1078
+ }
1079
+
1080
+ if(dataPT?.idSeller && !listAccountsSearch.includes(dataPT?.idSeller)){
1081
+ dataPT=null;
1082
+ }
1083
+
1084
+ return dataPT ? ApiResponse.response(200, dataPT) : ApiResponse.response(404, `Not found ${idPromotionOrTax}!`);
1085
+ }
1086
+
1087
+ /**
1088
+ * Obtener id unico de promocion almacenamiento interno
1089
+ * @param data -- objeto don los datos del body dentro de la peticion
1090
+ **/
1091
+ const getIdPromotionTax= ({data=null})=>{
1092
+ if(!data){
1093
+ return null;
1094
+ }
1095
+
1096
+ // si existe id externo para la promocion
1097
+ if(data?.idExternalPromotion){
1098
+ return `${data?.idExternalPromotion}-${data?.idSeller}`;
1099
+ }
1100
+
1101
+ const objPromotionOrtax= {
1102
+ "1": data?.name ?? "",
1103
+ "2": data?.description ?? "",
1104
+ "3": data?.beginDateUtc ?? null,
1105
+ "4": data?.endDateUtc ?? null,
1106
+ "6": data?.nominalShippingDiscountValue ?? 0.0,
1107
+ "7": data?.absoluteShippingDiscountValue ?? 0.0,
1108
+ "8": data?.nominalDiscountValue ?? 0.0,
1109
+ "9": data?.maximumUnitPriceDiscount ?? 0.0,
1110
+ "10": data?.percentualDiscountValue ?? 0.0,
1111
+ "11": data?.rebatePercentualDiscountValue ?? 0.0,
1112
+ "12": data?.percentualShippingDiscountValue ?? 0.0,
1113
+ "13": data?.percentualTax ?? 0.0,
1114
+ "14": data?.shippingPercentualTax ?? 0.0,
1115
+ "15": data?.percentualDiscountValueList1 ?? 0.0,
1116
+ "16": data?.percentualDiscountValueList2 ?? 0.0,
1117
+ "17": data?.nominalRewardValue ?? 0.0,
1118
+ "18": data?.percentualRewardValue ?? 0.0,
1119
+ "19": data?.nominalTax ?? 0.0,
1120
+ "20": data?.idSeller ?? "",
1121
+ "21": data?.idsSalesChannel?.length ?? 0,
1122
+ "22": data?.marketingTags?.length ?? 0,
1123
+ "23": data?.paymentsMethods?.length ?? 0,
1124
+ "24": data?.stores?.length ?? 0,
1125
+ "25": data?.campaigns?.length ?? 0,
1126
+ "26": data?.categories?.length ?? 0,
1127
+ "27": data?.brands?.length ?? 0,
1128
+ "28": data?.products?.length ?? 0,
1129
+ "29": data?.skus?.length ?? 0,
1130
+ "30": data?.collections1BuyTogether?.length ?? 0,
1131
+ "31": data?.collections2BuyTogether?.length ?? 0,
1132
+ "32": data?.minimumQuantityBuyTogether ?? 0,
1133
+ "33": data?.quantityToAffectBuyTogether ?? 0,
1134
+ "34": data?.listSku1BuyTogether?.length ?? 0,
1135
+ "35": data?.listSku2BuyTogether?.length ?? 0,
1136
+ "36": data?.coupon?.length ?? 0,
1137
+ "37": data?.totalValueFloor ?? 0.0,
1138
+ "38": data?.totalValueCeling ?? 0.0,
1139
+ "39": data?.collections?.length ?? 0,
1140
+ "40": data?.minInstallment ?? 0,
1141
+ "41": data?.maxInstallment ?? 0,
1142
+ "42": data?.clusterExpressions?.length ?? 0,
1143
+ "43": data?.piiClusterExpressions?.length ?? 0,
1144
+ "44": data?.productsSpecifications?.length ?? 0,
1145
+ "44": data?.affiliates ?? [],
1146
+ "46": data?.type ?? "regular",
1147
+ "47": data?.skusGift?.quantitySelectable ?? 0,
1148
+ "48": data?.skusGift?.gifts?.length ?? 0
1149
+ };
1150
+
1151
+ return Buffer.from(`${JSON.stringify(objPromotionOrtax)}`).toString('base64');
1152
+ };
1153
+
1154
+ /**
1155
+ * Obtener datos de la promocion
1156
+ * @param id -- id del impuesto
1157
+ * @param vtexApi -- vtexApi objeto servicios VTEX
1158
+ * */
1159
+ const archivePromotionOrtaxVtex= async ({id=null, vtexApi=null})=>{
1160
+ if(!vtexApi || !id){
1161
+ return null;
1162
+ }
1163
+ return new Promise(async(res, error)=>{
1164
+
1165
+ const resTaxes = await vtexApi.fetch(`/rnb/pvt/archive/calculatorConfiguration/${id}`, {
1166
+ method: "POST"
1167
+ });
1168
+ if(resTaxes?.status >= 200 && resTaxes?.status < 300){
1169
+ res(true);
1170
+ }else{
1171
+ res(null);
1172
+ }
1173
+ });
1174
+ }
1175
+
1176
+ /**
1177
+ * Obtener promocion o impuesto por id de vtex o id externo
1178
+ **/
1179
+ const archivetaxorpromotion= async (event)=>{
1180
+ let data = JSON.parse(event.body);
1181
+ const clientId = event?.requestContext?.authorizer?.claims?.client_id;
1182
+ const idPromotionOrTax= event?.pathParameters?.idCalculatorConfiguration ?? null;
1183
+
1184
+ if(!idPromotionOrTax){
1185
+ return ApiResponse.response(401, "Error request!");
1186
+ }
1187
+ const listAccounts = await ClientData.getClient(clientId);
1188
+ const listAccountsSearch= listAccounts?.AccountNames?.values;
1189
+
1190
+ // Obtener por id vtex
1191
+ let dataPT= await TaxPromotionsData.getPerId(idPromotionOrTax);
1192
+ if(!dataPT){
1193
+ dataPT= await TaxPromotionsData.getPerIdVtex(idPromotionOrTax);
1194
+ }
1195
+
1196
+ if(dataPT?.idSeller && !listAccountsSearch.includes(dataPT?.idSeller)){
1197
+ dataPT=null;
1198
+ }else if(dataPT?.idExternalPromotion && dataPT?.idSeller) {
1199
+ const accountName= dataPT?.idSeller;
1200
+ let dataAccount = await AccountData.getAccountDataByAccountName(accountName);
1201
+ if (!dataAccount) {
1202
+ Logger.error("Account not found: ", accountName, ". ClientId: ", clientId);
1203
+ return ApiResponse.response(404, "Account not found");
1204
+ }
1205
+ const accountNameParent= dataAccount?.ParentAccountName;
1206
+ if(dataAccount?.PromotionsPerParentAccount && dataAccount?.PromotionsPerParentAccount === true){
1207
+ dataAccount = await AccountData.getAccountDataByAccountName(accountNameParent);
1208
+ }
1209
+
1210
+ if (!dataAccount) {
1211
+ Logger.error("AccountParent not found: ", accountNameParent, ". ClientId: ", clientId);
1212
+ return ApiResponse.response(404, "Account Parent not found");
1213
+ }
1214
+
1215
+ const { an, key, token } = {
1216
+ an: dataAccount?.AccountName,
1217
+ key: dataAccount?.Credentials?.key,
1218
+ token: dataAccount?.Credentials?.token
1219
+ };
1220
+
1221
+ const vtexApi = new VtexApi(an, key, token);
1222
+
1223
+ const resArchiveVtex= await archivePromotionOrtaxVtex({id:dataPT?.idCalculatorConfiguration, vtexApi:vtexApi});
1224
+ if(resArchiveVtex === true){
1225
+ dataPT.isArchived= true;
1226
+ const responseSave= await TaxPromotionsData.createOrUpdate(dataPT);
1227
+ }else{
1228
+ dataPT= null;
1229
+ }
1230
+ }else{
1231
+ dataPT= null;
1232
+ }
1233
+
1234
+ return dataPT ? ApiResponse.response(204, "archived!") : ApiResponse.response(404, `Not found ${idPromotionOrTax}!`);
1235
+ }
1236
+
1237
+ /**
1238
+ * Dar delay antes de iniciar un proceso
1239
+ * @param time // tiempo en segundos para esperar
1240
+ **/
1241
+ const delayStatusProcess = (time) => {
1242
+ if(!time || time < 1){
1243
+ return true;
1244
+ }
1245
+ return new Promise((resolve, reject) => {
1246
+ setTimeout(function() {
1247
+ resolve(true);
1248
+ }, (time * 1000));
1249
+ })
1250
+ };
1251
+
1252
+ /**
1253
+ * Envio de SQS para salvar dentro de VTEX
1254
+ * @param datasend -- Objeto con envio de parametros salvar impuesto
1255
+ * @param sendErr -- Si es true envia a cola de error
1256
+ **/
1257
+ const sendSQStax = async (datasend, sendErr=false)=>{
1258
+ if(!SQS_PROCESSTAX_QUEUE_URL || !datasend){
1259
+ return "Error create sqs tax";
1260
+ }
1261
+ return new Promise(async (res, err)=>{
1262
+ try{
1263
+ let urlSqs= SQS_PROCESSTAX_QUEUE_URL;
1264
+ if(sendErr===true && SQS_PROCESSTAX_DQL_QUEUE_URL){
1265
+ urlSqs= SQS_PROCESSTAX_DQL_QUEUE_URL;
1266
+ }
1267
+ await AWSServices.sendSQSMessage(urlSqs, datasend);
1268
+ res("Notification sqs tax successfully");
1269
+ }catch (err){
1270
+ Logger.error('error crear SQS tax', err);
1271
+ res("Error create sqs tax");
1272
+ }
1273
+ });
1274
+ }
1275
+
1276
+ module.exports = {
1277
+ setTaxes,
1278
+ consumerapp,
1279
+ createorupdate,
1280
+ gettaxesorpromotions,
1281
+ gettaxorpromotion,
1282
+ createorupdatequeue,
1283
+ archivetaxorpromotion
1284
+ };