contentoh-components-library 21.6.49 → 21.6.51

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.
@@ -17,6 +17,8 @@ var _react = require("react");
17
17
 
18
18
  var _styles = require("./styles");
19
19
 
20
+ var _nonPropagable = require("./non-propagable");
21
+
20
22
  var _jsxRuntime = require("react/jsx-runtime");
21
23
 
22
24
  /*
@@ -46,7 +48,7 @@ var UMBRAL_SEGUNDO_PLANO = 20;
46
48
 
47
49
  var PropagateChangesModal = function PropagateChangesModal(_ref) {
48
50
  var _ref$changedAttribute = _ref.changedAttributes,
49
- changedAttributes = _ref$changedAttribute === void 0 ? [] : _ref$changedAttribute,
51
+ cambiosRecibidos = _ref$changedAttribute === void 0 ? [] : _ref$changedAttribute,
50
52
  _ref$variants = _ref.variants,
51
53
  variants = _ref$variants === void 0 ? [] : _ref$variants,
52
54
  _ref$groupMembers = _ref.groupMembers,
@@ -58,6 +60,15 @@ var PropagateChangesModal = function PropagateChangesModal(_ref) {
58
60
  _ref$saving = _ref.saving,
59
61
  saving = _ref$saving === void 0 ? false : _ref$saving;
60
62
 
63
+ /*
64
+ Segundo filtro, a propósito redundante: quien llama ya debería quitarlos —de
65
+ eso depende que el diálogo no se abra por un cambio que no propaga nada—,
66
+ pero ofrecer el UPC y descartarlo en el servidor es exactamente el camino
67
+ por el que un usuario concluye que la propagación no sirve. Vale más
68
+ repetirlo aquí que confiar en que ningún llamador futuro lo olvide.
69
+ */
70
+ var changedAttributes = (0, _nonPropagable.soloPropagables)(cambiosRecibidos);
71
+
61
72
  var _useState = (0, _react.useState)([]),
62
73
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
63
74
  chosenAttributes = _useState2[0],
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.soloPropagables = exports.UPC_ATTRIBUTE_ID = exports.SKU_ATTRIBUTE_ID = exports.NON_PROPAGABLE_ATTRIBUTES = void 0;
7
+
8
+ /*
9
+ Atributos que la propagación nunca copia.
10
+
11
+ UPC y SKU son la IDENTIDAD del producto, y una variante existe precisamente
12
+ porque la suya es distinta: el acuerdo lo dice literal —"cambian UPC/color/
13
+ talla"—. Bajarlos del padre dejaría dos productos con el mismo código de
14
+ barras, que es lo contrario de una variante.
15
+
16
+ El servidor ya los descarta y esa es la defensa de verdad: la exclusión vive
17
+ allá, no aquí, y aunque esta pantalla los mandara no se copiarían. Lo de este
18
+ archivo es otra cosa —que el diálogo no los OFREZCA—, porque ofrecer una
19
+ opción que se descarta en silencio es peor que no ofrecerla: el usuario elige
20
+ el UPC, guarda, no ve error, y concluye que la propagación está rota.
21
+
22
+ Los ids son los mismos que `variants/utils/constants.js` en el backend. Están
23
+ duplicados porque no hay un contrato compartido entre repos; si allá cambian,
24
+ aquí hay que cambiarlos.
25
+ */
26
+ var UPC_ATTRIBUTE_ID = 683;
27
+ exports.UPC_ATTRIBUTE_ID = UPC_ATTRIBUTE_ID;
28
+ var SKU_ATTRIBUTE_ID = 40001;
29
+ exports.SKU_ATTRIBUTE_ID = SKU_ATTRIBUTE_ID;
30
+ var NON_PROPAGABLE_ATTRIBUTES = [UPC_ATTRIBUTE_ID, SKU_ATTRIBUTE_ID];
31
+ /**
32
+ * Quita de una lista de cambios los que no se pueden propagar.
33
+ * @param {Array<{id: number}>} cambios
34
+ */
35
+
36
+ exports.NON_PROPAGABLE_ATTRIBUTES = NON_PROPAGABLE_ATTRIBUTES;
37
+
38
+ var soloPropagables = function soloPropagables() {
39
+ var cambios = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
40
+ return cambios.filter(function (c) {
41
+ return !NON_PROPAGABLE_ATTRIBUTES.includes(Number(c === null || c === void 0 ? void 0 : c.id));
42
+ });
43
+ };
44
+
45
+ exports.soloPropagables = soloPropagables;
@@ -73,6 +73,8 @@ var _VariantGroupModal = require("../../organisms/VariantGroupModal");
73
73
 
74
74
  var _PropagateChangesModal = require("../../organisms/PropagateChangesModal");
75
75
 
76
+ var _nonPropagable = require("../../organisms/PropagateChangesModal/non-propagable");
77
+
76
78
  var _api = require("../../organisms/LinkVariantsModal/api");
77
79
 
78
80
  var _ProductImageModal = require("../../organisms/ProductImageModal");
@@ -94,7 +96,7 @@ var _AiProductEdition = require("../../../contexts/AiProductEdition");
94
96
  var _jsxRuntime = require("react/jsx-runtime");
95
97
 
96
98
  var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
97
- var _location$state4, _state$product2, _state$product3, _state$product4, _state$product5, _state$product6, _state$product7, _state$product15, _family$variants2, _variantGroup$members2, _variantGroup$group, _state$product20, _state$product21, _state$product22, _state$active_retaile4, _state$product23, _state$product24, _state$product25, _variantGroup$group2, _location$state5, _location$state6, _state$active_retaile5, _state$active_retaile6, _state$images_values$2, _state$images_values10, _state$images_values11, _state$active_retaile7, _state$product26, _state$product27, _state$product28, _state$product29, _family$variants3, _family$variants4, _family$variants5, _variantGroup$members3, _variantGroup$members4, _state$active_percent, _state$active_percent2, _state$active_retaile8, _state$active_retaile9, _state$active_retaile10, _state$product35, _state$descriptions_i, _state$services2, _state$services2$data, _state$product36, _state$product37, _state$datasheets_inp, _state$datasheets_inp2, _state$datasheets_inp3, _state$product38, _state$images_values12;
99
+ var _state$product, _location$state4, _state$product3, _state$product4, _state$product5, _state$product6, _state$product7, _state$product8, _state$product17, _state$product22, _family$variants2, _variantGroup$members2, _variantGroup$group, _state$product23, _state$product24, _state$product25, _state$active_retaile4, _state$product26, _state$product27, _state$product28, _variantGroup$group2, _location$state5, _location$state6, _state$active_retaile5, _state$active_retaile6, _state$images_values$2, _state$images_values10, _state$images_values11, _state$active_retaile7, _state$product29, _state$product30, _state$product31, _state$product32, _family$variants3, _family$variants4, _family$variants5, _variantGroup$members3, _variantGroup$members4, _state$active_percent, _state$active_percent2, _state$active_retaile8, _state$active_retaile9, _state$active_retaile10, _state$product38, _state$descriptions_i, _state$services2, _state$services2$data, _state$product39, _state$product40, _state$datasheets_inp, _state$datasheets_inp2, _state$datasheets_inp3, _state$product41, _state$images_values12;
98
100
 
99
101
  var tabsSections = _ref.tabsSections,
100
102
  _ref$productSelected = _ref.productSelected,
@@ -174,6 +176,17 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
174
176
  _useState18 = (0, _slicedToArray2.default)(_useState17, 2),
175
177
  showGroupModal = _useState18[0],
176
178
  setShowGroupModal = _useState18[1];
179
+ /*
180
+ Un hijo no se agrupa como variante (decisión de producto, 2026-09-25).
181
+ Agrupar declara «estos son el mismo producto en otra presentación», y un
182
+ hijo ya declaró de dónde deriva; tener las dos cosas lo dejaba con dos
183
+ respuestas distintas a la misma pregunta. El servidor lo rechaza con
184
+ VARIANT_GROUP_NOT_FOR_CHILD, así que ofrecer el botón aquí sería ofrecer
185
+ algo que siempre falla.
186
+ */
187
+
188
+
189
+ var puedeAgruparse = !((_state$product = state.product) !== null && _state$product !== void 0 && _state$product.parentArticleId);
177
190
 
178
191
  var _useState19 = (0, _react.useState)(null),
179
192
  _useState20 = (0, _slicedToArray2.default)(_useState19, 2),
