ng-easycommerce 0.0.681 → 0.0.683

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +18 -0
  2. package/assets/ec-i18n/ct.json +3 -0
  3. package/assets/ec-i18n/en.json +7 -4
  4. package/assets/ec-i18n/es.json +3 -0
  5. package/assets/ec-i18n/fr.json +7 -4
  6. package/assets/ec-i18n/gl.json +3 -0
  7. package/assets/ec-i18n/pr.json +3 -0
  8. package/bundles/ng-easycommerce.umd.js +901 -83
  9. package/bundles/ng-easycommerce.umd.js.map +1 -1
  10. package/bundles/ng-easycommerce.umd.min.js +1 -1
  11. package/bundles/ng-easycommerce.umd.min.js.map +1 -1
  12. package/esm2015/lib/ec-component/auth-ec/auth-ec.component.js +7 -4
  13. package/esm2015/lib/ec-component/auth-ec/register-form-ec/register-form-ec.component.js +20 -21
  14. package/esm2015/lib/ec-component/auth-ec/register-wholesaler-form-ec/register-wholesaler-form-ec.component.js +7 -4
  15. package/esm2015/lib/ec-component/cart-ec/cart-ec.component.js +230 -2
  16. package/esm2015/lib/ec-component/checkout-ec/dataform-ec/dataform-ec.component.js +6 -3
  17. package/esm2015/lib/ec-component/checkout-ec/detail-checkout-block-ec/detail-checkout-block-ec.component.js +13 -4
  18. package/esm2015/lib/ec-component/index.js +4 -1
  19. package/esm2015/lib/ec-component/sidebar-ec/sidebar-ec.component.js +61 -1
  20. package/esm2015/lib/ec-component/widgets-ec/unit-promotion-price-ec/unit-promotion-price-ec.component.js +268 -0
  21. package/esm2015/lib/interfaces/cart-item.js +1 -1
  22. package/esm2015/lib/services/cart.service.js +186 -14
  23. package/esm2015/lib/services/checkout/checkout.service.js +2 -2
  24. package/esm2015/lib/utils/order-util.service.js +87 -1
  25. package/esm2015/public-api.js +2 -1
  26. package/esm5/lib/ec-component/auth-ec/auth-ec.component.js +7 -4
  27. package/esm5/lib/ec-component/auth-ec/register-form-ec/register-form-ec.component.js +20 -21
  28. package/esm5/lib/ec-component/auth-ec/register-wholesaler-form-ec/register-wholesaler-form-ec.component.js +7 -4
  29. package/esm5/lib/ec-component/cart-ec/cart-ec.component.js +236 -2
  30. package/esm5/lib/ec-component/checkout-ec/dataform-ec/dataform-ec.component.js +6 -3
  31. package/esm5/lib/ec-component/checkout-ec/detail-checkout-block-ec/detail-checkout-block-ec.component.js +13 -4
  32. package/esm5/lib/ec-component/index.js +4 -1
  33. package/esm5/lib/ec-component/sidebar-ec/sidebar-ec.component.js +61 -1
  34. package/esm5/lib/ec-component/widgets-ec/unit-promotion-price-ec/unit-promotion-price-ec.component.js +248 -0
  35. package/esm5/lib/interfaces/cart-item.js +1 -1
  36. package/esm5/lib/services/cart.service.js +188 -14
  37. package/esm5/lib/services/checkout/checkout.service.js +2 -2
  38. package/esm5/lib/utils/order-util.service.js +88 -1
  39. package/esm5/public-api.js +2 -1
  40. package/fesm2015/ng-easycommerce.js +913 -85
  41. package/fesm2015/ng-easycommerce.js.map +1 -1
  42. package/fesm5/ng-easycommerce.js +902 -85
  43. package/fesm5/ng-easycommerce.js.map +1 -1
  44. package/lib/ec-component/auth-ec/register-form-ec/register-form-ec.component.d.ts +1 -0
  45. package/lib/ec-component/cart-ec/cart-ec.component.d.ts +139 -0
  46. package/lib/ec-component/checkout-ec/dataform-ec/dataform-ec.component.d.ts +3 -1
  47. package/lib/ec-component/index.d.ts +1 -0
  48. package/lib/ec-component/sidebar-ec/sidebar-ec.component.d.ts +52 -0
  49. package/lib/ec-component/widgets-ec/unit-promotion-price-ec/unit-promotion-price-ec.component.d.ts +117 -0
  50. package/lib/interfaces/cart-item.d.ts +54 -0
  51. package/lib/services/cart.service.d.ts +98 -1
  52. package/lib/utils/order-util.service.d.ts +58 -0
  53. package/ng-easycommerce.metadata.json +1 -1
  54. package/package.json +1 -1
  55. package/public-api.d.ts +1 -0
@@ -2329,11 +2329,98 @@
2329
2329
  !forCart && new_state.push(total);
2330
2330
  return new_state;
2331
2331
  };
2332
+ /**
2333
+ * Construye el resumen de promociones que debe mostrarse en checkout y resúmenes de compra.
2334
+ *
2335
+ * @param cart Carrito u orden con estructura `totals` compatible.
2336
+ * @param forCart Cuando es `true`, omite subtotal y total para devolver solo las líneas intermedias.
2337
+ * @returns Lista de líneas normalizadas para renderizar el resumen.
2338
+ *
2339
+ * @remarks
2340
+ * A diferencia de `getPromotions`, este método solo considera descuentos de orden.
2341
+ */
2342
+ this.getSummaryPromotions = function (cart, forCart) {
2343
+ if (forCart === void 0) { forCart = false; }
2344
+ if (cart.checkoutState && cart.checkoutState == "completed")
2345
+ return;
2346
+ var new_state = [];
2347
+ var subtotal = { type: 'subtotal', name: 'subtotal', amount: cart.totals.subtotal };
2348
+ var total = { type: 'total', name: 'total', amount: cart.totals.total };
2349
+ var promotionAmount = _this.getSummaryPromotionAmount(cart);
2350
+ !forCart && new_state.push(subtotal);
2351
+ promotionAmount != 0 && new_state.push({
2352
+ type: 'discount',
2353
+ name: 'discount',
2354
+ amount: promotionAmount
2355
+ });
2356
+ !forCart && new_state.push(total);
2357
+ return new_state;
2358
+ };
2359
+ /**
2360
+ * Obtiene el monto de descuento que corresponde al resumen de la orden.
2361
+ *
2362
+ * @param cart Carrito u orden con `totals`.
2363
+ * @returns Monto de promociones de orden.
2364
+ *
2365
+ * @example
2366
+ * ```ts
2367
+ * const amount = this.orderUtils.getSummaryPromotionAmount(cart);
2368
+ * ```
2369
+ *
2370
+ * @remarks
2371
+ * Si el backend nuevo informa `promotionBreakdown.orderPromotions`, ese valor tiene prioridad.
2372
+ * Con backends viejos hace fallback a `totals.promotion` o `totals.discount`.
2373
+ */
2374
+ this.getSummaryPromotionAmount = function (cart) {
2375
+ var _a, _b, _c, _d, _e, _f, _g;
2376
+ if (_this.hasOrderPromotionsBreakdown(cart)) {
2377
+ return Number(((_c = (_b = (_a = cart) === null || _a === void 0 ? void 0 : _a.totals) === null || _b === void 0 ? void 0 : _b.promotionBreakdown) === null || _c === void 0 ? void 0 : _c.orderPromotions) || 0);
2378
+ }
2379
+ return Number(((_e = (_d = cart) === null || _d === void 0 ? void 0 : _d.totals) === null || _e === void 0 ? void 0 : _e.promotion) || ((_g = (_f = cart) === null || _f === void 0 ? void 0 : _f.totals) === null || _g === void 0 ? void 0 : _g.discount) || 0);
2380
+ };
2381
+ /**
2382
+ * Indica si el backend ya informa el desglose nuevo de promociones.
2383
+ *
2384
+ * @param cart Carrito u orden con `totals`.
2385
+ * @returns `true` cuando existe `promotionBreakdown.orderPromotions`.
2386
+ */
2387
+ this.hasOrderPromotionsBreakdown = function (cart) { var _a, _b; return Object.prototype.hasOwnProperty.call(((_b = (_a = cart) === null || _a === void 0 ? void 0 : _a.totals) === null || _b === void 0 ? void 0 : _b.promotionBreakdown) || {}, 'orderPromotions'); };
2388
+ /**
2389
+ * Indica si el carrito tiene un cupón aplicado, independientemente de cómo impacte en el resumen.
2390
+ *
2391
+ * @param cart Carrito actual.
2392
+ * @returns `true` cuando hay un código de cupón o una línea de descuento de tipo cupón.
2393
+ *
2394
+ * @remarks
2395
+ * Este helper evita atar la UI de `Quitar cupón` al monto de descuentos de orden.
2396
+ * Un cupón puede afectar promociones unitarias y dejar `orderPromotions = 0`.
2397
+ */
2398
+ this.hasAppliedCoupon = function (cart) {
2399
+ var _a, _b;
2400
+ if (Boolean((_a = cart) === null || _a === void 0 ? void 0 : _a.couponCode)) {
2401
+ return true;
2402
+ }
2403
+ return Array.isArray((_b = cart) === null || _b === void 0 ? void 0 : _b.cartDiscounts)
2404
+ && cart.cartDiscounts.some(function (discount) { var _a; return (((_a = discount) === null || _a === void 0 ? void 0 : _a.type) || '').toString().includes('coupon'); });
2405
+ };
2406
+ /**
2407
+ * Devuelve el monto efectivo de una línea de descuento/promoción.
2408
+ *
2409
+ * @param discount Línea cruda de descuento del backend.
2410
+ * @param cart Carrito asociado.
2411
+ * @returns Monto que debe mostrarse en UI.
2412
+ */
2332
2413
  this.getAmount = function (discount, cart) {
2333
2414
  if (discount.type != 'shipment')
2334
2415
  return discount.amount;
2335
2416
  return cart.totals.shipping;
2336
2417
  };
2418
+ /**
2419
+ * Homologa tipos crudos del backend al conjunto de tipos usado por checkout.
2420
+ *
2421
+ * @param type Tipo crudo (`order_promotion`, `order_coupon_promotion`, etc.).
2422
+ * @returns Tipo normalizado consumido por los componentes del core.
2423
+ */
2337
2424
  this.formatType = function (type) {
2338
2425
  var result;
2339
2426
  switch (type) {
@@ -3672,7 +3759,7 @@
3672
3759
  }); };
