@fiado/type-kit 3.636.0 → 3.637.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/_test_/unit/emailVerification/dtos/internal/EmailOwnersByEmailRequest.test.ts +29 -0
  2. package/_test_/unit/retailWizard/salePayments.test.ts +43 -35
  3. package/bin/emailVerification/dtos/internal/EmailOwnersByEmailRequest.d.ts +6 -0
  4. package/bin/emailVerification/dtos/internal/EmailOwnersByEmailRequest.js +25 -0
  5. package/bin/emailVerification/index.d.ts +1 -0
  6. package/bin/emailVerification/index.js +1 -0
  7. package/bin/retailWizard/dtos/SalePayment.d.ts +4 -1
  8. package/bin/retailWizard/dtos/SalePayment.js +8 -14
  9. package/bin/retailWizard/dtos/StoredSalePayment.d.ts +13 -0
  10. package/bin/retailWizard/dtos/StoredSalePayment.js +59 -0
  11. package/bin/retailWizard/dtos/requests/CreateAccessorySaleRequest.d.ts +1 -1
  12. package/bin/retailWizard/dtos/requests/CreateAccessorySaleRequest.js +2 -2
  13. package/bin/retailWizard/dtos/requests/DownPaymentRequest.d.ts +1 -1
  14. package/bin/retailWizard/dtos/requests/DownPaymentRequest.js +2 -2
  15. package/bin/retailWizard/dtos/requests/RegisterPaymentRequest.d.ts +1 -1
  16. package/bin/retailWizard/dtos/requests/RegisterPaymentRequest.js +2 -2
  17. package/bin/retailWizard/index.d.ts +2 -0
  18. package/bin/retailWizard/index.js +2 -0
  19. package/bin/retailWizard/validators/IsSalePaymentInputList.d.ts +2 -0
  20. package/bin/retailWizard/validators/IsSalePaymentInputList.js +11 -0
  21. package/bin/retailWizard/validators/IsSalePaymentList.d.ts +1 -1
  22. package/bin/retailWizard/validators/IsSalePaymentList.js +3 -3
  23. package/package.json +1 -1
  24. package/src/emailVerification/dtos/internal/EmailOwnersByEmailRequest.ts +11 -0
  25. package/src/emailVerification/index.ts +1 -0
  26. package/src/retailWizard/dtos/SalePayment.ts +9 -20
  27. package/src/retailWizard/dtos/StoredSalePayment.ts +46 -0
  28. package/src/retailWizard/dtos/requests/CreateAccessorySaleRequest.ts +3 -3
  29. package/src/retailWizard/dtos/requests/DownPaymentRequest.ts +3 -3
  30. package/src/retailWizard/dtos/requests/RegisterPaymentRequest.ts +3 -3
  31. package/src/retailWizard/index.ts +2 -0
  32. package/src/retailWizard/validators/IsSalePaymentInputList.ts +9 -0
  33. package/src/retailWizard/validators/IsSalePaymentList.ts +3 -3
@@ -0,0 +1,29 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validate } from 'class-validator';
4
+ import { EmailOwnersByEmailRequest } from '../../../../../src/emailVerification/dtos/internal/EmailOwnersByEmailRequest';
5
+ import * as emailVerification from '../../../../../src/emailVerification';
6
+
7
+ describe('EmailOwnersByEmailRequest', () => {
8
+ it('valida happy path (0 errores)', async () => {
9
+ const dto = plainToInstance(EmailOwnersByEmailRequest, { email: 'persona@ejemplo.com' });
10
+ const errors = await validate(dto);
11
+ expect(errors).toEqual([]);
12
+ });
13
+
14
+ it('falla si email no es un correo válido', async () => {
15
+ const dto = plainToInstance(EmailOwnersByEmailRequest, { email: 'no-es-correo' });
16
+ const errors = await validate(dto);
17
+ expect(errors.some(e => e.property === 'email')).toBe(true);
18
+ });
19
+
20
+ it('falla si falta email', async () => {
21
+ const dto = plainToInstance(EmailOwnersByEmailRequest, {});
22
+ const errors = await validate(dto);
23
+ expect(errors.some(e => e.property === 'email')).toBe(true);
24
+ });
25
+
26
+ it('se exporta desde el barrel de emailVerification', () => {
27
+ expect(emailVerification.EmailOwnersByEmailRequest).toBe(EmailOwnersByEmailRequest);
28
+ });
29
+ });
@@ -3,6 +3,7 @@ import { plainToInstance } from 'class-transformer';
3
3
  import { validateSync, type ValidationError } from 'class-validator';
4
4
  import { SalePayment } from '../../../src/retailWizard/dtos/SalePayment';
5
5
  import { WizardPayment } from '../../../src/retailWizard/dtos/WizardPayment';
6
+ import { StoredSalePayment } from '../../../src/retailWizard/dtos/StoredSalePayment';
6
7
  import { RegisterPaymentRequest } from '../../../src/retailWizard/dtos/requests/RegisterPaymentRequest';
7
8
  import { DownPaymentRequest } from '../../../src/retailWizard/dtos/requests/DownPaymentRequest';
8
9
  import { CreateAccessorySaleRequest } from '../../../src/retailWizard/dtos/requests/CreateAccessorySaleRequest';
@@ -28,17 +29,32 @@ const cash = { method: CASH, amountCents: 10000, cashConfirmedInRegister: true }
28
29
  const card = { method: CARD, amountCents: 5000, cardLast4: '4242', authCode: 'A1B2C3' };
29
30
  const wire = { method: WIRE, amountCents: 5000, speiTrackingKey: 'MBAN01002610', senderClabe: '012180001234567897' };
30
31
 
