contentoh-components-library 21.6.53 → 21.6.55

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.
@@ -629,9 +629,11 @@ var RetailerProductEditionView = function RetailerProductEditionView(_ref) {
629
629
  type: "SET_ACTIVE_RETAILER",
630
630
  payload: productNormalized.categoryRetailerInOrder[0]
631
631
  });
632
- setShotThd([58, 59, 60, 61].includes(productNormalized.categoryRetailerInOrder[0].id_retailer)); // Configurar statusArray según el rol del usuario
632
+ setShotThd([58, 59, 60, 61].includes(productNormalized.categoryRetailerInOrder[0].id_retailer)); // Los estatus evaluables salen del rol UNIDO a la asignación. Solo por
633
+ // rol, quien produce y además audita no tenía 'AC' en la lista y el
634
+ // envío se quedaba sin nada que mandar.
633
635
 
634
- setStatusArray((0, _utils.getStatusArrayByRole)(user.id_role)); // Cargar usuarios y asignaciones
636
+ setStatusArray((0, _utils.getStatusArrayForUser)(user, productNormalized)); // Cargar usuarios y asignaciones
635
637
 
636
638
  _context2.next = 10;
637
639
  return (0, _data.fetchUsers)(token);
@@ -1156,8 +1158,10 @@ var RetailerProductEditionView = function RetailerProductEditionView(_ref) {
1156
1158
  // tal cual, y el especialista que además es auditor alcanza la segunda fase.
1157
1159
 
1158
1160
  var canEvaluateAsFacilitator = retailerStatus === "IE" && ([1, 4, 5].includes(user.id_role) || isAssignedAs("facilitator", concept));
1159
- var canEvaluateAsAuditor = ["AC", "RP", "RCA", "SAC"].includes(retailerStatus) && ([1, 6].includes(user.id_role) || isAuditorAssigned());
1160
- return canEvaluateAsFacilitator || canEvaluateAsAuditor;
1161
+ var canEvaluateAsAuditor = ["AC", "RP", "RCA", "SAC"].includes(retailerStatus) && ([1, 6].includes(user.id_role) || isAuditorAssigned()); // Los roles 7 y 8 también pueden validar/rechazar lo que está en AC.
1162
+
1163
+ var canEvaluateAC = retailerStatus === "AC" && [7, 8].includes(user.id_role);
1164
+ return canEvaluateAsFacilitator || canEvaluateAsAuditor || canEvaluateAC;
1161
1165
  };
1162
1166
 
1163
1167
  var canShowBulkEvaluationButtons = function canShowBulkEvaluationButtons() {
@@ -1179,7 +1183,12 @@ var RetailerProductEditionView = function RetailerProductEditionView(_ref) {
1179
1183
 
1180
1184
  return ["AC", "RP", "RCA"].includes(srv === null || srv === void 0 ? void 0 : (_srv$status2 = srv.status) === null || _srv$status2 === void 0 ? void 0 : _srv$status2.replace(/.*\//, ""));
1181
1185
  }) && ([1, 6].includes(user.id_role) || isAuditorAssigned());
1182
- return canEvaluateAsFacilitator || canEvaluateAsAuditor;
1186
+ var canEvaluateAC = services.length > 0 && services.every(function (srv) {
1187
+ var _srv$status3;
1188
+
1189
+ return (srv === null || srv === void 0 ? void 0 : (_srv$status3 = srv.status) === null || _srv$status3 === void 0 ? void 0 : _srv$status3.replace(/.*\//, "")) === "AC";
1190
+ }) && [7, 8].includes(user.id_role);
1191
+ return canEvaluateAsFacilitator || canEvaluateAsAuditor || canEvaluateAC;
1183
1192
  };
1184
1193
 
1185
1194
  var getStatusByCurrentServiceAndRetailer = function getStatusByCurrentServiceAndRetailer() {
@@ -2481,6 +2490,23 @@ var RetailerProductEditionView = function RetailerProductEditionView(_ref) {
2481
2490
  return Promise.all(evaluationArray);
2482
2491
 
2483
2492
  case 7:
2493
+ if (!(evaluationArray.length === 0)) {
2494
+ _context15.next = 10;
2495
+ break;
2496
+ }
2497
+
2498
+ dispatch({
2499
+ type: "SET_MODAL",
2500
+ payload: {
2501
+ show: true,
2502
+ title: "Error",
2503
+ message: "No hay servicios que puedas evaluar en el estatus actual.",
2504
+ image: _errorModal.default
2505
+ }
2506
+ });
2507
+ return _context15.abrupt("return");
2508
+
2509
+ case 10:
2484
2510
  status = "".concat(result, "A"); // Actualizar el statusByRetailer para todos los retailers y conceptos
2485
2511
 
2486
2512
  updatedStatusByRetailer = state.product.statusByRetailer.map(function (item) {
@@ -2532,28 +2558,28 @@ var RetailerProductEditionView = function RetailerProductEditionView(_ref) {
2532
2558
  image: _genericModalCheck.default
2533
2559
  }
2534
2560
  });
2535
- _context15.next = 19;
2561
+ _context15.next = 22;
2536
2562
  break;
2537
2563
 
2538
- case 16:
2539
- _context15.prev = 16;
2564
+ case 19:
2565
+ _context15.prev = 19;
2540
2566
  _context15.t0 = _context15["catch"](1);
2541
2567
  console.error("Error in bulk evaluation:", _context15.t0);
2542
2568
 
2543
- case 19:
2544
- _context15.prev = 19;
2569
+ case 22:
2570
+ _context15.prev = 22;
2545
2571
  dispatch({
2546
2572
  type: "SET_SAVING",
2547
2573
  payload: false
2548
2574
  });
2549
- return _context15.finish(19);
2575
+ return _context15.finish(22);
2550
2576
 
2551
- case 22:
2577
+ case 25:
2552
2578
  case "end":
2553
2579
  return _context15.stop();
2554
2580
  }
2555
2581
  }
2556
- }, _callee15, null, [[1, 16, 19, 22]]);
2582
+ }, _callee15, null, [[1, 19, 22, 25]]);
2557
2583
  }));