3673
3760
  this.updateAsociatedData = function (cart) {
3674
3761
  var _a, _b, _c;
3675
- var result = _this.orderUtils.getPromotions(cart) || [];
3762
+ var result = _this.orderUtils.getSummaryPromotions(cart);
3676
3763
  var totals = (_a = cart) === null || _a === void 0 ? void 0 : _a.totals;
3677
3764
  if (!totals) {
3678
3765
  _this.asociatedDataSubject.next(result);
@@ -4808,11 +4895,23 @@
4808
4895
  _this.requestInProcess.next(false);
4809
4896
  return true;
4810
4897
  };
4898
+ /**
4899
+ * Reasigna `product.price` al precio base legacy que espera el template histórico del carrito.
4900
+ *
4901
+ * @param items Ítems normalizados del carrito.
4902
+ * @returns Los mismos ítems con `product.price` alineado al precio base mostrado en la tabla.
4903
+ *
4904
+ * @remarks
4905
+ * Este método no modifica `pricing.finalPrice`. Solo preserva compatibilidad con templates
4906
+ * viejos que todavía leen `item.product.price` directamente.
4907
+ */
4811
4908
  this.switchPriceInCartItem = function (items) {
4812
- //return items;
4813
4909
  return items.map(function (item) {
4910
+ var _a, _b, _c, _d;
4814
4911
  if (item.product) {
4815
- item.product.price = item.product.variants[0].saleprice ? item.product.variants[0].saleprice : item.product.variants[0].price;
4912
+ var pricing = _this.getItemPricing(item);
4913
+ var variant = (_a = item.product.variants) === null || _a === void 0 ? void 0 : _a[0];
4914
+ item.product.price = ((_b = pricing) === null || _b === void 0 ? void 0 : _b.basePrice) || ((_c = variant) === null || _c === void 0 ? void 0 : _c.saleprice) || ((_d = variant) === null || _d === void 0 ? void 0 : _d.price);
4816
4915
  }
4817
4916
  return item;
4818
4917
  });
@@ -4828,6 +4927,29 @@
4828
4927
  _this.updateLocalCart();
4829
4928
  _this.requestInProcess.next(false);
4830
4929
  };
4930
+ /**
4931
+ * Sincroniza `cartItemsSubject` con la última respuesta del backend.
4932
+ *
4933
+ * @param cart Respuesta de carrito recibida desde cualquier endpoint que devuelva `items`.
4934
+ * @returns `void`
4935
+ *
4936
+ * @remarks
4937
+ * Se reutiliza después de actualizar cantidades, aplicar cupón o remover productos para evitar
4938
+ * que la tabla quede con subtotales o promociones desactualizadas.
4939
+ */
4940
+ this.syncCartItemsFromResponse = function (cart) {
4941
+ var _a;
4942
+ if (!((_a = cart) === null || _a === void 0 ? void 0 : _a.items)) {
4943
+ return;
4944
+ }
4945
+ var previousItems = _this.items || [];
4946
+ var nextItems = _this.transformItems(cart.items).map(function (item) {
4947
+ var _a, _b;
4948
+ var previousItem = previousItems.find(function (prev) { return prev.item_id == item.item_id; });
4949
+ return __assign$a(__assign$a(__assign$a({}, previousItem), item), { failed: (_a = previousItem) === null || _a === void 0 ? void 0 : _a.failed, error: (_b = previousItem) === null || _b === void 0 ? void 0 : _b.error });
4950
+ });
4951
+ _this.updateCartItems(nextItems);
4952
+ };
4831
4953
  this.updateCartItemQuantity = function (variant_id, quantity, comments) {
4832
4954
  var normalizedComments = comments !== undefined ? ((comments !== null && comments !== void 0 ? comments : '')).trim() : undefined;
4833
4955
  var newItems = _this.items.map(function (it) {
@@ -4847,21 +4969,15 @@
4847
4969
  };
4848
4970
  this.appendToCart = function (cart) {
4849
4971
  _this.updateCartObj(cart);
4850
- _this.items = _this.transformItems(cart.items);
4851
- _this.count = _this.items.length;
4852
- _this.requestInProcess.next(false);
4853
- _this.updateLocalCart();
4972
+ _this.syncCartItemsFromResponse(cart);
4854
4973
  // this.toastrService.show('product-added');
4855
- _this.cartItemsSubject.next(_this.items);
4856
4974
  };
4857
4975
  this.removeCartItem = function (cart, product, toast) {
4858
4976
  if (toast === void 0) { toast = true; }
4859
4977
  _this.updateCartObj(cart, false);
4860
- _this.items.splice(_this.items.findIndex(function (item) { return item.item_id == product.item_id; }), 1);
4861
- _this.cartItemsSubject.next(_this.items);
4978
+ _this.syncCartItemsFromResponse(cart);
4862
4979
  toast && _this.requestInProcess.next(false);
4863
4980
  toast && _this.toastrService.show('product-removed');
4864
- _this.updateLocalCart();
4865
4981
  // this.googleAnalytics.removeFromCart(product);
4866
4982
  _this.analyticsService.callEvent('remove_from_cart', __assign$a(__assign$a({}, product), { currency: _this.consts.currency.code }));
4867
4983
  };
@@ -5030,7 +5146,11 @@
5030
5146
  _this.connection
5031
5147
  .put(_this.updateItemQuantityApi(_this.findItemByIdVariant(item.variant_id)), payload)
5032
5148
  .pipe(operators.finalize(function () { return _this.requestInProcess.next(false); }))
5033
- .subscribe(function (res) { return _this.updateCartObj(res) && _this.updateCartItemQuantity(item.variant_id, Number(quantity), comments); }, function (err) { return _this.handleError(err); });
5149
+ .subscribe(function (res) {
5150
+ _this.updateCartObj(res);
5151
+ _this.syncCartItemsFromResponse(res);
5152
+ _this.toastrService.show('product-updated', { quantity: quantity });
5153
+ }, function (err) { return _this.handleError(err); });
5034
5154
  }
5035
5155
  };
5036
5156
  this.validateQuantity = function (item, quantity) {
@@ -5133,7 +5253,50 @@
5133
5253
  this.getSubTotalAmount = function () {
5134
5254
  return _this.cart.pipe(operators.map(function (cart) { var _a, _b; return (_b = (_a = cart) === null || _a === void 0 ? void 0 : _a.totals) === null || _b === void 0 ? void 0 : _b.subtotal; }));
5135
5255
  };
5256
+ /**
5257
+ * Devuelve el descuento que debe mostrarse en el resumen de compra.
5258
+ *
5259
+ * @returns Observable con el monto de promociones de orden.
5260
+ *
5261
+ * @example
5262
+ * ```ts
5263
+ * this.summaryPromotionAmount$ = this.cartService.getSummaryPromotionAmount();
5264
+ * ```
5265
+ *
5266
+ * @remarks
5267
+ * Si el backend nuevo informa `totals.promotionBreakdown.orderPromotions`, se usa ese valor.
5268
+ * Si todavía no existe, el método hace fallback a `totals.promotion` para mantener compatibilidad.
5269
+ */
5270
+ this.getSummaryPromotionAmount = function () {
5271
+ return _this.cart.pipe(operators.map(function (cart) { return _this.orderUtils.getSummaryPromotionAmount(cart); }));
5272
+ };
5273
+ /**
5274
+ * Indica si existe un cupón aplicado en el carrito actual.
5275
+ *
5276
+ * @returns Observable booleano para controlar la visibilidad de `Quitar cupón`.
5277
+ *
5278
+ * @remarks
5279
+ * No debe atarse a `getSummaryPromotionAmount()`, porque un cupón puede afectar
5280
+ * solo promociones unitarias y dejar el descuento de orden en `0`.
5281
+ */
5282
+ this.hasAppliedCoupon = function () {
5283
+ return _this.cart.pipe(operators.map(function (cart) { return _this.orderUtils.hasAppliedCoupon(cart); }));
5284
+ };
5136
5285
  this.toDecimal = function (total) { return (total - Math.floor(total) == 0) ? total / 100 : total; };
5286
+ /**
5287
+ * Obtiene el precio normalizado de un ítem.
5288
+ *
5289
+ * @param item Ítem de carrito normalizado.
5290
+ * @returns Objeto `CartItemPricing` listo para renderizar precio base, tachado y final.
5291
+ *
5292
+ * @example
5293
+ * ```ts
5294
+ * const pricing = this.cartService.getItemPricing(item);
5295
+ * const showTooltip = pricing.hasUnitPromotions;
5296
+ * const finalPrice = pricing.finalPrice;
5297
+ * ```
5298
+ */
5299
+ this.getItemPricing = function (item) { var _a; return ((_a = item) === null || _a === void 0 ? void 0 : _a.pricing) || _this.buildCartItemPricing(item); };
5137
5300
  this.addCoupon = function (code) { return __awaiter$5(_this, void 0, void 0, function () {
5138
5301
  var result, e_1;
5139
5302
  return __generator$5(this, function (_a) {
@@ -5146,6 +5309,7 @@
5146
5309
  if (result.error || result.errors)
5147
5310
  return [2 /*return*/, { error: true, message: 'invalid-coupon' }];
5148
5311
  this.updateCartObj(result, false);
5312
+ this.syncCartItemsFromResponse(result);
5149
5313
  return [2 /*return*/, { error: false, message: 'ok' }];
5150
5314
  case 2:
5151
5315
  e_1 = _a.sent();
@@ -5157,7 +5321,11 @@
5157
5321
  this.removeCoupon = function () { return __awaiter$5(_this, void 0, void 0, function () {
5158
5322
  var _this = this;
5159
5323
  return __generator$5(this, function (_a) {
5160
- return [2 /*return*/, this.connection.delete(this.couponApi()).pipe(operators.map(function (res) { return _this.updateCartObj(res, false); })).toPromise()];
5324
+ return [2 /*return*/, this.connection.delete(this.couponApi()).pipe(operators.map(function (res) {
5325
+ _this.updateCartObj(res, false);
5326
+ _this.syncCartItemsFromResponse(res);
5327
+ return true;
5328
+ })).toPromise()];
5161
5329
  });
5162
5330
  }); };
5163
5331
  this.formatCoupon = function (cart) {
@@ -5220,6 +5388,18 @@
5220
5388
  /**
5221
5389
  * UTILS
5222
5390
  */
5391
+ /**
5392
+ * Transforma los ítems crudos del backend al contrato interno `CartItem`.
5393
+ *
5394
+ * @param server_item Respuesta `items` del endpoint de carrito.
5395
+ * @returns Arreglo de ítems normalizados, cada uno con `pricing` precomputado.
5396
+ *
5397
+ * @remarks
5398
+ * Este es el punto donde el core:
5399
+ * - preserva `unitPromotions`
5400
+ * - arma `pricing`
5401
+ * - mantiene la forma histórica del item consumido por los templates
5402
+ */
5223
5403
  this.transformItems = function (server_item) { return server_item.map(function (item) {
5224
5404
  item = {
5225
5405
  product: item.product,
@@ -5228,8 +5408,10 @@
5228
5408
  quantity: item.quantity,
5229
5409
  comments: item.comments || '',
5230
5410
  item_id: item.id,
5231
- total: item.total
5411
+ total: item.total,
5412
+ unitPromotions: Array.isArray(item.unitPromotions) ? item.unitPromotions : []
5232
5413
  };
5414
+ item.pricing = _this.buildCartItemPricing(item);
5233
5415
  // console.log(item.product.variants[0]);
5234
5416
  // console.log(item.product.variants[0].saleprice);
5235
5417
  // console.log(item.product.variants[0].price);
@@ -5239,6 +5421,85 @@
5239
5421
  // }, 100);
5240
5422
  return item;
5241
5423
  }); };
5424
+ /**
5425
+ * Construye la normalización de precios para un ítem del carrito.
5426
+ *
5427
+ * @param item Ítem normalizado del carrito.
5428
+ * @returns Estructura `CartItemPricing` con precio base, tachado, final y flags de UI.
5429
+ *
5430
+ * @example
5431
+ * ```ts
5432
+ * const pricing = this.buildCartItemPricing(item);
5433
+ * // pricing.basePrice => saleprice si existe, si no price
5434
+ * // pricing.finalPrice => basePrice + unitPromotionTotal
5435
+ * // pricing.effectiveDiscountPercent => % total contra el precio de referencia
5436
+ * ```
5437
+ */
5438
+ this.buildCartItemPricing = function (item) {
5439
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4;
5440
+ var variant = (_c = (_b = (_a = item) === null || _a === void 0 ? void 0 : _a.product) === null || _b === void 0 ? void 0 : _b.variants) === null || _c === void 0 ? void 0 : _c[0];
5441
+ var cartAndSidebarPrices = (_d = variant) === null || _d === void 0 ? void 0 : _d.cartAndSidebarPrices;
5442
+ // Si el backend nuevo informa `cartAndSidebarPrices`, ese es el precio correcto
5443
+ // para carrito/sidebar porque excluye impuestos de orden que no se listan por ítem.
5444
+ // Si no existe, se mantiene el fallback histórico.
5445
+ var basePrice = _this.parsePriceValue((_t = (_q = (_m = (_k = (_h = (_f = (_e = cartAndSidebarPrices) === null || _e === void 0 ? void 0 : _e.saleprice, (_f !== null && _f !== void 0 ? _f : (_g = cartAndSidebarPrices) === null || _g === void 0 ? void 0 : _g.price)), (_h !== null && _h !== void 0 ? _h : (_j = variant) === null || _j === void 0 ? void 0 : _j.saleprice)), (_k !== null && _k !== void 0 ? _k : (_l = variant) === null || _l === void 0 ? void 0 : _l.price)), (_m !== null && _m !== void 0 ? _m : (_p = (_o = item) === null || _o === void 0 ? void 0 : _o.product) === null || _p === void 0 ? void 0 : _p.saleprice)), (_q !== null && _q !== void 0 ? _q : (_s = (_r = item) === null || _r === void 0 ? void 0 : _r.product) === null || _s === void 0 ? void 0 : _s.price)), (_t !== null && _t !== void 0 ? _t : 0)));
5446
+ var strikePriceCandidate = _this.parsePriceValue((_0 = (_x = (_v = (_u = cartAndSidebarPrices) === null || _u === void 0 ? void 0 : _u.price, (_v !== null && _v !== void 0 ? _v : (_w = variant) === null || _w === void 0 ? void 0 : _w.price)), (_x !== null && _x !== void 0 ? _x : (_z = (_y = item) === null || _y === void 0 ? void 0 : _y.product) === null || _z === void 0 ? void 0 : _z.price)), (_0 !== null && _0 !== void 0 ? _0 : 0)));
5447
+ var normalizedBasePrice = isNaN(basePrice) ? 0 : basePrice;
5448
+ var normalizedStrikePrice = isNaN(strikePriceCandidate) ? 0 : strikePriceCandidate;
5449
+ var unitPromotionTotal = Array.isArray((_1 = item) === null || _1 === void 0 ? void 0 : _1.unitPromotions)
5450
+ ? item.unitPromotions.reduce(function (total, promotion) { var _a; return total + Number(((_a = promotion) === null || _a === void 0 ? void 0 : _a.amount) || 0); }, 0)
5451
+ : 0;
5452
+ var hasStrikePrice = normalizedStrikePrice > normalizedBasePrice && normalizedBasePrice > 0;
5453
+ var hasUnitPromotions = Array.isArray((_2 = item) === null || _2 === void 0 ? void 0 : _2.unitPromotions) && item.unitPromotions.length > 0;
5454
+ var finalPrice = hasUnitPromotions ? normalizedBasePrice + unitPromotionTotal : normalizedBasePrice;
5455
+ var productDiscount = Number(((_4 = (_3 = item) === null || _3 === void 0 ? void 0 : _3.product) === null || _4 === void 0 ? void 0 : _4.discount) || 0);
5456
+ var discountPercent = !isNaN(productDiscount) && productDiscount > 0
5457
+ ? Math.round(productDiscount)
5458
+ : hasStrikePrice
5459
+ ? Math.round(((normalizedStrikePrice - normalizedBasePrice) / normalizedStrikePrice) * 100)
5460
+ : 0;
5461
+ var effectiveReferencePrice = hasStrikePrice ? normalizedStrikePrice : normalizedBasePrice;
5462
+ var effectiveDiscountPercent = effectiveReferencePrice > 0 && finalPrice > 0 && effectiveReferencePrice > finalPrice
5463
+ ? Math.round(((effectiveReferencePrice - finalPrice) / effectiveReferencePrice) * 100)
5464
+ : discountPercent;
5465
+ return {
5466
+ basePrice: normalizedBasePrice,
5467
+ strikePrice: hasStrikePrice ? normalizedStrikePrice : null,
5468
+ finalPrice: finalPrice,
5469
+ unitPromotionTotal: unitPromotionTotal,
5470
+ hasStrikePrice: hasStrikePrice,
5471
+ hasUnitPromotions: hasUnitPromotions,
5472
+ discountPercent: discountPercent,
5473
+ effectiveDiscountPercent: effectiveDiscountPercent
5474
+ };
5475
+ };
5476
+ /**
5477
+ * Normaliza valores de precio provenientes del backend a `number`.
5478
+ *
5479
+ * @param value Valor numérico o string con formato local (`120.000`, `120000`, `120000-1`, etc.).
5480
+ * @returns Número parseado o `NaN` si el valor no es utilizable.
5481
+ *
5482
+ * @remarks
5483
+ * Se usa para soportar respuestas con separadores de miles, coma decimal o rangos.
5484
+ */
5485
+ this.parsePriceValue = function (value) {
5486
+ if (value === null || typeof value === 'undefined') {
5487
+ return NaN;
5488
+ }
5489
+ if (typeof value === 'number') {
5490
+ return value;
5491
+ }
5492
+ var raw = value.toString().trim();
5493
+ if (!raw) {
5494
+ return NaN;
5495
+ }
5496
+ var firstValue = raw.includes('-') ? raw.split('-')[0].trim() : raw;
5497
+ var normalized = firstValue
5498
+ .replace(/\s/g, '')
5499
+ .replace(/\.(?=\d{3}(\D|$))/g, '')
5500
+ .replace(',', '.');
5501
+ return Number(normalized);
5502
+ };
5242
5503
  this.getCreditAmount = function () {
5243
5504
  return _this.balanceCustomerSubject.pipe(operators.map(function (balanceCustomer) { var _a, _b; return _b = (_a = balanceCustomer) === null || _a === void 0 ? void 0 : _a.creditAmount, (_b !== null && _b !== void 0 ? _b : null); }));
5244
5505
  };
@@ -7852,7 +8113,209 @@
7852
8113
  _this.showTaxLegend = false;
7853
8114
  _this.cartLoading = false;
7854
8115
  _this.enableFieldNotesInArticleFile = false;
8116
+ _this.activeUnitPromotionItemId = null;
8117
+ _this.activeUnitPromotionSummaryStyles = {};
8118
+ _this.supportsUnitPromotionHover = false;
8119
+ /**
8120
+ * Convierte un monto crudo al formato decimal esperado por la UI.
8121
+ *
8122
+ * @param amount Monto en centavos o entero crudo.
8123
+ * @returns Monto decimal.
8124
+ */
7855
8125
  _this.toDecimal = function (amount) { return _this.consts.toDecimal(amount); };
8126
+ /** @param item Ítem del carrito. @returns Porcentaje de descuento legacy para el badge `% OFF`. */
8127
+ _this.getItemDiscount = function (item) { var _a; return Number(((_a = _this.cartService.getItemPricing(item)) === null || _a === void 0 ? void 0 : _a.discountPercent) || 0); };
8128
+ /**
8129
+ * Devuelve el porcentaje efectivo total del ítem, considerando promociones unitarias.
8130
+ *
8131
+ * @param item Ítem del carrito.
8132
+ * @returns Porcentaje entero calculado contra el precio de referencia del ítem.
8133
+ *
8134
+ * @remarks
8135
+ * Si existe precio tachado, compara `finalPrice` contra `strikePrice`.
8136
+ * Si no existe, usa `basePrice` como referencia.
8137
+ * Esto permite mostrar un badge coherente cuando el precio visible ya incluye
8138
+ * descuentos/promociones unitarias adicionales.
8139
+ *
8140
+ * @example
8141
+ * ```ts
8142
+ * // strikePrice 240000, finalPrice 45000 => 81
8143
+ * this.getItemEffectiveDiscount(item);
8144
+ * ```
8145
+ */
8146
+ _this.getItemEffectiveDiscount = function (item) { var _a; return Number(((_a = _this.cartService.getItemPricing(item)) === null || _a === void 0 ? void 0 : _a.effectiveDiscountPercent) || 0); };
8147
+ /** @param item Ítem del carrito. @returns Subtotal actual del renglón según backend. */
8148
+ _this.getDisplayedItemTotal = function (item) { var _a, _b; return Number((_b = (_a = item) === null || _a === void 0 ? void 0 : _a.total, (_b !== null && _b !== void 0 ? _b : 0))); };
8149
+ /** @param item Ítem del carrito. @returns `true` si el backend informó promociones unitarias. */
8150
+ _this.hasUnitPromotions = function (item) { var _a; return Boolean((_a = _this.cartService.getItemPricing(item)) === null || _a === void 0 ? void 0 : _a.hasUnitPromotions); };
8151
+ /** @param item Ítem del carrito. @returns `true` si el resumen activo pertenece a ese ítem. */
8152
+ _this.isUnitPromotionSummaryOpen = function (item) { var _a; return _this.activeUnitPromotionItemId === ((_a = item) === null || _a === void 0 ? void 0 : _a.item_id); };
8153
+ /**
8154
+ * Abre el resumen del ítem al entrar con el mouse en desktop.
8155
+ *
8156
+ * @param item Ítem del carrito.
8157
+ * @param anchor Elemento usado como ancla visual.
8158
+ * @returns `void`
8159
+ */
8160
+ _this.handleUnitPromotionMouseEnter = function (item, anchor) {
8161
+ if (!_this.supportsUnitPromotionHover) {
8162
+ return;
8163
+ }
8164
+ _this.openUnitPromotionSummary(item, anchor);
8165
+ };
8166
+ /**
8167
+ * Cierra el resumen al salir con el mouse en desktop.
8168
+ *
8169
+ * @param item Ítem asociado al resumen.
8170
+ * @returns `void`
8171
+ */
8172
+ _this.handleUnitPromotionMouseLeave = function (item) {
8173
+ if (!_this.supportsUnitPromotionHover) {
8174
+ return;
8175
+ }
8176
+ _this.closeUnitPromotionSummary(item);
8177
+ };
8178
+ /**
8179
+ * Abre el resumen de promociones unitarias para un ítem puntual.
8180
+ *
8181
+ * @param item Ítem del carrito.
8182
+ * @param anchor Elemento de referencia para posicionamiento.
8183
+ * @returns `void`
8184
+ */
8185
+ _this.openUnitPromotionSummary = function (item, anchor) {
8186
+ var _a, _b;
8187
+ if (!_this.hasUnitPromotions(item)) {
8188
+ return;
8189
+ }
8190
+ _this.activeUnitPromotionItemId = (_b = (_a = item) === null || _a === void 0 ? void 0 : _a.item_id, (_b !== null && _b !== void 0 ? _b : null));
8191
+ _this.updateUnitPromotionSummaryStyles(anchor);
8192
+ };
8193
+ /**
8194
+ * Cierra el resumen activo.
8195
+ *
8196
+ * @param item Si se envía, solo cierra cuando coincide con el ítem activo.
8197
+ * @returns `void`
8198
+ */
8199
+ _this.closeUnitPromotionSummary = function (item) {
8200
+ var _a;
8201
+ if (!item || _this.activeUnitPromotionItemId === ((_a = item) === null || _a === void 0 ? void 0 : _a.item_id)) {
8202
+ _this.activeUnitPromotionItemId = null;
8203
+ _this.activeUnitPromotionSummaryStyles = {};
8204
+ }
8205
+ };
8206
+ /**
8207
+ * Alterna manualmente la apertura del resumen para un ítem.
8208
+ *
8209
+ * @param item Ítem del carrito.
8210
+ * @param anchor Elemento de referencia.
8211
+ * @param event Evento del puntero.
8212
+ * @returns `void`
8213
+ */
8214
+ _this.toggleUnitPromotionSummary = function (item, anchor, event) {
8215
+ event.preventDefault();
8216
+ event.stopPropagation();
8217
+ if (!_this.hasUnitPromotions(item)) {
8218
+ return;
8219
+ }
8220
+ if (_this.isUnitPromotionSummaryOpen(item)) {
8221
+ _this.closeUnitPromotionSummary(item);
8222
+ return;
8223
+ }
8224
+ _this.openUnitPromotionSummary(item, anchor);
8225
+ };
8226
+ /**
8227
+ * Maneja el click/tap sobre el precio en dispositivos sin hover.
8228
+ *
8229
+ * @param item Ítem del carrito.
8230
+ * @param anchor Elemento usado como trigger.
8231
+ * @param event Evento de click/tap.
8232
+ * @returns `void`
8233
+ */
8234
+ _this.handleUnitPromotionPriceClick = function (item, anchor, event) {
8235
+ if (_this.supportsUnitPromotionHover) {
8236
+ return;
8237
+ }
8238
+ _this.toggleUnitPromotionSummary(item, anchor, event);
8239
+ };
8240
+ /**
8241
+ * Evita que eventos dentro del resumen se propaguen al documento.
8242
+ *
8243
+ * @param event Evento del puntero.
8244
+ * @returns `void`
8245
+ */
8246
+ _this.stopUnitPromotionSummaryEvent = function (event) {
8247
+ event.stopPropagation();
8248
+ };
8249
+ /** @param item Ítem del carrito. @returns Precio unitario base (`saleprice` o `price`). */
8250
+ _this.getOriginalUnitPrice = function (item) { var _a; return Number(((_a = _this.cartService.getItemPricing(item)) === null || _a === void 0 ? void 0 : _a.basePrice) || 0); };
8251
+ /** @param item Ítem del carrito. @returns Precio tachado legacy o `0`. */
8252
+ _this.getStrikeThroughUnitPrice = function (item) { var _a; return Number(((_a = _this.cartService.getItemPricing(item)) === null || _a === void 0 ? void 0 : _a.strikePrice) || 0); };
8253
+ /** @param item Ítem del carrito. @returns Suma de promociones unitarias aplicadas. */
8254
+ _this.getUnitPromotionTotal = function (item) { var _a; return Number(((_a = _this.cartService.getItemPricing(item)) === null || _a === void 0 ? void 0 : _a.unitPromotionTotal) || 0); };
8255
+ /** @param item Ítem del carrito. @returns Precio final unitario luego de promociones. */
8256
+ _this.getFinalUnitPrice = function (item) { var _a; return Number(((_a = _this.cartService.getItemPricing(item)) === null || _a === void 0 ? void 0 : _a.finalPrice) || 0); };
8257
+ /** @param item Ítem del carrito. @returns Precio principal a mostrar junto al trigger. */
8258
+ _this.getDisplayedUnitPrice = function (item) { var _a; return Number(((_a = _this.cartService.getItemPricing(item)) === null || _a === void 0 ? void 0 : _a.finalPrice) || 0); };
8259
+ /** @param item Ítem del carrito. @returns `true` si debe mostrarse el precio base junto al final. */
8260
+ _this.shouldShowOriginalUnitPrice = function (item) {
8261
+ return _this.hasUnitPromotions(item) && _this.getFinalUnitPrice(item) !== _this.getOriginalUnitPrice(item);
8262
+ };
8263
+ /** @param item Ítem del carrito. @returns `true` si además del base price existe tachado legacy. */
8264
+ _this.shouldShowLegacyPriceOrigin = function (item) {
8265
+ return _this.getStrikeThroughUnitPrice(item) > _this.getOriginalUnitPrice(item);
8266
+ };
8267
+ /** @param item Ítem del carrito. @returns Etiqueta final del resumen. */
8268
+ _this.getUnitPromotionFinalPriceLabel = function (item) {
8269
+ return _this.hasUnitPromotions(item) ? 'Precio final' : 'Precio unitario';
8270
+ };
8271
+ /**
8272
+ * Busca dentro de una lista el ítem que tiene actualmente el resumen abierto.
8273
+ *
8274
+ * @param items Lista de ítems del carrito.
8275
+ * @returns Ítem activo o `null`.
8276
+ */
8277
+ _this.getActiveUnitPromotionItem = function (items) { var _a; return ((_a = items) === null || _a === void 0 ? void 0 : _a.find(function (item) { var _a; return ((_a = item) === null || _a === void 0 ? void 0 : _a.item_id) === _this.activeUnitPromotionItemId; })) || null; };
8278
+ /** @param item Ítem del carrito. @returns Promociones unitarias crudas del backend. */
8279
+ _this.getUnitPromotions = function (item) { var _a; return Array.isArray((_a = item) === null || _a === void 0 ? void 0 : _a.unitPromotions) ? item.unitPromotions : []; };
8280
+ /**
8281
+ * Detecta si el dispositivo soporta `hover` real y debe comportarse como desktop.
8282
+ *
8283
+ * @returns `void`
8284
+ */
8285
+ _this.updateUnitPromotionViewportMode = function () {
8286
+ _this.supportsUnitPromotionHover = typeof window !== 'undefined'
8287
+ && typeof window.matchMedia === 'function'
8288
+ && window.matchMedia('(hover: hover) and (pointer: fine)').matches
8289
+ && window.innerWidth >= 768;
8290
+ };
8291
+ /**
8292
+ * Calcula estilos inline para mantener el resumen mobile dentro del viewport.
8293
+ *
8294
+ * @param anchor Elemento usado como ancla visual.
8295
+ * @returns `void`
8296
+ */
8297
+ _this.updateUnitPromotionSummaryStyles = function (anchor) {
8298
+ if (_this.supportsUnitPromotionHover || !anchor || typeof window === 'undefined') {
8299
+ _this.activeUnitPromotionSummaryStyles = {};
8300
+ return;
8301
+ }
8302
+ var viewportPadding = 12;
8303
+ var rect = anchor.getBoundingClientRect();
8304
+ var estimatedPopupHeight = 260;
8305
+ var nextTop = rect.bottom + 8;
8306
+ var maxTop = window.innerHeight - estimatedPopupHeight - viewportPadding;
8307
+ var top = Math.max(viewportPadding, Math.min(nextTop, maxTop));
8308
+ _this.activeUnitPromotionSummaryStyles = {
8309
+ left: viewportPadding + "px",
8310
+ right: viewportPadding + "px",
8311
+ top: top + "px",
8312
+ width: 'auto',
8313
+ 'max-width': 'none',
8314
+ 'max-height': "calc(100vh - " + (top + viewportPadding) + "px)",
8315
+ overflow: 'auto',
8316
+ position: 'fixed'
8317
+ };
8318
+ };
7856
8319
  _this.cartItemPlus = function (item) {
7857
8320
  var _a, _b;
7858
8321
  var multipleQty = ((_a = item.product.variants[0]) === null || _a === void 0 ? void 0 : _a.multipleQuantity) || 0;
@@ -7941,6 +8404,8 @@
7941
8404
  _this.ecOnConstruct();
7942
8405
  _this.isLoggedIn = _this.authService.isAuthenticated();
7943
8406
  _this.mediaUrl = _this.consts.mediaUrl();
8407
+ _this.summaryPromotionAmount$ = _this.cartService.getSummaryPromotionAmount();
8408
+ _this.hasAppliedCoupon$ = _this.cartService.hasAppliedCoupon();
7944
8409
  return _this;
7945
8410
  }
7946
8411
  CartEcComponent.prototype.ngOnChanges = function () {
@@ -7952,6 +8417,7 @@
7952
8417
  CartEcComponent.prototype.ngOnInit = function () {
7953
8418
  var _this = this;
7954
8419
  window.scroll(0, 0);
8420
+ this.updateUnitPromotionViewportMode();
7955
8421
  this.cartService.promotions.subscribe(function (promotions) { return _this.promotions = promotions; });
7956
8422
  // console.log(this.cartService.getTaxes());
7957
8423
  this.channelConfigService.channelConfig$.subscribe(function (channel) {
@@ -7973,6 +8439,26 @@
7973
8439
  });
7974
8440
  this.ecOnInit();
7975
8441
  };
8442
+ /** Cierra el resumen al hacer click fuera en desktop. */
8443
+ CartEcComponent.prototype.handleDocumentClick = function () {
8444
+ if (!this.supportsUnitPromotionHover) {
8445
+ return;
8446
+ }
8447
+ this.activeUnitPromotionItemId = null;
8448
+ this.activeUnitPromotionSummaryStyles = {};
8449
+ };
8450
+ /** Recalcula el modo de interacción y cierra el resumen al cambiar el viewport. */
8451
+ CartEcComponent.prototype.handleWindowResize = function () {
8452
+ this.updateUnitPromotionViewportMode();
8453
+ this.closeUnitPromotionSummary();
8454
+ };
8455
+ /** Cierra el resumen en mobile al hacer scroll para evitar desalineación visual. */
8456
+ CartEcComponent.prototype.handleWindowScroll = function () {
8457
+ if (this.supportsUnitPromotionHover) {
8458
+ return;
8459
+ }
8460
+ this.closeUnitPromotionSummary();
8461
+ };
7976
8462
  CartEcComponent.prototype.actualizarCantidad = function (item, cantidad, stock, id) {
7977
8463
  var _this = this;
7978
8464
  var _a, _b, _c;
@@ -8292,6 +8778,15 @@
8292
8778
  { type: AddressingService },
8293
8779
  { type: ChannelConfigService }
8294
8780
  ]; };
8781
+ __decorate$O([
8782
+ core.HostListener('document:click')
8783
+ ], CartEcComponent.prototype, "handleDocumentClick", null);
8784
+ __decorate$O([
8785
+ core.HostListener('window:resize')
8786
+ ], CartEcComponent.prototype, "handleWindowResize", null);
8787
+ __decorate$O([
8788
+ core.HostListener('window:scroll')
8789
+ ], CartEcComponent.prototype, "handleWindowScroll", null);
8295
8790
  CartEcComponent = __decorate$O([
8296
8791
  core.Component({
8297
8792
  selector: 'app-cart-ec',
@@ -8390,7 +8885,7 @@
8390
8885
  };
8391
8886
  var DataFormEcComponent = /** @class */ (function (_super) {
8392
8887
  __extends$h(DataFormEcComponent, _super);
8393
- function DataFormEcComponent(authService, fb, toast, addressingService, cartService, checkoutService, modalService, paramsService, consts, channelConfig) {
8888
+ function DataFormEcComponent(authService, fb, toast, addressingService, cartService, checkoutService, orderUtils, modalService, paramsService, consts, channelConfig) {
8394
8889
  var _this = _super.call(this) || this;
8395
8890
  _this.authService = authService;
8396
8891
  _this.fb = fb;
@@ -8398,6 +8893,7 @@
8398
8893
  _this.addressingService = addressingService;
8399
8894
  _this.cartService = cartService;
8400
8895
  _this.checkoutService = checkoutService;
8896
+ _this.orderUtils = orderUtils;
8401
8897
  _this.modalService = modalService;
8402
8898
  _this.paramsService = paramsService;
8403
8899
  _this.consts = consts;
@@ -9116,7 +9612,7 @@
9116
9612
  shipping: Number(totals.shipping || 0),
9117
9613
  total: Number(totals.total || 0),
9118
9614
  clientTaxes: Number(totals.clientTaxes || 0),
9119
- promotion: Number(totals.promotion || totals.discount || 0),
9615
+ promotion: _this.orderUtils.getSummaryPromotionAmount(order),
9120
9616
  items: Number(totals.items || 0)
9121
9617
  };
9122
9618
  };
@@ -9320,6 +9816,7 @@
9320
9816
  { type: AddressingService },
9321
9817
  { type: CartService },
9322
9818
  { type: CheckoutService },
9819
+ { type: OrderUtilityService },
9323
9820
  { type: modal.BsModalService },
9324
9821
  { type: ParametersService },
9325
9822
  { type: Constants },
@@ -16601,11 +17098,14 @@
16601
17098
  _this.router.navigateByUrl('home');
16602
17099
  }, function (error) {
16603
17100
  _this.register_loading = false;
16604
- if (error.status == 400) {
16605
- _this.toastr.show('email_already_registered');
17101
+ if (error.status == 409) {
17102
+ _this.toastr.show('email-register-channel-inactive');
17103
+ }
17104
+ else if (error.status == 400) {
17105
+ _this.toastr.show('email-already-registered');
16606
17106
  }
16607
17107
  else {
16608
- _this.toastr.show('Error en el registro. Vuelva a intentarlo más tarde.');
17108
+ _this.toastr.show('email-register-error');
16609
17109
  }
16610
17110
  });
16611
17111
  }
@@ -16786,26 +17286,7 @@
16786
17286
  }
16787
17287
  }, function (error) {
16788
17288
  _this.register_loading = false;
16789
- if (error.status == 400) {
16790
- var backendError = error.error;
16791
- if (backendError &&
16792
- backendError.errors &&
16793
- backendError.errors.email &&
16794
- backendError.errors.email.length > 0) {
16795
- // Mostrar el primer mensaje de error de email
16796
- _this.toastr.showPersistent(backendError.errors.email[0]);
16797
- }
16798
- else if (backendError && backendError.message) {
16799
- // Si no hay mensaje específico, pero hay mensaje general del backend
16800
- _this.toastr.showPersistent(backendError.message);
16801
- }
16802
- else {
16803
- _this.toastr.showPersistent('El email ingresado ya se encuentra registrado.');
16804
- }
16805
- }
16806
- else {
16807
- _this.toastr.show('Error en el registro. Vuelva a intentarlo más tarde.');
16808
- }
17289
+ _this.toastr.showPersistent(_this.resolveRegisterErrorMessage(error));
16809
17290
  });
16810
17291
  }
16811
17292
  else {
@@ -16915,6 +17396,24 @@
16915
17396
  return control.value.length > max ? { maxLength: true } : null;
16916
17397
  };
16917
17398
  };
17399
+ RegisterFormEcComponent.prototype.resolveRegisterErrorMessage = function (error) {
17400
+ var _a, _b, _c, _d, _e, _f, _g, _h;
17401
+ var backendError = (_a = error) === null || _a === void 0 ? void 0 : _a.error;
17402
+ var status = (_c = (_b = error) === null || _b === void 0 ? void 0 : _b.status, (_c !== null && _c !== void 0 ? _c : (_d = backendError) === null || _d === void 0 ? void 0 : _d.code));
17403
+ if (status === 409) {
17404
+ return 'email-register-channel-inactive';
17405
+ }
17406
+ if (status === 400) {
17407
+ if (((_g = (_f = (_e = backendError) === null || _e === void 0 ? void 0 : _e.errors) === null || _f === void 0 ? void 0 : _f.email) === null || _g === void 0 ? void 0 : _g.length) > 0) {
17408
+ return backendError.errors.email[0];
17409
+ }
17410
+ if ((_h = backendError) === null || _h === void 0 ? void 0 : _h.message) {
17411
+ return backendError.message;
17412
+ }
17413
+ return 'email-already-registered';
17414
+ }
17415
+ return 'email-register-error';
17416
+ };
16918
17417
  RegisterFormEcComponent.prototype.normalizeRegisterData = function (data) {
16919
17418
  var normalizeString = function (val) {
16920
17419
  return val === undefined || val === null || val.toString().trim() === '' ? null : val.toString().trim();
@@ -17408,11 +17907,14 @@
17408
17907
  }
17409
17908
  }, function (error) {
17410
17909
  _this.register_loading = false;
17411
- if (error.status == 400) {
17412
- _this.toastr.show('El email ingresado ya se encuentra registrado.');
17910
+ if (error.status == 409) {
17911
+ _this.toastr.show('email-register-channel-inactive');
17912
+ }
17913
+ else if (error.status == 400) {
17914
+ _this.toastr.show('email-already-registered');
17413
17915
  }
17414
17916
  else {
17415
- _this.toastr.show('Error en el registro. Vuelva a intentarlo más tarde.');
17917
+ _this.toastr.show('email-register-error');
17416
17918
  }
17417
17919
  });
17418
17920
  }
@@ -17712,9 +18214,16 @@
17712
18214
  }
17713
18215
  DetailCheckoutBlockEcComponent.prototype.ngOnInit = function () {
17714
18216
  var _this = this;
17715
- this.asociatedData && (this.data = this.asociatedData) ||
17716
- this.checkoutService.asociatedData$.subscribe(function (data) { return _this.data = data; });
17717
- this.calcularTotales();
18217
+ if (this.asociatedData) {
18218
+ this.data = this.asociatedData;
18219
+ this.calcularTotales();
18220
+ }
18221
+ else {
18222
+ this.checkoutService.asociatedData$.subscribe(function (data) {
18223
+ _this.data = data;
18224
+ _this.calcularTotales();
18225
+ });
18226
+ }
17718
18227
  this.ecOnInit();
17719
18228
  this.cartService.showPrice$.subscribe(function (showPrice) {
17720
18229
  _this.creditAccountShowPrices = showPrice;
@@ -17730,6 +18239,8 @@
17730
18239
  });
17731
18240
  };
17732
18241
  DetailCheckoutBlockEcComponent.prototype.calcularTotales = function () {
18242
+ this.discountTotal = 0;
18243
+ this.couponTotal = 0;
17733
18244
  if (this.data) {
17734
18245
  this.discountTotal = this.data
17735
18246
  .filter(function (item) { return item.type === 'discount'; })
@@ -22361,7 +22872,60 @@
22361
22872
  return null;
22362
22873
  }
22363
22874
  };
22875
+ /**
22876
+ * Devuelve el porcentaje de descuento a mostrar para un ítem del sidebar.
22877
+ *
22878
+ * @param item Ítem del carrito.
22879
+ * @returns Porcentaje entero de descuento.
22880
+ */
22881
+ this.getItemDiscount = function (item) { var _a; return Number(((_a = _this.cartService.getItemPricing(item)) === null || _a === void 0 ? void 0 : _a.discountPercent) || 0); };
22882
+ /**
22883
+ * Devuelve el porcentaje efectivo total del ítem, considerando promociones unitarias.
22884
+ *
22885
+ * @param item Ítem del carrito.
22886
+ * @returns Porcentaje entero calculado contra el precio de referencia del ítem.
22887
+ *
22888
+ * @remarks
22889
+ * Si el frontend muestra el precio final unitario junto con un precio tachado legacy,
22890
+ * este helper evita inconsistencias visuales en el badge `% OFF`.
22891
+ *
22892
+ * @example
22893
+ * ```ts
22894
+ * // strikePrice 240000, finalPrice 45000 => 81
22895
+ * this.getItemEffectiveDiscount(item);
22896
+ * ```
22897
+ */
22898
+ this.getItemEffectiveDiscount = function (item) { var _a; return Number(((_a = _this.cartService.getItemPricing(item)) === null || _a === void 0 ? void 0 : _a.effectiveDiscountPercent) || 0); };
22899
+ /**
22900
+ * Devuelve el precio tachado del renglón completo, escalado por cantidad.
22901
+ *
22902
+ * @param item Ítem del carrito.
22903
+ * @returns Total tachado del renglón o `0` cuando no corresponde mostrarlo.
22904
+ *
22905
+ * @remarks
22906
+ * Este helper es útil en sidebars que renderizan precios por renglón, no unitarios.
22907
+ * Ejemplo: si el precio tachado unitario es `15000` y la cantidad es `2`,
22908
+ * el valor mostrado debe ser `30000`.
22909
+ */
22910
+ this.getDisplayedItemStrikeThroughTotal = function (item) {
22911
+ var _a, _b;
22912
+ var strikePrice = Number(((_a = _this.cartService.getItemPricing(item)) === null || _a === void 0 ? void 0 : _a.strikePrice) || 0);
22913
+ var quantity = Number(((_b = item) === null || _b === void 0 ? void 0 : _b.quantity) || 0);
22914
+ if (strikePrice <= 0 || quantity <= 0) {
22915
+ return 0;
22916
+ }
22917
+ return strikePrice * quantity;
22918
+ };
22919
+ /**
22920
+ * Devuelve el subtotal actual del renglón según backend.
22921
+ *
22922
+ * @param item Ítem del carrito.
22923
+ * @returns Monto total del renglón.
22924
+ */
22925
+ this.getDisplayedItemTotal = function (item) { var _a, _b; return Number((_b = (_a = item) === null || _a === void 0 ? void 0 : _a.total, (_b !== null && _b !== void 0 ? _b : 0))); };
22364
22926
  this.mediaUrl = this.consts.mediaUrl();
22927
+ this.summaryPromotionAmount$ = this.cartService.getSummaryPromotionAmount();
22928
+ this.hasAppliedCoupon$ = this.cartService.hasAppliedCoupon();
22365
22929
  }
22366
22930
  SidebarEcComponent.prototype.ngOnInit = function () {
22367
22931
  var _this = this;
@@ -22435,6 +22999,13 @@
22435
22999
  path += variant.options.length ? "?variant=true" : "";
22436
23000
  this.router.navigateByUrl(path);
22437
23001
  };
23002
+ /**
23003
+ * Construye el badge `% OFF` legacy a partir de `price` y `saleprice`.
23004
+ *
23005
+ * @param saleprice Precio de venta actual.
23006
+ * @param price Precio original tachado.
23007
+ * @returns Texto del badge o string vacío cuando no corresponde mostrar descuento.
23008
+ */
22438
23009
  SidebarEcComponent.prototype.createDiscountMessage = function (saleprice, price) {
22439
23010
  if (isNaN(saleprice) || isNaN(price) || saleprice >= price || saleprice <= 0 || price <= 0) {
22440
23011
  return '';
@@ -22683,6 +23254,251 @@
22683
23254
  return BlockRenderEcComponent;
22684
23255
  }(ComponentHelper));
22685
23256
 
23257
+ var __decorate$26 = (this && this.__decorate) || function (decorators, target, key, desc) {
23258
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
23259
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
23260
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
23261
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
23262
+ };
23263
+ var UnitPromotionPriceEcComponent = /** @class */ (function () {
23264
+ function UnitPromotionPriceEcComponent(cartService) {
23265
+ var _this = this;
23266
+ this.cartService = cartService;
23267
+ /** Indica si el componente se está usando en un layout mobile. */
23268
+ this.mobile = false;
23269
+ this.summaryOpen = false;
23270
+ this.summaryStyles = {};
23271
+ this.supportsHover = false;
23272
+ /** @returns `true` cuando el ítem tiene promociones unitarias informadas por backend. */
23273
+ this.hasUnitPromotions = function () { var _a; return Boolean((_a = _this.cartService.getItemPricing(_this.item)) === null || _a === void 0 ? void 0 : _a.hasUnitPromotions); };
23274
+ /** @returns `true` cuando el popover/resumen está abierto. */
23275
+ this.isSummaryOpen = function () { return _this.summaryOpen; };
23276
+ /** @returns El precio base histórico del ítem (`saleprice` si existe, si no `price`). */
23277
+ this.getOriginalUnitPrice = function () { var _a; return Number(((_a = _this.cartService.getItemPricing(_this.item)) === null || _a === void 0 ? void 0 : _a.basePrice) || 0); };
23278
+ /** @returns La suma de los descuentos/promociones unitarios aplicados al ítem. */
23279
+ this.getUnitPromotionTotal = function () { var _a; return Number(((_a = _this.cartService.getItemPricing(_this.item)) === null || _a === void 0 ? void 0 : _a.unitPromotionTotal) || 0); };
23280
+ /** @returns El precio unitario final luego de aplicar promociones unitarias. */
23281
+ this.getFinalUnitPrice = function () { var _a; return Number(((_a = _this.cartService.getItemPricing(_this.item)) === null || _a === void 0 ? void 0 : _a.finalPrice) || 0); };
23282
+ /** @returns El precio principal que se renderiza junto al icono de ayuda. */
23283
+ this.getDisplayedUnitPrice = function () { var _a; return Number(((_a = _this.cartService.getItemPricing(_this.item)) === null || _a === void 0 ? void 0 : _a.finalPrice) || 0); };
23284
+ /** @returns Etiqueta del bloque final dentro del popover. */
23285
+ this.getUnitPromotionFinalPriceLabel = function () { return _this.hasUnitPromotions() ? 'Precio final' : 'Precio unitario'; };
23286
+ /** @returns Lista cruda de promociones unitarias a mostrar en el detalle. */
23287
+ this.getUnitPromotions = function () { var _a; return Array.isArray((_a = _this.item) === null || _a === void 0 ? void 0 : _a.unitPromotions) ? _this.item.unitPromotions : []; };
23288
+ /**
23289
+ * Abre el popover al pasar el mouse en dispositivos con hover real.
23290
+ *
23291
+ * @param anchor Elemento usado como referencia visual del popover.
23292
+ * @returns `void`
23293
+ */
23294
+ this.handleMouseEnter = function (anchor) {
23295
+ if (!_this.supportsHover) {
23296
+ return;
23297
+ }
23298
+ _this.openSummary(anchor);
23299
+ };
23300
+ /**
23301
+ * Cierra el popover al salir con el mouse en desktop.
23302
+ *
23303
+ * @returns `void`
23304
+ */
23305
+ this.handleMouseLeave = function () {
23306
+ if (!_this.supportsHover) {
23307
+ return;
23308
+ }
23309
+ _this.closeSummary();
23310
+ };
23311
+ /**
23312
+ * Alterna la apertura del popover con click/tap en dispositivos sin hover.
23313
+ *
23314
+ * @param anchor Elemento usado como ancla para posicionar el detalle.
23315
+ * @param event Evento del click/tap sobre el bloque de precio.
23316
+ * @returns `void`
23317
+ */
23318
+ this.handlePriceClick = function (anchor, event) {
23319
+ if (_this.supportsHover) {
23320
+ return;
23321
+ }
23322
+ _this.toggleSummary(anchor, event);
23323
+ };
23324
+ /**
23325
+ * Alterna manualmente el estado del resumen.
23326
+ *
23327
+ * @param anchor Elemento usado como ancla visual del popover.
23328
+ * @param event Evento que dispara la interacción.
23329
+ * @returns `void`
23330
+ */
23331
+ this.toggleSummary = function (anchor, event) {
23332
+ event.preventDefault();
23333
+ event.stopPropagation();
23334
+ if (!_this.hasUnitPromotions()) {
23335
+ return;
23336
+ }
23337
+ if (_this.isSummaryOpen()) {
23338
+ _this.closeSummary();
23339
+ return;
23340
+ }
23341
+ _this.openSummary(anchor);
23342
+ };
23343
+ /**
23344
+ * Cierra el popover y limpia los estilos calculados para mobile.
23345
+ *
23346
+ * @returns `void`
23347
+ */
23348
+ this.closeSummary = function () {
23349
+ _this.summaryOpen = false;
23350
+ _this.summaryStyles = {};
23351
+ };
23352
+ /**
23353
+ * Evita que un click dentro del popover se propague y lo cierre.
23354
+ *
23355
+ * @param event Evento del puntero.
23356
+ * @returns `void`
23357
+ */
23358
+ this.stopSummaryEvent = function (event) {
23359
+ event.stopPropagation();
23360
+ };
23361
+ /**
23362
+ * Abre el resumen y recalcula su posición.
23363
+ *
23364
+ * @param anchor Elemento de referencia para el posicionamiento.
23365
+ * @returns `void`
23366
+ */
23367
+ this.openSummary = function (anchor) {
23368
+ if (!_this.hasUnitPromotions()) {
23369
+ return;
23370
+ }
23371
+ _this.summaryOpen = true;
23372
+ _this.updateSummaryStyles(anchor);
23373
+ };
23374
+ /**
23375
+ * Detecta si la interacción debe comportarse como desktop (`hover`) o mobile (`click`).
23376
+ *
23377
+ * @returns `void`
23378
+ */
23379
+ this.updateViewportMode = function () {
23380
+ _this.supportsHover = typeof window !== 'undefined'
23381
+ && typeof window.matchMedia === 'function'
23382
+ && window.matchMedia('(hover: hover) and (pointer: fine)').matches
23383
+ && window.innerWidth >= 768;
23384
+ };
23385
+ /**
23386
+ * Calcula estilos inline para que el resumen mobile quede dentro del viewport.
23387
+ *
23388
+ * @param anchor Elemento tocado por el usuario.
23389
+ * @returns `void`
23390
+ */
23391
+ this.updateSummaryStyles = function (anchor) {
23392
+ if (_this.supportsHover || !anchor || typeof window === 'undefined') {
23393
+ _this.summaryStyles = {};
23394
+ return;
23395
+ }
23396
+ var viewportPadding = 12;
23397
+ var rect = anchor.getBoundingClientRect();
23398
+ var estimatedPopupHeight = 260;
23399
+ var nextTop = rect.bottom + 8;
23400
+ var maxTop = window.innerHeight - estimatedPopupHeight - viewportPadding;
23401
+ var top = Math.max(viewportPadding, Math.min(nextTop, maxTop));
23402
+ _this.summaryStyles = {
23403
+ left: viewportPadding + "px",
23404
+ right: viewportPadding + "px",
23405
+ top: top + "px",
23406
+ width: 'auto',
23407
+ 'max-width': 'none',
23408
+ 'max-height': "calc(100vh - " + (top + viewportPadding) + "px)",
23409
+ overflow: 'auto',
23410
+ position: 'fixed'
23411
+ };
23412
+ };
23413
+ }
23414
+ /**
23415
+ * Inicializa el modo de interacción según el dispositivo actual.
23416
+ *
23417
+ * @returns `void`
23418
+ */
23419
+ UnitPromotionPriceEcComponent.prototype.ngOnInit = function () {
23420
+ this.updateViewportMode();
23421
+ };
23422
+ /**
23423
+ * Cierra el resumen cuando se hace click fuera del componente en desktop.
23424
+ *
23425
+ * @returns `void`
23426
+ */
23427
+ UnitPromotionPriceEcComponent.prototype.handleDocumentClick = function () {
23428
+ if (!this.supportsHover) {
23429
+ return;
23430
+ }
23431
+ this.closeSummary();
23432
+ };
23433
+ /**
23434
+ * Recalcula el modo de interacción al cambiar el viewport.
23435
+ *
23436
+ * @returns `void`
23437
+ */
23438
+ UnitPromotionPriceEcComponent.prototype.handleWindowResize = function () {
23439
+ this.updateViewportMode();
23440
+ this.closeSummary();
23441
+ };
23442
+ /**
23443
+ * Cierra el resumen en mobile al hacer scroll para evitar que quede desacoplado del trigger.
23444
+ *
23445
+ * @returns `void`
23446
+ */
23447
+ UnitPromotionPriceEcComponent.prototype.handleWindowScroll = function () {
23448
+ if (this.supportsHover) {
23449
+ return;
23450
+ }
23451
+ this.closeSummary();
23452
+ };
23453
+ UnitPromotionPriceEcComponent.ctorParameters = function () { return [
23454
+ { type: CartService }
23455
+ ]; };
23456
+ __decorate$26([
23457
+ core.Input()
23458
+ ], UnitPromotionPriceEcComponent.prototype, "item", void 0);
23459
+ __decorate$26([
23460
+ core.Input()
23461
+ ], UnitPromotionPriceEcComponent.prototype, "mobile", void 0);
23462
+ __decorate$26([
23463
+ core.HostListener('document:click')
23464
+ ], UnitPromotionPriceEcComponent.prototype, "handleDocumentClick", null);
23465
+ __decorate$26([
23466
+ core.HostListener('window:resize')
23467
+ ], UnitPromotionPriceEcComponent.prototype, "handleWindowResize", null);
23468
+ __decorate$26([
23469
+ core.HostListener('window:scroll')
23470
+ ], UnitPromotionPriceEcComponent.prototype, "handleWindowScroll", null);
23471
+ UnitPromotionPriceEcComponent = __decorate$26([
23472
+ core.Component({
23473
+ selector: 'app-unit-promotion-price-ec',
23474
+ template: "<div\n class=\"ec-unit-promotion-price\"\n [class.ec-unit-promotion-price--mobile]=\"mobile\"\n [class.ec-unit-promotion-price--desktop]=\"!mobile\"\n>\n <div class=\"ec-unit-promotion-price__detail\">\n <div\n class=\"ec-unit-promotion-price__current-wrapper\"\n #priceAnchor\n (mouseenter)=\"handleMouseEnter(priceAnchor)\"\n (mouseleave)=\"handleMouseLeave()\"\n (click)=\"handlePriceClick(priceAnchor, $event)\"\n >\n <span\n class=\"ec-unit-promotion-price__current\"\n [class.ec-unit-promotion-price__current--clickable]=\"hasUnitPromotions() && !supportsHover\"\n >\n <strong class=\"ec-unit-promotion-price__value\">{{ getDisplayedUnitPrice() | ecCurrencySymbol }}</strong>\n\n <button\n *ngIf=\"hasUnitPromotions()\"\n type=\"button\"\n class=\"ec-unit-promotion-price__trigger\"\n [attr.aria-expanded]=\"isSummaryOpen()\"\n aria-label=\"Ver detalle de promociones unitarias\"\n (click)=\"toggleSummary(priceAnchor, $event)\"\n >\n <i class=\"bi bi-info-circle ec-unit-promotion-price__icon\"></i>\n </button>\n </span>\n\n <ng-container *ngIf=\"supportsHover && isSummaryOpen()\">\n <ng-container *ngTemplateOutlet=\"summaryTemplate\"></ng-container>\n </ng-container>\n </div>\n </div>\n\n <ng-container *ngIf=\"mobile && !supportsHover && isSummaryOpen()\">\n <button\n type=\"button\"\n class=\"ec-unit-promotion-price__backdrop\"\n aria-label=\"Cerrar detalle de promociones unitarias\"\n (click)=\"closeSummary()\"\n ></button>\n\n <ng-container *ngTemplateOutlet=\"summaryTemplate\"></ng-container>\n </ng-container>\n</div>\n\n<ng-template #summaryTemplate>\n <div\n class=\"ec-unit-promotion-price__summary\"\n [class.ec-unit-promotion-price__summary--mobile]=\"mobile\"\n [ngStyle]=\"summaryStyles\"\n (click)=\"stopSummaryEvent($event)\"\n >\n <div class=\"ec-unit-promotion-price__row ec-unit-promotion-price__row--original\">\n <span>Precio original</span>\n <span>{{ getOriginalUnitPrice() | ecCurrencySymbol }}</span>\n </div>\n\n <div class=\"ec-unit-promotion-price__row\" *ngFor=\"let promotion of getUnitPromotions()\">\n <span>{{ promotion.name }}</span>\n <span>{{ promotion.amount | ecCurrencySymbol }}</span>\n </div>\n\n <div class=\"ec-unit-promotion-price__divider\"></div>\n\n <div class=\"ec-unit-promotion-price__row ec-unit-promotion-price__row--total\">\n <span>Total descuentos</span>\n <span>{{ getUnitPromotionTotal() | ecCurrencySymbol }}</span>\n </div>\n\n <div class=\"ec-unit-promotion-price__row ec-unit-promotion-price__row--final\">\n <span>{{ getUnitPromotionFinalPriceLabel() }}</span>\n <span>{{ getFinalUnitPrice() | ecCurrencySymbol }}</span>\n </div>\n </div>\n</ng-template>\n",
23475
+ styles: [":host{display:inline-block;--ec-unit-promotion-current-gap:0.35rem;--ec-unit-promotion-current-font-size:1.25rem;--ec-unit-promotion-current-font-weight:700;--ec-unit-promotion-current-color:inherit;--ec-unit-promotion-icon-color:#6c757d;--ec-unit-promotion-icon-size:0.95rem;--ec-unit-promotion-summary-bg:#ffffff;--ec-unit-promotion-summary-shadow:0 12px 28px rgba(0, 0, 0, 0.18);--ec-unit-promotion-summary-padding:1rem 1.1rem;--ec-unit-promotion-summary-min-width:18rem;--ec-unit-promotion-summary-width:22rem;--ec-unit-promotion-summary-max-width:84vw;--ec-unit-promotion-summary-z-index:20;--ec-unit-promotion-row-color:#333333;--ec-unit-promotion-row-font-size:0.95rem;--ec-unit-promotion-row-line-height:1.35;--ec-unit-promotion-original-color:#c24a2a;--ec-unit-promotion-total-color:#16347a;--ec-unit-promotion-divider-color:#d9d9d9}.ec-unit-promotion-price{display:inline-flex;align-items:center}.ec-unit-promotion-price__detail{position:relative;display:inline-flex;flex-direction:column;align-items:flex-start}.ec-unit-promotion-price__current-wrapper{position:relative}.ec-unit-promotion-price__current{display:inline-flex;align-items:center;gap:var(--ec-unit-promotion-current-gap);color:var(--ec-unit-promotion-current-color);font-size:var(--ec-unit-promotion-current-font-size)}.ec-unit-promotion-price__current--clickable{cursor:pointer}.ec-unit-promotion-price__value{display:inline-flex}.ec-unit-promotion-price__current strong{font-weight:var(--ec-unit-promotion-current-font-weight)}.ec-unit-promotion-price__trigger{align-items:center;background:0 0;border:0;cursor:pointer;display:inline-flex;justify-content:center;padding:0}.ec-unit-promotion-price__icon{color:var(--ec-unit-promotion-icon-color);cursor:pointer;font-size:var(--ec-unit-promotion-icon-size);line-height:1}.ec-unit-promotion-price__summary{background:var(--ec-unit-promotion-summary-bg);box-shadow:var(--ec-unit-promotion-summary-shadow);min-width:var(--ec-unit-promotion-summary-min-width);padding:var(--ec-unit-promotion-summary-padding);position:absolute;right:0;top:calc(100% + .35rem);width:var(--ec-unit-promotion-summary-width);max-width:var(--ec-unit-promotion-summary-max-width);z-index:var(--ec-unit-promotion-summary-z-index)}.ec-unit-promotion-price__summary::before{background:var(--ec-unit-promotion-summary-bg);content:'';height:.9rem;position:absolute;right:.9rem;top:-.35rem;transform:rotate(45deg);width:.9rem}.ec-unit-promotion-price__summary--mobile{position:fixed;max-width:none;min-width:0;width:auto}.ec-unit-promotion-price__summary--mobile::before{display:none}.ec-unit-promotion-price__backdrop{background:0 0;border:0;inset:0;padding:0;position:fixed;z-index:calc(var(--ec-unit-promotion-summary-z-index) - 1)}.ec-unit-promotion-price__row{align-items:flex-start;color:var(--ec-unit-promotion-row-color);-moz-column-gap:.75rem;column-gap:.75rem;display:flex;font-size:var(--ec-unit-promotion-row-font-size);justify-content:space-between;line-height:var(--ec-unit-promotion-row-line-height)}.ec-unit-promotion-price__row+.ec-unit-promotion-price__row{margin-top:.65rem}.ec-unit-promotion-price__row span:first-child{flex:1 1 auto;font-weight:500}.ec-unit-promotion-price__row span:last-child{flex:0 0 auto;text-align:right;white-space:nowrap}.ec-unit-promotion-price__row--original{color:var(--ec-unit-promotion-original-color)}.ec-unit-promotion-price__row--final,.ec-unit-promotion-price__row--total{color:var(--ec-unit-promotion-total-color);font-weight:700}.ec-unit-promotion-price__divider{border-top:1px solid var(--ec-unit-promotion-divider-color);margin:.85rem 0}"]
23476
+ })
23477
+ /**
23478
+ * Renderiza el precio unitario final de un ítem con soporte para promociones unitarias.
23479
+ *
23480
+ * @remarks
23481
+ * Este componente resuelve la UX del precio neto con promociones unitarias:
23482
+ * - precio final unitario visible
23483
+ * - icono de información
23484
+ * - popover desktop/mobile con el desglose de descuentos
23485
+ *
23486
+ * El badge `% OFF` y el precio tachado legacy quedan fuera del componente
23487
+ * para que cada frontend pueda ubicarlos donde quiera.
23488
+ *
23489
+ * @example
23490
+ * ```html
23491
+ * <div class="price-block">
23492
+ * <div class="discount-badge" *ngIf="getItemDiscount(item) as discount">{{ discount }}% OFF</div>
23493
+ * <del *ngIf="shouldShowLegacyPriceOrigin(item)">{{ getStrikeThroughUnitPrice(item) | ecCurrencySymbol }}</del>
23494
+ * <app-unit-promotion-price-ec [item]="item" [mobile]="true"></app-unit-promotion-price-ec>
23495
+ * </div>
23496
+ * ```
23497
+ */
23498
+ ], UnitPromotionPriceEcComponent);
23499
+ return UnitPromotionPriceEcComponent;
23500
+ }());
23501
+
22686
23502
  // //Component base
22687
23503
  var components = [
22688
23504
  BlockBannerBoxesEcComponent,
@@ -22725,6 +23541,7 @@
22725
23541
  LoadingSectionEcComponent,
22726
23542
  MPCreditEcComponent,
22727
23543
  PriceEcComponent,
23544
+ UnitPromotionPriceEcComponent,
22728
23545
  RedsysCatchEcComponent,
22729
23546
  RedSysProEcComponent,
22730
23547
  RedSysRedirectEcComponent,
@@ -22771,7 +23588,7 @@
22771
23588
  SidebarEcComponent
22772
23589
  ];
22773
23590
 
22774
- var __decorate$26 = (this && this.__decorate) || function (decorators, target, key, desc) {
23591
+ var __decorate$27 = (this && this.__decorate) || function (decorators, target, key, desc) {
22775
23592
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
22776
23593
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
22777
23594
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -22878,16 +23695,16 @@
22878
23695
  { type: BlocksService },
22879
23696
  { type: router.Router }
22880
23697
  ]; };
22881
- __decorate$26([
23698
+ __decorate$27([
22882
23699
  core.Input()
22883
23700
  ], AddActionRedirectDirective.prototype, "ecAddActionRedirect", null);
22884
- __decorate$26([
23701
+ __decorate$27([
22885
23702
  core.Input()
22886
23703
  ], AddActionRedirectDirective.prototype, "classStrSpacing", null);
22887
- __decorate$26([
23704
+ __decorate$27([
22888
23705
  core.Input()
22889
23706
  ], AddActionRedirectDirective.prototype, "isTransparent", null);
22890
- AddActionRedirectDirective = __decorate$26([
23707
+ AddActionRedirectDirective = __decorate$27([
22891
23708
  core.Directive({
22892
23709
  selector: "[ecAddActionRedirect]",
22893
23710
  }),
@@ -22896,7 +23713,7 @@
22896
23713
  return AddActionRedirectDirective;
22897
23714
  }());
22898
23715
 
22899
- var __decorate$27 = (this && this.__decorate) || function (decorators, target, key, desc) {
23716
+ var __decorate$28 = (this && this.__decorate) || function (decorators, target, key, desc) {
22900
23717
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
22901
23718
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
22902
23719
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -22961,13 +23778,13 @@
22961
23778
  { type: core.TemplateRef },
22962
23779
  { type: core.ViewContainerRef }
22963
23780
  ]; };
22964
- __decorate$27([
23781
+ __decorate$28([
22965
23782
  core.Input()
22966
23783
  ], ProductStockDirective.prototype, "ecProductStockElse", void 0);
22967
- __decorate$27([
23784
+ __decorate$28([
22968
23785
  core.Input()
22969
23786
  ], ProductStockDirective.prototype, "ecProductStock", null);
22970
- ProductStockDirective = __decorate$27([
23787
+ ProductStockDirective = __decorate$28([
22971
23788
  core.Directive({
22972
23789
  selector: "[ecProductStock]"
22973
23790
  })
@@ -22975,7 +23792,7 @@
22975
23792
  return ProductStockDirective;
22976
23793
  }());
22977
23794
 
22978
- var __decorate$28 = (this && this.__decorate) || function (decorators, target, key, desc) {
23795
+ var __decorate$29 = (this && this.__decorate) || function (decorators, target, key, desc) {
22979
23796
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
22980
23797
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
22981
23798
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -23116,16 +23933,16 @@
23116
23933
  { type: core.ElementRef },
23117
23934
  { type: core.Renderer2 }
23118
23935
  ]; };
23119
- __decorate$28([
23936
+ __decorate$29([
23120
23937
  core.Input()
23121
23938
  ], ProductOffDirective.prototype, "ecProductOff", null);
23122
- __decorate$28([
23939
+ __decorate$29([
23123
23940
  core.Input()
23124
23941
  ], ProductOffDirective.prototype, "classStrSpacing", null);
23125
- __decorate$28([
23942
+ __decorate$29([
23126
23943
  core.Input()
23127
23944
  ], ProductOffDirective.prototype, "customMessage", null);
23128
- ProductOffDirective = __decorate$28([
23945
+ ProductOffDirective = __decorate$29([
23129
23946
  core.Directive({
23130
23947
  selector: "[ecProductOff]",
23131
23948
  }),
@@ -23134,7 +23951,7 @@
23134
23951
  return ProductOffDirective;
23135
23952
  }());
23136
23953
 
23137
- var __decorate$29 = (this && this.__decorate) || function (decorators, target, key, desc) {
23954
+ var __decorate$2a = (this && this.__decorate) || function (decorators, target, key, desc) {
23138
23955
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
23139
23956
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
23140
23957
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -23192,10 +24009,10 @@
23192
24009
  { type: core.Renderer2 },
23193
24010
  { type: Constants }
23194
24011
  ]; };
23195
- __decorate$29([
24012
+ __decorate$2a([
23196
24013
  core.Input()
23197
24014
  ], ProductMiniStandardDirective.prototype, "ecProductMiniStandard", null);
23198
- ProductMiniStandardDirective = __decorate$29([
24015
+ ProductMiniStandardDirective = __decorate$2a([
23199
24016
  core.Directive({
23200
24017
  selector: '[ecProductMiniStandard]'
23201
24018
  })
@@ -23203,7 +24020,7 @@
23203
24020
  return ProductMiniStandardDirective;
23204
24021
  }());
23205
24022
 
23206
- var __decorate$2a = (this && this.__decorate) || function (decorators, target, key, desc) {
24023
+ var __decorate$2b = (this && this.__decorate) || function (decorators, target, key, desc) {
23207
24024
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
23208
24025
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
23209
24026
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -23246,13 +24063,13 @@
23246
24063
  { type: core.ViewContainerRef },
23247
24064
  { type: AuthService }
23248
24065
  ]; };
23249
- __decorate$2a([
24066
+ __decorate$2b([
23250
24067
  core.Input()
23251
24068
  ], AuthWholesalerDirective.prototype, "ecAuthWholesalerElse", void 0);
23252
- __decorate$2a([
24069
+ __decorate$2b([
23253
24070
  core.Input()
23254
24071
  ], AuthWholesalerDirective.prototype, "ecAuthWholesaler", null);
23255
- AuthWholesalerDirective = __decorate$2a([
24072
+ AuthWholesalerDirective = __decorate$2b([
23256
24073
  core.Directive({
23257
24074
  selector: "[ecAuthWholesaler]"
23258
24075
  })
@@ -23260,7 +24077,7 @@
23260
24077
  return AuthWholesalerDirective;
23261
24078
  }());
23262
24079
 
23263
- var __decorate$2b = (this && this.__decorate) || function (decorators, target, key, desc) {
24080
+ var __decorate$2c = (this && this.__decorate) || function (decorators, target, key, desc) {
23264
24081
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
23265
24082
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
23266
24083
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -23282,10 +24099,10 @@
23282
24099
  { type: core.TemplateRef },
23283
24100
  { type: core.ViewContainerRef }
23284
24101
  ]; };
23285
- __decorate$2b([
24102
+ __decorate$2c([
23286
24103
  core.Input()
23287
24104
  ], ReloadViewDirective.prototype, "ecReloadView", void 0);
23288
- ReloadViewDirective = __decorate$2b([
24105
+ ReloadViewDirective = __decorate$2c([
23289
24106
  core.Directive({
23290
24107
  selector: '[ecReloadView]'
23291
24108
  })
@@ -23308,7 +24125,7 @@
23308
24125
  ReloadViewDirective,
23309
24126
  ];
23310
24127
 
23311
- var __decorate$2c = (this && this.__decorate) || function (decorators, target, key, desc) {
24128
+ var __decorate$2d = (this && this.__decorate) || function (decorators, target, key, desc) {
23312
24129
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
23313
24130
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
23314
24131
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -23397,7 +24214,7 @@
23397
24214
  { type: CurrencyService },
23398
24215
  { type: core.Injector }
23399
24216
  ]; };
23400
- ecCurrencySymbolPipe = __decorate$2c([
24217
+ ecCurrencySymbolPipe = __decorate$2d([
23401
24218
  core.Pipe({
23402
24219
  name: 'ecCurrencySymbol',
23403
24220
  pure: false
@@ -23406,7 +24223,7 @@
23406
24223
  return ecCurrencySymbolPipe;
23407
24224
  }());
23408
24225
 
23409
- var __decorate$2d = (this && this.__decorate) || function (decorators, target, key, desc) {
24226
+ var __decorate$2e = (this && this.__decorate) || function (decorators, target, key, desc) {
23410
24227
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
23411
24228
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
23412
24229
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -23422,7 +24239,7 @@
23422
24239
  EcSanitizerHtmlPipe.ctorParameters = function () { return [
23423
24240
  { type: platformBrowser.DomSanitizer }
23424
24241
  ]; };
23425
- EcSanitizerHtmlPipe = __decorate$2d([
24242
+ EcSanitizerHtmlPipe = __decorate$2e([
23426
24243
  core.Pipe({
23427
24244
  name: 'ecSanitizerHtml'
23428
24245
  })
@@ -23430,7 +24247,7 @@
23430
24247
  return EcSanitizerHtmlPipe;
23431
24248
  }());
23432
24249
 
23433
- var __decorate$2e = (this && this.__decorate) || function (decorators, target, key, desc) {
24250
+ var __decorate$2f = (this && this.__decorate) || function (decorators, target, key, desc) {
23434
24251
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
23435
24252
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
23436
24253
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -23446,7 +24263,7 @@
23446
24263
  EcSanitizerUrlPipe.ctorParameters = function () { return [
23447
24264
  { type: platformBrowser.DomSanitizer }
23448
24265
  ]; };
23449
- EcSanitizerUrlPipe = __decorate$2e([
24266
+ EcSanitizerUrlPipe = __decorate$2f([
23450
24267
  core.Pipe({
23451
24268
  name: 'ecSanitizerUrl'
23452
24269
  })
@@ -23461,7 +24278,7 @@
23461
24278
  EcSanitizerUrlPipe
23462
24279
  ];
23463
24280
 
23464
- var __decorate$2f = (this && this.__decorate) || function (decorators, target, key, desc) {
24281
+ var __decorate$2g = (this && this.__decorate) || function (decorators, target, key, desc) {
23465
24282
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
23466
24283
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
23467
24284
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -23548,7 +24365,7 @@
23548
24365
  };
23549
24366
  };
23550
24367
  var NgEasycommerceModule_1;
23551
- NgEasycommerceModule = NgEasycommerceModule_1 = __decorate$2f([
24368
+ NgEasycommerceModule = NgEasycommerceModule_1 = __decorate$2g([
23552
24369
  core.NgModule({
23553
24370
  exports: [
23554
24371
  OrderByPipe,
@@ -23589,7 +24406,7 @@
23589
24406
  return NgEasycommerceModule;
23590
24407
  }());
23591
24408
 
23592
- var __decorate$2g = (this && this.__decorate) || function (decorators, target, key, desc) {
24409
+ var __decorate$2h = (this && this.__decorate) || function (decorators, target, key, desc) {
23593
24410
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
23594
24411
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
23595
24412
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -23637,7 +24454,7 @@
23637
24454
  { type: ConnectionService }
23638
24455
  ]; };
23639
24456
  GiftCardService$1.ɵprov = core.ɵɵdefineInjectable({ factory: function GiftCardService_Factory() { return new GiftCardService(core.ɵɵinject(Constants), core.ɵɵinject(CartService), core.ɵɵinject(ConnectionService)); }, token: GiftCardService, providedIn: "root" });
23640
- GiftCardService$1 = __decorate$2g([
24457
+ GiftCardService$1 = __decorate$2h([
23641
24458
  core.Injectable({
23642
24459
  providedIn: 'root'
23643
24460
  })
@@ -23645,7 +24462,7 @@
23645
24462
  return GiftCardService$1;
23646
24463
  }());
23647
24464
 
23648
- var __decorate$2h = (this && this.__decorate) || function (decorators, target, key, desc) {
24465
+ var __decorate$2i = (this && this.__decorate) || function (decorators, target, key, desc) {
23649
24466
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
23650
24467
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
23651
24468
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -23701,7 +24518,7 @@
23701
24518
  { type: ngxToastr.ToastrService }
23702
24519
  ]; };
23703
24520
  WishlistService$1.ɵprov = core.ɵɵdefineInjectable({ factory: function WishlistService_Factory() { return new WishlistService(core.ɵɵinject(ngxToastr.ToastrService)); }, token: WishlistService, providedIn: "root" });
23704
- WishlistService$1 = __decorate$2h([
24521
+ WishlistService$1 = __decorate$2i([
23705
24522
  core.Injectable({
23706
24523
  providedIn: 'root'
23707
24524
  })
@@ -23709,7 +24526,7 @@
23709
24526
  return WishlistService$1;
23710
24527
  }());
23711
24528
 
23712
- var __decorate$2i = (this && this.__decorate) || function (decorators, target, key, desc) {
24529
+ var __decorate$2j = (this && this.__decorate) || function (decorators, target, key, desc) {
23713
24530
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
23714
24531
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
23715
24532
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -23744,7 +24561,7 @@
23744
24561
  StandardReuseStrategy.ctorParameters = function () { return [
23745
24562
  { type: undefined, decorators: [{ type: core.Inject, args: ['env',] }] }
23746
24563
  ]; };
23747
- StandardReuseStrategy = __decorate$2i([
24564
+ StandardReuseStrategy = __decorate$2j([
23748
24565
  core.Injectable(),
23749
24566
  __param$e(0, core.Inject('env'))
23750
24567
  ], StandardReuseStrategy);
@@ -23875,6 +24692,7 @@
23875
24692
  exports.SuccessEcComponent = SuccessEcComponent;
23876
24693
  exports.ToastCookiesEcComponent = ToastCookiesEcComponent;
23877
24694
  exports.ToastService = ToastService;
24695
+ exports.UnitPromotionPriceEcComponent = UnitPromotionPriceEcComponent;
23878
24696
  exports.User = User;
23879
24697
  exports.UserRoleGuardService = UserRoleGuardService;
23880
24698
  exports.UtilsService = UtilsService;