31
- describe('SalePayment', () => {
32
+ describe('SalePayment (forma del request)', () => {
33
+ it('acepta cualquier monto entero y comprobante en texto, sin revisar formato ni medio', () => {
34
+ expect(errorsOf(SalePayment, { method: CARD, amountCents: 0, cardLast4: '1', authCode: ' ' })).toEqual([]);
35
+ expect(errorsOf(SalePayment, { method: CASH, amountCents: -5, speiTrackingKey: 'MBAN-01' })).toEqual([]);
36
+ expect(errorsOf(SalePayment, { method: WIRE, amountCents: 1, senderClabe: null, cashConfirmedInRegister: null })).toEqual([]);
37
+ });
38
+
39
+ it('rechaza lo que no tiene la forma', () => {
40
+ expect(errorsOf(SalePayment, { method: 'FIADO', amountCents: 1 })).toEqual(['method']);
41
+ expect(errorsOf(SalePayment, { method: CASH, amountCents: 1.5 })).toEqual(['amountCents']);
42
+ expect(errorsOf(SalePayment, { method: CARD, amountCents: 1, cardLast4: 4242 })).toEqual(['cardLast4']);
43
+ expect(errorsOf(SalePayment, { method: CASH, amountCents: 1, cashConfirmedInRegister: 'yes' })).toEqual(['cashConfirmedInRegister']);
44
+ });
45
+ });
46
+
47
+ describe('StoredSalePayment (cobro ya registrado)', () => {
32
48
  it('acepta cada medio con comprobante', () => {
33
- expect(errorsOf(SalePayment, cash)).toEqual([]);
34
- expect(errorsOf(SalePayment, card)).toEqual([]);
35
- expect(errorsOf(SalePayment, wire)).toEqual([]);
49
+ expect(errorsOf(StoredSalePayment, cash)).toEqual([]);
50
+ expect(errorsOf(StoredSalePayment, card)).toEqual([]);
51
+ expect(errorsOf(StoredSalePayment, wire)).toEqual([]);
36
52
  });
37
53
 
38
54
  it('acepta tarjeta y SPEI sin comprobante, ausente o en null', () => {
39
- expect(errorsOf(SalePayment, { method: CARD, amountCents: 5000 })).toEqual([]);
40
- expect(errorsOf(SalePayment, { method: WIRE, amountCents: 5000, speiTrackingKey: null, senderClabe: null })).toEqual([]);
41
- expect(errorsOf(SalePayment, { method: CASH, amountCents: 5000, cashConfirmedInRegister: null })).toEqual([]);
55
+ expect(errorsOf(StoredSalePayment, { method: CARD, amountCents: 5000 })).toEqual([]);
56
+ expect(errorsOf(StoredSalePayment, { method: WIRE, amountCents: 5000, speiTrackingKey: null, senderClabe: null })).toEqual([]);
57
+ expect(errorsOf(StoredSalePayment, { method: CASH, amountCents: 5000, cashConfirmedInRegister: null })).toEqual([]);
42
58
  });
43
59
 
44
60
  it.each([
@@ -49,7 +65,7 @@ describe('SalePayment', () => {
49
65
  ['senderClabe', { ...wire, senderClabe: '0121' }],
50
66
  ['cashConfirmedInRegister', { ...cash, cashConfirmedInRegister: 'yes' }],
51
67
  ])('rechaza %s con formato inválido', (field, payload) => {
52
- expect(errorsOf(SalePayment, payload)).toEqual([field]);
68
+ expect(errorsOf(StoredSalePayment, payload)).toEqual([field]);
53
69
  });
54
70
 
55
71
  it.each([
@@ -57,13 +73,13 @@ describe('SalePayment', () => {
57
73
  ['speiTrackingKey', { ...card, speiTrackingKey: 'MBAN01' }],
58
74
  ['cashConfirmedInRegister', { ...wire, cashConfirmedInRegister: true }],
59
75
  ])('rechaza %s en un medio que no le corresponde', (field, payload) => {
60
- expect(errorsOf(SalePayment, payload)).toEqual([field]);
76
+ expect(errorsOf(StoredSalePayment, payload)).toEqual([field]);
61
77
  });
62
78
 
63
79
  it('rechaza un medio fuera del enum y un monto no positivo', () => {
64
- expect(errorsOf(SalePayment, { method: 'FIADO', amountCents: 100 })).toEqual(['method']);
65
- expect(errorsOf(SalePayment, { ...cash, amountCents: 0 })).toEqual(['amountCents']);
66
- expect(errorsOf(SalePayment, { ...cash, amountCents: 10.5 })).toEqual(['amountCents']);
80
+ expect(errorsOf(StoredSalePayment, { method: 'FIADO', amountCents: 100 })).toEqual(['method']);
81
+ expect(errorsOf(StoredSalePayment, { ...cash, amountCents: 0 })).toEqual(['amountCents']);
82
+ expect(errorsOf(StoredSalePayment, { ...cash, amountCents: 10.5 })).toEqual(['amountCents']);
67
83
  });
68
84
  });
69
85
 
@@ -72,10 +88,6 @@ describe('payments en RegisterPaymentRequest', () => {
72
88
  expect(errorsOf(RegisterPaymentRequest, { amountCents: 20000, payments: [cash, card, wire] })).toEqual([]);
73
89
  });
74
90
 
75
- it('acepta tarjeta repetida', () => {
76
- expect(errorsOf(RegisterPaymentRequest, { amountCents: 20000, payments: [cash, card, card] })).toEqual([]);
77
- });
78
-
79
91
  it('sigue aceptando el formato viejo', () => {
80
92
  expect(errorsOf(RegisterPaymentRequest, { method: CASH, amountCents: 20000, detail: { cashConfirmedInRegister: true } })).toEqual([]);
81
93
  });
@@ -84,24 +96,17 @@ describe('payments en RegisterPaymentRequest', () => {
84
96
  expect(errorsOf(RegisterPaymentRequest, { amountCents: 20000 })).toEqual(['method']);
85
97
  });
86
98
 
87
- it('rechaza efectivo o SPEI repetidos', () => {
88
- expect(errorsOf(RegisterPaymentRequest, { amountCents: 20000, payments: [cash, cash] })).toEqual(['payments']);
89
- expect(errorsOf(RegisterPaymentRequest, { amountCents: 10000, payments: [wire, wire] })).toEqual(['payments']);
90
- });
91
-
92
- it(`rechaza más de ${MAX_SALE_PAYMENTS} pagos o una lista vacía`, () => {
93
- expect(errorsOf(RegisterPaymentRequest, { amountCents: 25000, payments: [cash, card, card, wire] })).toEqual(['payments']);
94
- expect(errorsOf(RegisterPaymentRequest, { amountCents: 0, payments: [] })).toEqual(['payments']);
95
- });
96
-
97
- it('rechaza que la suma no cuadre con amountCents', () => {
98
- expect(errorsOf(RegisterPaymentRequest, { amountCents: 20001, payments: [cash, card, wire] })).toEqual(['payments']);
99
+ it('deja pasar las reglas de negocio para que el dominio responda con su code', () => {
100
+ expect(errorsOf(RegisterPaymentRequest, { amountCents: 20000, payments: [cash, cash] })).toEqual([]);
101
+ expect(errorsOf(RegisterPaymentRequest, { amountCents: 25000, payments: [cash, card, card, wire] })).toEqual([]);
102
+ expect(errorsOf(RegisterPaymentRequest, { amountCents: 0, payments: [] })).toEqual([]);
103
+ expect(errorsOf(RegisterPaymentRequest, { amountCents: 20001, payments: [cash, card, wire] })).toEqual([]);
104
+ expect(errorsOf(RegisterPaymentRequest, { amountCents: 15000, payments: [cash, { ...card, cardLast4: '1' }] })).toEqual([]);
99
105
  });
100
106
 
101
- it('reporta el campo del pago inválido', () => {
102
- expect(errorsOf(RegisterPaymentRequest, { amountCents: 15000, payments: [cash, { ...card, cardLast4: '1' }] })).toEqual([
103
- 'payments.1.cardLast4',
104
- ]);
107
+ it('rechaza lo que no tiene la forma y reporta el campo', () => {
108
+ expect(errorsOf(RegisterPaymentRequest, { amountCents: 1, payments: 'CASH' })).toEqual(['payments']);
109
+ expect(errorsOf(RegisterPaymentRequest, { amountCents: 1, payments: [{ ...card, method: 'FIADO' }] })).toEqual(['payments.0.method']);
105
110
  });
106
111
  });
107
112
 
@@ -135,16 +140,18 @@ describe('cobro de $0', () => {
135
140
  });
136
141
 
137
142
  describe('payments en los demás contratos', () => {
138
- it('DownPaymentRequest acepta solo payments y valida la suma', () => {
143
+ it('DownPaymentRequest acepta solo payments y deja la suma al dominio', () => {
139
144
  expect(errorsOf(DownPaymentRequest, { amountCents: 15000, payments: [cash, wire] })).toEqual([]);
140
- expect(errorsOf(DownPaymentRequest, { amountCents: 1, payments: [cash, wire] })).toEqual(['payments']);
145
+ expect(errorsOf(DownPaymentRequest, { amountCents: 1, payments: [cash, wire] })).toEqual([]);
146
+ expect(errorsOf(DownPaymentRequest, { amountCents: 1, payments: [{ ...wire, amountCents: 'x' }] })).toEqual(['payments.0.amountCents']);
141
147
  });
142
148
 
143
149
  it('CreateAccessorySaleRequest acepta solo payments y ya no exige paymentDetail', () => {
144
150
  const lines = [{ sku: 'ACC-1', qty: 1 }];
145
151
  expect(errorsOf(CreateAccessorySaleRequest, { lines, amountCents: 15000, payments: [cash, card] })).toEqual([]);
146
152
  expect(errorsOf(CreateAccessorySaleRequest, { lines, amountCents: 15000 })).toEqual(['paymentMethod']);
147
- expect(errorsOf(CreateAccessorySaleRequest, { lines, amountCents: 20000, payments: [cash, cash] })).toEqual(['payments']);
153
+ expect(errorsOf(CreateAccessorySaleRequest, { lines, amountCents: 20000, payments: [cash, cash] })).toEqual([]);
154
+ expect(errorsOf(CreateAccessorySaleRequest, { lines, amountCents: 1, payments: [{ ...card, authCode: 7 }] })).toEqual(['payments.0.authCode']);
148
155
  });
149
156
 
150
157
  it('WizardPayment guarda payments tipados', () => {
@@ -152,6 +159,7 @@ describe('payments en los demás contratos', () => {
152
159
  expect(errorsOf(WizardPayment, { ...base, payments: [cash, card] })).toEqual([]);
153
160
  expect(errorsOf(WizardPayment, base)).toEqual([]);
154
161
  expect(errorsOf(WizardPayment, { ...base, payments: [cash, cash] })).toEqual(['payments']);
162
+ expect(errorsOf(WizardPayment, { ...base, payments: [{ ...card, cardLast4: '1' }] })).toEqual(['payments.0.cardLast4']);
155
163
  });
156
164
 
157
165
  it('RetailPromotionInboundMessage acepta paymentMethods y rechaza valores fuera del enum', () => {
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Request interno (api-invoker) para buscar qué directorios tienen un correo.
3
+ */
4
+ export declare class EmailOwnersByEmailRequest {
5
+ email: string;
6
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.EmailOwnersByEmailRequest = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ /**
16
+ * Request interno (api-invoker) para buscar qué directorios tienen un correo.
17
+ */
18
+ class EmailOwnersByEmailRequest {
19
+ }
20
+ exports.EmailOwnersByEmailRequest = EmailOwnersByEmailRequest;
21
+ __decorate([
22
+ (0, class_transformer_1.Expose)(),
23
+ (0, class_validator_1.IsEmail)(),
24
+ __metadata("design:type", String)
25
+ ], EmailOwnersByEmailRequest.prototype, "email", void 0);
@@ -24,3 +24,4 @@ export * from './dtos/internal/EmailsByDirectoryRequest';
24
24
  export * from './dtos/internal/EmailsByDirectoryResponse';
25
25
  export * from './dtos/internal/EmailStartByDirectoryRequest';
26
26
  export * from './dtos/internal/EmailStartByDirectoryResponse';
27
+ export * from './dtos/internal/EmailOwnersByEmailRequest';
@@ -40,3 +40,4 @@ __exportStar(require("./dtos/internal/EmailsByDirectoryRequest"), exports);
40
40
  __exportStar(require("./dtos/internal/EmailsByDirectoryResponse"), exports);
41
41
  __exportStar(require("./dtos/internal/EmailStartByDirectoryRequest"), exports);
42
42
  __exportStar(require("./dtos/internal/EmailStartByDirectoryResponse"), exports);
43
+ __exportStar(require("./dtos/internal/EmailOwnersByEmailRequest"), exports);
@@ -1,5 +1,8 @@
1
1
  import { SalePaymentMethodEnum } from '../enums/SalePaymentMethodEnum';
2
- /** Un pago del cobro. El comprobante es opcional: si viene se valida y solo en su medio; si no, `null` o ausente. */
2
+ /**
3
+ * Un pago del cobro tal como llega en un request: solo la forma. Tope, uso único, suma, monto
4
+ * positivo y formato del comprobante los valida el dominio con su code.
5
+ */
3
6
  export declare class SalePayment {
4
7
  method: SalePaymentMethodEnum;
5
8
  amountCents: number;
@@ -12,12 +12,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.SalePayment = void 0;
13
13
  const class_transformer_1 = require("class-transformer");
14
14
  const class_validator_1 = require("class-validator");
15
- const retailIntegrationLimits_1 = require("../../retailIntegration/constants/retailIntegrationLimits");
16
15
  const SalePaymentMethodEnum_1 = require("../enums/SalePaymentMethodEnum");
17
- const OnlyForPaymentMethodConstraint_1 = require("../validators/OnlyForPaymentMethodConstraint");
18
- const { CASH, CARD, WIRE } = SalePaymentMethodEnum_1.SalePaymentMethodEnum;
19
16
  const hasValue = (field) => (o) => o[field] != null;
20
- /** Un pago del cobro. El comprobante es opcional: si viene se valida y solo en su medio; si no, `null` o ausente. */
17
+ /**
18
+ * Un pago del cobro tal como llega en un request: solo la forma. Tope, uso único, suma, monto
19
+ * positivo y formato del comprobante los valida el dominio con su code.
20
+ */
21
21
  class SalePayment {
22
22
  }
23
23
  exports.SalePayment = SalePayment;
@@ -29,41 +29,35 @@ __decorate([
29
29
  __decorate([
30
30
  (0, class_transformer_1.Expose)(),
31
31
  (0, class_validator_1.IsInt)(),
32
- (0, class_validator_1.Min)(1),
33
32
  __metadata("design:type", Number)
34
33
  ], SalePayment.prototype, "amountCents", void 0);
35
34
  __decorate([
36
35
  (0, class_transformer_1.Expose)(),
37
36
  (0, class_validator_1.ValidateIf)(hasValue('cashConfirmedInRegister')),
38
37
  (0, class_validator_1.IsBoolean)(),
39
- (0, class_validator_1.Validate)(OnlyForPaymentMethodConstraint_1.OnlyForPaymentMethodConstraint, [CASH]),
40
38
  __metadata("design:type", Boolean)
41
39
  ], SalePayment.prototype, "cashConfirmedInRegister", void 0);
42
40
  __decorate([
43
41
  (0, class_transformer_1.Expose)(),
44
42
  (0, class_validator_1.ValidateIf)(hasValue('cardLast4')),
45
- (0, class_validator_1.Matches)(retailIntegrationLimits_1.RETAIL_CARD_LAST4_PATTERN),
46
- (0, class_validator_1.Validate)(OnlyForPaymentMethodConstraint_1.OnlyForPaymentMethodConstraint, [CARD]),
43
+ (0, class_validator_1.IsString)(),
47
44
  __metadata("design:type", String)
48
45
  ], SalePayment.prototype, "cardLast4", void 0);
49
46
  __decorate([
50
47
  (0, class_transformer_1.Expose)(),
51
48
  (0, class_validator_1.ValidateIf)(hasValue('authCode')),
52
- (0, class_validator_1.Matches)(retailIntegrationLimits_1.RETAIL_SALE_ID_TEXT_PATTERN),
53
- (0, class_validator_1.Validate)(OnlyForPaymentMethodConstraint_1.OnlyForPaymentMethodConstraint, [CARD]),
49
+ (0, class_validator_1.IsString)(),
54
50
  __metadata("design:type", String)
55
51
  ], SalePayment.prototype, "authCode", void 0);
56
52
  __decorate([
57
53
  (0, class_transformer_1.Expose)(),
58
54
  (0, class_validator_1.ValidateIf)(hasValue('speiTrackingKey')),
59
- (0, class_validator_1.Matches)(retailIntegrationLimits_1.RETAIL_SPEI_TRACKING_KEY_PATTERN),
60
- (0, class_validator_1.Validate)(OnlyForPaymentMethodConstraint_1.OnlyForPaymentMethodConstraint, [WIRE]),
55
+ (0, class_validator_1.IsString)(),
61
56
  __metadata("design:type", String)
62
57
  ], SalePayment.prototype, "speiTrackingKey", void 0);
63
58
  __decorate([
64
59
  (0, class_transformer_1.Expose)(),
65
60
  (0, class_validator_1.ValidateIf)(hasValue('senderClabe')),
66
- (0, class_validator_1.Matches)(retailIntegrationLimits_1.RETAIL_CLABE_PATTERN),
67
- (0, class_validator_1.Validate)(OnlyForPaymentMethodConstraint_1.OnlyForPaymentMethodConstraint, [WIRE]),
61
+ (0, class_validator_1.IsString)(),
68
62
  __metadata("design:type", String)
69
63
  ], SalePayment.prototype, "senderClabe", void 0);
@@ -0,0 +1,13 @@
1
+ import { SalePayment } from './SalePayment';
2
+ /**
3
+ * Pago ya registrado (cobro de la sesión): monto positivo y comprobante con formato, solo en su medio.
4
+ * Repite las reglas de forma porque class-validator descarta las del padre en la propiedad que se redeclara.
5
+ */
6
+ export declare class StoredSalePayment extends SalePayment {
7
+ amountCents: number;
8
+ cashConfirmedInRegister?: boolean | null;
9
+ cardLast4?: string | null;
10
+ authCode?: string | null;
11
+ speiTrackingKey?: string | null;
12
+ senderClabe?: string | null;
13
+ }
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.StoredSalePayment = void 0;
13
+ const class_validator_1 = require("class-validator");
14
+ const retailIntegrationLimits_1 = require("../../retailIntegration/constants/retailIntegrationLimits");
15
+ const SalePaymentMethodEnum_1 = require("../enums/SalePaymentMethodEnum");
16
+ const OnlyForPaymentMethodConstraint_1 = require("../validators/OnlyForPaymentMethodConstraint");
17
+ const SalePayment_1 = require("./SalePayment");
18
+ const { CASH, CARD, WIRE } = SalePaymentMethodEnum_1.SalePaymentMethodEnum;
19
+ /**
20
+ * Pago ya registrado (cobro de la sesión): monto positivo y comprobante con formato, solo en su medio.
21
+ * Repite las reglas de forma porque class-validator descarta las del padre en la propiedad que se redeclara.
22
+ */
23
+ class StoredSalePayment extends SalePayment_1.SalePayment {
24
+ }
25
+ exports.StoredSalePayment = StoredSalePayment;
26
+ __decorate([
27
+ (0, class_validator_1.IsInt)(),
28
+ (0, class_validator_1.Min)(1),
29
+ __metadata("design:type", Number)
30
+ ], StoredSalePayment.prototype, "amountCents", void 0);
31
+ __decorate([
32
+ (0, class_validator_1.IsBoolean)(),
33
+ (0, class_validator_1.Validate)(OnlyForPaymentMethodConstraint_1.OnlyForPaymentMethodConstraint, [CASH]),
34
+ __metadata("design:type", Boolean)
35
+ ], StoredSalePayment.prototype, "cashConfirmedInRegister", void 0);
36
+ __decorate([
37
+ (0, class_validator_1.IsString)(),
38
+ (0, class_validator_1.Matches)(retailIntegrationLimits_1.RETAIL_CARD_LAST4_PATTERN),
39
+ (0, class_validator_1.Validate)(OnlyForPaymentMethodConstraint_1.OnlyForPaymentMethodConstraint, [CARD]),
40
+ __metadata("design:type", String)
41
+ ], StoredSalePayment.prototype, "cardLast4", void 0);
42
+ __decorate([
43
+ (0, class_validator_1.IsString)(),
44
+ (0, class_validator_1.Matches)(retailIntegrationLimits_1.RETAIL_SALE_ID_TEXT_PATTERN),
45
+ (0, class_validator_1.Validate)(OnlyForPaymentMethodConstraint_1.OnlyForPaymentMethodConstraint, [CARD]),
46
+ __metadata("design:type", String)
47
+ ], StoredSalePayment.prototype, "authCode", void 0);
48
+ __decorate([
49
+ (0, class_validator_1.IsString)(),
50
+ (0, class_validator_1.Matches)(retailIntegrationLimits_1.RETAIL_SPEI_TRACKING_KEY_PATTERN),
51
+ (0, class_validator_1.Validate)(OnlyForPaymentMethodConstraint_1.OnlyForPaymentMethodConstraint, [WIRE]),
52
+ __metadata("design:type", String)
53
+ ], StoredSalePayment.prototype, "speiTrackingKey", void 0);
54
+ __decorate([
55
+ (0, class_validator_1.IsString)(),
56
+ (0, class_validator_1.Matches)(retailIntegrationLimits_1.RETAIL_CLABE_PATTERN),
57
+ (0, class_validator_1.Validate)(OnlyForPaymentMethodConstraint_1.OnlyForPaymentMethodConstraint, [WIRE]),
58
+ __metadata("design:type", String)
59
+ ], StoredSalePayment.prototype, "senderClabe", void 0);
@@ -13,6 +13,6 @@ export declare class CreateAccessorySaleRequest {
13
13
  amountCents: number;
14
14
  /** @deprecated Usa el comprobante de cada elemento de `payments`. */
15
15
  paymentDetail?: SalePaymentDetail;
16
- /** Pagos del cobro (1 a 3); si viene, manda sobre `paymentMethod` y `paymentDetail`. */
16
+ /** Pagos del cobro; si viene, manda sobre `paymentMethod` y `paymentDetail`. */
17
17
  payments?: SalePayment[];
18
18
  }
@@ -15,7 +15,7 @@ const class_validator_1 = require("class-validator");
15
15
  const SalePaymentMethodEnum_1 = require("../../enums/SalePaymentMethodEnum");
16
16
  const SalePaymentDetail_1 = require("../SalePaymentDetail");
17
17
  const AccessorySaleLine_1 = require("../AccessorySaleLine");
18
- const IsSalePaymentList_1 = require("../../validators/IsSalePaymentList");
18
+ const IsSalePaymentInputList_1 = require("../../validators/IsSalePaymentInputList");
19
19
  /**
20
20
  * POST /wizard/accessory-sales — cierra la venta de mostrador, sin cliente.
21
21
  * `amountCents` es lo cobrado en caja: iguala la suma del catálogo y la de `payments`.
@@ -54,6 +54,6 @@ __decorate([
54
54
  __decorate([
55
55
  (0, class_transformer_1.Expose)(),
56
56
  (0, class_validator_1.IsOptional)(),
57
- (0, IsSalePaymentList_1.IsSalePaymentList)(),
57
+ (0, IsSalePaymentInputList_1.IsSalePaymentInputList)(),
58
58
  __metadata("design:type", Array)
59
59
  ], CreateAccessorySaleRequest.prototype, "payments", void 0);
@@ -16,6 +16,6 @@ export declare class DownPaymentRequest {
16
16
  amountCents: number;
17
17
  /** @deprecated Usa el comprobante de cada elemento de `payments`. */
18
18
  detail?: SalePaymentDetail;
19
- /** Pagos del cobro (1 a 3); si viene, manda sobre `method` y `detail`. */
19
+ /** Pagos del cobro; si viene, manda sobre `method` y `detail`. */
20
20
  payments?: SalePayment[];
21
21
  }
@@ -14,7 +14,7 @@ const class_transformer_1 = require("class-transformer");
14
14
  const class_validator_1 = require("class-validator");
15
15
  const SalePaymentMethodEnum_1 = require("../../enums/SalePaymentMethodEnum");
16
16
  const SalePaymentDetail_1 = require("../SalePaymentDetail");
17
- const IsSalePaymentList_1 = require("../../validators/IsSalePaymentList");
17
+ const IsSalePaymentInputList_1 = require("../../validators/IsSalePaymentInputList");
18
18
  /**
19
19
  * POST /wizard/sessions/:id/down-payment — cobro del ENGANCHE de la venta a crédito (paso 07,
20
20
  * pista SOFOM). Endpoint propio, separado del cobro de contado (`/payment`): acá la regla dura es
@@ -49,6 +49,6 @@ __decorate([
49
49
  __decorate([
50
50
  (0, class_transformer_1.Expose)(),
51
51
  (0, class_validator_1.IsOptional)(),
52
- (0, IsSalePaymentList_1.IsSalePaymentList)(),
52
+ (0, IsSalePaymentInputList_1.IsSalePaymentInputList)(),
53
53
  __metadata("design:type", Array)
54
54
  ], DownPaymentRequest.prototype, "payments", void 0);
@@ -12,6 +12,6 @@ export declare class RegisterPaymentRequest {
12
12
  amountCents: number;
13
13
  /** @deprecated Usa el comprobante de cada elemento de `payments`. */
14
14
  detail?: SalePaymentDetail;
15
- /** Pagos del cobro (1 a 3); si viene, manda sobre `method` y `detail`. */
15
+ /** Pagos del cobro; si viene, manda sobre `method` y `detail`. */
16
16
  payments?: SalePayment[];
17
17
  }
@@ -14,7 +14,7 @@ const class_transformer_1 = require("class-transformer");
14
14
  const class_validator_1 = require("class-validator");
15
15
  const SalePaymentMethodEnum_1 = require("../../enums/SalePaymentMethodEnum");
16
16
  const SalePaymentDetail_1 = require("../SalePaymentDetail");
17
- const IsSalePaymentList_1 = require("../../validators/IsSalePaymentList");
17
+ const IsSalePaymentInputList_1 = require("../../validators/IsSalePaymentInputList");
18
18
  /**
19
19
  * POST /wizard/sessions/:id/payment — registra el cobro de contado (idempotente por sesión). Regla
20
20
  * dura: `amountCents == cashPrice` de la reserva. `POST /payment/folio` genera el folio server-side
@@ -45,6 +45,6 @@ __decorate([
45
45
  __decorate([
46
46
  (0, class_transformer_1.Expose)(),
47
47
  (0, class_validator_1.IsOptional)(),
48
- (0, IsSalePaymentList_1.IsSalePaymentList)(),
48
+ (0, IsSalePaymentInputList_1.IsSalePaymentInputList)(),
49
49
  __metadata("design:type", Array)
50
50
  ], RegisterPaymentRequest.prototype, "payments", void 0);
@@ -41,6 +41,8 @@ export * from './dtos/WizardWelcome';
41
41
  export * from './dtos/WizardCreditPromotionBonus';
42
42
  export * from './dtos/SalePaymentDetail';
43
43
  export * from './dtos/SalePayment';
44
+ export * from './dtos/StoredSalePayment';
45
+ export * from './validators/IsSalePaymentInputList';
44
46
  export * from './validators/IsSalePaymentList';
45
47
  export * from './validators/OnlyForPaymentMethodConstraint';
46
48
  export * from './validators/PaymentsHaveSingleUseMethodsConstraint';
@@ -61,6 +61,8 @@ __exportStar(require("./dtos/WizardWelcome"), exports);
61
61
  __exportStar(require("./dtos/WizardCreditPromotionBonus"), exports);
62
62
  __exportStar(require("./dtos/SalePaymentDetail"), exports);
63
63
  __exportStar(require("./dtos/SalePayment"), exports);
64
+ __exportStar(require("./dtos/StoredSalePayment"), exports);
65
+ __exportStar(require("./validators/IsSalePaymentInputList"), exports);
64
66
  __exportStar(require("./validators/IsSalePaymentList"), exports);
65
67
  __exportStar(require("./validators/OnlyForPaymentMethodConstraint"), exports);
66
68
  __exportStar(require("./validators/PaymentsHaveSingleUseMethodsConstraint"), exports);
@@ -0,0 +1,2 @@
1
+ /** Forma de `payments` en un request: arreglo de pagos bien tipados. Las reglas de negocio las valida el dominio. */
2
+ export declare function IsSalePaymentInputList(): PropertyDecorator;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IsSalePaymentInputList = IsSalePaymentInputList;
4
+ const class_transformer_1 = require("class-transformer");
5
+ const class_validator_1 = require("class-validator");
6
+ const SalePayment_1 = require("../dtos/SalePayment");
7
+ /** Forma de `payments` en un request: arreglo de pagos bien tipados. Las reglas de negocio las valida el dominio. */
8
+ function IsSalePaymentInputList() {
9
+ const decorators = [(0, class_validator_1.IsArray)(), (0, class_validator_1.ValidateNested)({ each: true }), (0, class_transformer_1.Type)(() => SalePayment_1.SalePayment)];
10
+ return (target, propertyKey) => decorators.forEach((decorate) => decorate(target, propertyKey));
11
+ }
@@ -1,2 +1,2 @@
1
- /** Reglas de `payments`: 1 a 3 pagos válidos, efectivo y SPEI una vez, y la suma igual a `amountCents`. */
1
+ /** Reglas de `payments` ya registrados (cobro de la sesión): 1 a 3 pagos válidos, efectivo y SPEI una vez, y la suma igual a `amountCents`. */
2
2
  export declare function IsSalePaymentList(): PropertyDecorator;
@@ -4,17 +4,17 @@ exports.IsSalePaymentList = IsSalePaymentList;
4
4
  const class_transformer_1 = require("class-transformer");
5
5
  const class_validator_1 = require("class-validator");
6
6
  const retailWizardValidation_1 = require("../constants/retailWizardValidation");
7
- const SalePayment_1 = require("../dtos/SalePayment");
7
+ const StoredSalePayment_1 = require("../dtos/StoredSalePayment");
8
8
  const PaymentsHaveSingleUseMethodsConstraint_1 = require("./PaymentsHaveSingleUseMethodsConstraint");
9
9
  const PaymentsMatchAmountCentsConstraint_1 = require("./PaymentsMatchAmountCentsConstraint");
10
- /** Reglas de `payments`: 1 a 3 pagos válidos, efectivo y SPEI una vez, y la suma igual a `amountCents`. */
10
+ /** Reglas de `payments` ya registrados (cobro de la sesión): 1 a 3 pagos válidos, efectivo y SPEI una vez, y la suma igual a `amountCents`. */
11
11
  function IsSalePaymentList() {
12
12
  const decorators = [
13
13
  (0, class_validator_1.IsArray)(),
14
14
  (0, class_validator_1.ArrayMinSize)(1),
15
15
  (0, class_validator_1.ArrayMaxSize)(retailWizardValidation_1.MAX_SALE_PAYMENTS),
16
16
  (0, class_validator_1.ValidateNested)({ each: true }),
17
- (0, class_transformer_1.Type)(() => SalePayment_1.SalePayment),
17
+ (0, class_transformer_1.Type)(() => StoredSalePayment_1.StoredSalePayment),
18
18
  (0, class_validator_1.Validate)(PaymentsHaveSingleUseMethodsConstraint_1.PaymentsHaveSingleUseMethodsConstraint),
19
19
  (0, class_validator_1.Validate)(PaymentsMatchAmountCentsConstraint_1.PaymentsMatchAmountCentsConstraint),
20
20
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/type-kit",
3
- "version": "3.636.0",
3
+ "version": "3.637.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",
@@ -0,0 +1,11 @@
1
+ import { Expose } from 'class-transformer';
2
+ import { IsEmail } from 'class-validator';
3
+
4
+ /**
5
+ * Request interno (api-invoker) para buscar qué directorios tienen un correo.
6
+ */
7
+ export class EmailOwnersByEmailRequest {
8
+ @Expose()
9
+ @IsEmail()
10
+ email!: string;
11
+ }
@@ -24,3 +24,4 @@ export * from './dtos/internal/EmailsByDirectoryRequest';
24
24
  export * from './dtos/internal/EmailsByDirectoryResponse';
25
25
  export * from './dtos/internal/EmailStartByDirectoryRequest';
26
26
  export * from './dtos/internal/EmailStartByDirectoryResponse';
27
+ export * from './dtos/internal/EmailOwnersByEmailRequest';
@@ -1,18 +1,13 @@
1
1
  import { Expose } from 'class-transformer';
2
- import { IsBoolean, IsEnum, IsInt, Matches, Min, Validate, ValidateIf } from 'class-validator';
3
- import {
4
- RETAIL_CARD_LAST4_PATTERN,
5
- RETAIL_CLABE_PATTERN,
6
- RETAIL_SALE_ID_TEXT_PATTERN,
7
- RETAIL_SPEI_TRACKING_KEY_PATTERN,
8
- } from '../../retailIntegration/constants/retailIntegrationLimits';
2
+ import { IsBoolean, IsEnum, IsInt, IsString, ValidateIf } from 'class-validator';
9
3
  import { SalePaymentMethodEnum } from '../enums/SalePaymentMethodEnum';
10
- import { OnlyForPaymentMethodConstraint } from '../validators/OnlyForPaymentMethodConstraint';
11
4
 
12
- const { CASH, CARD, WIRE } = SalePaymentMethodEnum;
13
5
  const hasValue = (field: keyof SalePayment) => (o: SalePayment) => o[field] != null;
14
6
 
15
- /** Un pago del cobro. El comprobante es opcional: si viene se valida y solo en su medio; si no, `null` o ausente. */
7
+ /**
8
+ * Un pago del cobro tal como llega en un request: solo la forma. Tope, uso único, suma, monto
9
+ * positivo y formato del comprobante los valida el dominio con su code.
10
+ */
16
11
  export class SalePayment {
17
12
  @Expose()
18
13
  @IsEnum(SalePaymentMethodEnum)
@@ -20,36 +15,30 @@ export class SalePayment {
20
15
 
21
16
  @Expose()
22
17
  @IsInt()
23
- @Min(1)
24
18
  amountCents!: number;
25
19
 
26
20
  @Expose()
27
21
  @ValidateIf(hasValue('cashConfirmedInRegister'))
28
22
  @IsBoolean()
29
- @Validate(OnlyForPaymentMethodConstraint, [CASH])
30
23
  cashConfirmedInRegister?: boolean | null;
31
24
 
32
25
  @Expose()
33
26
  @ValidateIf(hasValue('cardLast4'))
34
- @Matches(RETAIL_CARD_LAST4_PATTERN)
35
- @Validate(OnlyForPaymentMethodConstraint, [CARD])
27
+ @IsString()
36
28
  cardLast4?: string | null;
37
29
 
38
30
  @Expose()
39
31
  @ValidateIf(hasValue('authCode'))
40
- @Matches(RETAIL_SALE_ID_TEXT_PATTERN)
41
- @Validate(OnlyForPaymentMethodConstraint, [CARD])
32
+ @IsString()
42
33
  authCode?: string | null;
43
34
 
44
35
  @Expose()
45
36
  @ValidateIf(hasValue('speiTrackingKey'))
46
- @Matches(RETAIL_SPEI_TRACKING_KEY_PATTERN)
47
- @Validate(OnlyForPaymentMethodConstraint, [WIRE])
37
+ @IsString()
48
38
  speiTrackingKey?: string | null;
49
39
 
50
40
  @Expose()
51
41
  @ValidateIf(hasValue('senderClabe'))
52
- @Matches(RETAIL_CLABE_PATTERN)
53
- @Validate(OnlyForPaymentMethodConstraint, [WIRE])
42
+ @IsString()
54
43
  senderClabe?: string | null;
55
44
  }
@@ -0,0 +1,46 @@
1
+ import { IsBoolean, IsInt, IsString, Min, Matches, Validate } from 'class-validator';
2
+ import {
3
+ RETAIL_CARD_LAST4_PATTERN,
4
+ RETAIL_CLABE_PATTERN,
5
+ RETAIL_SALE_ID_TEXT_PATTERN,
6
+ RETAIL_SPEI_TRACKING_KEY_PATTERN,
7
+ } from '../../retailIntegration/constants/retailIntegrationLimits';
8
+ import { SalePaymentMethodEnum } from '../enums/SalePaymentMethodEnum';
9
+ import { OnlyForPaymentMethodConstraint } from '../validators/OnlyForPaymentMethodConstraint';
10
+ import { SalePayment } from './SalePayment';
11
+
12
+ const { CASH, CARD, WIRE } = SalePaymentMethodEnum;
13
+
14
+ /**
15
+ * Pago ya registrado (cobro de la sesión): monto positivo y comprobante con formato, solo en su medio.
16
+ * Repite las reglas de forma porque class-validator descarta las del padre en la propiedad que se redeclara.
17
+ */
18
+ export class StoredSalePayment extends SalePayment {
19
+ @IsInt()
20
+ @Min(1)
21
+ declare amountCents: number;
22
+
23
+ @IsBoolean()
24
+ @Validate(OnlyForPaymentMethodConstraint, [CASH])
25
+ declare cashConfirmedInRegister?: boolean | null;
26
+
27
+ @IsString()
28
+ @Matches(RETAIL_CARD_LAST4_PATTERN)
29
+ @Validate(OnlyForPaymentMethodConstraint, [CARD])
30
+ declare cardLast4?: string | null;
31
+
32
+ @IsString()
33
+ @Matches(RETAIL_SALE_ID_TEXT_PATTERN)
34
+ @Validate(OnlyForPaymentMethodConstraint, [CARD])
35
+ declare authCode?: string | null;
36
+
37
+ @IsString()
38
+ @Matches(RETAIL_SPEI_TRACKING_KEY_PATTERN)
39
+ @Validate(OnlyForPaymentMethodConstraint, [WIRE])
40
+ declare speiTrackingKey?: string | null;
41
+
42
+ @IsString()
43
+ @Matches(RETAIL_CLABE_PATTERN)
44
+ @Validate(OnlyForPaymentMethodConstraint, [WIRE])
45
+ declare senderClabe?: string | null;
46
+ }
@@ -14,7 +14,7 @@ import { SalePaymentMethodEnum } from '../../enums/SalePaymentMethodEnum';
14
14
  import { SalePaymentDetail } from '../SalePaymentDetail';
15
15
  import { AccessorySaleLine } from '../AccessorySaleLine';
16
16
  import { SalePayment } from '../SalePayment';
17
- import { IsSalePaymentList } from '../../validators/IsSalePaymentList';
17
+ import { IsSalePaymentInputList } from '../../validators/IsSalePaymentInputList';
18
18
 
19
19
  /**
20
20
  * POST /wizard/accessory-sales — cierra la venta de mostrador, sin cliente.
@@ -47,9 +47,9 @@ export class CreateAccessorySaleRequest {
47
47
  @Type(() => SalePaymentDetail)
48
48
  paymentDetail?: SalePaymentDetail;
49
49
 
50
- /** Pagos del cobro (1 a 3); si viene, manda sobre `paymentMethod` y `paymentDetail`. */
50
+ /** Pagos del cobro; si viene, manda sobre `paymentMethod` y `paymentDetail`. */
51
51
  @Expose()
52
52
  @IsOptional()
53
- @IsSalePaymentList()
53
+ @IsSalePaymentInputList()
54
54
  payments?: SalePayment[];
55
55
  }
@@ -3,7 +3,7 @@ import { IsEnum, IsInt, IsOptional, Min, ValidateIf, ValidateNested } from 'clas
3
3
  import { SalePaymentMethodEnum } from '../../enums/SalePaymentMethodEnum';
4
4
  import { SalePaymentDetail } from '../SalePaymentDetail';
5
5
  import { SalePayment } from '../SalePayment';
6
- import { IsSalePaymentList } from '../../validators/IsSalePaymentList';
6
+ import { IsSalePaymentInputList } from '../../validators/IsSalePaymentInputList';
7
7
 
8
8
  /**
9
9
  * POST /wizard/sessions/:id/down-payment — cobro del ENGANCHE de la venta a crédito (paso 07,
@@ -33,9 +33,9 @@ export class DownPaymentRequest {
33
33
  @ValidateNested()
34
34
  detail?: SalePaymentDetail;
35
35
 
36
- /** Pagos del cobro (1 a 3); si viene, manda sobre `method` y `detail`. */
36
+ /** Pagos del cobro; si viene, manda sobre `method` y `detail`. */
37
37
  @Expose()
38
38
  @IsOptional()
39
- @IsSalePaymentList()
39
+ @IsSalePaymentInputList()
40
40
  payments?: SalePayment[];
41
41
  }
@@ -3,7 +3,7 @@ import { IsEnum, IsInt, IsOptional, ValidateIf, ValidateNested, Min } from 'clas
3
3
  import { SalePaymentMethodEnum } from '../../enums/SalePaymentMethodEnum';
4
4
  import { SalePaymentDetail } from '../SalePaymentDetail';
5
5
  import { SalePayment } from '../SalePayment';
6
- import { IsSalePaymentList } from '../../validators/IsSalePaymentList';
6
+ import { IsSalePaymentInputList } from '../../validators/IsSalePaymentInputList';
7
7
 
8
8
  /**
9
9
  * POST /wizard/sessions/:id/payment — registra el cobro de contado (idempotente por sesión). Regla
@@ -29,9 +29,9 @@ export class RegisterPaymentRequest {
29
29
  @ValidateNested()
30
30
  detail?: SalePaymentDetail;
31
31
 
32
- /** Pagos del cobro (1 a 3); si viene, manda sobre `method` y `detail`. */
32
+ /** Pagos del cobro; si viene, manda sobre `method` y `detail`. */
33
33
  @Expose()
34
34
  @IsOptional()
35
- @IsSalePaymentList()
35
+ @IsSalePaymentInputList()
36
36
  payments?: SalePayment[];
37
37
  }
@@ -46,6 +46,8 @@ export * from './dtos/WizardWelcome';
46
46
  export * from './dtos/WizardCreditPromotionBonus';
47
47
  export * from './dtos/SalePaymentDetail';
48
48
  export * from './dtos/SalePayment';
49
+ export * from './dtos/StoredSalePayment';
50
+ export * from './validators/IsSalePaymentInputList';
49
51
  export * from './validators/IsSalePaymentList';
50
52
  export * from './validators/OnlyForPaymentMethodConstraint';
51
53
  export * from './validators/PaymentsHaveSingleUseMethodsConstraint';
@@ -0,0 +1,9 @@
1
+ import { Type } from 'class-transformer';
2
+ import { IsArray, ValidateNested } from 'class-validator';
3
+ import { SalePayment } from '../dtos/SalePayment';
4
+
5
+ /** Forma de `payments` en un request: arreglo de pagos bien tipados. Las reglas de negocio las valida el dominio. */
6
+ export function IsSalePaymentInputList(): PropertyDecorator {
7
+ const decorators: PropertyDecorator[] = [IsArray(), ValidateNested({ each: true }), Type(() => SalePayment)];
8
+ return (target, propertyKey) => decorators.forEach((decorate) => decorate(target, propertyKey));
9
+ }
@@ -1,18 +1,18 @@
1
1
  import { Type } from 'class-transformer';
2
2
  import { ArrayMaxSize, ArrayMinSize, IsArray, Validate, ValidateNested } from 'class-validator';
3
3
  import { MAX_SALE_PAYMENTS } from '../constants/retailWizardValidation';
4
- import { SalePayment } from '../dtos/SalePayment';
4
+ import { StoredSalePayment } from '../dtos/StoredSalePayment';
5
5
  import { PaymentsHaveSingleUseMethodsConstraint } from './PaymentsHaveSingleUseMethodsConstraint';
6
6
  import { PaymentsMatchAmountCentsConstraint } from './PaymentsMatchAmountCentsConstraint';
7
7
 
8
- /** Reglas de `payments`: 1 a 3 pagos válidos, efectivo y SPEI una vez, y la suma igual a `amountCents`. */
8
+ /** Reglas de `payments` ya registrados (cobro de la sesión): 1 a 3 pagos válidos, efectivo y SPEI una vez, y la suma igual a `amountCents`. */
9
9
  export function IsSalePaymentList(): PropertyDecorator {
10
10
  const decorators: PropertyDecorator[] = [
11
11
  IsArray(),
12
12
  ArrayMinSize(1),
13
13
  ArrayMaxSize(MAX_SALE_PAYMENTS),
14
14
  ValidateNested({ each: true }),
15
- Type(() => SalePayment),
15
+ Type(() => StoredSalePayment),
16
16
  Validate(PaymentsHaveSingleUseMethodsConstraint),
17
17
  Validate(PaymentsMatchAmountCentsConstraint),
18
18
  ];