@@ -358,10 +371,10 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
358
371
  (0, _react.useEffect)(function () {
359
372
  if (!state.product || !state.active_retailer) return;
360
373
  console.log("Fetch services and percentages");
361
- var _state$product = state.product,
362
- id_article = _state$product.id_article,
363
- version = _state$product.version,
364
- id_order = _state$product.id_order;
374
+ var _state$product2 = state.product,
375
+ id_article = _state$product2.id_article,
376
+ version = _state$product2.version,
377
+ id_order = _state$product2.id_order;
365
378
  var _state$active_retaile = state.active_retailer,
366
379
  category = _state$active_retaile.category,
367
380
  id_category = _state$active_retaile.id_category,
@@ -519,7 +532,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
519
532
  }();
520
533
 
521
534
  fetchData();
522
- }, [(_state$product2 = state.product) === null || _state$product2 === void 0 ? void 0 : _state$product2.datasheet_status, (_state$product3 = state.product) === null || _state$product3 === void 0 ? void 0 : _state$product3.description_status, (_state$product4 = state.product) === null || _state$product4 === void 0 ? void 0 : _state$product4.images_status, (_state$product5 = state.product) === null || _state$product5 === void 0 ? void 0 : _state$product5.status, (_state$product6 = state.product) === null || _state$product6 === void 0 ? void 0 : _state$product6.percentages, (_state$product7 = state.product) === null || _state$product7 === void 0 ? void 0 : _state$product7.version, state.active_retailer, token, linkNonce]); // Actualizador de campos del ui para que coincidan con el retailer activo
535
+ }, [(_state$product3 = state.product) === null || _state$product3 === void 0 ? void 0 : _state$product3.datasheet_status, (_state$product4 = state.product) === null || _state$product4 === void 0 ? void 0 : _state$product4.description_status, (_state$product5 = state.product) === null || _state$product5 === void 0 ? void 0 : _state$product5.images_status, (_state$product6 = state.product) === null || _state$product6 === void 0 ? void 0 : _state$product6.status, (_state$product7 = state.product) === null || _state$product7 === void 0 ? void 0 : _state$product7.percentages, (_state$product8 = state.product) === null || _state$product8 === void 0 ? void 0 : _state$product8.version, state.active_retailer, token, linkNonce]); // Actualizador de campos del ui para que coincidan con el retailer activo
523
536
 
524
537
  (0, _react.useEffect)(function () {
525
538
  if (!state.active_retailer) return;
@@ -578,9 +591,9 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
578
591
  }, [state.services]); // Helper functions
579
592
 