2558
2584
 
2559
2585
  return function sendBulkEvaluation(_x6) {
@@ -2715,7 +2741,8 @@ var RetailerProductEditionView = function RetailerProductEditionView(_ref) {
2715
2741
  switch (id_rol) {
2716
2742
  case 7:
2717
2743
  case 8:
2718
- var canSendEvaluation = statusArray.includes(statusBySelectedRetailerService); // const conditionTwo = statusArray.includes(product?.status);
2744
+ // AC se valida/rechaza desde el panel, no se reenvía con "Enviar evaluación".
2745
+ var canSendEvaluation = statusBySelectedRetailerService !== "AC" && statusArray.includes(statusBySelectedRetailerService); // const conditionTwo = statusArray.includes(product?.status);
2719
2746
  // const conditionThree =
2720
2747
  // servicesByTab.filter((service) =>
2721
2748
  // statusArray.includes(service.status?.replace(/.*\//, "")),
@@ -33,164 +33,74 @@ TextEditor.args = {
33
33
  },
34
34
  token: "eyJraWQiOiJEV3owZnNieXg2MXNFcVduN3RCXC81bVhod3ZNbFZIOTgwUnZcL3RjT0lKdEk9IiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiI4ZDAxMDIxNC01YmZhLTQzYzMtOTZmYi1jNTU2ZGMwNTc3NGIiLCJjb2duaXRvOmdyb3VwcyI6WyJjb2xhYm9yYWRvcmVzX2NvbnRlbnRvaCJdLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiaXNzIjoiaHR0cHM6XC9cL2NvZ25pdG8taWRwLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tXC91cy1lYXN0LTFfbFN6UVo0WjdSIiwiY29nbml0bzp1c2VybmFtZSI6IjhkMDEwMjE0LTViZmEtNDNjMy05NmZiLWM1NTZkYzA1Nzc0YiIsImF1ZCI6IjUyZDlza2tkY2c4cWpwODhvb2sxdXNlNm1rIiwiZXZlbnRfaWQiOiIzYzc3Y2JjMC02ZTM0LTRhZDQtOGJjMy02MmJmNGRhOTYxMTUiLCJ0b2tlbl91c2UiOiJpZCIsImF1dGhfdGltZSI6MTc2ODQ5NjU3NywibmFtZSI6IkNvbGFib3JhZG9yIiwicGhvbmVfbnVtYmVyIjoiKzUyMTExMSIsImV4cCI6MTc2ODUwMDE3NywiaWF0IjoxNzY4NDk2NTc3LCJlbWFpbCI6ImthcmFmZTMyMThAbW9tMmtpZC5jb20ifQ.FhBvgESIAX90v1_2auyejto5NrMetq5qHoFxzh9lRr07UsYw2iKdDG29VyJLZ_bPStSUx-424U7FR1ctSD9mU831TKuwSyGyGKLz0mO70Ume7pgt8zfN0C_YWv5MFG4thcMrvMfEuyzfUhvQ944HBjXvqzyjcOdCjsFx9gVEnLh1bsXe1MJrUx8H1KN5gNrrkkTE7Qo3ybyr_WZF1002JsdMaoFg2UP3H5gzcbcuxgtjNuyhqaXGnoCBsPhu6SOAwWLEu1pZMty88OFteEWEdxJxCbzKaj8IomT8U4Tjiti4tshMkXRnxHBqAkGzLDu3ypbG4S31CR7RgDxRIVqntw",
35
35
  productSelected: {
36
- orderId: 10424,
37
- status: "CA",
38
- datasheet_status: "CA",
39
- prio: "none",
40
- version: 3,
41
- description_status: "CA",
42
- images_status: "CA",
43
- brand: "Marca",
44
- retailerOrder: 0,
45
- missing: {
46
- datasheet: null,
47
- descriptions: null,
48
- images: null
49
- },
36
+ articleId: 150504,
50
37
  services: {
51
38
  datasheets: 1,
52
39
  descriptions: 1,
53
40
  images: 1
54
41
  },
42
+ orderId: 11130,
43
+ city: "CDMX, México",
44
+ status: "AC",
45
+ datasheet_status: "AC",
46
+ prio: "none",
47
+ version: 3,
48
+ description_status: "AC",
49
+ images_status: "AC",
50
+ statusByRetailer: [{
51
+ status: "AC",
52
+ service: "datasheet",
53
+ retailer_id: 9,
54
+ task_user_group_id: 4
55
+ }, {
56
+ status: "AC",
57
+ service: "description",
58
+ retailer_id: 9,
59
+ task_user_group_id: 4
60
+ }, {
61
+ status: "AC",
62
+ service: "images",
63
+ retailer_id: 9,
64
+ task_user_group_id: 4
65
+ }],
55
66
  article: {
56
- category: "Categoría Genérica Rappi|Categoría Genérica|Categoría Genérica",
67
+ id_article: 150504,
68
+ id_category: 6103,
69
+ brand: "Generico",
70
+ name: "Pruebas Tech",
71
+ upc: "43876912836",
72
+ sku: "43876912836",
73
+ timestamp: "2026-09-26T03:09:13.000Z",
74
+ active: 1,
75
+ company_id: 1116,
57
76
  company_name: "Walmart SA de CV",
58
77
  country: "México",
59
- id_category: "4911",
78
+ id_order: 11130,
60
79
  id_datasheet_especialist: 426,
61
80
  id_datasheet_facilitator: null,
62
81
  id_description_especialist: 426,
63
82
  id_description_facilitator: null,
64
83
  id_images_especialist: 427,
65
84
  id_images_facilitator: null,
66
- id_order: 10424,
67
- id_article: 144832,
68
- id_auditor: 425,
69
- name: "Copia prod cadenas 1",
70
- timestamp: "2025-11-16T00:32:13.000Z",
71
- upc: "100023",
72
- sku: "900006",
85
+ id_auditor: 426,
86
+ id_recepcionist: null,
87
+ category: "Alimentos y Bebidas|Amazon Súper|Abarrotes",
73
88
  categoryRetailer: [{
74
- id_category: 3431,
75
- id_retailer: 24,
76
- category_name: "Abarrotes Básicos Alsuper|Abarrotes Básicos|Abarrotes Básicos",
77
- retailer_name: "Alsuper"
78
- }, {
79
- id_category: 3435,
80
- id_retailer: 21,
81
- category_name: "Bebés Cuidado e Higiene|Bebés Cuidado e Higiene|Bebés Cuidado e Higiene",
82
- retailer_name: "Anicetos"
83
- }, {
84
- id_category: 3438,
85
- id_retailer: 1008,
86
- category_name: "Categoría Genérica App Olímpica|Categoría Genérica|Categoría Genérica",
87
- retailer_name: "App Olímpica"
88
- }, {
89
- id_category: 3439,
90
- id_retailer: 2004,
91
- category_name: "Categoría Genérica Automercado|Categoría Genérica Automercado|Categoría Genérica Automercado",
92
- retailer_name: "Automercado"
93
- }, {
94
- id_category: 4774,
95
- id_retailer: 1032,
96
- category_name: "Categoría Genérica IMPIRA Colombia|Categoría Genérica|Categoría Genérica",
97
- retailer_name: "IMPIRA Colombia"
98
- }, {
99
- id_category: 4911,
100
- id_retailer: 16,
101
- category_name: "Categoría Genérica Rappi|Categoría Genérica|Categoría Genérica",
102
- retailer_name: "Rappi"
103
- }, {
104
89
  id_category: 6103,
105
90
  id_retailer: 9,
106
91
  category_name: "Alimentos y Bebidas|Amazon Súper|Abarrotes",
107
92
  retailer_name: "Amazon"
108
- }, {
109
- id_category: 6792,
110
- id_retailer: 32,
111
- category_name: "Categoría Salud y Belleza Coppel|Categoría Salud y Belleza|Categoría Salud y Belleza",
112
- retailer_name: "Coppel"
113
- }, {
114
- id_category: 7008,
115
- id_retailer: 3,
116
- category_name: "Bebés|Accesorios para Bebés|Accesorios para Bebés",
117
- retailer_name: "Sam´s Club"
118
93
  }]
119
94
  },
120
95
  retailers: [{
121
- id: 3,
122
- name: "Sam´s Club"
123
- }, {
124
- id: 16,
125
- name: "Rappi"
126
- }, {
127
- id: 32,
128
- name: "Coppel"
129
- }, {
130
- id: 1008,
131
- name: "App Olímpica"
96
+ id: 9,
97
+ name: "Amazon"
132
98
  }],
133
- statusByRetailer: [{
134
- status: "RA/AS",
135
- service: "datasheet",
136
- retailer_id: 3
137
- }, {
138
- status: "RA/AS",
139
- service: "description",
140
- retailer_id: 3
141
- }, {
142
- status: "AA",
143
- service: "images",
144
- retailer_id: 3
145
- }, {
146
- status: "AC",
147
- service: "datasheet",
148
- retailer_id: 16
149
- }, {
150
- status: "AC",
151
- service: "description",
152
- retailer_id: 16
153
- }, {
154
- status: "AC",
155
- service: "images",
156
- retailer_id: 16
157
- }, {
158
- status: "AC",
159
- service: "datasheet",
160
- retailer_id: 32
161
- }, {
162
- status: "AC",
163
- service: "description",
164
- retailer_id: 32
165
- }, {
166
- status: "AC",
167
- service: "images",
168
- retailer_id: 32
169
- }, {
170
- status: "PA",
171
- service: "datasheet",
172
- retailer_id: 1032
173
- }, {
174
- status: "PA",
175
- service: "description",
176
- retailer_id: 1032
177
- }, {
178
- status: "PA",
179
- service: "images",
180
- retailer_id: 1032
181
- }, {
182
- status: "PA",
183
- service: "datasheet",
184
- retailer_id: 2004
185
- }, {
186
- status: "PA",
187
- service: "description",
188
- retailer_id: 2004
189
- }, {
190
- status: "PA",
191
- service: "images",
192
- retailer_id: 2004
193
- }]
99
+ variantsCount: 0,
100
+ parent: null,
101
+ parentArticleId: null,
102
+ country: "México",
103
+ upc: "43876912836"
194
104
  },
195
105
  user: {
196
106
  id_user: 426,
@@ -5,10 +5,12 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.translateService = exports.translateConcept = exports.sendMessage = exports.normalizeProduct = exports.getStatusArrayByRole = exports.getInputsData = exports.getConceptsByRole = exports.getConceptByTab = exports.getAuditVersion = exports.createMessage = exports.calculateRequiredNull = exports.buildCollaboratorAssignations = void 0;
8
+ exports.translateService = exports.translateConcept = exports.sendMessage = exports.normalizeProduct = exports.getStatusArrayForUser = exports.getStatusArrayByRole = exports.getInputsData = exports.getConceptsByRole = exports.getConceptByTab = exports.getAuditVersion = exports.createMessage = exports.calculateRequiredNull = exports.buildCollaboratorAssignations = void 0;
9
9
 
10
10
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
11
 
12
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/toConsumableArray"));
13
+
12
14
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/slicedToArray"));
13
15
 
14
16
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/asyncToGenerator"));
@@ -228,7 +230,7 @@ var getStatusArrayByRole = function getStatusArrayByRole(idRole) {
228
230
 
229
231
  case 7:
230
232
  case 8:
231
- return ["PA", "AS", "CA", "RC", "RA", "RP", "RCA"];
233
+ return ["PA", "AS", "CA", "RC", "RA", "RP", "RCA", "AC"];
232
234
 
233
235
  case 4:
234
236
  case 5:
@@ -241,9 +243,54 @@ var getStatusArrayByRole = function getStatusArrayByRole(idRole) {
241
243
  return [];
242
244
  }
243
245
  };
246
+ /**
247
+ * Estatus en los que esta persona puede evaluar ESTE producto.
248
+ *
249
+ * Unión de lo que le toca por ROL y de lo que le toca por ASIGNACIÓN. Antes
250
+ * solo se preguntaba el rol, y de ahí salía el defecto: un Especialista de
251
+ * Textos asignado como auditor no tenía 'AC' en su lista. El botón sí
252
+ * aparecía —esa compuerta ya mira la asignación—, pero `sendBulkEvaluation`
253
+ * filtra con esta lista, se quedaba sin una sola petición que mandar, y aun
254
+ * así pintaba 'AA' en pantalla y anunciaba éxito. El cambio se veía y no
255
+ * existía en la base.
256
+ *
257
+ * Se expresa reusando `getStatusArrayByRole`: cada slot ocupado aporta los
258
+ * estatus del rol que clásicamente lo ocupaba, y se unen sin repetir.
259
+ */
260
+
244
261
 
245
262
  exports.getStatusArrayByRole = getStatusArrayByRole;
246
263
 
264
+ var getStatusArrayForUser = function getStatusArrayForUser(user, product) {
265
+ // `normalizeProduct` pone 0 cuando no hay nadie asignado, no null.
266
+ var mine = function mine(value) {
267
+ return !!value && value === (user === null || user === void 0 ? void 0 : user.id_user);
268
+ };
269
+
270
+ var roles = [user === null || user === void 0 ? void 0 : user.id_role];
271
+ if (mine(product === null || product === void 0 ? void 0 : product.id_auditor)) roles.push(6);
272
+ var services = ["datasheet", "description", "images"];
273
+
274
+ if (services.some(function (s) {
275
+ return mine(product === null || product === void 0 ? void 0 : product["id_".concat(s, "_especialist")]);
276
+ })) {
277
+ roles.push(7);
278
+ }
279
+
280
+ if (["datasheet", "description"].some(function (s) {
281
+ return mine(product === null || product === void 0 ? void 0 : product["id_".concat(s, "_facilitator")]);
282
+ })) {
283
+ roles.push(4);
284
+ }
285
+
286
+ if (mine(product === null || product === void 0 ? void 0 : product.id_images_facilitator)) roles.push(5);
287
+ return (0, _toConsumableArray2.default)(new Set(roles.flatMap(function (role) {
288
+ return getStatusArrayByRole(role);
289
+ })));
290
+ };
291
+
292
+ exports.getStatusArrayForUser = getStatusArrayForUser;
293
+
247
294
  var getConceptsByRole = function getConceptsByRole(idRole) {
248
295
  switch (idRole) {
249
296
  case 4:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "contentoh-components-library",
3
- "version": "21.6.53",
3
+ "version": "21.6.55",
4
4
  "dependencies": {
5
5
  "@aws-amplify/auth": "^4.5.3",
6
6
  "@aws-amplify/datastore": "^3.11.0",
@@ -17,7 +17,7 @@ import {
17
17
  createMessage,
18
18
  sendMessage,
19
19
  translateConcept,
20
- getStatusArrayByRole,
20
+ getStatusArrayForUser,
21
21
  getConceptsByRole,
22
22
  buildCollaboratorAssignations,
23
23
  calculateRequiredNull,
@@ -374,8 +374,10 @@ const RetailerProductEditionView = ({
374
374
  ),
375
375
  );
376
376
 
377
- // Configurar statusArray según el rol del usuario
378
- setStatusArray(getStatusArrayByRole(user.id_role));
377
+ // Los estatus evaluables salen del rol UNIDO a la asignación. Solo por
378
+ // rol, quien produce y además audita no tenía 'AC' en la lista y el
379
+ // envío se quedaba sin nada que mandar.
380
+ setStatusArray(getStatusArrayForUser(user, productNormalized));
379
381
 
380
382
  // Cargar usuarios y asignaciones
381
383
  const users = await fetchUsers(token);
@@ -786,7 +788,11 @@ const RetailerProductEditionView = ({
786
788
  ["AC", "RP", "RCA", "SAC"].includes(retailerStatus) &&
787
789
  ([1, 6].includes(user.id_role) || isAuditorAssigned());
788
790
 
789
- return canEvaluateAsFacilitator || canEvaluateAsAuditor;
791
+ // Los roles 7 y 8 también pueden validar/rechazar lo que está en AC.
792
+ const canEvaluateAC =
793
+ retailerStatus === "AC" && [7, 8].includes(user.id_role);
794
+
795
+ return canEvaluateAsFacilitator || canEvaluateAsAuditor || canEvaluateAC;
790
796
  };
791
797
 
792
798
  const canShowBulkEvaluationButtons = () => {
@@ -806,7 +812,12 @@ const RetailerProductEditionView = ({
806
812
  ["AC", "RP", "RCA"].includes(srv?.status?.replace(/.*\//, "")),
807
813
  ) && ([1, 6].includes(user.id_role) || isAuditorAssigned());
808
814
 
809
- return canEvaluateAsFacilitator || canEvaluateAsAuditor;
815
+ const canEvaluateAC =
816
+ services.length > 0 &&
817
+ services.every((srv) => srv?.status?.replace(/.*\//, "") === "AC") &&
818
+ [7, 8].includes(user.id_role);
819
+
820
+ return canEvaluateAsFacilitator || canEvaluateAsAuditor || canEvaluateAC;
810
821
  };
811
822
 
812
823
  const getStatusByCurrentServiceAndRetailer = () => {
@@ -1760,6 +1771,24 @@ const RetailerProductEditionView = ({
1760
1771
 
1761
1772
  await Promise.all(evaluationArray);
1762
1773
 
1774
+ // Sin una sola petición no hubo evaluación. Seguir de largo es lo que
1775
+ // pintaba el estatus nuevo y anunciaba éxito mientras la base no se
1776
+ // enteraba: el cambio se veía en pantalla y no existía. Un no-op tiene
1777
+ // que decirlo, no fingir que funcionó.
1778
+ if (evaluationArray.length === 0) {
1779
+ dispatch({
1780
+ type: "SET_MODAL",
1781
+ payload: {
1782
+ show: true,
1783
+ title: "Error",
1784
+ message:
1785
+ "No hay servicios que puedas evaluar en el estatus actual.",
1786
+ image: errorIcon,
1787
+ },
1788
+ });
1789
+ return;
1790
+ }
1791
+
1763
1792
  const status = `${result}A`;
1764
1793
 
1765
1794
  // Actualizar el statusByRetailer para todos los retailers y conceptos
@@ -1951,9 +1980,10 @@ const RetailerProductEditionView = ({
1951
1980
  switch (id_rol) {
1952
1981
  case 7:
1953
1982
  case 8:
1954
- const canSendEvaluation = statusArray.includes(
1955
- statusBySelectedRetailerService,
1956
- );
1983
+ // AC se valida/rechaza desde el panel, no se reenvía con "Enviar evaluación".
1984
+ const canSendEvaluation =
1985
+ statusBySelectedRetailerService !== "AC" &&
1986
+ statusArray.includes(statusBySelectedRetailerService);
1957
1987
 
1958
1988
  // const conditionTwo = statusArray.includes(product?.status);
1959
1989
 
@@ -18,123 +18,82 @@ TextEditor.args = {
18
18
  token:
19
19
  "eyJraWQiOiJEV3owZnNieXg2MXNFcVduN3RCXC81bVhod3ZNbFZIOTgwUnZcL3RjT0lKdEk9IiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiI4ZDAxMDIxNC01YmZhLTQzYzMtOTZmYi1jNTU2ZGMwNTc3NGIiLCJjb2duaXRvOmdyb3VwcyI6WyJjb2xhYm9yYWRvcmVzX2NvbnRlbnRvaCJdLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiaXNzIjoiaHR0cHM6XC9cL2NvZ25pdG8taWRwLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tXC91cy1lYXN0LTFfbFN6UVo0WjdSIiwiY29nbml0bzp1c2VybmFtZSI6IjhkMDEwMjE0LTViZmEtNDNjMy05NmZiLWM1NTZkYzA1Nzc0YiIsImF1ZCI6IjUyZDlza2tkY2c4cWpwODhvb2sxdXNlNm1rIiwiZXZlbnRfaWQiOiIzYzc3Y2JjMC02ZTM0LTRhZDQtOGJjMy02MmJmNGRhOTYxMTUiLCJ0b2tlbl91c2UiOiJpZCIsImF1dGhfdGltZSI6MTc2ODQ5NjU3NywibmFtZSI6IkNvbGFib3JhZG9yIiwicGhvbmVfbnVtYmVyIjoiKzUyMTExMSIsImV4cCI6MTc2ODUwMDE3NywiaWF0IjoxNzY4NDk2NTc3LCJlbWFpbCI6ImthcmFmZTMyMThAbW9tMmtpZC5jb20ifQ.FhBvgESIAX90v1_2auyejto5NrMetq5qHoFxzh9lRr07UsYw2iKdDG29VyJLZ_bPStSUx-424U7FR1ctSD9mU831TKuwSyGyGKLz0mO70Ume7pgt8zfN0C_YWv5MFG4thcMrvMfEuyzfUhvQ944HBjXvqzyjcOdCjsFx9gVEnLh1bsXe1MJrUx8H1KN5gNrrkkTE7Qo3ybyr_WZF1002JsdMaoFg2UP3H5gzcbcuxgtjNuyhqaXGnoCBsPhu6SOAwWLEu1pZMty88OFteEWEdxJxCbzKaj8IomT8U4Tjiti4tshMkXRnxHBqAkGzLDu3ypbG4S31CR7RgDxRIVqntw",
20
20
  productSelected: {
21
- orderId: 10424,
22
- status: "CA",
23
- datasheet_status: "CA",
21
+ articleId: 150504,
22
+ services: {
23
+ datasheets: 1,
24
+ descriptions: 1,
25
+ images: 1,
26
+ },
27
+ orderId: 11130,
28
+ city: "CDMX, México",
29
+ status: "AC",
30
+ datasheet_status: "AC",
24
31
  prio: "none",
25
32
  version: 3,
26
- description_status: "CA",
27
- images_status: "CA",
28
- brand: "Marca",
29
- retailerOrder: 0,
30
- missing: { datasheet: null, descriptions: null, images: null },
31
- services: { datasheets: 1, descriptions: 1, images: 1 },
33
+ description_status: "AC",
34
+ images_status: "AC",
35
+ statusByRetailer: [
36
+ {
37
+ status: "AC",
38
+ service: "datasheet",
39
+ retailer_id: 9,
40
+ task_user_group_id: 4,
41
+ },
42
+ {
43
+ status: "AC",
44
+ service: "description",
45
+ retailer_id: 9,
46
+ task_user_group_id: 4,
47
+ },
48
+ {
49
+ status: "AC",
50
+ service: "images",
51
+ retailer_id: 9,
52
+ task_user_group_id: 4,
53
+ },
54
+ ],
32
55
  article: {
33
- category:
34
- "Categoría Genérica Rappi|Categoría Genérica|Categoría Genérica",
56
+ id_article: 150504,
57
+ id_category: 6103,
58
+ brand: "Generico",
59
+ name: "Pruebas Tech",
60
+ upc: "43876912836",
61
+ sku: "43876912836",
62
+ timestamp: "2026-09-26T03:09:13.000Z",
63
+ active: 1,
64
+ company_id: 1116,
35
65
  company_name: "Walmart SA de CV",
36
66
  country: "México",
37
- id_category: "4911",
67
+ id_order: 11130,
38
68
  id_datasheet_especialist: 426,
39
69
  id_datasheet_facilitator: null,
40
70
  id_description_especialist: 426,
41
71
  id_description_facilitator: null,
42
72
  id_images_especialist: 427,
43
73
  id_images_facilitator: null,
44
- id_order: 10424,
45
- id_article: 144832,
46
- id_auditor: 425,
47
- name: "Copia prod cadenas 1",
48
- timestamp: "2025-11-16T00:32:13.000Z",
49
- upc: "100023",
50
- sku: "900006",
74
+ id_auditor: 426,
75
+ id_recepcionist: null,
76
+ category: "Alimentos y Bebidas|Amazon Súper|Abarrotes",
51
77
  categoryRetailer: [
52
- {
53
- id_category: 3431,
54
- id_retailer: 24,
55
- category_name:
56
- "Abarrotes Básicos Alsuper|Abarrotes Básicos|Abarrotes Básicos",
57
- retailer_name: "Alsuper",
58
- },
59
- {
60
- id_category: 3435,
61
- id_retailer: 21,
62
- category_name:
63
- "Bebés Cuidado e Higiene|Bebés Cuidado e Higiene|Bebés Cuidado e Higiene",
64
- retailer_name: "Anicetos",
65
- },
66
- {
67
- id_category: 3438,
68
- id_retailer: 1008,
69
- category_name:
70
- "Categoría Genérica App Olímpica|Categoría Genérica|Categoría Genérica",
71
- retailer_name: "App Olímpica",
72
- },
73
- {
74
- id_category: 3439,
75
- id_retailer: 2004,
76
- category_name:
77
- "Categoría Genérica Automercado|Categoría Genérica Automercado|Categoría Genérica Automercado",
78
- retailer_name: "Automercado",
79
- },
80
- {
81
- id_category: 4774,
82
- id_retailer: 1032,
83
- category_name:
84
- "Categoría Genérica IMPIRA Colombia|Categoría Genérica|Categoría Genérica",
85
- retailer_name: "IMPIRA Colombia",
86
- },
87
- {
88
- id_category: 4911,
89
- id_retailer: 16,
90
- category_name:
91
- "Categoría Genérica Rappi|Categoría Genérica|Categoría Genérica",
92
- retailer_name: "Rappi",
93
- },
94
78
  {
95
79
  id_category: 6103,
96
80
  id_retailer: 9,
97
81
  category_name: "Alimentos y Bebidas|Amazon Súper|Abarrotes",
98
82
  retailer_name: "Amazon",
99
83
  },
100
- {
101
- id_category: 6792,
102
- id_retailer: 32,
103
- category_name:
104
- "Categoría Salud y Belleza Coppel|Categoría Salud y Belleza|Categoría Salud y Belleza",
105
- retailer_name: "Coppel",
106
- },
107
- {
108
- id_category: 7008,
109
- id_retailer: 3,
110
- category_name: "Bebés|Accesorios para Bebés|Accesorios para Bebés",
111
- retailer_name: "Sam´s Club",
112
- },
113
84
  ],
114
85
  },
115
86
  retailers: [
116
- { id: 3, name: "Sam´s Club" },
117
- { id: 16, name: "Rappi" },
118
- { id: 32, name: "Coppel" },
119
- { id: 1008, name: "App Olímpica" },
120
- ],
121
- statusByRetailer: [
122
- { status: "RA/AS", service: "datasheet", retailer_id: 3 },
123
- { status: "RA/AS", service: "description", retailer_id: 3 },
124
- { status: "AA", service: "images", retailer_id: 3 },
125
- { status: "AC", service: "datasheet", retailer_id: 16 },
126
- { status: "AC", service: "description", retailer_id: 16 },
127
- { status: "AC", service: "images", retailer_id: 16 },
128
- { status: "AC", service: "datasheet", retailer_id: 32 },
129
- { status: "AC", service: "description", retailer_id: 32 },
130
- { status: "AC", service: "images", retailer_id: 32 },
131
- { status: "PA", service: "datasheet", retailer_id: 1032 },
132
- { status: "PA", service: "description", retailer_id: 1032 },
133
- { status: "PA", service: "images", retailer_id: 1032 },
134
- { status: "PA", service: "datasheet", retailer_id: 2004 },
135
- { status: "PA", service: "description", retailer_id: 2004 },
136
- { status: "PA", service: "images", retailer_id: 2004 },
87
+ {
88
+ id: 9,
89
+ name: "Amazon",
90
+ },
137
91
  ],
92
+ variantsCount: 0,
93
+ parent: null,
94
+ parentArticleId: null,
95
+ country: "México",
96
+ upc: "43876912836",
138
97
  },
139
98
  user: {
140
99
  id_user: 426,
@@ -186,7 +186,7 @@ export const getStatusArrayByRole = (idRole) => {
186
186
  ];
187
187
  case 7:
188
188
  case 8:
189
- return ["PA", "AS", "CA", "RC", "RA", "RP", "RCA"];
189
+ return ["PA", "AS", "CA", "RC", "RA", "RP", "RCA", "AC"];
190
190
  case 4:
191
191
  case 5:
192
192
  return ["RC", "AC", "AA", "AP", "ACA"];
@@ -197,6 +197,40 @@ export const getStatusArrayByRole = (idRole) => {
197
197
  }
198
198
  };
199
199
 
200
+ /**
201
+ * Estatus en los que esta persona puede evaluar ESTE producto.
202
+ *
203
+ * Unión de lo que le toca por ROL y de lo que le toca por ASIGNACIÓN. Antes
204
+ * solo se preguntaba el rol, y de ahí salía el defecto: un Especialista de
205
+ * Textos asignado como auditor no tenía 'AC' en su lista. El botón sí
206
+ * aparecía —esa compuerta ya mira la asignación—, pero `sendBulkEvaluation`
207
+ * filtra con esta lista, se quedaba sin una sola petición que mandar, y aun
208
+ * así pintaba 'AA' en pantalla y anunciaba éxito. El cambio se veía y no
209
+ * existía en la base.
210
+ *
211
+ * Se expresa reusando `getStatusArrayByRole`: cada slot ocupado aporta los
212
+ * estatus del rol que clásicamente lo ocupaba, y se unen sin repetir.
213
+ */
214
+ export const getStatusArrayForUser = (user, product) => {
215
+ // `normalizeProduct` pone 0 cuando no hay nadie asignado, no null.
216
+ const mine = (value) => !!value && value === user?.id_user;
217
+
218
+ const roles = [user?.id_role];
219
+
220
+ if (mine(product?.id_auditor)) roles.push(6);
221
+
222
+ const services = ["datasheet", "description", "images"];
223
+ if (services.some((s) => mine(product?.[`id_${s}_especialist`]))) {
224
+ roles.push(7);
225
+ }
226
+ if (["datasheet", "description"].some((s) => mine(product?.[`id_${s}_facilitator`]))) {
227
+ roles.push(4);
228
+ }
229
+ if (mine(product?.id_images_facilitator)) roles.push(5);
230
+
231
+ return [...new Set(roles.flatMap((role) => getStatusArrayByRole(role)))];
232
+ };
233
+
200
234
  export const getConceptsByRole = (idRole) => {
201
235
  switch (idRole) {
202
236
  case 4: