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,249 @@
1
+ const DynamoAWS = require("aws-sdk/clients/dynamodb");
2
+ const Validation = require("../common/utils/validation-data");
3
+ const Logger = require("../common/utils/logger");
4
+
5
+ const TAX_PROMOTION_TABLE = process?.env?.TAX_PROMOTION_TABLE;
6
+ const LIMIT_ITEMS_PROMOTIONS= process?.env?.LIMIT_ITEMS_PROMOTIONS ?? 100;
7
+
8
+ /**
9
+ * Obtner listado de promociones o impuestos
10
+ * @param seller -- Id de seller dentro del json promociones
11
+ **/
12
+ const getPerId = async (IdExternalPromotion= null) => {
13
+ if(!IdExternalPromotion){
14
+ return null;
15
+ }
16
+ try {
17
+ const dynamodb = new DynamoAWS.DocumentClient();
18
+ const params = {
19
+ TableName: TAX_PROMOTION_TABLE,
20
+ Key: {
21
+ "IdExternalPromotion": IdExternalPromotion
22
+ }
23
+ };
24
+ const response = await dynamodb.get(params).promise();
25
+ return response?.Item ? Validation.transformFirstKeysToLowerCaseValue(response?.Item) : null;
26
+ } catch (err) {
27
+ Logger.error("Error getting account data: ", err);
28
+ return null;
29
+ }
30
+ };
31
+
32
+ /**
33
+ * Obtner listado de promociones o impuestos
34
+ * @param seller -- Id de seller dentro del json promociones
35
+ **/
36
+ const getPerIdVtex = async (IdCalculatorConfiguration= null) => {
37
+ if(!IdCalculatorConfiguration){
38
+ return null;
39
+ }
40
+ try {
41
+ const params = {
42
+ TableName: TAX_PROMOTION_TABLE,
43
+ IndexName: "IdCalculatorConfigurationIndex",
44
+ KeyConditionExpression: "#n0 = :v0",
45
+ ExpressionAttributeNames: {
46
+ "#n0": "IdCalculatorConfiguration"
47
+ },
48
+ ExpressionAttributeValues: {
49
+ ":v0": IdCalculatorConfiguration
50
+ },
51
+ Limit: 100,
52
+ Select: "ALL_ATTRIBUTES",
53
+ ReturnConsumedCapacity: "TOTAL"
54
+ };
55
+ const response = await getListCompleteItems(params, 1, "query");
56
+ return response?.Items[0] ? Validation.transformFirstKeysToLowerCaseValue(response?.Items[0]) : null;
57
+ } catch (err) {
58
+ Logger.error("Error getting tax or promotion data: ", err);
59
+ return null;
60
+ }
61
+ };
62
+
63
+ /**
64
+ * Obtener lista de items dynamo
65
+ * */
66
+ const getListCompleteItems= async (params, total=100, process="scan")=>{
67
+ if(parseInt(params?.Limit)===0){
68
+ return {Items:[], LastEvaluatedKey:null};
69
+ }
70
+ let limitP= total, countItems=0, listItems=[], lastEvaluatedKey=null;
71
+ return new Promise(async function(resolve, reject){
72
+ const dynamodb = new DynamoAWS.DocumentClient();
73
+ while (countItems < limitP) {
74
+ let res= await dynamodb[process](params).promise();
75
+ for (let i = 0; i < res.Items.length; i++) {
76
+ listItems= [...listItems, res.Items[i]];
77
+ }
78
+ countItems+= parseInt(res?.Count);
79
+ params.ExclusiveStartKey= res?.LastEvaluatedKey;
80
+ lastEvaluatedKey=res?.LastEvaluatedKey;
81
+ if(!res?.LastEvaluatedKey || listItems?.length === total){
82
+ countItems= limitP;
83
+ }
84
+ }
85
+
86
+ resolve({Items:listItems, LastEvaluatedKey:lastEvaluatedKey});
87
+ });
88
+
89
+ };
90
+
91
+ /**
92
+ * CREAR O ACTULALIZA PROMOCION O IMPUESTO EN DYNAMODB
93
+ * @param taxPromotionData -- json con datos de la promocion o impuesto
94
+ **/
95
+ const createOrUpdate = async (taxPromotionData) => {
96
+ const dynamodb = new DynamoAWS.DocumentClient();
97
+ let data = Validation.transformFirstKeysToUpperCaseValue(taxPromotionData);
98
+
99
+ if(data?.IdCalculatorConfiguration === null || data?.IdCalculatorConfiguration === ""){
100
+ delete data?.IdCalculatorConfiguration;
101
+ }
102
+ try {
103
+ const params = {
104
+ TableName: TAX_PROMOTION_TABLE,
105
+ Item: data,
106
+ ConditionExpression: "attribute_not_exists(IdExternalPromotion)",
107
+ };
108
+
109
+ await dynamodb.put(params).promise();
110
+
111
+ return taxPromotionData;
112
+ } catch (err) {
113
+
114
+ if (err.code === "ConditionalCheckFailedException" || err.code === "ValidationException") {
115
+ try{
116
+ let dataUpdateDynamo= setDataUpdateDynamo(data, 60);
117
+ for (var i = 0; i < dataUpdateDynamo.length; i++) {
118
+ let updateExpression='set';
119
+ let ExpressionAttributeNames={};
120
+ let ExpressionAttributeValues = {};
121
+ for (const property in dataUpdateDynamo[i]) {
122
+ if(property != 'IdExternalPromotion' && property != 'IdExternalPromotion'){
123
+ updateExpression += ` #${property} = :${property} ,`;
124
+ ExpressionAttributeNames['#'+property] = property ;
125
+ ExpressionAttributeValues[':'+property]=dataUpdateDynamo[i][property];
126
+ }
127
+ }
128
+ updateExpression= updateExpression.slice(0, -1);
129
+
130
+ let res2= await dynamodb.update({
131
+ TableName: TAX_PROMOTION_TABLE,
132
+ Key:{
133
+ IdExternalPromotion: data?.IdExternalPromotion
134
+ },
135
+ UpdateExpression: updateExpression,
136
+ ExpressionAttributeNames: ExpressionAttributeNames,
137
+ ExpressionAttributeValues: ExpressionAttributeValues
138
+ }).promise();
139
+ }
140
+
141
+ return taxPromotionData;
142
+ }catch(err2){
143
+ if(err2.code === "ConditionalCheckFailedException"){
144
+ return taxPromotionData;
145
+ }
146
+ Logger.error('err2err2',err2);
147
+ return null
148
+ }
149
+
150
+ }
151
+ Logger.error('error create', err);
152
+ return null;
153
+ }
154
+ };
155
+
156
+ /**
157
+ * Ajuste la cantidad de propiedades validar dentro de dynamo
158
+ * @param data -- json promotion
159
+ * @param limit -- limite propiedades dynamo
160
+ **/
161
+ const setDataUpdateDynamo= (data, limit=100)=>{
162
+ let arraData= [], objInternal={}, countItems=0, lengthData=Object.keys(data).length;
163
+ for (let item in data) {
164
+ countItems++;
165
+ if(Object.keys(objInternal).length < limit){
166
+ objInternal[item]= data[item];
167
+ }else{
168
+ arraData=[...arraData,objInternal];
169
+ objInternal={};
170
+ objInternal[item]= data[item];
171
+ }
172
+
173
+ if(countItems === lengthData){
174
+ arraData=[...arraData,objInternal];
175
+ }
176
+ }
177
+
178
+ return arraData;
179
+ };
180
+
181
+ /**
182
+ * Obtener lista de promociones almacenadas en dynamodb
183
+ * @param filters -- filtros que se pueden realizar en la entidad de datos IdSeller | TypeSearch
184
+ **/
185
+ const getAllPromotionsOrTaxes = async (filters) => {
186
+ if(!filters || !filters?.IdSeller || typeof filters?.IdSeller !== 'object' || filters?.IdSeller?.length === 0){
187
+ return [];
188
+ }
189
+
190
+ try {
191
+ let params = {
192
+ TableName: TAX_PROMOTION_TABLE,
193
+ ExpressionAttributeNames: {
194
+ "#IdSeller": "IdSeller",
195
+ "#Type": "Type",
196
+ "#IsArchived": "IsArchived"
197
+ },
198
+ ExpressionAttributeValues: {
199
+ ":Tax": "tax",
200
+ ":IsArchived": false
201
+ },
202
+ FilterExpression: filters?.TypeSearch === 'taxes' ? `#Type = :Tax` : `#Type <> :Tax`,
203
+ Limit: LIMIT_ITEMS_PROMOTIONS,
204
+ Select: "ALL_ATTRIBUTES",
205
+ ReturnConsumedCapacity: "TOTAL"
206
+ };
207
+
208
+ params.FilterExpression+= ' AND #IsArchived = :IsArchived';
209
+
210
+ if(filters?.IdSeller || typeof filters?.IdSeller === 'object'){
211
+ let listConditionsSeller=[];
212
+ for (var i = 0; i < filters?.IdSeller?.length; i++) {
213
+ params.ExpressionAttributeValues[":SellerV"+i]= filters?.IdSeller[i];
214
+ listConditionsSeller=[...listConditionsSeller, `#IdSeller = :SellerV${i}`]
215
+ }
216
+ params.FilterExpression+= ` AND (${listConditionsSeller.join(' OR ')})`;
217
+ }
218
+ const response = await getListCompleteItems(params,LIMIT_ITEMS_PROMOTIONS);
219
+ return response?.Items?.length > 0 ? response?.Items.map(it=>Validation.transformFirstKeysToLowerCaseValue(it)) : [];
220
+ } catch (err) {
221
+ Logger.error("Error getting tax or promotion data: ", err);
222
+ return null;
223
+ }
224
+ };
225
+
226
+ const bindIdExternalPromotionToOrderData = async (orderVtex)=>{
227
+ try {
228
+ const benefits = orderVtex?.ratesAndBenefitsData?.rateAndBenefitsIdentifiers;
229
+ if (typeof benefits !== 'undefined' && benefits.length > 0){
230
+ for (var item of benefits) {
231
+ let dataPromotion = await getPerIdVtex(item?.id);
232
+ item.IdExternalPromotion = (typeof dataPromotion?.idExternalPromotion !== 'undefined' ? dataPromotion?.idExternalPromotion : null);
233
+ }
234
+ orderVtex.ratesAndBenefitsData.rateAndBenefitsIdentifiers = benefits;
235
+ }
236
+ return orderVtex;
237
+ } catch (err) {
238
+ Logger.error("Error promotion data: ", err);
239
+ return null;
240
+ }
241
+ }
242
+
243
+ module.exports = {
244
+ createOrUpdate,
245
+ getPerId,
246
+ getPerIdVtex,
247
+ getAllPromotionsOrTaxes,
248
+ bindIdExternalPromotionToOrderData,
249
+ };
@@ -0,0 +1,262 @@
1
+ const ApiResponse = require("../../common/utils/api-response");
2
+ const AccountData = require("../../entities/account");
3
+ const AccountErrors = require("../../common/utils/account-error-helper");
4
+ const DataTablesHelper = require("../../common/utils/data-tables-helper");
5
+ const Logger = require("../../common/utils/logger");
6
+
7
+ /**
8
+ * Ordena recursivamente las propiedades de un objeto en orden alfabético
9
+ */
10
+ function sortObjectPropertiesAlphabetically(obj) {
11
+ if (obj === null || typeof obj !== 'object' || Array.isArray(obj)) {
12
+ return obj;
13
+ }
14
+
15
+ const sortedKeys = Object.keys(obj).sort();
16
+ const sortedObj = {};
17
+
18
+ for (const key of sortedKeys) {
19
+ if (obj[key] !== null && typeof obj[key] === 'object' && !Array.isArray(obj[key])) {
20
+ sortedObj[key] = sortObjectPropertiesAlphabetically(obj[key]);
21
+ } else {
22
+ sortedObj[key] = obj[key];
23
+ }
24
+ }
25
+
26
+ return sortedObj;
27
+ }
28
+
29
+ /**
30
+ * Obtiene una lista de cuentas con soporte DataTables y Legacy - CON VALIDACIONES
31
+ */
32
+ const getAccounts = async (event) => {
33
+ try {
34
+ const queryStringParameters = event.queryStringParameters || {};
35
+ const parentAccountName = queryStringParameters.parent;
36
+
37
+ Logger.debug("Raw query parameters:", queryStringParameters);
38
+
39
+ if (!DataTablesHelper) {
40
+ Logger.error("DataTablesHelper not loaded");
41
+ throw new Error("DataTablesHelper module not found");
42
+ }
43
+
44
+ const isDataTables = DataTablesHelper.isDataTablesFormat(queryStringParameters);
45
+
46
+ let queryParams;
47
+ if (isDataTables) {
48
+ try {
49
+ queryParams = DataTablesHelper.parseDataTablesParams(queryStringParameters);
50
+ Logger.debug("Parsed DataTables params:", queryParams);
51
+ } catch (parseError) {
52
+ Logger.error("Error parsing DataTables params:", parseError);
53
+ // Fallback a Legacy si DataTables parsing falla
54
+ queryParams = {
55
+ _limit: 10,
56
+ _sort: "asc",
57
+ draw: parseInt(queryStringParameters.draw) || 1
58
+ };
59
+ }
60
+ } else {
61
+ queryParams = {
62
+ _limit: queryStringParameters._limit,
63
+ _sort: queryStringParameters._sort,
64
+ _from: queryStringParameters._from,
65
+ _to: queryStringParameters._to,
66
+ _moduleActive: queryStringParameters._moduleActive,
67
+ _accountPattern: queryStringParameters._accountPattern,
68
+ _integration: queryStringParameters._integration,
69
+ _like: queryStringParameters._like,
70
+ _fields: queryStringParameters._fields,
71
+ _excludeFields: queryStringParameters._excludeFields
72
+ };
73
+
74
+ Object.keys(queryParams).forEach(key =>
75
+ queryParams[key] === undefined && delete queryParams[key]
76
+ );
77
+
78
+ Logger.debug("Parsed Legacy params:", queryParams);
79
+ }
80
+
81
+ if (parentAccountName) {
82
+ queryParams.parentAccountName = parentAccountName;
83
+ }
84
+
85
+ if (!AccountData.getAccountsForDataTables) {
86
+ Logger.error("getAccountsForDataTables function not found in AccountData");
87
+ throw new Error("Required function not available");
88
+ }
89
+
90
+ const result = await AccountData.getAccountsForDataTables(queryParams);
91
+
92
+ if (!result) {
93
+ Logger.error("No result from getAccountsForDataTables");
94
+ if (isDataTables) {
95
+ return ApiResponse.response(200, DataTablesHelper.formatDataTablesResponse(
96
+ [], queryParams.draw || 1, 0, 0
97
+ ));
98
+ } else {
99
+ return await AccountErrors.createError('ACCOUNT_029', {
100
+ parentAccountName: parentAccountName || 'N/A'
101
+ });
102
+ }
103
+ }
104
+
105
+ if (result.error) {
106
+ Logger.error("Error in result:", result.error);
107
+ if (isDataTables) {
108
+ return ApiResponse.response(500, DataTablesHelper.formatDataTablesResponse(
109
+ [], queryParams.draw || 1, 0, 0
110
+ ));
111
+ } else {
112
+ return await AccountErrors.createWithLogging('ACCOUNT_030', new Error(result.error));
113
+ }
114
+ }
115
+
116
+ if (!result.items && !result.data) {
117
+ if (isDataTables) {
118
+ return ApiResponse.response(200, DataTablesHelper.formatDataTablesResponse(
119
+ [],
120
+ queryParams.draw,
121
+ 0,
122
+ 0
123
+ ));
124
+ } else {
125
+ // Error Legacy
126
+ return await AccountErrors.createError('ACCOUNT_029', {
127
+ parentAccountName: parentAccountName || 'N/A'
128
+ });
129
+ }
130
+ }
131
+
132
+ if (isDataTables) {
133
+ const dataTablesResponse = DataTablesHelper.formatDataTablesResponse(
134
+ result.data || result.items || [],
135
+ queryParams.draw,
136
+ result.recordsTotal || 0,
137
+ result.recordsFiltered || result.count || 0
138
+ );
139
+
140
+ Logger.debug("DataTables response:", {
141
+ draw: dataTablesResponse.draw,
142
+ recordsTotal: dataTablesResponse.recordsTotal,
143
+ recordsFiltered: dataTablesResponse.recordsFiltered,
144
+ dataLength: dataTablesResponse.data.length
145
+ });
146
+
147
+ return ApiResponse.response(200, dataTablesResponse);
148
+ } else {
149
+ const sortedItems = (result.items || result.data || []).map(sortObjectPropertiesAlphabetically);
150
+
151
+ return ApiResponse.response(200, {
152
+ message: "Accounts retrieved successfully",
153
+ data: sortedItems,
154
+ count: result.count,
155
+ pagination: {
156
+ nextToken: result.lastEvaluatedKey,
157
+ hasMore: result.lastEvaluatedKey !== null,
158
+ limit: parseInt(queryParams._limit) || 100
159
+ }
160
+ });
161
+ }
162
+
163
+ } catch (error) {
164
+ Logger.error("Error retrieving accounts:", error);
165
+
166
+ const isDataTables = DataTablesHelper && DataTablesHelper.isDataTablesFormat
167
+ ? DataTablesHelper.isDataTablesFormat(event.queryStringParameters || {})
168
+ : false;
169
+
170
+ if (isDataTables && DataTablesHelper.formatDataTablesResponse) {
171
+ return ApiResponse.response(500, DataTablesHelper.formatDataTablesResponse(
172
+ [],
173
+ parseInt(event.queryStringParameters?.draw) || 1,
174
+ 0,
175
+ 0
176
+ ));
177
+ } else {
178
+ return await AccountErrors.createWithLogging('ACCOUNT_030', error);
179
+ }
180
+ }
181
+ };
182
+
183
+ // MANTENER getAccount y deleteAccount sin cambios (son las mismas funciones que ya tienes)
184
+
185
+ /**
186
+ * Obtiene una cuenta específica por su AccountName
187
+ */
188
+ const getAccount = async (event) => {
189
+ try {
190
+ const { an } = event.pathParameters || {};
191
+
192
+ if (!an) {
193
+ return await AccountErrors.createError('ACCOUNT_027');
194
+ }
195
+
196
+ const queryStringParameters = event.queryStringParameters || {};
197
+ const queryParams = {
198
+ _fields: queryStringParameters._fields,
199
+ _excludeFields: queryStringParameters._excludeFields
200
+ };
201
+
202
+ Object.keys(queryParams).forEach(key =>
203
+ queryParams[key] === undefined && delete queryParams[key]
204
+ );
205
+
206
+ const account = await AccountData.getAccountDataByAccountName(an, queryParams);
207
+
208
+ if (!account) {
209
+ return await AccountErrors.createError('ACCOUNT_028', { accountName: an });
210
+ }
211
+
212
+ const sortedAccount = sortObjectPropertiesAlphabetically(account);
213
+
214
+ return ApiResponse.response(200, {
215
+ message: "Account retrieved successfully",
216
+ data: sortedAccount
217
+ });
218
+ } catch (error) {
219
+ Logger.error(`Error retrieving account:`, error);
220
+ return await AccountErrors.createWithLogging('ACCOUNT_030', error);
221
+ }
222
+ };
223
+
224
+ /**
225
+ * Elimina una cuenta específica por su AccountName
226
+ */
227
+ const deleteAccount = async (event) => {
228
+ try {
229
+ const { an } = event.pathParameters || {};
230
+
231
+ if (!an) {
232
+ return await AccountErrors.createError('ACCOUNT_027');
233
+ }
234
+
235
+ Logger.info(`Attempting to delete account: ${an}`);
236
+
237
+ const account = await AccountData.getAccountDataByAccountName(an);
238
+ if (!account) {
239
+ return await AccountErrors.createError('ACCOUNT_028', { accountName: an });
240
+ }
241
+
242
+ const result = await AccountData.deleteAccountByAccountName(an);
243
+
244
+ if (result.success) {
245
+ return ApiResponse.response(200, {
246
+ message: result.message,
247
+ deleted: true
248
+ });
249
+ } else {
250
+ return await AccountErrors.createError('ACCOUNT_030');
251
+ }
252
+ } catch (error) {
253
+ Logger.error(`Error deleting account:`, error);
254
+ return await AccountErrors.createWithLogging('ACCOUNT_030', error);
255
+ }
256
+ };
257
+
258
+ module.exports = {
259
+ getAccounts,
260
+ getAccount,
261
+ deleteAccount,
262
+ };