580
593
  var canShowValidationButtons = function canShowValidationButtons() {
581
- var _state$product8;
594
+ var _state$product9;
582
595
 
583
- if (!((_state$product8 = state.product) !== null && _state$product8 !== void 0 && _state$product8.statusByRetailer)) return false;
596
+ if (!((_state$product9 = state.product) !== null && _state$product9 !== void 0 && _state$product9.statusByRetailer)) return false;
584
597
 
585
598
  try {
586
599
  var currentService = (0, _utils.getConceptByTab)(state.active_tab); // const currentStatus = state.product[`${currentService}_status`];
@@ -701,9 +714,9 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
701
714
  };
702
715
 
703
716
  var handleOnClickSaveImages = function handleOnClickSaveImages() {
704
- var _state$product9, _state$product9$servi;
717
+ var _state$product10, _state$product10$serv;
705
718
 
706
- if (((_state$product9 = state.product) === null || _state$product9 === void 0 ? void 0 : (_state$product9$servi = _state$product9.services) === null || _state$product9$servi === void 0 ? void 0 : _state$product9$servi.images) === 1) {
719
+ if (((_state$product10 = state.product) === null || _state$product10 === void 0 ? void 0 : (_state$product10$serv = _state$product10.services) === null || _state$product10$serv === void 0 ? void 0 : _state$product10$serv.images) === 1) {
707
720
  updateImages();
708
721
  }
709
722
  };
@@ -858,7 +871,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
858
871
 
859
872
  var retailerId = (_state$active_retaile2 = state.active_retailer) === null || _state$active_retaile2 === void 0 ? void 0 : _state$active_retaile2.id_retailer;
860
873
  var inputs = (_state$services$datas = (_state$services = state.services) === null || _state$services === void 0 ? void 0 : (_state$services$datas2 = _state$services.datasheets) === null || _state$services$datas2 === void 0 ? void 0 : _state$services$datas2.inputs) !== null && _state$services$datas !== void 0 ? _state$services$datas : {};
861
- return ((_state$updated_datash = state.updated_datasheets_inputs) !== null && _state$updated_datash !== void 0 ? _state$updated_datash : []).map(function (item) {
874
+ var cambios = ((_state$updated_datash = state.updated_datasheets_inputs) !== null && _state$updated_datash !== void 0 ? _state$updated_datash : []).map(function (item) {
862
875
  var _input$name;
863
876
 
864
877
  var input = inputs["".concat(item.attributeId, "_").concat(retailerId)];
@@ -868,6 +881,14 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
868
881
  value: item.value
869
882
  };
870
883
  });
884
+ /*
885
+ UPC y SKU se quitan aquí y no dentro del diálogo porque esta lista también
886
+ decide SI el diálogo se abre. Editar solo el UPC no tiene nada que
887
+ propagar, así que preguntarlo sería pedirle al usuario una decisión sobre
888
+ un conjunto vacío.
889
+ */
890
+
891
+ return (0, _nonPropagable.soloPropagables)(cambios);
871
892
  };
872
893
 
873
894
  var handleOnClickSave = function handleOnClickSave() {
@@ -882,7 +903,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
882
903
 
883
904
  case "Ficha técnica":
884
905
  {
885
- var _variantGroup$members, _state$product10;
906
+ var _variantGroup$members, _state$product11, _state$product12;
886
907
 
887
908
  // Guardar un padre con hijos abre la decisión de propagar. Sin este
888
909
  // paso el cambio se queda solo en el padre y los hijos se van
@@ -896,7 +917,21 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
896
917
  var companeras = ((_variantGroup$members = variantGroup === null || variantGroup === void 0 ? void 0 : variantGroup.members) !== null && _variantGroup$members !== void 0 ? _variantGroup$members : []).filter(function (m) {
897
918
  return !m.isCurrent;
898
919
  });
899
- var hayDestinos = ((_state$product10 = state.product) === null || _state$product10 === void 0 ? void 0 : _state$product10.variantsCount) > 0 || companeras.length > 0;
920
+ /*
921
+ Un HIJO no propaga a nadie, y hay que decirlo explícitamente.
922
+ Sin este corte el diálogo se abría desde la ficha de un hijo y le
923
+ ofrecía a sus HERMANOS como si fueran sus hijos: `family.variants`
924
+ mira la familia desde el padre —eso es lo correcto para navegar entre
925
+ hermanos— pero aquí se estaba leyendo como «los destinos de este
926
+ producto». El servidor resolvía los destinos por su cuenta y no
927
+ escribía nada, así que el usuario elegía hermanos, guardaba, y no
928
+ pasaba nada: un no-operativo silencioso.
929
+ Un hijo tampoco puede estar agrupado desde 2026-09-25, así que para
930
+ él no queda ningún destino posible.
931
+ */
932
+
933
+ var esHijo = !!((_state$product11 = state.product) !== null && _state$product11 !== void 0 && _state$product11.parentArticleId);
934
+ var hayDestinos = !esHijo && (((_state$product12 = state.product) === null || _state$product12 === void 0 ? void 0 : _state$product12.variantsCount) > 0 || companeras.length > 0);
900
935
  var cambios = cambiosDeFichaTecnica();
901
936
 
902
937
  if (hayDestinos && cambios.length > 0) {
@@ -963,7 +998,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
963
998
  var loadFamily = /*#__PURE__*/function () {
964
999
  var _ref7 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
965
1000
  var forzar,
966
- _state$product11,
1001
+ _state$product13,
967
1002
  res,
968
1003
  _args3 = arguments;
969
1004
 
@@ -984,7 +1019,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
984
1019
  _context3.prev = 3;
985
1020
  _context3.next = 6;
986
1021
  return _axios.default.post("".concat(process.env.REACT_APP_VARIANTS_ENDPOINT, "/family"), {
987
- articleId: (_state$product11 = state.product) === null || _state$product11 === void 0 ? void 0 : _state$product11.id_article
1022
+ articleId: (_state$product13 = state.product) === null || _state$product13 === void 0 ? void 0 : _state$product13.id_article
988
1023
  }, {
989
1024
  headers: {
990
1025
  Authorization: token
@@ -1163,14 +1198,14 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
1163
1198
 
1164
1199
 
1165
1200
  var handleOnUnlinked = function handleOnUnlinked(result) {
1166
- var _state$product$varian, _state$product12, _updatedProduct$varia;
1201
+ var _state$product$varian, _state$product14, _updatedProduct$varia;
1167
1202
 
1168
1203
  if (!result) return;
1169
1204
  var updatedProduct = result.mode === "self" ? (0, _objectSpread4.default)((0, _objectSpread4.default)({}, state.product), {}, {
1170
1205
  parentArticleId: null,
1171
1206
  variantsCount: 0
1172
1207
  }) : (0, _objectSpread4.default)((0, _objectSpread4.default)({}, state.product), {}, {
1173
- variantsCount: Math.max(((_state$product$varian = (_state$product12 = state.product) === null || _state$product12 === void 0 ? void 0 : _state$product12.variantsCount) !== null && _state$product$varian !== void 0 ? _state$product$varian : 1) - 1, 0)
1208
+ variantsCount: Math.max(((_state$product$varian = (_state$product14 = state.product) === null || _state$product14 === void 0 ? void 0 : _state$product14.variantsCount) !== null && _state$product$varian !== void 0 ? _state$product$varian : 1) - 1, 0)
1174
1209
  });
1175
1210
  dispatch({
1176
1211
  type: "SET_PRODUCT",
@@ -1220,7 +1255,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
1220
1255
  var loadVariantGroup = /*#__PURE__*/function () {
1221
1256
  var _ref9 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() {
1222
1257
  var forzar,
1223
- _state$product13,
1258
+ _state$product15,
1224
1259
  res,
1225
1260
  data,
1226
1261
  _args5 = arguments;
@@ -1242,7 +1277,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
1242
1277
  _context5.prev = 3;
1243
1278
  _context5.next = 6;
1244
1279
  return _axios.default.post("".concat(process.env.REACT_APP_VARIANTS_ENDPOINT, "/group"), {
1245
- articleId: (_state$product13 = state.product) === null || _state$product13 === void 0 ? void 0 : _state$product13.id_article
1280
+ articleId: (_state$product15 = state.product) === null || _state$product15 === void 0 ? void 0 : _state$product15.id_article
1246
1281
  }, {
1247
1282
  headers: {
1248
1283
  Authorization: token
@@ -1280,16 +1315,16 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
1280
1315
  }();
1281
1316
 
1282
1317
  (0, _react.useEffect)(function () {
1283
- var _state$product14;
1318
+ var _state$product16;
1284
1319
 
1285
- if (!((_state$product14 = state.product) !== null && _state$product14 !== void 0 && _state$product14.id_article)) return;
1320
+ if (!((_state$product16 = state.product) !== null && _state$product16 !== void 0 && _state$product16.id_article)) return;
1286
1321
  loadVariantGroup(true); // eslint-disable-next-line react-hooks/exhaustive-deps
1287
- }, [(_state$product15 = state.product) === null || _state$product15 === void 0 ? void 0 : _state$product15.id_article]); // Saca el producto del grupo. Los demás miembros siguen agrupados entre ellos;
1322
+ }, [(_state$product17 = state.product) === null || _state$product17 === void 0 ? void 0 : _state$product17.id_article]); // Saca el producto del grupo. Los demás miembros siguen agrupados entre ellos;
1288
1323
  // si era el último, el grupo deja de existir, porque no vive en ninguna tabla.
1289
1324
 
1290
1325
  var handleOnLeaveGroup = /*#__PURE__*/function () {
1291
1326
  var _ref10 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6() {
1292
- var _state$product16, res;
1327
+ var _state$product18, res;
1293
1328
 
1294
1329
  return _regenerator.default.wrap(function _callee6$(_context6) {
1295
1330
  while (1) {
@@ -1298,7 +1333,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
1298
1333
  _context6.prev = 0;
1299
1334
  _context6.next = 3;
1300
1335
  return _axios.default.post("".concat(process.env.REACT_APP_VARIANTS_ENDPOINT, "/leave"), {
1301
- articleId: (_state$product16 = state.product) === null || _state$product16 === void 0 ? void 0 : _state$product16.id_article
1336
+ articleId: (_state$product18 = state.product) === null || _state$product18 === void 0 ? void 0 : _state$product18.id_article
1302
1337
  }, {
1303
1338
  headers: {
1304
1339
  Authorization: token
@@ -1436,11 +1471,11 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
1436
1471
 
1437
1472
 
1438
1473
  var handleOnLinkedVariants = function handleOnLinkedVariants(result) {
1439
- var _state$product$varian2, _state$product17, _result$linked, _result$parentArticle;
1474
+ var _state$product$varian2, _state$product19, _result$linked, _result$parentArticle;
1440
1475
 
1441
1476
  if (!result) return;
1442
1477
  var updatedProduct = result.mode === "children" ? (0, _objectSpread4.default)((0, _objectSpread4.default)({}, state.product), {}, {
1443
- variantsCount: ((_state$product$varian2 = (_state$product17 = state.product) === null || _state$product17 === void 0 ? void 0 : _state$product17.variantsCount) !== null && _state$product$varian2 !== void 0 ? _state$product$varian2 : 0) + ((_result$linked = result.linked) !== null && _result$linked !== void 0 ? _result$linked : []).length
1478
+ variantsCount: ((_state$product$varian2 = (_state$product19 = state.product) === null || _state$product19 === void 0 ? void 0 : _state$product19.variantsCount) !== null && _state$product$varian2 !== void 0 ? _state$product$varian2 : 0) + ((_result$linked = result.linked) !== null && _result$linked !== void 0 ? _result$linked : []).length
1444
1479
  }) : (0, _objectSpread4.default)((0, _objectSpread4.default)({}, state.product), {}, {
1445
1480
  parentArticleId: (_result$parentArticle = result.parentArticleId) !== null && _result$parentArticle !== void 0 ? _result$parentArticle : null,
1446
1481
  variantsCount: 0
@@ -1499,7 +1534,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
1499
1534
 
1500
1535
  var handleOnRestoreInheritance = /*#__PURE__*/function () {
1501
1536
  var _ref12 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(attributeId) {
1502
- var _state$product18;
1537
+ var _state$product20;
1503
1538
 
1504
1539
  var kind,
1505
1540
  esDescripcion,
@@ -1512,7 +1547,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
1512
1547
  case 0:
1513
1548
  kind = _args8.length > 1 && _args8[1] !== undefined ? _args8[1] : "attribute";
1514
1549
 
1515
- if (!(!attributeId || !((_state$product18 = state.product) !== null && _state$product18 !== void 0 && _state$product18.id_article))) {
1550
+ if (!(!attributeId || !((_state$product20 = state.product) !== null && _state$product20 !== void 0 && _state$product20.id_article))) {
1516
1551
  _context8.next = 3;
1517
1552
  break;
1518
1553
  }
@@ -1622,7 +1657,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
1622
1657
 
1623
1658
  var sendEvaluation = /*#__PURE__*/function () {
1624
1659
  var _ref13 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(result) {
1625
- var _state$product$id_ord, _state$active_retaile3, _state$product$status, _state$product$status2, _state$product19;
1660
+ var _state$product$id_ord, _state$active_retaile3, _state$product$status, _state$product$status2, _state$product21;
1626
1661
 
1627
1662
  var concept, articleId, orderId, retailerId, evalStatus, data, _newStatuses$newStatu, _state$services_data, res, newStatuses, serviceStatus, updatedStatusByRetailer, updatedProduct, updatedServicesData;
1628
1663
 
@@ -1638,7 +1673,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
1638
1673
  articleId = state.product.id_article;
1639
1674
  orderId = (_state$product$id_ord = state.product.id_order) !== null && _state$product$id_ord !== void 0 ? _state$product$id_ord : state.product.orderId;
1640
1675
  retailerId = (_state$active_retaile3 = state.active_retailer) === null || _state$active_retaile3 === void 0 ? void 0 : _state$active_retaile3.id_retailer;
1641
- evalStatus = ((_state$product$status = state.product.statusByRetailer) === null || _state$product$status === void 0 ? void 0 : (_state$product$status2 = _state$product$status[retailerId]) === null || _state$product$status2 === void 0 ? void 0 : _state$product$status2[concept]) || state.product["".concat(concept, "_status")] || ((_state$product19 = state.product) === null || _state$product19 === void 0 ? void 0 : _state$product19.version_status);
1676
+ evalStatus = ((_state$product$status = state.product.statusByRetailer) === null || _state$product$status === void 0 ? void 0 : (_state$product$status2 = _state$product$status[retailerId]) === null || _state$product$status2 === void 0 ? void 0 : _state$product$status2[concept]) || state.product["".concat(concept, "_status")] || ((_state$product21 = state.product) === null || _state$product21 === void 0 ? void 0 : _state$product21.version_status);
1642
1677
  data = {
1643
1678
  articleId: articleId,
1644
1679
  orderId: orderId,
@@ -2122,7 +2157,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
2122
2157
  jwt: token
2123
2158
  }), pendingPropagation && /*#__PURE__*/(0, _jsxRuntime.jsx)(_PropagateChangesModal.PropagateChangesModal, {
2124
2159
  changedAttributes: pendingPropagation.cambios,
2125
- variants: ((_family$variants2 = family === null || family === void 0 ? void 0 : family.variants) !== null && _family$variants2 !== void 0 ? _family$variants2 : []).filter(function (v) {
2160
+ variants: (_state$product22 = state.product) !== null && _state$product22 !== void 0 && _state$product22.parentArticleId ? [] : ((_family$variants2 = family === null || family === void 0 ? void 0 : family.variants) !== null && _family$variants2 !== void 0 ? _family$variants2 : []).filter(function (v) {
2126
2161
  return !v.isCurrent;
2127
2162
  }),
2128
2163
  groupMembers: ((_variantGroup$members2 = variantGroup === null || variantGroup === void 0 ? void 0 : variantGroup.members) !== null && _variantGroup$members2 !== void 0 ? _variantGroup$members2 : []).filter(function (m) {
@@ -2138,9 +2173,9 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
2138
2173
  saveDatasheets(token, propagation !== null && propagation !== void 0 ? propagation : undefined);
2139
2174
  }
2140
2175
  }), showLinkVariants && /*#__PURE__*/(0, _jsxRuntime.jsx)(_LinkVariantsModal.LinkVariantsModal, {
2141
- articleId: (_state$product20 = state.product) === null || _state$product20 === void 0 ? void 0 : _state$product20.id_article,
2142
- articleName: (_state$product21 = state.product) === null || _state$product21 === void 0 ? void 0 : _state$product21.name,
2143
- articleUpc: (_state$product22 = state.product) === null || _state$product22 === void 0 ? void 0 : _state$product22.upc,
2176
+ articleId: (_state$product23 = state.product) === null || _state$product23 === void 0 ? void 0 : _state$product23.id_article,
2177
+ articleName: (_state$product24 = state.product) === null || _state$product24 === void 0 ? void 0 : _state$product24.name,
2178
+ articleUpc: (_state$product25 = state.product) === null || _state$product25 === void 0 ? void 0 : _state$product25.upc,
2144
2179
  activeRetailerId: (_state$active_retaile4 = state.active_retailer) === null || _state$active_retaile4 === void 0 ? void 0 : _state$active_retaile4.id_retailer,
2145
2180
  token: token,
2146
2181
  onClose: function onClose() {
@@ -2148,9 +2183,9 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
2148
2183
  },
2149
2184
  onLinked: handleOnLinkedVariants
2150
2185
  }), showGroupModal && /*#__PURE__*/(0, _jsxRuntime.jsx)(_VariantGroupModal.VariantGroupModal, {
2151
- articleId: (_state$product23 = state.product) === null || _state$product23 === void 0 ? void 0 : _state$product23.id_article,
2152
- articleName: (_state$product24 = state.product) === null || _state$product24 === void 0 ? void 0 : _state$product24.name,
2153
- articleUpc: (_state$product25 = state.product) === null || _state$product25 === void 0 ? void 0 : _state$product25.upc,
2186
+ articleId: (_state$product26 = state.product) === null || _state$product26 === void 0 ? void 0 : _state$product26.id_article,
2187
+ articleName: (_state$product27 = state.product) === null || _state$product27 === void 0 ? void 0 : _state$product27.name,
2188
+ articleUpc: (_state$product28 = state.product) === null || _state$product28 === void 0 ? void 0 : _state$product28.upc,
2154
2189
  currentGroup: (_variantGroup$group2 = variantGroup === null || variantGroup === void 0 ? void 0 : variantGroup.group) !== null && _variantGroup$group2 !== void 0 ? _variantGroup$group2 : null,
2155
2190
  token: token,
2156
2191
  onClose: function onClose() {
@@ -2309,7 +2344,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
2309
2344
  activeImage: (_state$images_values10 = state.images_values) !== null && _state$images_values10 !== void 0 && _state$images_values10.values ? (_state$images_values11 = state.images_values) === null || _state$images_values11 === void 0 ? void 0 : _state$images_values11.values[state.current_image] : {},
2310
2345
  assignationsImages: assig,
2311
2346
  retailerSelected: (_state$active_retaile7 = state.active_retailer) === null || _state$active_retaile7 === void 0 ? void 0 : _state$active_retaile7.id_retailer,
2312
- imagesStatus: ((_state$product26 = state.product) === null || _state$product26 === void 0 ? void 0 : _state$product26.images_status) || "-",
2347
+ imagesStatus: ((_state$product29 = state.product) === null || _state$product29 === void 0 ? void 0 : _state$product29.images_status) || "-",
2313
2348
  isRetailer: isRetailer,
2314
2349
  setShowVersionSelector: setShowVersionSelector,
2315
2350
  version: state.product.version,
@@ -2322,7 +2357,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
2322
2357
  className: "product-information",
2323
2358
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
2324
2359
  className: "product-information",
2325
- children: [!((_state$product27 = state.product) !== null && _state$product27 !== void 0 && _state$product27.parentArticleId) && /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
2360
+ children: [!((_state$product30 = state.product) !== null && _state$product30 !== void 0 && _state$product30.parentArticleId) && /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
2326
2361
  className: "variants-actions",
2327
2362
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
2328
2363
  type: "button",
@@ -2331,7 +2366,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
2331
2366
  return setShowLinkVariants(true);
2332
2367
  },
2333
2368
  children: "Ligar productos"
2334
- }), ((_state$product28 = state.product) === null || _state$product28 === void 0 ? void 0 : _state$product28.variantsCount) > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)("button", {
2369
+ }), ((_state$product31 = state.product) === null || _state$product31 === void 0 ? void 0 : _state$product31.variantsCount) > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)("button", {
2335
2370
  type: "button",
2336
2371
  className: "variants-count",
2337
2372
  "aria-expanded": showFamily,
@@ -2346,7 +2381,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
2346
2381
  children: showFamily ? " ▴" : " ▾"
2347
2382
  })]
2348
2383
  })]
2349
- }), ((_state$product29 = state.product) === null || _state$product29 === void 0 ? void 0 : _state$product29.parentArticleId) && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
2384
+ }), ((_state$product32 = state.product) === null || _state$product32 === void 0 ? void 0 : _state$product32.parentArticleId) && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
2350
2385
  className: "variants-actions",
2351
2386
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("button", {
2352
2387
  type: "button",
@@ -2395,13 +2430,13 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
2395
2430
  className: "desvincular",
2396
2431
  title: "Dejar de ser hijo de este producto",
2397
2432
  onClick: function onClick() {
2398
- var _state$product30, _state$product31, _state$product32;
2433
+ var _state$product33, _state$product34, _state$product35;
2399
2434
 
2400
2435
  return setPorDesvincular({
2401
2436
  mode: "self",
2402
- childArticleId: (_state$product30 = state.product) === null || _state$product30 === void 0 ? void 0 : _state$product30.id_article,
2403
- childName: (_state$product31 = state.product) === null || _state$product31 === void 0 ? void 0 : _state$product31.name,
2404
- childUpc: (_state$product32 = state.product) === null || _state$product32 === void 0 ? void 0 : _state$product32.upc,
2437
+ childArticleId: (_state$product33 = state.product) === null || _state$product33 === void 0 ? void 0 : _state$product33.id_article,
2438
+ childName: (_state$product34 = state.product) === null || _state$product34 === void 0 ? void 0 : _state$product34.name,
2439
+ childUpc: (_state$product35 = state.product) === null || _state$product35 === void 0 ? void 0 : _state$product35.upc,
2405
2440
  parentName: family.parent.name,
2406
2441
  parentUpc: family.parent.upc
2407
2442
  });
@@ -2433,15 +2468,15 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
2433
2468
  className: "desvincular",
2434
2469
  title: "Desvincular este hijo",
2435
2470
  onClick: function onClick() {
2436
- var _state$product33, _state$product34;
2471
+ var _state$product36, _state$product37;
2437
2472
 
2438
2473
  return setPorDesvincular({
2439
2474
  mode: "child",
2440
2475
  childArticleId: variant.articleId,
2441
2476
  childName: variant.name,
2442
2477
  childUpc: variant.upc,
2443
- parentName: (_state$product33 = state.product) === null || _state$product33 === void 0 ? void 0 : _state$product33.name,
2444
- parentUpc: (_state$product34 = state.product) === null || _state$product34 === void 0 ? void 0 : _state$product34.upc
2478
+ parentName: (_state$product36 = state.product) === null || _state$product36 === void 0 ? void 0 : _state$product36.name,
2479
+ parentUpc: (_state$product37 = state.product) === null || _state$product37 === void 0 ? void 0 : _state$product37.upc
2445
2480
  });
2446
2481
  },
2447
2482
  children: "Desvincular"
@@ -2457,7 +2492,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
2457
2492
  onClick: openMultipleEdition,
2458
2493
  children: preparandoEdicionMultiple ? "Abriendo…" : "Editar los ".concat(family.variants.length, " hijos juntos")
2459
2494
  })]
2460
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
2495
+ }), puedeAgruparse && /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
2461
2496
  className: "variants-actions",
2462
2497
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
2463
2498
  type: "button",
@@ -2480,7 +2515,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
2480
2515
  children: showGroup ? " ▴" : " ▾"
2481
2516
  })]
2482
2517
  })]
2483
- }), showGroup && (variantGroup === null || variantGroup === void 0 ? void 0 : variantGroup.group) && /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
2518
+ }), puedeAgruparse && showGroup && (variantGroup === null || variantGroup === void 0 ? void 0 : variantGroup.group) && /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
2484
2519
  className: "variants-family",
2485
2520
  children: [((_variantGroup$members3 = variantGroup.members) !== null && _variantGroup$members3 !== void 0 ? _variantGroup$members3 : []).filter(function (miembro) {
2486
2521
  return !miembro.isCurrent;
@@ -2568,7 +2603,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
2568
2603
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
2569
2604
  className: "services-information-container " + (imageLayout && state.active_tab === "Imágenes" ? "image-services" : ""),
2570
2605
  children: state.saving ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Loading.Loading, {}) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
2571
- children: [state.active_tab === "Descripción" && (((_state$product35 = state.product) === null || _state$product35 === void 0 ? void 0 : _state$product35.description_status) !== "NS" ? (_state$descriptions_i = state.descriptions_inputs) !== null && _state$descriptions_i !== void 0 && _state$descriptions_i[0] ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_InputGroup.InputGroup, {
2606
+ children: [state.active_tab === "Descripción" && (((_state$product38 = state.product) === null || _state$product38 === void 0 ? void 0 : _state$product38.description_status) !== "NS" ? (_state$descriptions_i = state.descriptions_inputs) !== null && _state$descriptions_i !== void 0 && _state$descriptions_i[0] ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_InputGroup.InputGroup, {
2572
2607
  activeSection: state.active_tab,
2573
2608
  inputGroup: state.descriptions_inputs[0],
2574
2609
  updatedDescriptions: state.updated_descriptions_inputs
@@ -2579,7 +2614,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
2579
2614
  ,
2580
2615
  variant: (_state$services2 = state.services) === null || _state$services2 === void 0 ? void 0 : (_state$services2$data = _state$services2.datasheets) === null || _state$services2$data === void 0 ? void 0 : _state$services2$data.variant,
2581
2616
  onRestoreInheritance: handleOnRestoreInheritance,
2582
- articleId: (_state$product36 = state.product) === null || _state$product36 === void 0 ? void 0 : _state$product36.id_article,
2617
+ articleId: (_state$product39 = state.product) === null || _state$product39 === void 0 ? void 0 : _state$product39.id_article,
2583
2618
  version: state.product.version,
2584
2619
  isShowbox: false,
2585
2620
  dinamicHeight: true,
@@ -2591,7 +2626,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
2591
2626
  }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_ScreenHeader.ScreenHeader, {
2592
2627
  text: "No cuentas con este servicio",
2593
2628
  headerType: "input-name-header"
2594
- })), state.active_tab === "Ficha técnica" && (((_state$product37 = state.product) === null || _state$product37 === void 0 ? void 0 : _state$product37.datasheet_status) !== "NS" ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
2629
+ })), state.active_tab === "Ficha técnica" && (((_state$product40 = state.product) === null || _state$product40 === void 0 ? void 0 : _state$product40.datasheet_status) !== "NS" ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
2595
2630
  children: ((_state$datasheets_inp = state.datasheets_inputs) === null || _state$datasheets_inp === void 0 ? void 0 : (_state$datasheets_inp2 = _state$datasheets_inp[0]) === null || _state$datasheets_inp2 === void 0 ? void 0 : (_state$datasheets_inp3 = _state$datasheets_inp2.data) === null || _state$datasheets_inp3 === void 0 ? void 0 : _state$datasheets_inp3.length) > 0 ? state.datasheets_inputs[0].data.map(function (dataGroup, index) {
2596
2631
  var _state$datasheets_inp4, _state$services3, _state$services3$data, _state$services$datas3;
2597
2632
 
@@ -2621,7 +2656,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
2621
2656
  }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_ScreenHeader.ScreenHeader, {
2622
2657
  text: "No cuentas con este servicio",
2623
2658
  headerType: "input-name-header"
2624
- })), state.active_tab === "Imágenes" && (((_state$product38 = state.product) === null || _state$product38 === void 0 ? void 0 : _state$product38.images_status) !== "NS" ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
2659
+ })), state.active_tab === "Imágenes" && (((_state$product41 = state.product) === null || _state$product41 === void 0 ? void 0 : _state$product41.images_status) !== "NS" ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
2625
2660
  children: [!imageLayout && /*#__PURE__*/(0, _jsxRuntime.jsx)(_GalleryHeader.GalleryHeader, {
2626
2661
  checkAll: state.all_image_checked // Determina si el checkbox "Seleccionar todo" está marcado
2627
2662
  ,
@@ -81,6 +81,8 @@ var _VariantGroupModal = require("../../organisms/VariantGroupModal");
81
81
 
82
82
  var _PropagateChangesModal = require("../../organisms/PropagateChangesModal");
83
83
 
84
+ var _nonPropagable = require("../../organisms/PropagateChangesModal/non-propagable");
85
+
84
86
  var _api = require("../../organisms/LinkVariantsModal/api");
85
87
 
86
88
  var _genericModalCheck = _interopRequireDefault(require("../../../assets/images/genericModal/genericModalCheck.svg"));
@@ -1314,6 +1316,18 @@ var RetailerProductEditionView = function RetailerProductEditionView(_ref) {
1314
1316
  return !v.isCurrent;
1315
1317
  }).length;
1316
1318
  var esHijoDeOtro = family !== null && family !== void 0 && family.error ? !!((_state$product11 = state.product) !== null && _state$product11 !== void 0 && _state$product11.parentArticleId) : !!(family !== null && family !== void 0 && family.parent);
1319
+ /*
1320
+ Un hijo no se agrupa como variante (decisión de producto, 2026-09-25).
1321
+ Agrupar declara «estos son el mismo producto en otra presentación», y un
1322
+ hijo ya declaró de dónde deriva. El servidor lo rechaza con
1323
+ VARIANT_GROUP_NOT_FOR_CHILD, así que ofrecer el botón sería ofrecer algo
1324
+ que siempre falla.
1325
+ Se apoya en `esHijoDeOtro` y no en `state.product` porque en esta pantalla
1326
+ el producto sale de sessionStorage: la señal buena es la familia recién
1327
+ consultada, con el producto solo como respaldo si esa consulta falló.
1328
+ */
1329
+
1330
+ var puedeAgruparse = !esHijoDeOtro;
1317
1331
  /*
1318
1332
  Abre otro producto de la familia.
1319
1333
  Cambiar la URL no basta: esta pantalla no lee el producto de la ruta sino de
@@ -1797,7 +1811,7 @@ var RetailerProductEditionView = function RetailerProductEditionView(_ref) {
1797
1811
 
1798
1812
  var retailerId = (_state$active_retaile4 = state.active_retailer) === null || _state$active_retaile4 === void 0 ? void 0 : _state$active_retaile4.id_retailer;
1799
1813
  var inputs = (_state$services$datas = (_state$services = state.services) === null || _state$services === void 0 ? void 0 : (_state$services$datas2 = _state$services.datasheets) === null || _state$services$datas2 === void 0 ? void 0 : _state$services$datas2.inputs) !== null && _state$services$datas !== void 0 ? _state$services$datas : {};
1800
- return ((_state$updated_datash = state.updated_datasheets_inputs) !== null && _state$updated_datash !== void 0 ? _state$updated_datash : []).map(function (item) {
1814
+ var cambios = ((_state$updated_datash = state.updated_datasheets_inputs) !== null && _state$updated_datash !== void 0 ? _state$updated_datash : []).map(function (item) {
1801
1815
  var _input$name;
1802
1816
 
1803
1817
  var input = inputs["".concat(item.attributeId, "_").concat(retailerId)];
@@ -1807,11 +1821,19 @@ var RetailerProductEditionView = function RetailerProductEditionView(_ref) {
1807
1821
  value: item.value
1808
1822
  };
1809
1823
  });
1824
+ /*
1825
+ UPC y SKU se quitan aquí y no dentro del diálogo porque esta lista también
1826
+ decide SI el diálogo se abre. Editar solo el UPC no tiene nada que
1827
+ propagar, así que preguntarlo sería pedirle al usuario una decisión sobre
1828
+ un conjunto vacío.
1829
+ */
1830
+
1831
+ return (0, _nonPropagable.soloPropagables)(cambios);
1810
1832
  };
1811
1833
 
1812
1834
  var handleOnClickSave = /*#__PURE__*/function () {
1813
1835
  var _ref16 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11() {
1814
- var _familia$variants, _variantGroup$members, cambios, familia, hijos, companeras;
1836
+ var _familia, _familia$variants, _variantGroup$members, cambios, familia, esHijo, hijos, companeras;
1815
1837
 
1816
1838
  return _regenerator.default.wrap(function _callee11$(_context11) {
1817
1839
  while (1) {
@@ -1826,7 +1848,7 @@ var RetailerProductEditionView = function RetailerProductEditionView(_ref) {
1826
1848
 
1827
1849
  case 2:
1828
1850
  _context11.t0 = state.active_tab;
1829
- _context11.next = _context11.t0 === "Descripción" ? 5 : _context11.t0 === "Ficha técnica" ? 8 : _context11.t0 === "Imágenes" ? 33 : 36;
1851
+ _context11.next = _context11.t0 === "Descripción" ? 5 : _context11.t0 === "Ficha técnica" ? 8 : _context11.t0 === "Imágenes" ? 34 : 37;
1830
1852
  break;
1831
1853
 
1832
1854
  case 5:
@@ -1834,7 +1856,7 @@ var RetailerProductEditionView = function RetailerProductEditionView(_ref) {
1834
1856
  return saveDescriptions(token);
1835
1857
 
1836
1858
  case 7:
1837
- return _context11.abrupt("break", 37);
1859
+ return _context11.abrupt("break", 38);
1838
1860
 
1839
1861
  case 8:
1840
1862
  cambios = cambiosDeFichaTecnica();
@@ -1848,7 +1870,7 @@ var RetailerProductEditionView = function RetailerProductEditionView(_ref) {
1848
1870
  return saveDatasheets(token);
1849
1871
 
1850
1872
  case 12:
1851
- return _context11.abrupt("break", 37);
1873
+ return _context11.abrupt("break", 38);
1852
1874
 
1853
1875
  case 13:
1854
1876
  /*
@@ -1921,7 +1943,17 @@ var RetailerProductEditionView = function RetailerProductEditionView(_ref) {
1921
1943
  return _context11.abrupt("return");
1922
1944
 
1923
1945
  case 25:
1924
- hijos = ((_familia$variants = familia.variants) !== null && _familia$variants !== void 0 ? _familia$variants : []).filter(function (v) {
1946
+ /*
1947
+ Un HIJO no propaga a nadie, y hay que decirlo explícitamente.
1948
+ `familia.variants` mira la familia desde el PADRE —eso es lo correcto
1949
+ para navegar entre hermanos— así que desde la ficha de un hijo esa
1950
+ lista son sus HERMANOS. Leerla como «los destinos de este producto»
1951
+ hacía que el diálogo le ofreciera heredar a sus hermanos. El servidor
1952
+ resolvía los destinos por su cuenta y no escribía nada, de modo que el
1953
+ usuario elegía, guardaba, y no pasaba nada: un no-operativo silencioso.
1954
+ */
1955
+ esHijo = !!((_familia = familia) !== null && _familia !== void 0 && _familia.parent);
1956
+ hijos = esHijo ? [] : ((_familia$variants = familia.variants) !== null && _familia$variants !== void 0 ? _familia$variants : []).filter(function (v) {
1925
1957
  return !v.isCurrent;
1926
1958
  });
1927
1959
  /*
@@ -1932,10 +1964,11 @@ var RetailerProductEditionView = function RetailerProductEditionView(_ref) {
1932
1964
 
1933
1965
  companeras = ((_variantGroup$members = variantGroup === null || variantGroup === void 0 ? void 0 : variantGroup.members) !== null && _variantGroup$members !== void 0 ? _variantGroup$members : []).filter(function (m) {
1934
1966
  return !m.isCurrent;
1935
- });
1967
+ }); // Un hijo tampoco puede estar agrupado desde 2026-09-25, así que para
1968
+ // él no queda ningún destino posible.
1936
1969
 
1937
- if (!(hijos.length > 0 || companeras.length > 0)) {
1938
- _context11.next = 30;
1970
+ if (!(!esHijo && (hijos.length > 0 || companeras.length > 0))) {
1971
+ _context11.next = 31;
1939
1972
  break;
1940
1973
  }
1941
1974
 
@@ -1944,28 +1977,28 @@ var RetailerProductEditionView = function RetailerProductEditionView(_ref) {
1944
1977
  });
1945
1978
  return _context11.abrupt("return");
1946
1979
 
1947
- case 30:
1948
- _context11.next = 32;
1980
+ case 31:
1981
+ _context11.next = 33;
1949
1982
  return saveDatasheets(token);
1950
1983
 
1951
- case 32:
1952
- return _context11.abrupt("break", 37);
1953
-
1954
1984
  case 33:
1955
- _context11.next = 35;
1956
- return updateImages(token);
1985
+ return _context11.abrupt("break", 38);
1957
1986
 
1958
- case 35:
1959
- return _context11.abrupt("break", 37);
1987
+ case 34:
1988
+ _context11.next = 36;
1989
+ return updateImages(token);
1960
1990
 
1961
1991
  case 36:
1962
- return _context11.abrupt("break", 37);
1992
+ return _context11.abrupt("break", 38);
1963
1993
 
1964
1994
  case 37:
1965
- _context11.next = 39;
1995
+ return _context11.abrupt("break", 38);
1996
+
1997
+ case 38:
1998
+ _context11.next = 40;
1966
1999
  return loadData(false);
1967
2000
 
1968
- case 39:
2001
+ case 40:
1969
2002
  case "end":
1970
2003
  return _context11.stop();
1971
2004
  }
@@ -2894,7 +2927,7 @@ var RetailerProductEditionView = function RetailerProductEditionView(_ref) {
2894
2927
  headerTop: headerTop,
2895
2928
  children: [pendingPropagation && /*#__PURE__*/(0, _jsxRuntime.jsx)(_PropagateChangesModal.PropagateChangesModal, {
2896
2929
  changedAttributes: pendingPropagation.cambios,
2897
- variants: ((_family$variants2 = family === null || family === void 0 ? void 0 : family.variants) !== null && _family$variants2 !== void 0 ? _family$variants2 : []).filter(function (v) {
2930
+ variants: esHijoDeOtro ? [] : ((_family$variants2 = family === null || family === void 0 ? void 0 : family.variants) !== null && _family$variants2 !== void 0 ? _family$variants2 : []).filter(function (v) {
2898
2931
  return !v.isCurrent;
2899
2932
  }),
2900
2933
  groupMembers: ((_variantGroup$members2 = variantGroup === null || variantGroup === void 0 ? void 0 : variantGroup.members) !== null && _variantGroup$members2 !== void 0 ? _variantGroup$members2 : []).filter(function (m) {
@@ -3239,7 +3272,7 @@ var RetailerProductEditionView = function RetailerProductEditionView(_ref) {
3239
3272
  className: "loading",
3240
3273
  children: avisoFamilia
3241
3274
  })]
3242
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
3275
+ }), puedeAgruparse && /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
3243
3276
  className: "variants-actions",
3244
3277
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
3245
3278
  type: "button",
@@ -3262,7 +3295,7 @@ var RetailerProductEditionView = function RetailerProductEditionView(_ref) {
3262
3295
  children: showGroup ? " ▴" : " ▾"
3263
3296
  })]
3264
3297
  })]
3265
- }), showGroup && (variantGroup === null || variantGroup === void 0 ? void 0 : variantGroup.group) && /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
3298
+ }), puedeAgruparse && showGroup && (variantGroup === null || variantGroup === void 0 ? void 0 : variantGroup.group) && /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
3266
3299
  className: "variants-family",
3267
3300
  children: [((_variantGroup$members3 = variantGroup.members) !== null && _variantGroup$members3 !== void 0 ? _variantGroup$members3 : []).filter(function (miembro) {
3268
3301
  return !miembro.isCurrent;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "contentoh-components-library",
3
- "version": "21.6.49",
3
+ "version": "21.6.51",
4
4
  "dependencies": {
5
5
  "@aws-amplify/auth": "^4.5.3",
6
6
  "@aws-amplify/datastore": "^3.11.0",
@@ -10,6 +10,7 @@ import {
10
10
  Note,
11
11
  Footer,
12
12
  } from "./styles";
13
+ import { soloPropagables } from "./non-propagable";
13
14
 
14
15
  /*
15
16
  Diálogo de propagación al guardar un producto padre.
@@ -38,7 +39,7 @@ import {
38
39
  const UMBRAL_SEGUNDO_PLANO = 20;
39
40
 
40
41
  export const PropagateChangesModal = ({
41
- changedAttributes = [],
42
+ changedAttributes: cambiosRecibidos = [],
42
43
  variants = [],
43
44
  groupMembers = [],
44
45
  groupCode = null,
@@ -46,6 +47,15 @@ export const PropagateChangesModal = ({
46
47
  onConfirm,
47
48
  saving = false,
48
49
  }) => {
50
+ /*
51
+ Segundo filtro, a propósito redundante: quien llama ya debería quitarlos —de
52
+ eso depende que el diálogo no se abra por un cambio que no propaga nada—,
53
+ pero ofrecer el UPC y descartarlo en el servidor es exactamente el camino
54
+ por el que un usuario concluye que la propagación no sirve. Vale más
55
+ repetirlo aquí que confiar en que ningún llamador futuro lo olvide.
56
+ */
57
+ const changedAttributes = soloPropagables(cambiosRecibidos);
58
+
49
59
  const [chosenAttributes, setChosenAttributes] = useState([]);
50
60
 
51
61
  /*
@@ -0,0 +1,29 @@
1
+ /*
2
+ Atributos que la propagación nunca copia.
3
+
4
+ UPC y SKU son la IDENTIDAD del producto, y una variante existe precisamente
5
+ porque la suya es distinta: el acuerdo lo dice literal —"cambian UPC/color/
6
+ talla"—. Bajarlos del padre dejaría dos productos con el mismo código de
7
+ barras, que es lo contrario de una variante.
8
+
9
+ El servidor ya los descarta y esa es la defensa de verdad: la exclusión vive
10
+ allá, no aquí, y aunque esta pantalla los mandara no se copiarían. Lo de este
11
+ archivo es otra cosa —que el diálogo no los OFREZCA—, porque ofrecer una
12
+ opción que se descarta en silencio es peor que no ofrecerla: el usuario elige
13
+ el UPC, guarda, no ve error, y concluye que la propagación está rota.
14
+
15
+ Los ids son los mismos que `variants/utils/constants.js` en el backend. Están
16
+ duplicados porque no hay un contrato compartido entre repos; si allá cambian,
17
+ aquí hay que cambiarlos.
18
+ */
19
+ export const UPC_ATTRIBUTE_ID = 683;
20
+ export const SKU_ATTRIBUTE_ID = 40001;
21
+
22
+ export const NON_PROPAGABLE_ATTRIBUTES = [UPC_ATTRIBUTE_ID, SKU_ATTRIBUTE_ID];
23
+
24
+ /**
25
+ * Quita de una lista de cambios los que no se pueden propagar.
26
+ * @param {Array<{id: number}>} cambios
27
+ */
28
+ export const soloPropagables = (cambios = []) =>
29
+ cambios.filter((c) => !NON_PROPAGABLE_ATTRIBUTES.includes(Number(c?.id)));
@@ -42,6 +42,7 @@ import { LinkVariantsModal } from "../../organisms/LinkVariantsModal";
42
42
  import { UnlinkVariantModal } from "../../organisms/UnlinkVariantModal";
43
43
  import { VariantGroupModal } from "../../organisms/VariantGroupModal";
44
44
  import { PropagateChangesModal } from "../../organisms/PropagateChangesModal";
45
+ import { soloPropagables } from "../../organisms/PropagateChangesModal/non-propagable";
45
46
  import { readPayload } from "../../organisms/LinkVariantsModal/api";
46
47
  import { ProductImageModal } from "../../organisms/ProductImageModal";
47
48
  import { VersionSelector } from "../../organisms/VersionSelector";
@@ -95,6 +96,17 @@ const ProviderProductEditionView = ({
95
96
  const [variantGroup, setVariantGroup] = useState(null);
96
97
  const [showGroup, setShowGroup] = useState(false);
97
98
  const [showGroupModal, setShowGroupModal] = useState(false);
99
+
100
+ /*
101
+ Un hijo no se agrupa como variante (decisión de producto, 2026-09-25).
102
+
103
+ Agrupar declara «estos son el mismo producto en otra presentación», y un
104
+ hijo ya declaró de dónde deriva; tener las dos cosas lo dejaba con dos
105
+ respuestas distintas a la misma pregunta. El servidor lo rechaza con
106
+ VARIANT_GROUP_NOT_FOR_CHILD, así que ofrecer el botón aquí sería ofrecer
107
+ algo que siempre falla.
108
+ */
109
+ const puedeAgruparse = !state.product?.parentArticleId;
98
110
  const [pendingPropagation, setPendingPropagation] = useState(null);
99
111
  const [preparandoPropagacion, setPreparandoPropagacion] = useState(false);
100
112
  const [preparandoEdicionMultiple, setPreparandoEdicionMultiple] =
@@ -712,7 +724,7 @@ const ProviderProductEditionView = ({
712
724
  const retailerId = state.active_retailer?.id_retailer;
713
725
  const inputs = state.services?.datasheets?.inputs ?? {};
714
726
 
715
- return (state.updated_datasheets_inputs ?? []).map((item) => {
727
+ const cambios = (state.updated_datasheets_inputs ?? []).map((item) => {
716
728
  const input = inputs[`${item.attributeId}_${retailerId}`];
717
729
  return {
718
730
  id: Number(item.attributeId),
@@ -720,6 +732,14 @@ const ProviderProductEditionView = ({
720
732
  value: item.value,
721
733
  };
722
734
  });
735
+
736
+ /*
737
+ UPC y SKU se quitan aquí y no dentro del diálogo porque esta lista también
738
+ decide SI el diálogo se abre. Editar solo el UPC no tiene nada que
739
+ propagar, así que preguntarlo sería pedirle al usuario una decisión sobre
740
+ un conjunto vacío.
741
+ */
742
+ return soloPropagables(cambios);
723
743
  };
724
744
 
725
745
  const handleOnClickSave = () => {
@@ -742,8 +762,24 @@ const ProviderProductEditionView = ({
742
762
  const companeras = (variantGroup?.members ?? []).filter(
743
763
  (m) => !m.isCurrent
744
764
  );
765
+ /*
766
+ Un HIJO no propaga a nadie, y hay que decirlo explícitamente.
767
+
768
+ Sin este corte el diálogo se abría desde la ficha de un hijo y le
769
+ ofrecía a sus HERMANOS como si fueran sus hijos: `family.variants`
770
+ mira la familia desde el padre —eso es lo correcto para navegar entre
771
+ hermanos— pero aquí se estaba leyendo como «los destinos de este
772
+ producto». El servidor resolvía los destinos por su cuenta y no
773
+ escribía nada, así que el usuario elegía hermanos, guardaba, y no
774
+ pasaba nada: un no-operativo silencioso.
775
+
776
+ Un hijo tampoco puede estar agrupado desde 2026-09-25, así que para
777
+ él no queda ningún destino posible.
778
+ */
779
+ const esHijo = !!state.product?.parentArticleId;
745
780
  const hayDestinos =
746
- state.product?.variantsCount > 0 || companeras.length > 0;
781
+ !esHijo &&
782
+ (state.product?.variantsCount > 0 || companeras.length > 0);
747
783
  const cambios = cambiosDeFichaTecnica();
748
784
 
749
785
  if (hayDestinos && cambios.length > 0) {
@@ -1650,7 +1686,11 @@ const ProviderProductEditionView = ({
1650
1686
  {pendingPropagation && (
1651
1687
  <PropagateChangesModal
1652
1688
  changedAttributes={pendingPropagation.cambios}
1653
- variants={(family?.variants ?? []).filter((v) => !v.isCurrent)}
1689
+ variants={
1690
+ state.product?.parentArticleId
1691
+ ? []
1692
+ : (family?.variants ?? []).filter((v) => !v.isCurrent)
1693
+ }
1654
1694
  groupMembers={(variantGroup?.members ?? []).filter(
1655
1695
  (m) => !m.isCurrent
1656
1696
  )}
@@ -2058,6 +2098,7 @@ const ProviderProductEditionView = ({
2058
2098
  código compartido que dice "estos son el mismo producto en
2059
2099
  otra presentación". Mezclarlos en una sola caja haría creer
2060
2100
  que agrupar hereda algo, que es justo lo que no pasa. */}
2101
+ {puedeAgruparse && (
2061
2102
  <div className="variants-actions">
2062
2103
  <button
2063
2104
  type="button"
@@ -2079,8 +2120,9 @@ const ProviderProductEditionView = ({
2079
2120
  </button>
2080
2121
  )}
2081
2122
  </div>
2123
+ )}
2082
2124
 
2083
- {showGroup && variantGroup?.group && (
2125
+ {puedeAgruparse && showGroup && variantGroup?.group && (
2084
2126
  <div className="variants-family">
2085
2127
  {/* Los hermanos de grupo NO se listan como padre/hijo: aquí
2086
2128
  nadie hereda de nadie, así que no hay rol que mostrar,
@@ -54,6 +54,7 @@ import { LinkVariantsModal } from "../../organisms/LinkVariantsModal";
54
54
  import { UnlinkVariantModal } from "../../organisms/UnlinkVariantModal";
55
55
  import { VariantGroupModal } from "../../organisms/VariantGroupModal";
56
56
  import { PropagateChangesModal } from "../../organisms/PropagateChangesModal";
57
+ import { soloPropagables } from "../../organisms/PropagateChangesModal/non-propagable";
57
58
  import { readPayload } from "../../organisms/LinkVariantsModal/api";
58
59
 
59
60
  import successIcon from "../../../assets/images/genericModal/genericModalCheck.svg";
@@ -197,6 +198,7 @@ const RetailerProductEditionView = ({
197
198
  const [variantGroup, setVariantGroup] = useState(null);
198
199
  const [showGroup, setShowGroup] = useState(false);
199
200
  const [showGroupModal, setShowGroupModal] = useState(false);
201
+
200
202
  // Qué vínculo se está por romper, o null si no hay diálogo abierto. Guarda al
201
203
  // HIJO, que es quien lleva la relación y lo que pide la acción `unlink`.
202
204
  const [porDesvincular, setPorDesvincular] = useState(null);
@@ -901,6 +903,20 @@ const RetailerProductEditionView = ({
901
903
  ? !!state.product?.parentArticleId
902
904
  : !!family?.parent;
903
905
 
906
+ /*
907
+ Un hijo no se agrupa como variante (decisión de producto, 2026-09-25).
908
+
909
+ Agrupar declara «estos son el mismo producto en otra presentación», y un
910
+ hijo ya declaró de dónde deriva. El servidor lo rechaza con
911
+ VARIANT_GROUP_NOT_FOR_CHILD, así que ofrecer el botón sería ofrecer algo
912
+ que siempre falla.
913
+
914
+ Se apoya en `esHijoDeOtro` y no en `state.product` porque en esta pantalla
915
+ el producto sale de sessionStorage: la señal buena es la familia recién
916
+ consultada, con el producto solo como respaldo si esa consulta falló.
917
+ */
918
+ const puedeAgruparse = !esHijoDeOtro;
919
+
904
920
  /*
905
921
  Abre otro producto de la familia.
906
922
 
@@ -1236,7 +1252,7 @@ const RetailerProductEditionView = ({
1236
1252
  const retailerId = state.active_retailer?.id_retailer;
1237
1253
  const inputs = state.services?.datasheets?.inputs ?? {};
1238
1254
 
1239
- return (state.updated_datasheets_inputs ?? []).map((item) => {
1255
+ const cambios = (state.updated_datasheets_inputs ?? []).map((item) => {
1240
1256
  const input = inputs[`${item.attributeId}_${retailerId}`];
1241
1257
  return {
1242
1258
  id: Number(item.attributeId),
@@ -1244,6 +1260,14 @@ const RetailerProductEditionView = ({
1244
1260
  value: item.value,
1245
1261
  };
1246
1262
  });
1263
+
1264
+ /*
1265
+ UPC y SKU se quitan aquí y no dentro del diálogo porque esta lista también
1266
+ decide SI el diálogo se abre. Editar solo el UPC no tiene nada que
1267
+ propagar, así que preguntarlo sería pedirle al usuario una decisión sobre
1268
+ un conjunto vacío.
1269
+ */
1270
+ return soloPropagables(cambios);
1247
1271
  };
1248
1272
 
1249
1273
  const handleOnClickSave = async () => {
@@ -1317,7 +1341,20 @@ const RetailerProductEditionView = ({
1317
1341
  return;
1318
1342
  }
1319
1343
 
1320
- const hijos = (familia.variants ?? []).filter((v) => !v.isCurrent);
1344
+ /*
1345
+ Un HIJO no propaga a nadie, y hay que decirlo explícitamente.
1346
+
1347
+ `familia.variants` mira la familia desde el PADRE —eso es lo correcto
1348
+ para navegar entre hermanos— así que desde la ficha de un hijo esa
1349
+ lista son sus HERMANOS. Leerla como «los destinos de este producto»
1350
+ hacía que el diálogo le ofreciera heredar a sus hermanos. El servidor
1351
+ resolvía los destinos por su cuenta y no escribía nada, de modo que el
1352
+ usuario elegía, guardaba, y no pasaba nada: un no-operativo silencioso.
1353
+ */
1354
+ const esHijo = !!familia?.parent;
1355
+ const hijos = esHijo
1356
+ ? []
1357
+ : (familia.variants ?? []).filter((v) => !v.isCurrent);
1321
1358
 
1322
1359
  /*
1323
1360
  También cuentan las compañeras de grupo: un producto puede no tener
@@ -1328,7 +1365,9 @@ const RetailerProductEditionView = ({
1328
1365
  (m) => !m.isCurrent
1329
1366
  );
1330
1367
 
1331
- if (hijos.length > 0 || companeras.length > 0) {
1368
+ // Un hijo tampoco puede estar agrupado desde 2026-09-25, así que para
1369
+ // él no queda ningún destino posible.
1370
+ if (!esHijo && (hijos.length > 0 || companeras.length > 0)) {
1332
1371
  setPendingPropagation({ cambios });
1333
1372
  return;
1334
1373
  }
@@ -2092,7 +2131,11 @@ const RetailerProductEditionView = ({
2092
2131
  {pendingPropagation && (
2093
2132
  <PropagateChangesModal
2094
2133
  changedAttributes={pendingPropagation.cambios}
2095
- variants={(family?.variants ?? []).filter((v) => !v.isCurrent)}
2134
+ variants={
2135
+ esHijoDeOtro
2136
+ ? []
2137
+ : (family?.variants ?? []).filter((v) => !v.isCurrent)
2138
+ }
2096
2139
  groupMembers={(variantGroup?.members ?? []).filter(
2097
2140
  (m) => !m.isCurrent
2098
2141
  )}
@@ -2499,6 +2542,7 @@ const RetailerProductEditionView = ({
2499
2542
  herencia y tiene jerarquía; esto es solo un código compartido
2500
2543
  que dice "estos son el mismo producto en otra presentación".
2501
2544
  Juntarlos haría creer que agrupar hereda algo, que no pasa. */}
2545
+ {puedeAgruparse && (
2502
2546
  <div className="variants-actions">
2503
2547
  <button
2504
2548
  type="button"
@@ -2520,8 +2564,9 @@ const RetailerProductEditionView = ({
2520
2564
  </button>
2521
2565
  )}
2522
2566
  </div>
2567
+ )}
2523
2568
 
2524
- {showGroup && variantGroup?.group && (
2569
+ {puedeAgruparse && showGroup && variantGroup?.group && (
2525
2570
  <div className="variants-family">
2526
2571
  {(variantGroup.members ?? [])
2527
2572
  .filter((miembro) => !miembro.isCurrent)