@fiado/type-kit 3.601.0 → 3.603.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.
- package/_test_/unit/retailIntegration/retailSaleContracts.test.ts +162 -10
- package/_test_/unit/retailIntegration/retailSystemEnums.test.ts +3 -1
- package/bin/collection/dtos/AuthorizeCollectionMovementRequest.d.ts +7 -0
- package/bin/collection/dtos/AuthorizeCollectionMovementRequest.js +5 -0
- package/bin/retailIntegration/constants/retailIntegrationLimits.d.ts +15 -0
- package/bin/retailIntegration/constants/retailIntegrationLimits.js +16 -1
- package/bin/retailIntegration/dtos/CancelRetailSaleRequest.d.ts +7 -0
- package/bin/retailIntegration/dtos/CancelRetailSaleRequest.js +34 -1
- package/bin/retailIntegration/enums/RetailPaymentFrequencyEnum.d.ts +6 -0
- package/bin/retailIntegration/enums/RetailPaymentFrequencyEnum.js +10 -0
- package/bin/retailIntegration/enums/RetailPaymentMethodEnum.d.ts +3 -2
- package/bin/retailIntegration/enums/RetailPaymentMethodEnum.js +3 -2
- package/bin/retailIntegration/enums/index.d.ts +1 -0
- package/bin/retailIntegration/enums/index.js +1 -0
- package/bin/retailIntegration/index.d.ts +2 -0
- package/bin/retailIntegration/index.js +2 -0
- package/bin/retailIntegration/models/RetailSystemSale.d.ts +23 -2
- package/bin/retailIntegration/models/RetailSystemSale.js +89 -11
- package/bin/retailIntegration/validators/IsCalendarDate.d.ts +6 -0
- package/bin/retailIntegration/validators/IsCalendarDate.js +25 -0
- package/bin/retailIntegration/validators/IsIsoDateTimeWithZone.js +2 -6
- package/bin/retailIntegration/validators/calendarDate.d.ts +2 -0
- package/bin/retailIntegration/validators/calendarDate.js +8 -0
- package/bin/retailIntegration/validators/saleValidators.d.ts +26 -0
- package/bin/retailIntegration/validators/saleValidators.js +100 -0
- package/package.json +1 -1
- package/src/collection/dtos/AuthorizeCollectionMovementRequest.ts +9 -1
- package/src/retailIntegration/constants/retailIntegrationLimits.ts +22 -0
- package/src/retailIntegration/dtos/CancelRetailSaleRequest.ts +14 -2
- package/src/retailIntegration/enums/RetailPaymentFrequencyEnum.ts +6 -0
- package/src/retailIntegration/enums/RetailPaymentMethodEnum.ts +3 -2
- package/src/retailIntegration/enums/index.ts +1 -0
- package/src/retailIntegration/index.ts +2 -0
- package/src/retailIntegration/models/RetailSystemSale.ts +57 -10
- package/src/retailIntegration/validators/IsCalendarDate.ts +16 -0
- package/src/retailIntegration/validators/IsIsoDateTimeWithZone.ts +1 -6
- package/src/retailIntegration/validators/calendarDate.ts +5 -0
- package/src/retailIntegration/validators/saleValidators.ts +80 -0
|
@@ -23,6 +23,12 @@ async function errorsOf(cls: new () => object, plain: object): Promise<string[]>
|
|
|
23
23
|
return paths(await validate(plainToInstance(cls, plain)));
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
const cashPayment = { method: 'CASH', amount: '400.00', cardLast4: null, authCode: null, speiTrackingKey: null, senderClabe: null } as const;
|
|
27
|
+
const cardPayment = { method: 'CARD', amount: '200.00', cardLast4: '4242', authCode: 'A1B2C3', speiTrackingKey: null, senderClabe: null } as const;
|
|
28
|
+
const wirePayment = {
|
|
29
|
+
method: 'WIRE', amount: '200.00', cardLast4: null, authCode: null, speiTrackingKey: '123456789012345678', senderClabe: '012180001234567897',
|
|
30
|
+
} as const;
|
|
31
|
+
|
|
26
32
|
// Literal tipado: prueba en compilación que la clase sigue aceptando objetos planos.
|
|
27
33
|
const sale: RetailSystemSale = {
|
|
28
34
|
saleId: '7f0c2a52-1b7e-4f0e-9d7a-2a1d3c4b5e6f',
|
|
@@ -33,30 +39,39 @@ const sale: RetailSystemSale = {
|
|
|
33
39
|
saleType: 'CREDIT',
|
|
34
40
|
financier: 'SUREKEEP',
|
|
35
41
|
creditId: 'CR-991',
|
|
42
|
+
credit: {
|
|
43
|
+
paymentFrequency: 'WEEKLY', installments: 16, installmentAmount: '260.67', downPayment: '600.00', totalToPay: '4170.72', firstPaymentDate: '2026-10-30',
|
|
44
|
+
},
|
|
36
45
|
currencyId: 'MXN',
|
|
37
46
|
customer: { customerId: 'C-1', names: 'Ana', paternalLastName: 'López', maternalLastName: null, phone: '7221234567' },
|
|
38
47
|
equipmentPrice: '5999.00',
|
|
39
48
|
amountPaid: '600.00',
|
|
40
|
-
|
|
49
|
+
payments: [cashPayment, cardPayment],
|
|
41
50
|
lines: [
|
|
42
51
|
{
|
|
43
52
|
lineId: 'L1', sku: 'IPH-15', qty: 1, basePrice: '5999.00', discount: '0.00', paymentType: 'CREDIT',
|
|
44
|
-
financedAmount: '5399.00', role: null, components: [{ sku: 'IPH-15', qty: 1, identifiers: ['356789012345678'] }],
|
|
53
|
+
financedAmount: '5399.00', role: null, promotionId: null, components: [{ sku: 'IPH-15', qty: 1, identifiers: ['356789012345678'] }],
|
|
45
54
|
},
|
|
46
55
|
{
|
|
47
56
|
lineId: 'L2', sku: 'FUNDA-1', qty: 1, basePrice: '0.00', discount: '0.00', paymentType: 'CASH',
|
|
48
|
-
financedAmount: '0.00', role: 'GIFT', components: [],
|
|
57
|
+
financedAmount: '0.00', role: 'GIFT', promotionId: 'PRM-0012', components: [],
|
|
49
58
|
},
|
|
50
59
|
],
|
|
51
60
|
};
|
|
52
61
|
|
|
62
|
+
const cashSale = { ...sale, saleType: 'CASH', financier: 'NONE', creditId: null, credit: null };
|
|
63
|
+
|
|
53
64
|
describe('RetailSystemSale (body de privateRegisterRetailSale)', () => {
|
|
54
|
-
it('acepta una venta completa', async () => {
|
|
65
|
+
it('acepta una venta a crédito SureKeep completa', async () => {
|
|
55
66
|
expect(await errorsOf(RetailSystemSale, sale)).toEqual([]);
|
|
56
67
|
});
|
|
57
68
|
|
|
58
|
-
it('acepta
|
|
59
|
-
expect(await errorsOf(RetailSystemSale,
|
|
69
|
+
it('acepta una venta de contado con creditId y credit en null', async () => {
|
|
70
|
+
expect(await errorsOf(RetailSystemSale, cashSale)).toEqual([]);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('acepta una referida sin creditId ni credit', async () => {
|
|
74
|
+
expect(await errorsOf(RetailSystemSale, { ...sale, financier: 'PAYJOY', creditId: null, credit: null })).toEqual([]);
|
|
60
75
|
});
|
|
61
76
|
|
|
62
77
|
it.each([
|
|
@@ -67,14 +82,19 @@ describe('RetailSystemSale (body de privateRegisterRetailSale)', () => {
|
|
|
67
82
|
['financier', { financier: 'OTRO' }],
|
|
68
83
|
['currencyId', { currencyId: 'EUR' }],
|
|
69
84
|
['equipmentPrice', { equipmentPrice: '5999' }],
|
|
70
|
-
['
|
|
71
|
-
['paymentMethod', { paymentMethod: 'BITCOIN' }],
|
|
85
|
+
['equipmentPrice', { equipmentPrice: '1234567890123.00' }],
|
|
72
86
|
['creditId', { creditId: undefined }],
|
|
87
|
+
['credit', { credit: undefined }],
|
|
88
|
+
['payments', { payments: undefined }],
|
|
73
89
|
['lines', { lines: [] }],
|
|
74
90
|
])('rechaza %s inválido', async (field, patch) => {
|
|
75
91
|
expect(await errorsOf(RetailSystemSale, { ...sale, ...patch })).toEqual([field]);
|
|
76
92
|
});
|
|
77
93
|
|
|
94
|
+
it.each(['722123456', '72212345678', '+527221234567', '722-123-4567'])('rechaza customer.phone %s', async (phone) => {
|
|
95
|
+
expect(await errorsOf(RetailSystemSale, { ...sale, customer: { ...sale.customer, phone } })).toEqual(['customer.phone']);
|
|
96
|
+
});
|
|
97
|
+
|
|
78
98
|
it('valida el cliente anidado', async () => {
|
|
79
99
|
expect(await errorsOf(RetailSystemSale, { ...sale, customer: { ...sale.customer, names: '' } })).toEqual(['customer.names']);
|
|
80
100
|
});
|
|
@@ -90,11 +110,130 @@ describe('RetailSystemSale (body de privateRegisterRetailSale)', () => {
|
|
|
90
110
|
});
|
|
91
111
|
});
|
|
92
112
|
|
|
113
|
+
describe('RetailSystemSale.credit', () => {
|
|
114
|
+
it('SUREKEEP exige credit y creditId', async () => {
|
|
115
|
+
expect(await errorsOf(RetailSystemSale, { ...sale, credit: null })).toEqual(['financier']);
|
|
116
|
+
expect(await errorsOf(RetailSystemSale, { ...sale, creditId: null })).toEqual(['financier']);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('contado exige credit y creditId en null', async () => {
|
|
120
|
+
expect(await errorsOf(RetailSystemSale, { ...cashSale, credit: sale.credit })).toEqual(['financier']);
|
|
121
|
+
expect(await errorsOf(RetailSystemSale, { ...cashSale, creditId: 'CR-1' })).toEqual(['financier']);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it.each([
|
|
125
|
+
['paymentFrequency', { paymentFrequency: 'DAILY' }],
|
|
126
|
+
['installments', { installments: 0 }],
|
|
127
|
+
['installments', { installments: 1.5 }],
|
|
128
|
+
['installmentAmount', { installmentAmount: '260.6' }],
|
|
129
|
+
['downPayment', { downPayment: undefined }],
|
|
130
|
+
['totalToPay', { totalToPay: '1234567890123.00' }],
|
|
131
|
+
['firstPaymentDate', { firstPaymentDate: '2026-02-30' }],
|
|
132
|
+
['firstPaymentDate', { firstPaymentDate: '2026-10-30T00:00:00Z' }],
|
|
133
|
+
])('rechaza credit.%s inválido', async (field, patch) => {
|
|
134
|
+
expect(await errorsOf(RetailSystemSale, { ...sale, credit: { ...sale.credit, ...patch } })).toEqual([`credit.${field}`]);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
describe('RetailSystemSale.payments', () => {
|
|
139
|
+
it('acepta [] cuando amountPaid es 0.00', async () => {
|
|
140
|
+
expect(await errorsOf(RetailSystemSale, { ...sale, amountPaid: '0.00', payments: [] })).toEqual([]);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('acepta WIRE con y sin senderClabe', async () => {
|
|
144
|
+
expect(await errorsOf(RetailSystemSale, { ...sale, payments: [cashPayment, wirePayment] })).toEqual([]);
|
|
145
|
+
expect(await errorsOf(RetailSystemSale, { ...sale, payments: [cashPayment, { ...wirePayment, senderClabe: null }] })).toEqual([]);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('acepta FIADO sin detalle', async () => {
|
|
149
|
+
expect(await errorsOf(RetailSystemSale, { ...sale, payments: [{ ...cashPayment, method: 'FIADO', amount: '600.00' }] })).toEqual([]);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it('rechaza que la suma no cuadre con amountPaid', async () => {
|
|
153
|
+
expect(await errorsOf(RetailSystemSale, { ...sale, payments: [cashPayment] })).toEqual(['payments']);
|
|
154
|
+
expect(await errorsOf(RetailSystemSale, { ...sale, payments: [] })).toEqual(['payments']);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it.each([
|
|
158
|
+
['method', { method: 'SPEI' }],
|
|
159
|
+
['amount', { amount: '0.00' }],
|
|
160
|
+
['amount', { amount: '400' }],
|
|
161
|
+
['cardLast4', { cardLast4: '4242' }],
|
|
162
|
+
['cardLast4', { cardLast4: undefined }],
|
|
163
|
+
['authCode', { authCode: 'X' }],
|
|
164
|
+
['speiTrackingKey', { speiTrackingKey: undefined }],
|
|
165
|
+
['senderClabe', { senderClabe: undefined }],
|
|
166
|
+
])('rechaza %s fuera de regla en CASH', async (field, patch) => {
|
|
167
|
+
const payments = [{ ...cashPayment, ...patch }, cardPayment];
|
|
168
|
+
expect(await errorsOf(RetailSystemSale, { ...sale, payments })).toEqual([`payments.0.${field}`]);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it.each([
|
|
172
|
+
['cardLast4', { cardLast4: null }],
|
|
173
|
+
['cardLast4', { cardLast4: '424' }],
|
|
174
|
+
['authCode', { authCode: null }],
|
|
175
|
+
['authCode', { authCode: ' ' }],
|
|
176
|
+
['authCode', { authCode: 'A'.repeat(65) }],
|
|
177
|
+
['speiTrackingKey', { speiTrackingKey: '123456789012345678' }],
|
|
178
|
+
])('rechaza %s fuera de regla en CARD', async (field, patch) => {
|
|
179
|
+
const payments = [cashPayment, { ...cardPayment, ...patch }];
|
|
180
|
+
expect(await errorsOf(RetailSystemSale, { ...sale, payments })).toEqual([`payments.1.${field}`]);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it.each([
|
|
184
|
+
['speiTrackingKey', { speiTrackingKey: null }],
|
|
185
|
+
['speiTrackingKey', { speiTrackingKey: '12345' }],
|
|
186
|
+
['senderClabe', { senderClabe: '0121' }],
|
|
187
|
+
['cardLast4', { cardLast4: '4242' }],
|
|
188
|
+
])('rechaza %s fuera de regla en WIRE', async (field, patch) => {
|
|
189
|
+
const payments = [cashPayment, { ...wirePayment, ...patch }];
|
|
190
|
+
expect(await errorsOf(RetailSystemSale, { ...sale, payments })).toEqual([`payments.1.${field}`]);
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
describe('RetailSystemSale.lines[].promotionId', () => {
|
|
195
|
+
it('la llave es obligatoria aunque sea null', async () => {
|
|
196
|
+
const lines = [{ ...sale.lines[0], promotionId: undefined }, sale.lines[1]];
|
|
197
|
+
expect(await errorsOf(RetailSystemSale, { ...sale, lines })).toEqual(['lines.0.promotionId']);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it('acepta una promoción en una línea con descuento', async () => {
|
|
201
|
+
const lines = [{ ...sale.lines[0], discount: '500.00', promotionId: 'PRM-1' }, sale.lines[1]];
|
|
202
|
+
expect(await errorsOf(RetailSystemSale, { ...sale, lines })).toEqual([]);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it.each([
|
|
206
|
+
['vacío', ' '],
|
|
207
|
+
['más de 64', 'P'.repeat(65)],
|
|
208
|
+
])('rechaza promotionId %s', async (_case, promotionId) => {
|
|
209
|
+
const lines = [{ ...sale.lines[0], promotionId }, sale.lines[1]];
|
|
210
|
+
expect(await errorsOf(RetailSystemSale, { ...sale, lines })).toEqual(['lines.0.promotionId']);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it('un regalo exige promotionId', async () => {
|
|
214
|
+
const lines = [sale.lines[0], { ...sale.lines[1], promotionId: null }];
|
|
215
|
+
expect(await errorsOf(RetailSystemSale, { ...sale, lines })).toEqual(['lines.1.promotionId']);
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
|
|
93
219
|
describe('CancelRetailSaleRequest', () => {
|
|
94
|
-
const cancel = {
|
|
220
|
+
const cancel: CancelRetailSaleRequest = {
|
|
221
|
+
saleId: sale.saleId,
|
|
222
|
+
cancelledAt: '2026-10-25T19:00:00-06:00',
|
|
223
|
+
reason: 'Cliente desistió',
|
|
224
|
+
damaged: [
|
|
225
|
+
{ sku: 'IPH-15', identifier: '356789012345678', qty: 1 },
|
|
226
|
+
{ sku: 'FUNDA-1', identifier: null, qty: 3 },
|
|
227
|
+
],
|
|
228
|
+
};
|
|
95
229
|
|
|
96
|
-
it('acepta la cancelación', async () => {
|
|
230
|
+
it('acepta la cancelación con y sin dañados', async () => {
|
|
97
231
|
expect(await errorsOf(CancelRetailSaleRequest, cancel)).toEqual([]);
|
|
232
|
+
expect(await errorsOf(CancelRetailSaleRequest, { ...cancel, damaged: [] })).toEqual([]);
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
it('acepta reason de 200 caracteres', async () => {
|
|
236
|
+
expect(await errorsOf(CancelRetailSaleRequest, { ...cancel, reason: 'r'.repeat(200) })).toEqual([]);
|
|
98
237
|
});
|
|
99
238
|
|
|
100
239
|
it.each([
|
|
@@ -102,10 +241,23 @@ describe('CancelRetailSaleRequest', () => {
|
|
|
102
241
|
['cancelledAt', { cancelledAt: '2026-02-31T10:00:00Z' }],
|
|
103
242
|
['reason', { reason: '' }],
|
|
104
243
|
['reason', { reason: undefined }],
|
|
244
|
+
['reason', { reason: 'r'.repeat(201) }],
|
|
245
|
+
['damaged', { damaged: undefined }],
|
|
105
246
|
])('rechaza %s inválido', async (field, patch) => {
|
|
106
247
|
expect(await errorsOf(CancelRetailSaleRequest, { ...cancel, ...patch })).toEqual([field]);
|
|
107
248
|
});
|
|
108
249
|
|
|
250
|
+
it.each([
|
|
251
|
+
['sku', { sku: 'a/b' }],
|
|
252
|
+
['identifier', { identifier: undefined }],
|
|
253
|
+
['identifier', { identifier: ' ' }],
|
|
254
|
+
['qty', { qty: 0 }],
|
|
255
|
+
['qty', { qty: 2 }],
|
|
256
|
+
])('rechaza damaged[].%s inválido', async (field, patch) => {
|
|
257
|
+
const damaged = [{ ...cancel.damaged[0], ...patch }];
|
|
258
|
+
expect(await errorsOf(CancelRetailSaleRequest, { ...cancel, damaged })).toEqual([`damaged.0.${field}`]);
|
|
259
|
+
});
|
|
260
|
+
|
|
109
261
|
it('la respuesta trae el saleId', () => {
|
|
110
262
|
const response: CancelRetailSaleResponse = { saleId: cancel.saleId };
|
|
111
263
|
expect(response.saleId).toBe(cancel.saleId);
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
RetailFinancierEnum,
|
|
6
6
|
RetailLinePaymentTypeEnum,
|
|
7
7
|
RetailMdmProviderEnum,
|
|
8
|
+
RetailPaymentFrequencyEnum,
|
|
8
9
|
RetailPaymentMethodEnum,
|
|
9
10
|
RetailPieceReasonEnum,
|
|
10
11
|
RetailPieceStatusEnum,
|
|
@@ -35,7 +36,8 @@ describe('enums de los objetos del retailer', () => {
|
|
|
35
36
|
[RetailUserAccessStatusEnum, ['ACTIVE', 'SUSPENDED', 'INACTIVE']],
|
|
36
37
|
[RetailSaleTypeEnum, ['CASH', 'CREDIT', 'EXTERNAL_REFERRAL']],
|
|
37
38
|
[RetailSaleFinancierEnum, ['NONE', 'SUREKEEP', 'PAYJOY', 'CREDIYA', 'LESPAGO', 'INNOVA']],
|
|
38
|
-
[RetailPaymentMethodEnum, ['CASH', 'CARD', '
|
|
39
|
+
[RetailPaymentMethodEnum, ['CASH', 'CARD', 'WIRE', 'FIADO']],
|
|
40
|
+
[RetailPaymentFrequencyEnum, ['WEEKLY', 'BIWEEKLY', 'MONTHLY']],
|
|
39
41
|
[RetailLinePaymentTypeEnum, ['CASH', 'CREDIT']],
|
|
40
42
|
])('%p trae exactamente los valores del contrato', (enumObject, values) => {
|
|
41
43
|
expect(Object.values(enumObject)).toEqual(values);
|
|
@@ -18,4 +18,11 @@ export declare class AuthorizeCollectionMovementRequest {
|
|
|
18
18
|
* no romper a quien todavía no manda tarifa.
|
|
19
19
|
*/
|
|
20
20
|
pricing?: CollectionPricingDto;
|
|
21
|
+
/**
|
|
22
|
+
* La config del producto en el motor permite un reserve/débito PARCIAL cuando la wallet no cubre
|
|
23
|
+
* el monto completo. Presente en `true`, el procesador reserva/debita lo disponible por encima de
|
|
24
|
+
* su mínimo por moneda y responde `PARTIAL`. Ausente o `false` conserva el comportamiento de todo
|
|
25
|
+
* o nada: si el saldo no cubre el monto, responde `NONE`.
|
|
26
|
+
*/
|
|
27
|
+
allowPartial?: boolean;
|
|
21
28
|
}
|
|
@@ -63,3 +63,8 @@ __decorate([
|
|
|
63
63
|
(0, class_transformer_1.Type)(() => CollectionPricingDto_1.CollectionPricingDto),
|
|
64
64
|
__metadata("design:type", CollectionPricingDto_1.CollectionPricingDto)
|
|
65
65
|
], AuthorizeCollectionMovementRequest.prototype, "pricing", void 0);
|
|
66
|
+
__decorate([
|
|
67
|
+
(0, class_validator_1.IsOptional)(),
|
|
68
|
+
(0, class_validator_1.IsBoolean)(),
|
|
69
|
+
__metadata("design:type", Boolean)
|
|
70
|
+
], AuthorizeCollectionMovementRequest.prototype, "allowPartial", void 0);
|
|
@@ -45,3 +45,18 @@ export declare const RETAIL_LINE_INDEX_MIN = 0;
|
|
|
45
45
|
export declare const RETAIL_LINE_INDEX_MAX = 999;
|
|
46
46
|
/** Rango máximo de `GET /inventory/movements`: 7 días en milisegundos. */
|
|
47
47
|
export declare const RETAIL_MOVEMENTS_RANGE_MAX_MS: number;
|
|
48
|
+
/** Decimal de la venta y la cancelación: hasta 12 enteros y dos decimales, nunca negativo. */
|
|
49
|
+
export declare const RETAIL_SALE_DECIMAL_PATTERN: RegExp;
|
|
50
|
+
/** Decimal de la venta mayor que cero, como `payments[].amount`. */
|
|
51
|
+
export declare const RETAIL_SALE_POSITIVE_DECIMAL_PATTERN: RegExp;
|
|
52
|
+
/** Texto libre corto de la venta, como `authCode` y `promotionId`: no vacío y de a lo más 64. */
|
|
53
|
+
export declare const RETAIL_SALE_ID_TEXT_PATTERN: RegExp;
|
|
54
|
+
/** Últimos 4 dígitos de la tarjeta en un pago `CARD`. */
|
|
55
|
+
export declare const RETAIL_CARD_LAST4_PATTERN: RegExp;
|
|
56
|
+
/** Clave de rastreo SPEI y CLABE de un pago `WIRE`: 18 dígitos. */
|
|
57
|
+
export declare const RETAIL_SPEI_TRACKING_KEY_PATTERN: RegExp;
|
|
58
|
+
export declare const RETAIL_CLABE_PATTERN: RegExp;
|
|
59
|
+
/** Tope del motivo de cancelación de una venta. */
|
|
60
|
+
export declare const RETAIL_CANCEL_REASON_MAX_LENGTH = 200;
|
|
61
|
+
/** Teléfono del cliente en la venta: 10 dígitos. */
|
|
62
|
+
export declare const RETAIL_CUSTOMER_PHONE_PATTERN: RegExp;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RETAIL_MOVEMENTS_RANGE_MAX_MS = exports.RETAIL_LINE_INDEX_MAX = exports.RETAIL_LINE_INDEX_MIN = exports.RETAIL_ERROR_CODE_MAX_LENGTH = exports.RETAIL_EXTERNAL_ID_PATTERN = exports.RETAIL_NEXT_TOKEN_MAX_LENGTH = exports.RETAIL_EVENT_DECIMAL_PATTERN = exports.RETAIL_ELIGIBLE_FINANCIERS_MAX = exports.RETAIL_EVENT_STOCK_MAX = exports.RETAIL_LONG_TEXT_MAX_LENGTH = exports.RETAIL_SHORT_TEXT_MAX_LENGTH = exports.RETAIL_ID_TEXT_MAX_LENGTH = exports.RETAIL_EVENT_PIECES_MAX = exports.RETAIL_LIVE_CHECK_IDENTIFIERS_MAX = exports.RETAIL_DECIMAL_PATTERN = exports.RETAIL_SKU_PATTERN = exports.RETAIL_ZIP_CODE_MAX_LENGTH = exports.RETAIL_ZIP_CODE_MIN_LENGTH = exports.RETAIL_STORE_CODE_MAX_LENGTH = exports.RETAIL_ZONE_ID_PATTERN = exports.RETAIL_ENTITY_ID_PATTERN = exports.RETAIL_TENANT_ID_PATTERN = exports.RETAIL_LIST_LIMIT_MAX = exports.RETAIL_LIST_LIMIT_MIN = exports.RETAIL_EVENT_ID_MAX_LENGTH = void 0;
|
|
3
|
+
exports.RETAIL_CUSTOMER_PHONE_PATTERN = exports.RETAIL_CANCEL_REASON_MAX_LENGTH = exports.RETAIL_CLABE_PATTERN = exports.RETAIL_SPEI_TRACKING_KEY_PATTERN = exports.RETAIL_CARD_LAST4_PATTERN = exports.RETAIL_SALE_ID_TEXT_PATTERN = exports.RETAIL_SALE_POSITIVE_DECIMAL_PATTERN = exports.RETAIL_SALE_DECIMAL_PATTERN = exports.RETAIL_MOVEMENTS_RANGE_MAX_MS = exports.RETAIL_LINE_INDEX_MAX = exports.RETAIL_LINE_INDEX_MIN = exports.RETAIL_ERROR_CODE_MAX_LENGTH = exports.RETAIL_EXTERNAL_ID_PATTERN = exports.RETAIL_NEXT_TOKEN_MAX_LENGTH = exports.RETAIL_EVENT_DECIMAL_PATTERN = exports.RETAIL_ELIGIBLE_FINANCIERS_MAX = exports.RETAIL_EVENT_STOCK_MAX = exports.RETAIL_LONG_TEXT_MAX_LENGTH = exports.RETAIL_SHORT_TEXT_MAX_LENGTH = exports.RETAIL_ID_TEXT_MAX_LENGTH = exports.RETAIL_EVENT_PIECES_MAX = exports.RETAIL_LIVE_CHECK_IDENTIFIERS_MAX = exports.RETAIL_DECIMAL_PATTERN = exports.RETAIL_SKU_PATTERN = exports.RETAIL_ZIP_CODE_MAX_LENGTH = exports.RETAIL_ZIP_CODE_MIN_LENGTH = exports.RETAIL_STORE_CODE_MAX_LENGTH = exports.RETAIL_ZONE_ID_PATTERN = exports.RETAIL_ENTITY_ID_PATTERN = exports.RETAIL_TENANT_ID_PATTERN = exports.RETAIL_LIST_LIMIT_MAX = exports.RETAIL_LIST_LIMIT_MIN = exports.RETAIL_EVENT_ID_MAX_LENGTH = void 0;
|
|
4
4
|
/** Tope de `eventId`: el límite seguro de una llave de DynamoDB. */
|
|
5
5
|
exports.RETAIL_EVENT_ID_MAX_LENGTH = 1024;
|
|
6
6
|
/** Rango de `limit` en las listas paginadas del retailer. */
|
|
@@ -48,3 +48,18 @@ exports.RETAIL_LINE_INDEX_MIN = 0;
|
|
|
48
48
|
exports.RETAIL_LINE_INDEX_MAX = 999;
|
|
49
49
|
/** Rango máximo de `GET /inventory/movements`: 7 días en milisegundos. */
|
|
50
50
|
exports.RETAIL_MOVEMENTS_RANGE_MAX_MS = 7 * 24 * 60 * 60 * 1000;
|
|
51
|
+
/** Decimal de la venta y la cancelación: hasta 12 enteros y dos decimales, nunca negativo. */
|
|
52
|
+
exports.RETAIL_SALE_DECIMAL_PATTERN = /^\d{1,12}\.\d{2}$/;
|
|
53
|
+
/** Decimal de la venta mayor que cero, como `payments[].amount`. */
|
|
54
|
+
exports.RETAIL_SALE_POSITIVE_DECIMAL_PATTERN = /^(?=.*[1-9])\d{1,12}\.\d{2}$/;
|
|
55
|
+
/** Texto libre corto de la venta, como `authCode` y `promotionId`: no vacío y de a lo más 64. */
|
|
56
|
+
exports.RETAIL_SALE_ID_TEXT_PATTERN = /^(?=.*\S).{1,64}$/;
|
|
57
|
+
/** Últimos 4 dígitos de la tarjeta en un pago `CARD`. */
|
|
58
|
+
exports.RETAIL_CARD_LAST4_PATTERN = /^\d{4}$/;
|
|
59
|
+
/** Clave de rastreo SPEI y CLABE de un pago `WIRE`: 18 dígitos. */
|
|
60
|
+
exports.RETAIL_SPEI_TRACKING_KEY_PATTERN = /^\d{18}$/;
|
|
61
|
+
exports.RETAIL_CLABE_PATTERN = /^\d{18}$/;
|
|
62
|
+
/** Tope del motivo de cancelación de una venta. */
|
|
63
|
+
exports.RETAIL_CANCEL_REASON_MAX_LENGTH = 200;
|
|
64
|
+
/** Teléfono del cliente en la venta: 10 dígitos. */
|
|
65
|
+
exports.RETAIL_CUSTOMER_PHONE_PATTERN = /^\d{10}$/;
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
/** Lo que regresa dañado al cancelar; `identifier` en `null` si el producto es `QUANTITY`. */
|
|
2
|
+
export declare class RetailSystemDamagedItem {
|
|
3
|
+
sku: string;
|
|
4
|
+
identifier: string | null;
|
|
5
|
+
qty: number;
|
|
6
|
+
}
|
|
1
7
|
/** Cuerpo de `POST /private/retail/sales/cancel`; el `saleId` es el mismo del registro. */
|
|
2
8
|
export declare class CancelRetailSaleRequest {
|
|
3
9
|
saleId: string;
|
|
4
10
|
cancelledAt: string;
|
|
5
11
|
reason: string;
|
|
12
|
+
damaged: RetailSystemDamagedItem[];
|
|
6
13
|
}
|
|
@@ -9,9 +9,35 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
9
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.CancelRetailSaleRequest = void 0;
|
|
12
|
+
exports.CancelRetailSaleRequest = exports.RetailSystemDamagedItem = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
13
14
|
const class_validator_1 = require("class-validator");
|
|
15
|
+
const retailIntegrationLimits_1 = require("../constants/retailIntegrationLimits");
|
|
14
16
|
const IsIsoDateTimeWithZone_1 = require("../validators/IsIsoDateTimeWithZone");
|
|
17
|
+
const payloadValidators_1 = require("../validators/payloadValidators");
|
|
18
|
+
const saleValidators_1 = require("../validators/saleValidators");
|
|
19
|
+
/** Lo que regresa dañado al cancelar; `identifier` en `null` si el producto es `QUANTITY`. */
|
|
20
|
+
class RetailSystemDamagedItem {
|
|
21
|
+
}
|
|
22
|
+
exports.RetailSystemDamagedItem = RetailSystemDamagedItem;
|
|
23
|
+
__decorate([
|
|
24
|
+
(0, class_validator_1.IsString)(),
|
|
25
|
+
(0, class_validator_1.Matches)(retailIntegrationLimits_1.RETAIL_SKU_PATTERN),
|
|
26
|
+
__metadata("design:type", String)
|
|
27
|
+
], RetailSystemDamagedItem.prototype, "sku", void 0);
|
|
28
|
+
__decorate([
|
|
29
|
+
(0, class_validator_1.ValidateIf)(payloadValidators_1.isNullOrValidated),
|
|
30
|
+
(0, class_validator_1.IsString)(),
|
|
31
|
+
(0, class_validator_1.Matches)(/\S/),
|
|
32
|
+
(0, class_validator_1.MaxLength)(retailIntegrationLimits_1.RETAIL_SHORT_TEXT_MAX_LENGTH),
|
|
33
|
+
__metadata("design:type", String)
|
|
34
|
+
], RetailSystemDamagedItem.prototype, "identifier", void 0);
|
|
35
|
+
__decorate([
|
|
36
|
+
(0, class_validator_1.IsInt)(),
|
|
37
|
+
(0, class_validator_1.Min)(1),
|
|
38
|
+
(0, class_validator_1.Validate)(saleValidators_1.QtyMatchesIdentifier),
|
|
39
|
+
__metadata("design:type", Number)
|
|
40
|
+
], RetailSystemDamagedItem.prototype, "qty", void 0);
|
|
15
41
|
/** Cuerpo de `POST /private/retail/sales/cancel`; el `saleId` es el mismo del registro. */
|
|
16
42
|
class CancelRetailSaleRequest {
|
|
17
43
|
}
|
|
@@ -28,5 +54,12 @@ __decorate([
|
|
|
28
54
|
__decorate([
|
|
29
55
|
(0, class_validator_1.IsString)(),
|
|
30
56
|
(0, class_validator_1.Matches)(/\S/),
|
|
57
|
+
(0, class_validator_1.MaxLength)(retailIntegrationLimits_1.RETAIL_CANCEL_REASON_MAX_LENGTH),
|
|
31
58
|
__metadata("design:type", String)
|
|
32
59
|
], CancelRetailSaleRequest.prototype, "reason", void 0);
|
|
60
|
+
__decorate([
|
|
61
|
+
(0, class_validator_1.IsArray)(),
|
|
62
|
+
(0, class_validator_1.ValidateNested)({ each: true }),
|
|
63
|
+
(0, class_transformer_1.Type)(() => RetailSystemDamagedItem),
|
|
64
|
+
__metadata("design:type", Array)
|
|
65
|
+
], CancelRetailSaleRequest.prototype, "damaged", void 0);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RetailPaymentFrequencyEnum = void 0;
|
|
4
|
+
/** Cada cuánto paga el cliente en `credit.paymentFrequency`. */
|
|
5
|
+
var RetailPaymentFrequencyEnum;
|
|
6
|
+
(function (RetailPaymentFrequencyEnum) {
|
|
7
|
+
RetailPaymentFrequencyEnum["WEEKLY"] = "WEEKLY";
|
|
8
|
+
RetailPaymentFrequencyEnum["BIWEEKLY"] = "BIWEEKLY";
|
|
9
|
+
RetailPaymentFrequencyEnum["MONTHLY"] = "MONTHLY";
|
|
10
|
+
})(RetailPaymentFrequencyEnum || (exports.RetailPaymentFrequencyEnum = RetailPaymentFrequencyEnum = {}));
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.RetailPaymentMethodEnum = void 0;
|
|
4
|
-
/**
|
|
4
|
+
/** Medio de pago de `payments[].method` en la venta. */
|
|
5
5
|
var RetailPaymentMethodEnum;
|
|
6
6
|
(function (RetailPaymentMethodEnum) {
|
|
7
7
|
RetailPaymentMethodEnum["CASH"] = "CASH";
|
|
8
8
|
RetailPaymentMethodEnum["CARD"] = "CARD";
|
|
9
|
-
RetailPaymentMethodEnum["
|
|
9
|
+
RetailPaymentMethodEnum["WIRE"] = "WIRE";
|
|
10
|
+
RetailPaymentMethodEnum["FIADO"] = "FIADO";
|
|
10
11
|
})(RetailPaymentMethodEnum || (exports.RetailPaymentMethodEnum = RetailPaymentMethodEnum = {}));
|
|
@@ -18,6 +18,7 @@ export * from './RetailUserAccessStatusEnum';
|
|
|
18
18
|
export * from './RetailSaleTypeEnum';
|
|
19
19
|
export * from './RetailSaleFinancierEnum';
|
|
20
20
|
export * from './RetailPaymentMethodEnum';
|
|
21
|
+
export * from './RetailPaymentFrequencyEnum';
|
|
21
22
|
export * from './RetailLinePaymentTypeEnum';
|
|
22
23
|
export * from './RetailSaleLineRoleEnum';
|
|
23
24
|
export * from './RetailEventRejectCodeEnum';
|
|
@@ -34,6 +34,7 @@ __exportStar(require("./RetailUserAccessStatusEnum"), exports);
|
|
|
34
34
|
__exportStar(require("./RetailSaleTypeEnum"), exports);
|
|
35
35
|
__exportStar(require("./RetailSaleFinancierEnum"), exports);
|
|
36
36
|
__exportStar(require("./RetailPaymentMethodEnum"), exports);
|
|
37
|
+
__exportStar(require("./RetailPaymentFrequencyEnum"), exports);
|
|
37
38
|
__exportStar(require("./RetailLinePaymentTypeEnum"), exports);
|
|
38
39
|
__exportStar(require("./RetailSaleLineRoleEnum"), exports);
|
|
39
40
|
__exportStar(require("./RetailEventRejectCodeEnum"), exports);
|
|
@@ -3,6 +3,8 @@ export * from './constants/retailIntegrationErrorHttpStatus';
|
|
|
3
3
|
export * from './enums';
|
|
4
4
|
export * from './validators/IsIsoDateTimeWithZone';
|
|
5
5
|
export * from './validators/IsMovementsRangeValid';
|
|
6
|
+
export * from './validators/IsCalendarDate';
|
|
7
|
+
export * from './validators/saleValidators';
|
|
6
8
|
export * from './dtos/RetailEventEnvelope';
|
|
7
9
|
export * from './dtos/ReceiveStoreEventRequest';
|
|
8
10
|
export * from './dtos/ReceiveRetailUserEventRequest';
|
|
@@ -19,6 +19,8 @@ __exportStar(require("./constants/retailIntegrationErrorHttpStatus"), exports);
|
|
|
19
19
|
__exportStar(require("./enums"), exports);
|
|
20
20
|
__exportStar(require("./validators/IsIsoDateTimeWithZone"), exports);
|
|
21
21
|
__exportStar(require("./validators/IsMovementsRangeValid"), exports);
|
|
22
|
+
__exportStar(require("./validators/IsCalendarDate"), exports);
|
|
23
|
+
__exportStar(require("./validators/saleValidators"), exports);
|
|
22
24
|
__exportStar(require("./dtos/RetailEventEnvelope"), exports);
|
|
23
25
|
__exportStar(require("./dtos/ReceiveStoreEventRequest"), exports);
|
|
24
26
|
__exportStar(require("./dtos/ReceiveRetailUserEventRequest"), exports);
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { RetailLinePaymentTypeEnum, RetailPaymentMethodEnum, RetailSaleFinancierEnum, RetailSaleLineRoleEnum, RetailSaleTypeEnum } from '../enums';
|
|
1
|
+
import { RetailLinePaymentTypeEnum, RetailPaymentFrequencyEnum, RetailPaymentMethodEnum, RetailSaleFinancierEnum, RetailSaleLineRoleEnum, RetailSaleTypeEnum } from '../enums';
|
|
2
2
|
import { RetailCurrency } from './RetailSystemProduct';
|
|
3
3
|
export type RetailSaleType = `${RetailSaleTypeEnum}`;
|
|
4
4
|
export type RetailSaleFinancier = `${RetailSaleFinancierEnum}`;
|
|
5
5
|
export type RetailPaymentMethod = `${RetailPaymentMethodEnum}`;
|
|
6
|
+
export type RetailPaymentFrequency = `${RetailPaymentFrequencyEnum}`;
|
|
6
7
|
export type RetailLinePaymentType = `${RetailLinePaymentTypeEnum}`;
|
|
7
8
|
export type RetailSaleLineRole = `${RetailSaleLineRoleEnum}`;
|
|
8
9
|
export declare class RetailSystemSaleCustomer {
|
|
@@ -12,6 +13,24 @@ export declare class RetailSystemSaleCustomer {
|
|
|
12
13
|
maternalLastName: string | null;
|
|
13
14
|
phone: string;
|
|
14
15
|
}
|
|
16
|
+
/** Condiciones del crédito; todas obligatorias cuando `credit` no es `null`. */
|
|
17
|
+
export declare class RetailSystemSaleCredit {
|
|
18
|
+
paymentFrequency: RetailPaymentFrequency;
|
|
19
|
+
installments: number;
|
|
20
|
+
installmentAmount: string;
|
|
21
|
+
downPayment: string;
|
|
22
|
+
totalToPay: string;
|
|
23
|
+
firstPaymentDate: string;
|
|
24
|
+
}
|
|
25
|
+
/** Un medio de pago de `amountPaid`; las seis llaves van siempre, en `null` las que no aplican. */
|
|
26
|
+
export declare class RetailSystemSalePayment {
|
|
27
|
+
method: RetailPaymentMethod;
|
|
28
|
+
amount: string;
|
|
29
|
+
cardLast4: string | null;
|
|
30
|
+
authCode: string | null;
|
|
31
|
+
speiTrackingKey: string | null;
|
|
32
|
+
senderClabe: string | null;
|
|
33
|
+
}
|
|
15
34
|
export declare class RetailSystemSaleComponent {
|
|
16
35
|
sku: string;
|
|
17
36
|
qty: number;
|
|
@@ -26,6 +45,7 @@ export declare class RetailSystemSaleLine {
|
|
|
26
45
|
paymentType: RetailLinePaymentType;
|
|
27
46
|
financedAmount: string;
|
|
28
47
|
role: RetailSaleLineRole | null;
|
|
48
|
+
promotionId: string | null;
|
|
29
49
|
components: RetailSystemSaleComponent[];
|
|
30
50
|
}
|
|
31
51
|
/** Cuerpo de `POST /sales` de la doc y de `privateRegisterRetailSale`; `saleId` es la llave de idempotencia. */
|
|
@@ -38,10 +58,11 @@ export declare class RetailSystemSale {
|
|
|
38
58
|
saleType: RetailSaleType;
|
|
39
59
|
financier: RetailSaleFinancier;
|
|
40
60
|
creditId: string | null;
|
|
61
|
+
credit: RetailSystemSaleCredit | null;
|
|
41
62
|
currencyId: RetailCurrency;
|
|
42
63
|
customer: RetailSystemSaleCustomer;
|
|
43
64
|
equipmentPrice: string;
|
|
44
65
|
amountPaid: string;
|
|
45
|
-
|
|
66
|
+
payments: RetailSystemSalePayment[];
|
|
46
67
|
lines: RetailSystemSaleLine[];
|
|
47
68
|
}
|