@fiado/type-kit 3.539.0 → 3.540.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/retailCustomer/ensureCustomerByPhoneRequest.test.ts +30 -0
- package/_test_/unit/retailWizard/accessorySaleRequests.test.ts +108 -0
- package/_test_/unit/retailWizard/cancelSaleConditions.test.ts +2 -1
- package/_test_/unit/retailWizard/portalCancelSaleRequest.test.ts +34 -0
- package/bin/retailCustomer/dtos/requests/EnsureCustomerByPhoneRequest.d.ts +9 -0
- package/bin/retailCustomer/dtos/requests/EnsureCustomerByPhoneRequest.js +34 -0
- package/bin/retailCustomer/dtos/responses/EnsureCustomerByPhoneResponse.d.ts +5 -0
- package/bin/retailCustomer/dtos/responses/EnsureCustomerByPhoneResponse.js +2 -0
- package/bin/retailCustomer/index.d.ts +2 -0
- package/bin/retailCustomer/index.js +2 -0
- package/bin/retailWizard/dtos/AccessorySaleLine.d.ts +7 -0
- package/bin/retailWizard/dtos/AccessorySaleLine.js +38 -0
- package/bin/retailWizard/dtos/Sale.d.ts +5 -1
- package/bin/retailWizard/dtos/requests/CreateAccessorySaleRequest.d.ts +18 -0
- package/bin/retailWizard/dtos/requests/CreateAccessorySaleRequest.js +69 -0
- package/bin/retailWizard/dtos/requests/PortalCancelSaleRequest.d.ts +12 -0
- package/bin/retailWizard/dtos/requests/PortalCancelSaleRequest.js +43 -0
- package/bin/retailWizard/dtos/requests/SendAccessoryOtpRequest.d.ts +4 -0
- package/bin/retailWizard/dtos/requests/SendAccessoryOtpRequest.js +25 -0
- package/bin/retailWizard/dtos/requests/VerifyAccessoryOtpRequest.d.ts +4 -0
- package/bin/retailWizard/dtos/requests/VerifyAccessoryOtpRequest.js +24 -0
- package/bin/retailWizard/dtos/responses/AccessoryOtpChallenge.d.ts +7 -0
- package/bin/retailWizard/dtos/responses/AccessoryOtpChallenge.js +2 -0
- package/bin/retailWizard/dtos/responses/VerifyAccessoryOtpResponse.d.ts +7 -0
- package/bin/retailWizard/dtos/responses/VerifyAccessoryOtpResponse.js +2 -0
- package/bin/retailWizard/enums/SaleChannelEnum.d.ts +5 -0
- package/bin/retailWizard/enums/SaleChannelEnum.js +9 -0
- package/bin/retailWizard/index.d.ts +8 -0
- package/bin/retailWizard/index.js +8 -0
- package/package.json +1 -1
- package/src/retailCustomer/dtos/requests/EnsureCustomerByPhoneRequest.ts +20 -0
- package/src/retailCustomer/dtos/responses/EnsureCustomerByPhoneResponse.ts +6 -0
- package/src/retailCustomer/index.ts +2 -0
- package/src/retailWizard/dtos/AccessorySaleLine.ts +23 -0
- package/src/retailWizard/dtos/Sale.ts +5 -1
- package/src/retailWizard/dtos/requests/CreateAccessorySaleRequest.ts +64 -0
- package/src/retailWizard/dtos/requests/PortalCancelSaleRequest.ts +29 -0
- package/src/retailWizard/dtos/requests/SendAccessoryOtpRequest.ts +11 -0
- package/src/retailWizard/dtos/requests/VerifyAccessoryOtpRequest.ts +10 -0
- package/src/retailWizard/dtos/responses/AccessoryOtpChallenge.ts +7 -0
- package/src/retailWizard/dtos/responses/VerifyAccessoryOtpResponse.ts +7 -0
- package/src/retailWizard/enums/SaleChannelEnum.ts +5 -0
- package/src/retailWizard/index.ts +8 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { plainToInstance } from 'class-transformer';
|
|
3
|
+
import { validateSync } from 'class-validator';
|
|
4
|
+
import { EnsureCustomerByPhoneRequest } from '../../../src/retailCustomer/dtos/requests/EnsureCustomerByPhoneRequest';
|
|
5
|
+
import * as RetailCustomer from '../../../src/retailCustomer';
|
|
6
|
+
|
|
7
|
+
function errorsOf(payload: Record<string, unknown>): string[] {
|
|
8
|
+
const dto = plainToInstance(EnsureCustomerByPhoneRequest, payload, { excludeExtraneousValues: true });
|
|
9
|
+
return validateSync(dto).map((e) => e.property);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
describe('EnsureCustomerByPhoneRequest', () => {
|
|
13
|
+
it('acepta celular de 10 dígitos y tienda', () => {
|
|
14
|
+
expect(errorsOf({ phone: '5512345678', originStoreId: 'store-1' })).toEqual([]);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('rechaza un celular con lada o separadores', () => {
|
|
18
|
+
expect(errorsOf({ phone: '+525512345678', originStoreId: 'store-1' })).toContain('phone');
|
|
19
|
+
expect(errorsOf({ phone: '55-1234-5678', originStoreId: 'store-1' })).toContain('phone');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('exige la tienda de alta', () => {
|
|
23
|
+
expect(errorsOf({ phone: '5512345678' })).toContain('originStoreId');
|
|
24
|
+
expect(errorsOf({ phone: '5512345678', originStoreId: '' })).toContain('originStoreId');
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('se exporta en el barrel', () => {
|
|
28
|
+
expect(RetailCustomer.EnsureCustomerByPhoneRequest).toBe(EnsureCustomerByPhoneRequest);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { plainToInstance } from 'class-transformer';
|
|
3
|
+
import { validateSync } from 'class-validator';
|
|
4
|
+
import { SendAccessoryOtpRequest } from '../../../src/retailWizard/dtos/requests/SendAccessoryOtpRequest';
|
|
5
|
+
import { VerifyAccessoryOtpRequest } from '../../../src/retailWizard/dtos/requests/VerifyAccessoryOtpRequest';
|
|
6
|
+
import { CreateAccessorySaleRequest } from '../../../src/retailWizard/dtos/requests/CreateAccessorySaleRequest';
|
|
7
|
+
import { SaleChannelEnum } from '../../../src/retailWizard/enums/SaleChannelEnum';
|
|
8
|
+
import { SalePaymentMethodEnum } from '../../../src/retailWizard/enums/SalePaymentMethodEnum';
|
|
9
|
+
import * as RetailWizard from '../../../src/retailWizard';
|
|
10
|
+
|
|
11
|
+
function errorsOf<T extends object>(cls: new () => T, payload: Record<string, unknown>): string[] {
|
|
12
|
+
const dto = plainToInstance(cls, payload, { excludeExtraneousValues: true });
|
|
13
|
+
return validateSync(dto).map((e) => e.property);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const validSale = {
|
|
17
|
+
otpChallengeId: 'chl-1',
|
|
18
|
+
lines: [{ sku: 'ACC-1', qty: 2 }],
|
|
19
|
+
paymentMethod: SalePaymentMethodEnum.CASH,
|
|
20
|
+
amountCents: 39800,
|
|
21
|
+
paymentDetail: { cashConfirmedInRegister: true },
|
|
22
|
+
privacyNoticeAccepted: true,
|
|
23
|
+
privacyNoticeVersion: 'AVISO-2026-10',
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
describe('SendAccessoryOtpRequest', () => {
|
|
27
|
+
it('acepta un celular de 10 dígitos', () => {
|
|
28
|
+
expect(errorsOf(SendAccessoryOtpRequest, { phone: '5512345678' })).toEqual([]);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it.each(['+525512345678', '55 1234 5678', '551234567', ''])('rechaza %p', (phone) => {
|
|
32
|
+
expect(errorsOf(SendAccessoryOtpRequest, { phone })).toContain('phone');
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
describe('VerifyAccessoryOtpRequest', () => {
|
|
37
|
+
it('acepta el código de 4 dígitos de messages-business', () => {
|
|
38
|
+
expect(errorsOf(VerifyAccessoryOtpRequest, { code: '1234' })).toEqual([]);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('rechaza un código de 3 dígitos', () => {
|
|
42
|
+
expect(errorsOf(VerifyAccessoryOtpRequest, { code: '123' })).toContain('code');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('rechaza un código ausente', () => {
|
|
46
|
+
expect(errorsOf(VerifyAccessoryOtpRequest, {})).toContain('code');
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe('CreateAccessorySaleRequest', () => {
|
|
51
|
+
it('acepta una venta válida', () => {
|
|
52
|
+
expect(errorsOf(CreateAccessorySaleRequest, validSale)).toEqual([]);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('acepta piezas con identificadores', () => {
|
|
56
|
+
const payload = { ...validSale, lines: [{ sku: 'ACC-1', qty: 1, identifiers: ['SER-1'] }] };
|
|
57
|
+
expect(errorsOf(CreateAccessorySaleRequest, payload)).toEqual([]);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('rechaza un carrito vacío', () => {
|
|
61
|
+
expect(errorsOf(CreateAccessorySaleRequest, { ...validSale, lines: [] })).toContain('lines');
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('rechaza una línea con qty 0', () => {
|
|
65
|
+
expect(errorsOf(CreateAccessorySaleRequest, { ...validSale, lines: [{ sku: 'ACC-1', qty: 0 }] })).toContain('lines');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('rechaza un medio de pago fuera del enum', () => {
|
|
69
|
+
expect(errorsOf(CreateAccessorySaleRequest, { ...validSale, paymentMethod: 'WALLET' })).toContain('paymentMethod');
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('rechaza un monto negativo o decimal', () => {
|
|
73
|
+
expect(errorsOf(CreateAccessorySaleRequest, { ...validSale, amountCents: -1 })).toContain('amountCents');
|
|
74
|
+
expect(errorsOf(CreateAccessorySaleRequest, { ...validSale, amountCents: 10.5 })).toContain('amountCents');
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('exige el comprobante del cobro', () => {
|
|
78
|
+
const { paymentDetail: _omit, ...rest } = validSale;
|
|
79
|
+
expect(errorsOf(CreateAccessorySaleRequest, rest)).toContain('paymentDetail');
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('exige la versión del aviso de privacidad', () => {
|
|
83
|
+
expect(errorsOf(CreateAccessorySaleRequest, { ...validSale, privacyNoticeVersion: '' })).toContain('privacyNoticeVersion');
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('privacyNoticeAccepted no booleano → error de formato', () => {
|
|
87
|
+
expect(errorsOf(CreateAccessorySaleRequest, { ...validSale, privacyNoticeAccepted: 'si' })).toContain('privacyNoticeAccepted');
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('el medio WIRE (SPEI) es válido', () => {
|
|
91
|
+
expect(errorsOf(CreateAccessorySaleRequest, { ...validSale, paymentMethod: SalePaymentMethodEnum.WIRE })).toEqual([]);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('exige el reto OTP', () => {
|
|
95
|
+
expect(errorsOf(CreateAccessorySaleRequest, { ...validSale, otpChallengeId: '' })).toContain('otpChallengeId');
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
describe('barrel retailWizard', () => {
|
|
100
|
+
it('exporta los contratos del cobro de accesorios', () => {
|
|
101
|
+
expect(RetailWizard.SendAccessoryOtpRequest).toBeDefined();
|
|
102
|
+
expect(RetailWizard.VerifyAccessoryOtpRequest).toBeDefined();
|
|
103
|
+
expect(RetailWizard.CreateAccessorySaleRequest).toBeDefined();
|
|
104
|
+
expect(RetailWizard.AccessorySaleLine).toBeDefined();
|
|
105
|
+
expect(RetailWizard.SaleChannelEnum.ACCESSORY_COUNTER).toBe('ACCESSORY_COUNTER');
|
|
106
|
+
expect(SaleChannelEnum.WIZARD).toBe('WIZARD');
|
|
107
|
+
});
|
|
108
|
+
});
|
|
@@ -2,7 +2,7 @@ import 'reflect-metadata';
|
|
|
2
2
|
import { plainToInstance, type ClassConstructor } from 'class-transformer';
|
|
3
3
|
import { validateSync, type ValidationError } from 'class-validator';
|
|
4
4
|
import { ReturnPieceCondition } from '../../../src/retailCatalog';
|
|
5
|
-
import { BackofficeCancelSaleRequest, CancelSaleRequest } from '../../../src/retailWizard';
|
|
5
|
+
import { BackofficeCancelSaleRequest, CancelSaleRequest, PortalCancelSaleRequest } from '../../../src/retailWizard';
|
|
6
6
|
|
|
7
7
|
function paths(errors: ValidationError[], prefix = ''): string[] {
|
|
8
8
|
return errors.flatMap((e) => {
|
|
@@ -23,6 +23,7 @@ const conditions = [
|
|
|
23
23
|
describe.each([
|
|
24
24
|
['CancelSaleRequest', CancelSaleRequest, { reason: 'Cliente se arrepintió' }],
|
|
25
25
|
['BackofficeCancelSaleRequest', BackofficeCancelSaleRequest, { reason: 'Cliente se arrepintió' }],
|
|
26
|
+
['PortalCancelSaleRequest', PortalCancelSaleRequest, { reason: 'Cliente se arrepintió' }],
|
|
26
27
|
] as const)('%s con condición por pieza', (_name, cls, base) => {
|
|
27
28
|
it('sin returnConditions sigue validando', () => expect(errorsOf(cls, base)).toEqual([]));
|
|
28
29
|
it('acepta condiciones y las hidrata aun con excludeExtraneousValues', () => {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { plainToInstance } from 'class-transformer';
|
|
3
|
+
import { validateSync } from 'class-validator';
|
|
4
|
+
import { PortalCancelSaleRequest } from '../../../src/retailWizard';
|
|
5
|
+
|
|
6
|
+
function errorsOf(payload: object): string[] {
|
|
7
|
+
const dto = plainToInstance(PortalCancelSaleRequest, payload, { excludeExtraneousValues: true });
|
|
8
|
+
return validateSync(dto).map((e) => e.property);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
describe('PortalCancelSaleRequest', () => {
|
|
12
|
+
it('acepta motivo de 10 a 200 caracteres con el equipo confirmado', () => {
|
|
13
|
+
expect(errorsOf({ reason: 'Cliente se arrepintió', equipmentVerified: true })).toEqual([]);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('exige el motivo con la misma longitud que la cancelación del Admin VL', () => {
|
|
17
|
+
expect(errorsOf({})).toContain('reason');
|
|
18
|
+
expect(errorsOf({ reason: 'corto' })).toContain('reason');
|
|
19
|
+
expect(errorsOf({ reason: 'x'.repeat(201) })).toContain('reason');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('rechaza el string "false" como equipmentVerified', () => {
|
|
23
|
+
expect(errorsOf({ reason: 'Cliente se arrepintió', equipmentVerified: 'false' })).toContain('equipmentVerified');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('no expone la excepción de cancelación tardía', () => {
|
|
27
|
+
const dto = plainToInstance(
|
|
28
|
+
PortalCancelSaleRequest,
|
|
29
|
+
{ reason: 'Cliente se arrepintió', outOfWindowExceptionId: 'EXC-1' },
|
|
30
|
+
{ excludeExtraneousValues: true },
|
|
31
|
+
);
|
|
32
|
+
expect(dto).not.toHaveProperty('outOfWindowExceptionId');
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* POST /private/customers/ensure-by-phone — da de alta al cliente solo con su celular verificado,
|
|
3
|
+
* o devuelve el que ya existe con ese número.
|
|
4
|
+
*/
|
|
5
|
+
export declare class EnsureCustomerByPhoneRequest {
|
|
6
|
+
phone: string;
|
|
7
|
+
/** Tienda del primer contacto; no cambia si el cliente ya existía. */
|
|
8
|
+
originStoreId: string;
|
|
9
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
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.EnsureCustomerByPhoneRequest = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
const regex_1 = require("../../../helpers/constans/regex");
|
|
16
|
+
/**
|
|
17
|
+
* POST /private/customers/ensure-by-phone — da de alta al cliente solo con su celular verificado,
|
|
18
|
+
* o devuelve el que ya existe con ese número.
|
|
19
|
+
*/
|
|
20
|
+
class EnsureCustomerByPhoneRequest {
|
|
21
|
+
}
|
|
22
|
+
exports.EnsureCustomerByPhoneRequest = EnsureCustomerByPhoneRequest;
|
|
23
|
+
__decorate([
|
|
24
|
+
(0, class_transformer_1.Expose)(),
|
|
25
|
+
(0, class_validator_1.IsString)(),
|
|
26
|
+
(0, class_validator_1.Matches)(regex_1.regexPhoneMx, { message: 'phone debe tener 10 dígitos' }),
|
|
27
|
+
__metadata("design:type", String)
|
|
28
|
+
], EnsureCustomerByPhoneRequest.prototype, "phone", void 0);
|
|
29
|
+
__decorate([
|
|
30
|
+
(0, class_transformer_1.Expose)(),
|
|
31
|
+
(0, class_validator_1.IsString)(),
|
|
32
|
+
(0, class_validator_1.MinLength)(1),
|
|
33
|
+
__metadata("design:type", String)
|
|
34
|
+
], EnsureCustomerByPhoneRequest.prototype, "originStoreId", void 0);
|
|
@@ -19,11 +19,13 @@ export * from './dtos/requests/KycReviewRequest';
|
|
|
19
19
|
export * from './dtos/requests/WelcomeAccreditationRequest';
|
|
20
20
|
export * from './dtos/requests/WelcomeAccreditationResultRequest';
|
|
21
21
|
export * from './dtos/requests/UpsertPromotionBonusRequest';
|
|
22
|
+
export * from './dtos/requests/EnsureCustomerByPhoneRequest';
|
|
22
23
|
export * from './dtos/responses/CustomerResponse';
|
|
23
24
|
export * from './dtos/responses/Customer360Response';
|
|
24
25
|
export * from './dtos/responses/WelcomeBonusResponse';
|
|
25
26
|
export * from './dtos/responses/WelcomeAccreditationResponse';
|
|
26
27
|
export * from './dtos/responses/PromotionBonusEntryResponse';
|
|
28
|
+
export * from './dtos/responses/EnsureCustomerByPhoneResponse';
|
|
27
29
|
export * from './events/CustomerCreatedV1';
|
|
28
30
|
export * from './events/CustomerUpdatedV1';
|
|
29
31
|
export * from './events/CustomerKycVerifiedV1';
|
|
@@ -38,12 +38,14 @@ __exportStar(require("./dtos/requests/KycReviewRequest"), exports);
|
|
|
38
38
|
__exportStar(require("./dtos/requests/WelcomeAccreditationRequest"), exports);
|
|
39
39
|
__exportStar(require("./dtos/requests/WelcomeAccreditationResultRequest"), exports);
|
|
40
40
|
__exportStar(require("./dtos/requests/UpsertPromotionBonusRequest"), exports);
|
|
41
|
+
__exportStar(require("./dtos/requests/EnsureCustomerByPhoneRequest"), exports);
|
|
41
42
|
// Response DTOs
|
|
42
43
|
__exportStar(require("./dtos/responses/CustomerResponse"), exports);
|
|
43
44
|
__exportStar(require("./dtos/responses/Customer360Response"), exports);
|
|
44
45
|
__exportStar(require("./dtos/responses/WelcomeBonusResponse"), exports);
|
|
45
46
|
__exportStar(require("./dtos/responses/WelcomeAccreditationResponse"), exports);
|
|
46
47
|
__exportStar(require("./dtos/responses/PromotionBonusEntryResponse"), exports);
|
|
48
|
+
__exportStar(require("./dtos/responses/EnsureCustomerByPhoneResponse"), exports);
|
|
47
49
|
// Contratos de eventos (PascalCase + sufijo V1)
|
|
48
50
|
__exportStar(require("./events/CustomerCreatedV1"), exports);
|
|
49
51
|
__exportStar(require("./events/CustomerUpdatedV1"), exports);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Línea del carrito de accesorios; el precio lo pone el catálogo, no el request. */
|
|
2
|
+
export declare class AccessorySaleLine {
|
|
3
|
+
sku: string;
|
|
4
|
+
qty: number;
|
|
5
|
+
/** Serie de cada pieza cuando el SKU se rastrea por pieza; ausente si se rastrea por cantidad. */
|
|
6
|
+
identifiers?: string[];
|
|
7
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
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.AccessorySaleLine = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
/** Línea del carrito de accesorios; el precio lo pone el catálogo, no el request. */
|
|
16
|
+
class AccessorySaleLine {
|
|
17
|
+
}
|
|
18
|
+
exports.AccessorySaleLine = AccessorySaleLine;
|
|
19
|
+
__decorate([
|
|
20
|
+
(0, class_transformer_1.Expose)(),
|
|
21
|
+
(0, class_validator_1.IsString)(),
|
|
22
|
+
(0, class_validator_1.MinLength)(1),
|
|
23
|
+
__metadata("design:type", String)
|
|
24
|
+
], AccessorySaleLine.prototype, "sku", void 0);
|
|
25
|
+
__decorate([
|
|
26
|
+
(0, class_transformer_1.Expose)(),
|
|
27
|
+
(0, class_validator_1.IsInt)(),
|
|
28
|
+
(0, class_validator_1.Min)(1),
|
|
29
|
+
__metadata("design:type", Number)
|
|
30
|
+
], AccessorySaleLine.prototype, "qty", void 0);
|
|
31
|
+
__decorate([
|
|
32
|
+
(0, class_transformer_1.Expose)(),
|
|
33
|
+
(0, class_validator_1.IsOptional)(),
|
|
34
|
+
(0, class_validator_1.IsArray)(),
|
|
35
|
+
(0, class_validator_1.ArrayMaxSize)(100),
|
|
36
|
+
(0, class_validator_1.IsString)({ each: true }),
|
|
37
|
+
__metadata("design:type", Array)
|
|
38
|
+
], AccessorySaleLine.prototype, "identifiers", void 0);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { SaleTypeEnum } from '../enums/SaleTypeEnum';
|
|
2
2
|
import type { SaleStatusEnum } from '../enums/SaleStatusEnum';
|
|
3
3
|
import type { SalePaymentMethodEnum } from '../enums/SalePaymentMethodEnum';
|
|
4
|
+
import type { SaleChannelEnum } from '../enums/SaleChannelEnum';
|
|
4
5
|
import type { ExternalProviderEnum } from '../enums/ExternalProviderEnum';
|
|
5
6
|
import type { CentralSyncStatusEnum } from '../enums/CentralSyncStatusEnum';
|
|
6
7
|
import type { SalePaymentDetail } from './SalePaymentDetail';
|
|
@@ -17,7 +18,10 @@ export interface Sale {
|
|
|
17
18
|
storeId: string;
|
|
18
19
|
sellerRetailUserId: string;
|
|
19
20
|
retailCustomerId: string;
|
|
20
|
-
|
|
21
|
+
/** Sesión del wizard que cerró la venta; ausente en la venta de mostrador. */
|
|
22
|
+
wizardSessionId?: string;
|
|
23
|
+
/** Canal de la venta; ausente = `WIZARD` (ventas anteriores al campo). */
|
|
24
|
+
saleChannel?: SaleChannelEnum;
|
|
21
25
|
type: SaleTypeEnum;
|
|
22
26
|
externalProvider: ExternalProviderEnum | null;
|
|
23
27
|
/** SKU del teléfono de la venta; `null` en la venta sin teléfono (en DDB se omite). */
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SalePaymentMethodEnum } from '../../enums/SalePaymentMethodEnum';
|
|
2
|
+
import { SalePaymentDetail } from '../SalePaymentDetail';
|
|
3
|
+
import { AccessorySaleLine } from '../AccessorySaleLine';
|
|
4
|
+
/**
|
|
5
|
+
* POST /wizard/accessory-sales — cierra la venta de mostrador con el celular ya verificado.
|
|
6
|
+
* `amountCents` es lo cobrado en caja y debe igualar la suma del catálogo.
|
|
7
|
+
*/
|
|
8
|
+
export declare class CreateAccessorySaleRequest {
|
|
9
|
+
otpChallengeId: string;
|
|
10
|
+
lines: AccessorySaleLine[];
|
|
11
|
+
paymentMethod: SalePaymentMethodEnum;
|
|
12
|
+
amountCents: number;
|
|
13
|
+
paymentDetail: SalePaymentDetail;
|
|
14
|
+
/** El cliente aceptó el aviso de privacidad; sin `true` el back responde 400 PRIVACY_NOTICE_REQUIRED. */
|
|
15
|
+
privacyNoticeAccepted?: boolean;
|
|
16
|
+
/** Versión del aviso de privacidad que se mostró. */
|
|
17
|
+
privacyNoticeVersion: string;
|
|
18
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
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.CreateAccessorySaleRequest = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
const SalePaymentMethodEnum_1 = require("../../enums/SalePaymentMethodEnum");
|
|
16
|
+
const SalePaymentDetail_1 = require("../SalePaymentDetail");
|
|
17
|
+
const AccessorySaleLine_1 = require("../AccessorySaleLine");
|
|
18
|
+
/**
|
|
19
|
+
* POST /wizard/accessory-sales — cierra la venta de mostrador con el celular ya verificado.
|
|
20
|
+
* `amountCents` es lo cobrado en caja y debe igualar la suma del catálogo.
|
|
21
|
+
*/
|
|
22
|
+
class CreateAccessorySaleRequest {
|
|
23
|
+
}
|
|
24
|
+
exports.CreateAccessorySaleRequest = CreateAccessorySaleRequest;
|
|
25
|
+
__decorate([
|
|
26
|
+
(0, class_transformer_1.Expose)(),
|
|
27
|
+
(0, class_validator_1.IsString)(),
|
|
28
|
+
(0, class_validator_1.MinLength)(1),
|
|
29
|
+
__metadata("design:type", String)
|
|
30
|
+
], CreateAccessorySaleRequest.prototype, "otpChallengeId", void 0);
|
|
31
|
+
__decorate([
|
|
32
|
+
(0, class_transformer_1.Expose)(),
|
|
33
|
+
(0, class_validator_1.IsArray)(),
|
|
34
|
+
(0, class_validator_1.ArrayMinSize)(1),
|
|
35
|
+
(0, class_validator_1.ArrayMaxSize)(50),
|
|
36
|
+
(0, class_validator_1.ValidateNested)({ each: true }),
|
|
37
|
+
(0, class_transformer_1.Type)(() => AccessorySaleLine_1.AccessorySaleLine),
|
|
38
|
+
__metadata("design:type", Array)
|
|
39
|
+
], CreateAccessorySaleRequest.prototype, "lines", void 0);
|
|
40
|
+
__decorate([
|
|
41
|
+
(0, class_transformer_1.Expose)(),
|
|
42
|
+
(0, class_validator_1.IsEnum)(SalePaymentMethodEnum_1.SalePaymentMethodEnum),
|
|
43
|
+
__metadata("design:type", String)
|
|
44
|
+
], CreateAccessorySaleRequest.prototype, "paymentMethod", void 0);
|
|
45
|
+
__decorate([
|
|
46
|
+
(0, class_transformer_1.Expose)(),
|
|
47
|
+
(0, class_validator_1.IsInt)(),
|
|
48
|
+
(0, class_validator_1.Min)(0),
|
|
49
|
+
__metadata("design:type", Number)
|
|
50
|
+
], CreateAccessorySaleRequest.prototype, "amountCents", void 0);
|
|
51
|
+
__decorate([
|
|
52
|
+
(0, class_transformer_1.Expose)(),
|
|
53
|
+
(0, class_validator_1.IsDefined)(),
|
|
54
|
+
(0, class_validator_1.ValidateNested)(),
|
|
55
|
+
(0, class_transformer_1.Type)(() => SalePaymentDetail_1.SalePaymentDetail),
|
|
56
|
+
__metadata("design:type", SalePaymentDetail_1.SalePaymentDetail)
|
|
57
|
+
], CreateAccessorySaleRequest.prototype, "paymentDetail", void 0);
|
|
58
|
+
__decorate([
|
|
59
|
+
(0, class_transformer_1.Expose)(),
|
|
60
|
+
(0, class_validator_1.IsOptional)(),
|
|
61
|
+
(0, class_validator_1.IsBoolean)(),
|
|
62
|
+
__metadata("design:type", Boolean)
|
|
63
|
+
], CreateAccessorySaleRequest.prototype, "privacyNoticeAccepted", void 0);
|
|
64
|
+
__decorate([
|
|
65
|
+
(0, class_transformer_1.Expose)(),
|
|
66
|
+
(0, class_validator_1.IsString)(),
|
|
67
|
+
(0, class_validator_1.MinLength)(1),
|
|
68
|
+
__metadata("design:type", String)
|
|
69
|
+
], CreateAccessorySaleRequest.prototype, "privacyNoticeVersion", void 0);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ReturnPieceCondition } from '../../../retailCatalog/dtos/requests/ReturnPieceCondition';
|
|
2
|
+
/**
|
|
3
|
+
* POST /portal/sales/:saleId/cancel — el vendedor cancela una venta cerrada de su tienda, dentro de la
|
|
4
|
+
* ventana. Mismas validaciones que `BackofficeCancelSaleRequest`, sin la excepción de cancelación tardía.
|
|
5
|
+
*/
|
|
6
|
+
export declare class PortalCancelSaleRequest {
|
|
7
|
+
reason: string;
|
|
8
|
+
/** Equipo o piezas confirmados en tienda; ausente cuenta como no confirmado. */
|
|
9
|
+
equipmentVerified?: boolean;
|
|
10
|
+
/** Condición de cada pieza que regresa al inventario; las no listadas vuelven GOOD. */
|
|
11
|
+
returnConditions?: ReturnPieceCondition[];
|
|
12
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
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.PortalCancelSaleRequest = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
const ReturnPieceCondition_1 = require("../../../retailCatalog/dtos/requests/ReturnPieceCondition");
|
|
16
|
+
/**
|
|
17
|
+
* POST /portal/sales/:saleId/cancel — el vendedor cancela una venta cerrada de su tienda, dentro de la
|
|
18
|
+
* ventana. Mismas validaciones que `BackofficeCancelSaleRequest`, sin la excepción de cancelación tardía.
|
|
19
|
+
*/
|
|
20
|
+
class PortalCancelSaleRequest {
|
|
21
|
+
}
|
|
22
|
+
exports.PortalCancelSaleRequest = PortalCancelSaleRequest;
|
|
23
|
+
__decorate([
|
|
24
|
+
(0, class_transformer_1.Expose)(),
|
|
25
|
+
(0, class_validator_1.IsString)(),
|
|
26
|
+
(0, class_validator_1.MinLength)(10),
|
|
27
|
+
(0, class_validator_1.MaxLength)(200),
|
|
28
|
+
__metadata("design:type", String)
|
|
29
|
+
], PortalCancelSaleRequest.prototype, "reason", void 0);
|
|
30
|
+
__decorate([
|
|
31
|
+
(0, class_transformer_1.Expose)(),
|
|
32
|
+
(0, class_validator_1.IsOptional)(),
|
|
33
|
+
(0, class_validator_1.IsBoolean)(),
|
|
34
|
+
__metadata("design:type", Boolean)
|
|
35
|
+
], PortalCancelSaleRequest.prototype, "equipmentVerified", void 0);
|
|
36
|
+
__decorate([
|
|
37
|
+
(0, class_transformer_1.Expose)(),
|
|
38
|
+
(0, class_validator_1.IsOptional)(),
|
|
39
|
+
(0, class_validator_1.IsArray)(),
|
|
40
|
+
(0, class_validator_1.ValidateNested)({ each: true }),
|
|
41
|
+
(0, class_transformer_1.Type)(() => ReturnPieceCondition_1.ReturnPieceCondition),
|
|
42
|
+
__metadata("design:type", Array)
|
|
43
|
+
], PortalCancelSaleRequest.prototype, "returnConditions", void 0);
|
|
@@ -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.SendAccessoryOtpRequest = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
const regex_1 = require("../../../helpers/constans/regex");
|
|
16
|
+
/** POST /wizard/accessory-sales/otp — manda el OTP al celular del cliente del mostrador. */
|
|
17
|
+
class SendAccessoryOtpRequest {
|
|
18
|
+
}
|
|
19
|
+
exports.SendAccessoryOtpRequest = SendAccessoryOtpRequest;
|
|
20
|
+
__decorate([
|
|
21
|
+
(0, class_transformer_1.Expose)(),
|
|
22
|
+
(0, class_validator_1.IsString)(),
|
|
23
|
+
(0, class_validator_1.Matches)(regex_1.regexPhoneMx, { message: 'phone debe tener 10 dígitos' }),
|
|
24
|
+
__metadata("design:type", String)
|
|
25
|
+
], SendAccessoryOtpRequest.prototype, "phone", void 0);
|
|
@@ -0,0 +1,24 @@
|
|
|
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.VerifyAccessoryOtpRequest = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
/** POST /wizard/accessory-sales/otp/{otpChallengeId}/verify — código que dicta el cliente. */
|
|
16
|
+
class VerifyAccessoryOtpRequest {
|
|
17
|
+
}
|
|
18
|
+
exports.VerifyAccessoryOtpRequest = VerifyAccessoryOtpRequest;
|
|
19
|
+
__decorate([
|
|
20
|
+
(0, class_transformer_1.Expose)(),
|
|
21
|
+
(0, class_validator_1.IsString)(),
|
|
22
|
+
(0, class_validator_1.Length)(4, 8),
|
|
23
|
+
__metadata("design:type", String)
|
|
24
|
+
], VerifyAccessoryOtpRequest.prototype, "code", void 0);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SaleChannelEnum = void 0;
|
|
4
|
+
/** Canal por el que se cerró la venta: el wizard por sesión o el mostrador de accesorios. */
|
|
5
|
+
var SaleChannelEnum;
|
|
6
|
+
(function (SaleChannelEnum) {
|
|
7
|
+
SaleChannelEnum["WIZARD"] = "WIZARD";
|
|
8
|
+
SaleChannelEnum["ACCESSORY_COUNTER"] = "ACCESSORY_COUNTER";
|
|
9
|
+
})(SaleChannelEnum || (exports.SaleChannelEnum = SaleChannelEnum = {}));
|
|
@@ -29,6 +29,7 @@ export * from './enums/WizardLineStatusEnum';
|
|
|
29
29
|
export * from './enums/LinePaymentTypeEnum';
|
|
30
30
|
export * from './enums/WizardLineRoleEnum';
|
|
31
31
|
export * from './enums/EmailStateEnum';
|
|
32
|
+
export * from './enums/SaleChannelEnum';
|
|
32
33
|
export * from './dtos/WizardConsents';
|
|
33
34
|
export * from './dtos/WizardPayment';
|
|
34
35
|
export * from './dtos/WizardProduct';
|
|
@@ -52,6 +53,7 @@ export * from './dtos/WizardFinancingPreview';
|
|
|
52
53
|
export * from './dtos/WizardReservedLine';
|
|
53
54
|
export * from './dtos/WizardGiftLine';
|
|
54
55
|
export * from './dtos/SaleLine';
|
|
56
|
+
export * from './dtos/AccessorySaleLine';
|
|
55
57
|
export * from './dtos/WizardSession';
|
|
56
58
|
export * from './dtos/OtpVerification';
|
|
57
59
|
export * from './dtos/Sale';
|
|
@@ -97,6 +99,9 @@ export * from './dtos/requests/CompleteSaleRequest';
|
|
|
97
99
|
export * from './dtos/requests/SuggestIdentifiersQuery';
|
|
98
100
|
export * from './dtos/requests/SendEmailOtpRequest';
|
|
99
101
|
export * from './dtos/requests/VerifyEmailOtpRequest';
|
|
102
|
+
export * from './dtos/requests/SendAccessoryOtpRequest';
|
|
103
|
+
export * from './dtos/requests/VerifyAccessoryOtpRequest';
|
|
104
|
+
export * from './dtos/requests/CreateAccessorySaleRequest';
|
|
100
105
|
export * from './dtos/responses/KycPrepareResponse';
|
|
101
106
|
export * from './dtos/responses/ProofOfAddressPrepareResponse';
|
|
102
107
|
export * from './dtos/responses/SessionFinanciersResponse';
|
|
@@ -115,6 +120,8 @@ export * from './dtos/responses/ProspectResumeResponse';
|
|
|
115
120
|
export * from './dtos/responses/CancelOtherStoreSaleResponse';
|
|
116
121
|
export * from './dtos/responses/ProspectByPhoneResponse';
|
|
117
122
|
export * from './dtos/responses/AppOnboardingResponse';
|
|
123
|
+
export * from './dtos/responses/AccessoryOtpChallenge';
|
|
124
|
+
export * from './dtos/responses/VerifyAccessoryOtpResponse';
|
|
118
125
|
export * from './enums/SaleFinancierEnum';
|
|
119
126
|
export * from './enums/SaleExceptionTypeEnum';
|
|
120
127
|
export * from './enums/SaleExceptionStatusEnum';
|
|
@@ -138,6 +145,7 @@ export * from './dtos/requests/ApplySaleExceptionRequest';
|
|
|
138
145
|
export * from './dtos/requests/AddSaleExceptionNoteRequest';
|
|
139
146
|
export * from './dtos/requests/RunSalesReportRequest';
|
|
140
147
|
export * from './dtos/requests/BackofficeCancelSaleRequest';
|
|
148
|
+
export * from './dtos/requests/PortalCancelSaleRequest';
|
|
141
149
|
export * from './dtos/responses/BackofficeSalesStatsResponse';
|
|
142
150
|
export * from './dtos/responses/BackofficeSalesKpisResponse';
|
|
143
151
|
export * from './dtos/responses/BackofficeReportsResponse';
|
|
@@ -48,6 +48,7 @@ __exportStar(require("./enums/WizardLineStatusEnum"), exports);
|
|
|
48
48
|
__exportStar(require("./enums/LinePaymentTypeEnum"), exports);
|
|
49
49
|
__exportStar(require("./enums/WizardLineRoleEnum"), exports);
|
|
50
50
|
__exportStar(require("./enums/EmailStateEnum"), exports);
|
|
51
|
+
__exportStar(require("./enums/SaleChannelEnum"), exports);
|
|
51
52
|
// DTOs anidados
|
|
52
53
|
__exportStar(require("./dtos/WizardConsents"), exports);
|
|
53
54
|
__exportStar(require("./dtos/WizardPayment"), exports);
|
|
@@ -74,6 +75,7 @@ __exportStar(require("./dtos/WizardFinancingPreview"), exports);
|
|
|
74
75
|
__exportStar(require("./dtos/WizardReservedLine"), exports);
|
|
75
76
|
__exportStar(require("./dtos/WizardGiftLine"), exports);
|
|
76
77
|
__exportStar(require("./dtos/SaleLine"), exports);
|
|
78
|
+
__exportStar(require("./dtos/AccessorySaleLine"), exports);
|
|
77
79
|
// Entidades principales (shapes de estado/persistencia — planas)
|
|
78
80
|
__exportStar(require("./dtos/WizardSession"), exports);
|
|
79
81
|
__exportStar(require("./dtos/OtpVerification"), exports);
|
|
@@ -122,6 +124,9 @@ __exportStar(require("./dtos/requests/CompleteSaleRequest"), exports);
|
|
|
122
124
|
__exportStar(require("./dtos/requests/SuggestIdentifiersQuery"), exports);
|
|
123
125
|
__exportStar(require("./dtos/requests/SendEmailOtpRequest"), exports);
|
|
124
126
|
__exportStar(require("./dtos/requests/VerifyEmailOtpRequest"), exports);
|
|
127
|
+
__exportStar(require("./dtos/requests/SendAccessoryOtpRequest"), exports);
|
|
128
|
+
__exportStar(require("./dtos/requests/VerifyAccessoryOtpRequest"), exports);
|
|
129
|
+
__exportStar(require("./dtos/requests/CreateAccessorySaleRequest"), exports);
|
|
125
130
|
// Response DTOs (output tipado por endpoint)
|
|
126
131
|
__exportStar(require("./dtos/responses/KycPrepareResponse"), exports);
|
|
127
132
|
__exportStar(require("./dtos/responses/ProofOfAddressPrepareResponse"), exports);
|
|
@@ -141,6 +146,8 @@ __exportStar(require("./dtos/responses/ProspectResumeResponse"), exports);
|
|
|
141
146
|
__exportStar(require("./dtos/responses/CancelOtherStoreSaleResponse"), exports);
|
|
142
147
|
__exportStar(require("./dtos/responses/ProspectByPhoneResponse"), exports);
|
|
143
148
|
__exportStar(require("./dtos/responses/AppOnboardingResponse"), exports);
|
|
149
|
+
__exportStar(require("./dtos/responses/AccessoryOtpChallenge"), exports);
|
|
150
|
+
__exportStar(require("./dtos/responses/VerifyAccessoryOtpResponse"), exports);
|
|
144
151
|
// ── F3 · Backoffice VentasLuga ────────────────────────────────────────────────
|
|
145
152
|
// Enums
|
|
146
153
|
__exportStar(require("./enums/SaleFinancierEnum"), exports);
|
|
@@ -169,6 +176,7 @@ __exportStar(require("./dtos/requests/ApplySaleExceptionRequest"), exports);
|
|
|
169
176
|
__exportStar(require("./dtos/requests/AddSaleExceptionNoteRequest"), exports);
|
|
170
177
|
__exportStar(require("./dtos/requests/RunSalesReportRequest"), exports);
|
|
171
178
|
__exportStar(require("./dtos/requests/BackofficeCancelSaleRequest"), exports);
|
|
179
|
+
__exportStar(require("./dtos/requests/PortalCancelSaleRequest"), exports);
|
|
172
180
|
// Responses
|
|
173
181
|
__exportStar(require("./dtos/responses/BackofficeSalesStatsResponse"), exports);
|
|
174
182
|
__exportStar(require("./dtos/responses/BackofficeSalesKpisResponse"), exports);
|
package/package.json
CHANGED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Expose } from 'class-transformer';
|
|
2
|
+
import { IsString, Matches, MinLength } from 'class-validator';
|
|
3
|
+
import { regexPhoneMx } from '../../../helpers/constans/regex';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* POST /private/customers/ensure-by-phone — da de alta al cliente solo con su celular verificado,
|
|
7
|
+
* o devuelve el que ya existe con ese número.
|
|
8
|
+
*/
|
|
9
|
+
export class EnsureCustomerByPhoneRequest {
|
|
10
|
+
@Expose()
|
|
11
|
+
@IsString()
|
|
12
|
+
@Matches(regexPhoneMx, { message: 'phone debe tener 10 dígitos' })
|
|
13
|
+
phone!: string;
|
|
14
|
+
|
|
15
|
+
/** Tienda del primer contacto; no cambia si el cliente ya existía. */
|
|
16
|
+
@Expose()
|
|
17
|
+
@IsString()
|
|
18
|
+
@MinLength(1)
|
|
19
|
+
originStoreId!: string;
|
|
20
|
+
}
|
|
@@ -24,6 +24,7 @@ export * from './dtos/requests/KycReviewRequest';
|
|
|
24
24
|
export * from './dtos/requests/WelcomeAccreditationRequest';
|
|
25
25
|
export * from './dtos/requests/WelcomeAccreditationResultRequest';
|
|
26
26
|
export * from './dtos/requests/UpsertPromotionBonusRequest';
|
|
27
|
+
export * from './dtos/requests/EnsureCustomerByPhoneRequest';
|
|
27
28
|
|
|
28
29
|
// Response DTOs
|
|
29
30
|
export * from './dtos/responses/CustomerResponse';
|
|
@@ -31,6 +32,7 @@ export * from './dtos/responses/Customer360Response';
|
|
|
31
32
|
export * from './dtos/responses/WelcomeBonusResponse';
|
|
32
33
|
export * from './dtos/responses/WelcomeAccreditationResponse';
|
|
33
34
|
export * from './dtos/responses/PromotionBonusEntryResponse';
|
|
35
|
+
export * from './dtos/responses/EnsureCustomerByPhoneResponse';
|
|
34
36
|
|
|
35
37
|
// Contratos de eventos (PascalCase + sufijo V1)
|
|
36
38
|
export * from './events/CustomerCreatedV1';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Expose } from 'class-transformer';
|
|
2
|
+
import { ArrayMaxSize, IsArray, IsInt, IsOptional, IsString, Min, MinLength } from 'class-validator';
|
|
3
|
+
|
|
4
|
+
/** Línea del carrito de accesorios; el precio lo pone el catálogo, no el request. */
|
|
5
|
+
export class AccessorySaleLine {
|
|
6
|
+
@Expose()
|
|
7
|
+
@IsString()
|
|
8
|
+
@MinLength(1)
|
|
9
|
+
sku!: string;
|
|
10
|
+
|
|
11
|
+
@Expose()
|
|
12
|
+
@IsInt()
|
|
13
|
+
@Min(1)
|
|
14
|
+
qty!: number;
|
|
15
|
+
|
|
16
|
+
/** Serie de cada pieza cuando el SKU se rastrea por pieza; ausente si se rastrea por cantidad. */
|
|
17
|
+
@Expose()
|
|
18
|
+
@IsOptional()
|
|
19
|
+
@IsArray()
|
|
20
|
+
@ArrayMaxSize(100)
|
|
21
|
+
@IsString({ each: true })
|
|
22
|
+
identifiers?: string[];
|
|
23
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { SaleTypeEnum } from '../enums/SaleTypeEnum';
|
|
2
2
|
import type { SaleStatusEnum } from '../enums/SaleStatusEnum';
|
|
3
3
|
import type { SalePaymentMethodEnum } from '../enums/SalePaymentMethodEnum';
|
|
4
|
+
import type { SaleChannelEnum } from '../enums/SaleChannelEnum';
|
|
4
5
|
import type { ExternalProviderEnum } from '../enums/ExternalProviderEnum';
|
|
5
6
|
import type { CentralSyncStatusEnum } from '../enums/CentralSyncStatusEnum';
|
|
6
7
|
import type { SalePaymentDetail } from './SalePaymentDetail';
|
|
@@ -18,7 +19,10 @@ export interface Sale {
|
|
|
18
19
|
storeId: string;
|
|
19
20
|
sellerRetailUserId: string;
|
|
20
21
|
retailCustomerId: string;
|
|
21
|
-
|
|
22
|
+
/** Sesión del wizard que cerró la venta; ausente en la venta de mostrador. */
|
|
23
|
+
wizardSessionId?: string;
|
|
24
|
+
/** Canal de la venta; ausente = `WIZARD` (ventas anteriores al campo). */
|
|
25
|
+
saleChannel?: SaleChannelEnum;
|
|
22
26
|
type: SaleTypeEnum;
|
|
23
27
|
externalProvider: ExternalProviderEnum | null;
|
|
24
28
|
/** SKU del teléfono de la venta; `null` en la venta sin teléfono (en DDB se omite). */
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Expose, Type } from 'class-transformer';
|
|
2
|
+
import {
|
|
3
|
+
ArrayMaxSize,
|
|
4
|
+
ArrayMinSize,
|
|
5
|
+
IsArray,
|
|
6
|
+
IsBoolean,
|
|
7
|
+
IsDefined,
|
|
8
|
+
IsEnum,
|
|
9
|
+
IsInt,
|
|
10
|
+
IsOptional,
|
|
11
|
+
IsString,
|
|
12
|
+
Min,
|
|
13
|
+
MinLength,
|
|
14
|
+
ValidateNested,
|
|
15
|
+
} from 'class-validator';
|
|
16
|
+
import { SalePaymentMethodEnum } from '../../enums/SalePaymentMethodEnum';
|
|
17
|
+
import { SalePaymentDetail } from '../SalePaymentDetail';
|
|
18
|
+
import { AccessorySaleLine } from '../AccessorySaleLine';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* POST /wizard/accessory-sales — cierra la venta de mostrador con el celular ya verificado.
|
|
22
|
+
* `amountCents` es lo cobrado en caja y debe igualar la suma del catálogo.
|
|
23
|
+
*/
|
|
24
|
+
export class CreateAccessorySaleRequest {
|
|
25
|
+
@Expose()
|
|
26
|
+
@IsString()
|
|
27
|
+
@MinLength(1)
|
|
28
|
+
otpChallengeId!: string;
|
|
29
|
+
|
|
30
|
+
@Expose()
|
|
31
|
+
@IsArray()
|
|
32
|
+
@ArrayMinSize(1)
|
|
33
|
+
@ArrayMaxSize(50)
|
|
34
|
+
@ValidateNested({ each: true })
|
|
35
|
+
@Type(() => AccessorySaleLine)
|
|
36
|
+
lines!: AccessorySaleLine[];
|
|
37
|
+
|
|
38
|
+
@Expose()
|
|
39
|
+
@IsEnum(SalePaymentMethodEnum)
|
|
40
|
+
paymentMethod!: SalePaymentMethodEnum;
|
|
41
|
+
|
|
42
|
+
@Expose()
|
|
43
|
+
@IsInt()
|
|
44
|
+
@Min(0)
|
|
45
|
+
amountCents!: number;
|
|
46
|
+
|
|
47
|
+
@Expose()
|
|
48
|
+
@IsDefined()
|
|
49
|
+
@ValidateNested()
|
|
50
|
+
@Type(() => SalePaymentDetail)
|
|
51
|
+
paymentDetail!: SalePaymentDetail;
|
|
52
|
+
|
|
53
|
+
/** El cliente aceptó el aviso de privacidad; sin `true` el back responde 400 PRIVACY_NOTICE_REQUIRED. */
|
|
54
|
+
@Expose()
|
|
55
|
+
@IsOptional()
|
|
56
|
+
@IsBoolean()
|
|
57
|
+
privacyNoticeAccepted?: boolean;
|
|
58
|
+
|
|
59
|
+
/** Versión del aviso de privacidad que se mostró. */
|
|
60
|
+
@Expose()
|
|
61
|
+
@IsString()
|
|
62
|
+
@MinLength(1)
|
|
63
|
+
privacyNoticeVersion!: string;
|
|
64
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Expose, Type } from 'class-transformer';
|
|
2
|
+
import { IsArray, IsBoolean, IsOptional, IsString, MaxLength, MinLength, ValidateNested } from 'class-validator';
|
|
3
|
+
import { ReturnPieceCondition } from '../../../retailCatalog/dtos/requests/ReturnPieceCondition';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* POST /portal/sales/:saleId/cancel — el vendedor cancela una venta cerrada de su tienda, dentro de la
|
|
7
|
+
* ventana. Mismas validaciones que `BackofficeCancelSaleRequest`, sin la excepción de cancelación tardía.
|
|
8
|
+
*/
|
|
9
|
+
export class PortalCancelSaleRequest {
|
|
10
|
+
@Expose()
|
|
11
|
+
@IsString()
|
|
12
|
+
@MinLength(10)
|
|
13
|
+
@MaxLength(200)
|
|
14
|
+
reason!: string;
|
|
15
|
+
|
|
16
|
+
/** Equipo o piezas confirmados en tienda; ausente cuenta como no confirmado. */
|
|
17
|
+
@Expose()
|
|
18
|
+
@IsOptional()
|
|
19
|
+
@IsBoolean()
|
|
20
|
+
equipmentVerified?: boolean;
|
|
21
|
+
|
|
22
|
+
/** Condición de cada pieza que regresa al inventario; las no listadas vuelven GOOD. */
|
|
23
|
+
@Expose()
|
|
24
|
+
@IsOptional()
|
|
25
|
+
@IsArray()
|
|
26
|
+
@ValidateNested({ each: true })
|
|
27
|
+
@Type(() => ReturnPieceCondition)
|
|
28
|
+
returnConditions?: ReturnPieceCondition[];
|
|
29
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Expose } from 'class-transformer';
|
|
2
|
+
import { IsString, Matches } from 'class-validator';
|
|
3
|
+
import { regexPhoneMx } from '../../../helpers/constans/regex';
|
|
4
|
+
|
|
5
|
+
/** POST /wizard/accessory-sales/otp — manda el OTP al celular del cliente del mostrador. */
|
|
6
|
+
export class SendAccessoryOtpRequest {
|
|
7
|
+
@Expose()
|
|
8
|
+
@IsString()
|
|
9
|
+
@Matches(regexPhoneMx, { message: 'phone debe tener 10 dígitos' })
|
|
10
|
+
phone!: string;
|
|
11
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Expose } from 'class-transformer';
|
|
2
|
+
import { IsString, Length } from 'class-validator';
|
|
3
|
+
|
|
4
|
+
/** POST /wizard/accessory-sales/otp/{otpChallengeId}/verify — código que dicta el cliente. */
|
|
5
|
+
export class VerifyAccessoryOtpRequest {
|
|
6
|
+
@Expose()
|
|
7
|
+
@IsString()
|
|
8
|
+
@Length(4, 8)
|
|
9
|
+
code!: string;
|
|
10
|
+
}
|
|
@@ -32,6 +32,7 @@ export * from './enums/WizardLineStatusEnum';
|
|
|
32
32
|
export * from './enums/LinePaymentTypeEnum';
|
|
33
33
|
export * from './enums/WizardLineRoleEnum';
|
|
34
34
|
export * from './enums/EmailStateEnum';
|
|
35
|
+
export * from './enums/SaleChannelEnum';
|
|
35
36
|
|
|
36
37
|
// DTOs anidados
|
|
37
38
|
export * from './dtos/WizardConsents';
|
|
@@ -57,6 +58,7 @@ export * from './dtos/WizardFinancingPreview';
|
|
|
57
58
|
export * from './dtos/WizardReservedLine';
|
|
58
59
|
export * from './dtos/WizardGiftLine';
|
|
59
60
|
export * from './dtos/SaleLine';
|
|
61
|
+
export * from './dtos/AccessorySaleLine';
|
|
60
62
|
|
|
61
63
|
// Entidades principales (shapes de estado/persistencia — planas)
|
|
62
64
|
export * from './dtos/WizardSession';
|
|
@@ -108,6 +110,9 @@ export * from './dtos/requests/CompleteSaleRequest';
|
|
|
108
110
|
export * from './dtos/requests/SuggestIdentifiersQuery';
|
|
109
111
|
export * from './dtos/requests/SendEmailOtpRequest';
|
|
110
112
|
export * from './dtos/requests/VerifyEmailOtpRequest';
|
|
113
|
+
export * from './dtos/requests/SendAccessoryOtpRequest';
|
|
114
|
+
export * from './dtos/requests/VerifyAccessoryOtpRequest';
|
|
115
|
+
export * from './dtos/requests/CreateAccessorySaleRequest';
|
|
111
116
|
|
|
112
117
|
// Response DTOs (output tipado por endpoint)
|
|
113
118
|
export * from './dtos/responses/KycPrepareResponse';
|
|
@@ -128,6 +133,8 @@ export * from './dtos/responses/ProspectResumeResponse';
|
|
|
128
133
|
export * from './dtos/responses/CancelOtherStoreSaleResponse';
|
|
129
134
|
export * from './dtos/responses/ProspectByPhoneResponse';
|
|
130
135
|
export * from './dtos/responses/AppOnboardingResponse';
|
|
136
|
+
export * from './dtos/responses/AccessoryOtpChallenge';
|
|
137
|
+
export * from './dtos/responses/VerifyAccessoryOtpResponse';
|
|
131
138
|
|
|
132
139
|
// ── F3 · Backoffice VentasLuga ────────────────────────────────────────────────
|
|
133
140
|
// Enums
|
|
@@ -160,6 +167,7 @@ export * from './dtos/requests/ApplySaleExceptionRequest';
|
|
|
160
167
|
export * from './dtos/requests/AddSaleExceptionNoteRequest';
|
|
161
168
|
export * from './dtos/requests/RunSalesReportRequest';
|
|
162
169
|
export * from './dtos/requests/BackofficeCancelSaleRequest';
|
|
170
|
+
export * from './dtos/requests/PortalCancelSaleRequest';
|
|
163
171
|
|
|
164
172
|
// Responses
|
|
165
173
|
export * from './dtos/responses/BackofficeSalesStatsResponse';
|