@fiado/type-kit 3.459.0 → 3.461.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/retailCatalog/catalogEnums.test.ts +34 -0
- package/_test_/unit/retailCatalog/stockRequests.test.ts +156 -0
- package/_test_/unit/retailWizard/multiItemRequests.test.ts +114 -0
- package/_test_/unit/retailWizard/multiItemShapes.test.ts +126 -0
- package/bin/card/enums/Status.d.ts +6 -1
- package/bin/card/enums/Status.js +5 -0
- package/bin/retailCatalog/dtos/Product.d.ts +15 -1
- package/bin/retailCatalog/dtos/ProductComponent.d.ts +5 -0
- package/bin/retailCatalog/dtos/ProductComponent.js +29 -0
- package/bin/retailCatalog/dtos/requests/GetInventorySkuQuery.d.ts +10 -0
- package/bin/retailCatalog/dtos/requests/GetInventorySkuQuery.js +42 -0
- package/bin/retailCatalog/dtos/requests/InventoryLensQuery.d.ts +5 -0
- package/bin/retailCatalog/dtos/requests/InventoryLensQuery.js +11 -0
- package/bin/retailCatalog/dtos/requests/ReleaseStockRequest.d.ts +8 -0
- package/bin/retailCatalog/dtos/requests/ReleaseStockRequest.js +34 -0
- package/bin/retailCatalog/dtos/requests/RenewReservationsRequest.d.ts +6 -0
- package/bin/retailCatalog/dtos/requests/RenewReservationsRequest.js +30 -0
- package/bin/retailCatalog/dtos/requests/ReservationLineRef.d.ts +5 -0
- package/bin/retailCatalog/dtos/requests/ReservationLineRef.js +25 -0
- package/bin/retailCatalog/dtos/requests/ReserveStockRequest.d.ts +10 -0
- package/bin/retailCatalog/dtos/requests/ReserveStockRequest.js +42 -0
- package/bin/retailCatalog/dtos/requests/ReturnStockRequest.d.ts +9 -0
- package/bin/retailCatalog/dtos/requests/ReturnStockRequest.js +38 -0
- package/bin/retailCatalog/dtos/requests/SellStockRequest.d.ts +7 -0
- package/bin/retailCatalog/dtos/requests/SellStockRequest.js +34 -0
- package/bin/retailCatalog/dtos/requests/StockLine.d.ts +14 -0
- package/bin/retailCatalog/dtos/requests/StockLine.js +56 -0
- package/bin/retailCatalog/dtos/requests/SuggestPiecesQuery.d.ts +5 -0
- package/bin/retailCatalog/dtos/requests/SuggestPiecesQuery.js +26 -0
- package/bin/retailCatalog/dtos/requests/SyncInventoryRequest.d.ts +47 -0
- package/bin/retailCatalog/dtos/requests/SyncInventoryRequest.js +173 -0
- package/bin/retailCatalog/dtos/responses/GetInventorySkuResponse.d.ts +34 -0
- package/bin/retailCatalog/dtos/responses/GetInventorySkuResponse.js +2 -0
- package/bin/retailCatalog/dtos/responses/InventoryLensResponse.d.ts +43 -2
- package/bin/retailCatalog/dtos/responses/ListSkuPricesResponse.d.ts +6 -0
- package/bin/retailCatalog/dtos/responses/ListSkuPricesResponse.js +2 -0
- package/bin/retailCatalog/dtos/responses/ReleaseStockResponse.d.ts +10 -0
- package/bin/retailCatalog/dtos/responses/ReleaseStockResponse.js +2 -0
- package/bin/retailCatalog/dtos/responses/RenewReservationsResponse.d.ts +10 -0
- package/bin/retailCatalog/dtos/responses/RenewReservationsResponse.js +2 -0
- package/bin/retailCatalog/dtos/responses/ReserveStockResponse.d.ts +25 -0
- package/bin/retailCatalog/dtos/responses/ReserveStockResponse.js +2 -0
- package/bin/retailCatalog/dtos/responses/ReturnStockResponse.d.ts +4 -0
- package/bin/retailCatalog/dtos/responses/ReturnStockResponse.js +2 -0
- package/bin/retailCatalog/dtos/responses/SellStockResponse.d.ts +18 -0
- package/bin/retailCatalog/dtos/responses/SellStockResponse.js +2 -0
- package/bin/retailCatalog/dtos/responses/SkuPriceEntry.d.ts +9 -0
- package/bin/retailCatalog/dtos/responses/SkuPriceEntry.js +2 -0
- package/bin/retailCatalog/dtos/responses/StoreCatalogItem.d.ts +29 -0
- package/bin/retailCatalog/dtos/responses/StoreCatalogItem.js +2 -0
- package/bin/retailCatalog/dtos/responses/SuggestPiecesResponse.d.ts +6 -0
- package/bin/retailCatalog/dtos/responses/SuggestPiecesResponse.js +2 -0
- package/bin/retailCatalog/dtos/responses/SyncInventoryResponse.d.ts +13 -0
- package/bin/retailCatalog/dtos/responses/SyncInventoryResponse.js +2 -0
- package/bin/retailCatalog/dtos/validation/ValidateProductResponse.d.ts +6 -1
- package/bin/retailCatalog/enums/InventoryLensFilterEnum.d.ts +3 -1
- package/bin/retailCatalog/enums/InventoryLensFilterEnum.js +2 -0
- package/bin/retailCatalog/enums/InventoryLensPeriodEnum.d.ts +7 -0
- package/bin/retailCatalog/enums/InventoryLensPeriodEnum.js +11 -0
- package/bin/retailCatalog/enums/InventoryMovementTypeEnum.d.ts +9 -0
- package/bin/retailCatalog/enums/InventoryMovementTypeEnum.js +13 -0
- package/bin/retailCatalog/enums/InventorySyncRejectionCodeEnum.d.ts +9 -0
- package/bin/retailCatalog/enums/InventorySyncRejectionCodeEnum.js +13 -0
- package/bin/retailCatalog/enums/InventorySyncResultStatusEnum.d.ts +6 -0
- package/bin/retailCatalog/enums/InventorySyncResultStatusEnum.js +10 -0
- package/bin/retailCatalog/enums/PriceSourceEnum.d.ts +4 -0
- package/bin/retailCatalog/enums/PriceSourceEnum.js +8 -0
- package/bin/retailCatalog/enums/ProductCategoryEnum.d.ts +9 -0
- package/bin/retailCatalog/enums/ProductCategoryEnum.js +13 -0
- package/bin/retailCatalog/enums/TrackingModeEnum.d.ts +6 -0
- package/bin/retailCatalog/enums/TrackingModeEnum.js +10 -0
- package/bin/retailCatalog/index.d.ts +29 -0
- package/bin/retailCatalog/index.js +30 -0
- package/bin/retailWizard/dtos/Sale.d.ts +7 -0
- package/bin/retailWizard/dtos/SaleLine.d.ts +16 -0
- package/bin/retailWizard/dtos/SaleLine.js +2 -0
- package/bin/retailWizard/dtos/WizardLineIdentifiers.d.ts +5 -0
- package/bin/retailWizard/dtos/WizardLineIdentifiers.js +2 -0
- package/bin/retailWizard/dtos/WizardLineProduct.d.ts +15 -0
- package/bin/retailWizard/dtos/WizardLineProduct.js +2 -0
- package/bin/retailWizard/dtos/WizardProduct.d.ts +6 -0
- package/bin/retailWizard/dtos/WizardReservedLine.d.ts +35 -0
- package/bin/retailWizard/dtos/WizardReservedLine.js +2 -0
- package/bin/retailWizard/dtos/WizardSession.d.ts +5 -0
- package/bin/retailWizard/dtos/requests/AddProductRequest.d.ts +4 -8
- package/bin/retailWizard/dtos/requests/AddProductRequest.js +9 -8
- package/bin/retailWizard/dtos/requests/CompleteSaleRequest.d.ts +16 -0
- package/bin/retailWizard/dtos/requests/CompleteSaleRequest.js +59 -0
- package/bin/retailWizard/dtos/requests/DeleteProductRequest.d.ts +3 -1
- package/bin/retailWizard/dtos/requests/DeleteProductRequest.js +7 -1
- package/bin/retailWizard/dtos/requests/QuoteRequest.d.ts +2 -0
- package/bin/retailWizard/dtos/requests/QuoteRequest.js +7 -0
- package/bin/retailWizard/dtos/requests/SuggestIdentifiersQuery.d.ts +5 -0
- package/bin/retailWizard/dtos/requests/SuggestIdentifiersQuery.js +30 -0
- package/bin/retailWizard/enums/LinePaymentTypeEnum.d.ts +7 -0
- package/bin/retailWizard/enums/LinePaymentTypeEnum.js +11 -0
- package/bin/retailWizard/enums/WizardLineStatusEnum.d.ts +9 -0
- package/bin/retailWizard/enums/WizardLineStatusEnum.js +13 -0
- package/bin/retailWizard/index.d.ts +8 -0
- package/bin/retailWizard/index.js +8 -0
- package/package.json +1 -1
- package/src/card/enums/Status.ts +6 -1
- package/src/retailCatalog/dtos/Product.ts +17 -1
- package/src/retailCatalog/dtos/ProductComponent.ts +14 -0
- package/src/retailCatalog/dtos/requests/GetInventorySkuQuery.ts +27 -0
- package/src/retailCatalog/dtos/requests/InventoryLensQuery.ts +12 -1
- package/src/retailCatalog/dtos/requests/ReleaseStockRequest.ts +19 -0
- package/src/retailCatalog/dtos/requests/RenewReservationsRequest.ts +15 -0
- package/src/retailCatalog/dtos/requests/ReservationLineRef.ts +10 -0
- package/src/retailCatalog/dtos/requests/ReserveStockRequest.ts +24 -0
- package/src/retailCatalog/dtos/requests/ReturnStockRequest.ts +22 -0
- package/src/retailCatalog/dtos/requests/SellStockRequest.ts +18 -0
- package/src/retailCatalog/dtos/requests/StockLine.ts +36 -0
- package/src/retailCatalog/dtos/requests/SuggestPiecesQuery.ts +11 -0
- package/src/retailCatalog/dtos/requests/SyncInventoryRequest.ts +145 -0
- package/src/retailCatalog/dtos/responses/GetInventorySkuResponse.ts +38 -0
- package/src/retailCatalog/dtos/responses/InventoryLensResponse.ts +48 -2
- package/src/retailCatalog/dtos/responses/ListSkuPricesResponse.ts +7 -0
- package/src/retailCatalog/dtos/responses/ReleaseStockResponse.ts +11 -0
- package/src/retailCatalog/dtos/responses/RenewReservationsResponse.ts +11 -0
- package/src/retailCatalog/dtos/responses/ReserveStockResponse.ts +27 -0
- package/src/retailCatalog/dtos/responses/ReturnStockResponse.ts +4 -0
- package/src/retailCatalog/dtos/responses/SellStockResponse.ts +20 -0
- package/src/retailCatalog/dtos/responses/SkuPriceEntry.ts +10 -0
- package/src/retailCatalog/dtos/responses/StoreCatalogItem.ts +31 -0
- package/src/retailCatalog/dtos/responses/SuggestPiecesResponse.ts +7 -0
- package/src/retailCatalog/dtos/responses/SyncInventoryResponse.ts +15 -0
- package/src/retailCatalog/dtos/validation/ValidateProductResponse.ts +6 -1
- package/src/retailCatalog/enums/InventoryLensFilterEnum.ts +2 -0
- package/src/retailCatalog/enums/InventoryLensPeriodEnum.ts +7 -0
- package/src/retailCatalog/enums/InventoryMovementTypeEnum.ts +9 -0
- package/src/retailCatalog/enums/InventorySyncRejectionCodeEnum.ts +9 -0
- package/src/retailCatalog/enums/InventorySyncResultStatusEnum.ts +6 -0
- package/src/retailCatalog/enums/PriceSourceEnum.ts +4 -0
- package/src/retailCatalog/enums/ProductCategoryEnum.ts +9 -0
- package/src/retailCatalog/enums/TrackingModeEnum.ts +6 -0
- package/src/retailCatalog/index.ts +31 -0
- package/src/retailWizard/dtos/Sale.ts +7 -0
- package/src/retailWizard/dtos/SaleLine.ts +17 -0
- package/src/retailWizard/dtos/WizardLineIdentifiers.ts +5 -0
- package/src/retailWizard/dtos/WizardLineProduct.ts +16 -0
- package/src/retailWizard/dtos/WizardProduct.ts +7 -0
- package/src/retailWizard/dtos/WizardReservedLine.ts +36 -0
- package/src/retailWizard/dtos/WizardSession.ts +5 -0
- package/src/retailWizard/dtos/requests/AddProductRequest.ts +9 -8
- package/src/retailWizard/dtos/requests/CompleteSaleRequest.ts +41 -0
- package/src/retailWizard/dtos/requests/DeleteProductRequest.ts +7 -1
- package/src/retailWizard/dtos/requests/QuoteRequest.ts +8 -1
- package/src/retailWizard/dtos/requests/SuggestIdentifiersQuery.ts +15 -0
- package/src/retailWizard/enums/LinePaymentTypeEnum.ts +7 -0
- package/src/retailWizard/enums/WizardLineStatusEnum.ts +9 -0
- package/src/retailWizard/index.ts +8 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import * as RetailCatalog from '../../../src/retailCatalog';
|
|
3
|
+
|
|
4
|
+
describe('retailCatalog — enums del inventario multi-item', () => {
|
|
5
|
+
it('expone las categorías de producto', () => {
|
|
6
|
+
expect(Object.values(RetailCatalog.ProductCategoryEnum)).toEqual(['PHONE', 'SIM', 'MODEM', 'ACCESSORY', 'BUNDLE']);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('expone los modos de rastreo', () => {
|
|
10
|
+
expect(Object.values(RetailCatalog.TrackingModeEnum)).toEqual(['IMEI', 'SERIAL', 'QUANTITY']);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('expone los tipos de movimiento', () => {
|
|
14
|
+
expect(Object.values(RetailCatalog.InventoryMovementTypeEnum)).toEqual([
|
|
15
|
+
'ENTRY', 'RESERVATION', 'RELEASE', 'SALE', 'RETURN', 'ADJUSTMENT',
|
|
16
|
+
]);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('expone el resultado por ítem de la puerta de entrada y sus códigos de rechazo', () => {
|
|
20
|
+
expect(Object.values(RetailCatalog.InventorySyncResultStatusEnum)).toEqual(['APPLIED', 'NOOP', 'REJECTED']);
|
|
21
|
+
expect(Object.values(RetailCatalog.InventorySyncRejectionCodeEnum)).toEqual([
|
|
22
|
+
'DUPLICATE_IDENTIFIER', 'ADJUSTMENT_EXCEEDS_AVAILABLE', 'FUTURE_PRICE_NOT_SUPPORTED',
|
|
23
|
+
]);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('expone el origen del precio y los periodos del lente', () => {
|
|
27
|
+
expect(Object.values(RetailCatalog.PriceSourceEnum)).toEqual(['ZENTRAL_SYNC']);
|
|
28
|
+
expect(Object.values(RetailCatalog.InventoryLensPeriodEnum)).toEqual(['7d', '30d', '90d', 'all']);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('agrega el modo lista al filtro del lente sin quitar los existentes', () => {
|
|
32
|
+
expect(Object.values(RetailCatalog.InventoryLensFilterEnum)).toEqual(['critical', 'stale', 'gap', 'transfers', 'list']);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { plainToInstance, type ClassConstructor } from 'class-transformer';
|
|
3
|
+
import { validateSync, type ValidationError } from 'class-validator';
|
|
4
|
+
import {
|
|
5
|
+
GetInventorySkuQuery,
|
|
6
|
+
InventoryLensFilterEnum,
|
|
7
|
+
InventoryLensQuery,
|
|
8
|
+
MdmLockModeEnum,
|
|
9
|
+
MdmProviderEnum,
|
|
10
|
+
ProductCategoryEnum,
|
|
11
|
+
ReleaseStockRequest,
|
|
12
|
+
RenewReservationsRequest,
|
|
13
|
+
ReserveStockRequest,
|
|
14
|
+
ReturnStockRequest,
|
|
15
|
+
SellStockRequest,
|
|
16
|
+
SuggestPiecesQuery,
|
|
17
|
+
SyncInventoryRequest,
|
|
18
|
+
TrackingModeEnum,
|
|
19
|
+
} from '../../../src/retailCatalog';
|
|
20
|
+
|
|
21
|
+
function paths(errors: ValidationError[], prefix = ''): string[] {
|
|
22
|
+
return errors.flatMap((e) => {
|
|
23
|
+
const p = prefix ? `${prefix}.${e.property}` : e.property;
|
|
24
|
+
return e.children && e.children.length > 0 ? paths(e.children, p) : [p];
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function errorsOf<T extends object>(cls: ClassConstructor<T>, payload: object): string[] {
|
|
29
|
+
return paths(validateSync(plainToInstance(cls, payload) as object));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const saleLine = { lineId: 'L1', sku: 'KIT-1', qty: 1, components: [{ sku: 'SIM-1', qty: 1, identifiers: ['8952'] }] };
|
|
33
|
+
|
|
34
|
+
describe('ReserveStockRequest', () => {
|
|
35
|
+
const ok = { sessionId: 's', lineId: 'L1', reservationId: 'r', retailerId: 'ret', sku: 'SKU-1', qty: 2 };
|
|
36
|
+
it('acepta un request completo', () => expect(errorsOf(ReserveStockRequest, ok)).toEqual([]));
|
|
37
|
+
it('rechaza qty menor a 1', () => expect(errorsOf(ReserveStockRequest, { ...ok, qty: 0 })).toContain('qty'));
|
|
38
|
+
it('rechaza sin reservationId', () => {
|
|
39
|
+
const { reservationId: _omit, ...rest } = ok;
|
|
40
|
+
expect(errorsOf(ReserveStockRequest, rest)).toContain('reservationId');
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
describe('RenewReservationsRequest y ReleaseStockRequest', () => {
|
|
45
|
+
it('acepta líneas con lineId y reservationId', () => {
|
|
46
|
+
expect(errorsOf(RenewReservationsRequest, { sessionId: 's', lines: [{ lineId: 'L1', reservationId: 'r' }] })).toEqual([]);
|
|
47
|
+
});
|
|
48
|
+
it('valida cada línea anidada', () => {
|
|
49
|
+
expect(errorsOf(RenewReservationsRequest, { sessionId: 's', lines: [{ lineId: 'L1' }] })).toContain('lines.0.reservationId');
|
|
50
|
+
});
|
|
51
|
+
it('release exige onlyExpired booleano', () => {
|
|
52
|
+
const base = { sessionId: 's', lines: [{ lineId: 'L1', reservationId: 'r' }] };
|
|
53
|
+
expect(errorsOf(ReleaseStockRequest, { ...base, onlyExpired: false })).toEqual([]);
|
|
54
|
+
expect(errorsOf(ReleaseStockRequest, base)).toContain('onlyExpired');
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
describe('SuggestPiecesQuery', () => {
|
|
59
|
+
it('acepta un prefijo de 4 caracteres', () => expect(errorsOf(SuggestPiecesQuery, { sku: 'SKU-1', prefix: '3569' })).toEqual([]));
|
|
60
|
+
it('rechaza un prefijo corto', () => expect(errorsOf(SuggestPiecesQuery, { sku: 'SKU-1', prefix: '356' })).toContain('prefix'));
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe('SellStockRequest y ReturnStockRequest', () => {
|
|
64
|
+
it('acepta una venta con componentes e identificadores', () => {
|
|
65
|
+
expect(errorsOf(SellStockRequest, { sessionId: 's', retailerId: 'ret', lines: [saleLine] })).toEqual([]);
|
|
66
|
+
});
|
|
67
|
+
it('valida los identificadores del componente', () => {
|
|
68
|
+
const bad = { ...saleLine, components: [{ sku: 'SIM-1', qty: 1, identifiers: [123] }] };
|
|
69
|
+
expect(errorsOf(SellStockRequest, { sessionId: 's', retailerId: 'ret', lines: [bad] })).toContain('lines.0.components.0.identifiers');
|
|
70
|
+
});
|
|
71
|
+
it('devolución exige saleId y soldAt ISO', () => {
|
|
72
|
+
const ok = { saleId: 'sale', retailerId: 'ret', soldAt: '2026-09-23T10:00:00.000Z', lines: [saleLine] };
|
|
73
|
+
expect(errorsOf(ReturnStockRequest, ok)).toEqual([]);
|
|
74
|
+
expect(errorsOf(ReturnStockRequest, { ...ok, soldAt: 'ayer' })).toContain('soldAt');
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
describe('SyncInventoryRequest', () => {
|
|
79
|
+
const product = {
|
|
80
|
+
sku: 'KIT-1',
|
|
81
|
+
category: ProductCategoryEnum.BUNDLE,
|
|
82
|
+
trackingMode: TrackingModeEnum.QUANTITY,
|
|
83
|
+
sellable: true,
|
|
84
|
+
showInSalesFlow: true,
|
|
85
|
+
eligibleFinanciers: ['SUREKEEP'],
|
|
86
|
+
components: [{ sku: 'SIM-1', qty: 1 }],
|
|
87
|
+
tier: null,
|
|
88
|
+
price: { listPriceCents: 100000, basePriceCents: 90000, effectiveFrom: '2026-09-23T00:00:00.000Z' },
|
|
89
|
+
};
|
|
90
|
+
it('acepta productos y stock por cantidad o por identificadores', () => {
|
|
91
|
+
const stock = [{ storeId: 'st', sku: 'SIM-1', qty: 5 }, { storeId: 'st', sku: 'PH-1', identifiers: ['356938035643809'] }];
|
|
92
|
+
expect(errorsOf(SyncInventoryRequest, { products: [product], stock })).toEqual([]);
|
|
93
|
+
});
|
|
94
|
+
it('rechaza categoría desconocida y precio sin vigencia', () => {
|
|
95
|
+
const bad = { ...product, category: 'TABLET', price: { basePriceCents: 1 } };
|
|
96
|
+
const errors = errorsOf(SyncInventoryRequest, { products: [bad], stock: [] });
|
|
97
|
+
expect(errors).toEqual(expect.arrayContaining(['products.0.category', 'products.0.price.effectiveFrom']));
|
|
98
|
+
});
|
|
99
|
+
it('valida los componentes del kit', () => {
|
|
100
|
+
const bad = { ...product, components: [{ sku: 'SIM-1', qty: 0 }] };
|
|
101
|
+
expect(errorsOf(SyncInventoryRequest, { products: [bad], stock: [] })).toContain('products.0.components.0.qty');
|
|
102
|
+
});
|
|
103
|
+
it('acepta los datos descriptivos y MDM del producto nuevo', () => {
|
|
104
|
+
const full = {
|
|
105
|
+
...product,
|
|
106
|
+
brand: 'Samsung',
|
|
107
|
+
model: 'A15',
|
|
108
|
+
capacity: '128GB',
|
|
109
|
+
color: 'Negro',
|
|
110
|
+
description: 'Equipo de gama media',
|
|
111
|
+
imageUrl: 'https://cdn.example.com/a15.png',
|
|
112
|
+
mdmEnabled: true,
|
|
113
|
+
mdmProvider: MdmProviderEnum.TRUSTONIC,
|
|
114
|
+
mdmLockMode: MdmLockModeEnum.ONDEMAND,
|
|
115
|
+
};
|
|
116
|
+
expect(errorsOf(SyncInventoryRequest, { products: [full], stock: [] })).toEqual([]);
|
|
117
|
+
});
|
|
118
|
+
it('acepta mdmProvider y mdmLockMode en null', () => {
|
|
119
|
+
const noMdm = { ...product, mdmEnabled: false, mdmProvider: null, mdmLockMode: null };
|
|
120
|
+
expect(errorsOf(SyncInventoryRequest, { products: [noMdm], stock: [] })).toEqual([]);
|
|
121
|
+
});
|
|
122
|
+
it('rechaza tipos incorrectos en los datos descriptivos y MDM', () => {
|
|
123
|
+
const bad = {
|
|
124
|
+
...product,
|
|
125
|
+
brand: 1,
|
|
126
|
+
model: 2,
|
|
127
|
+
capacity: 3,
|
|
128
|
+
color: 4,
|
|
129
|
+
description: 5,
|
|
130
|
+
imageUrl: 6,
|
|
131
|
+
mdmEnabled: 'yes',
|
|
132
|
+
mdmProvider: 'ACME',
|
|
133
|
+
mdmLockMode: 'NEVER',
|
|
134
|
+
};
|
|
135
|
+
const errors = errorsOf(SyncInventoryRequest, { products: [bad], stock: [] });
|
|
136
|
+
const fields = ['brand', 'model', 'capacity', 'color', 'description', 'imageUrl', 'mdmEnabled', 'mdmProvider', 'mdmLockMode'];
|
|
137
|
+
expect(errors).toEqual(expect.arrayContaining(fields.map((f) => `products.0.${f}`)));
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
describe('InventoryLensQuery en modo lista', () => {
|
|
142
|
+
it('acepta filter=list con period y storeId', () => {
|
|
143
|
+
expect(errorsOf(InventoryLensQuery, { filter: InventoryLensFilterEnum.LIST, period: '30d', storeId: 'st' })).toEqual([]);
|
|
144
|
+
});
|
|
145
|
+
it('sigue aceptando filter solo', () => expect(errorsOf(InventoryLensQuery, { filter: 'critical' })).toEqual([]));
|
|
146
|
+
it('rechaza un periodo desconocido', () => expect(errorsOf(InventoryLensQuery, { filter: 'list', period: '15d' })).toContain('period'));
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
describe('GetInventorySkuQuery', () => {
|
|
150
|
+
it('convierte limit del query string a número', () => {
|
|
151
|
+
const dto = plainToInstance(GetInventorySkuQuery, { limit: '20', period: '7d' });
|
|
152
|
+
expect(dto.limit).toBe(20);
|
|
153
|
+
expect(validateSync(dto)).toEqual([]);
|
|
154
|
+
});
|
|
155
|
+
it('rechaza limit fuera de rango', () => expect(errorsOf(GetInventorySkuQuery, { limit: '0' })).toContain('limit'));
|
|
156
|
+
});
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { plainToInstance, type ClassConstructor } from 'class-transformer';
|
|
3
|
+
import { validateSync, type ValidationError } from 'class-validator';
|
|
4
|
+
import {
|
|
5
|
+
AddProductRequest,
|
|
6
|
+
CompleteSaleRequest,
|
|
7
|
+
DeleteProductRequest,
|
|
8
|
+
QuoteRequest,
|
|
9
|
+
SuggestIdentifiersQuery,
|
|
10
|
+
} from '../../../src/retailWizard';
|
|
11
|
+
|
|
12
|
+
function paths(errors: ValidationError[], prefix = ''): string[] {
|
|
13
|
+
return errors.flatMap((e) => {
|
|
14
|
+
const p = prefix ? `${prefix}.${e.property}` : e.property;
|
|
15
|
+
return e.children && e.children.length > 0 ? paths(e.children, p) : [p];
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function toDto<T extends object>(cls: ClassConstructor<T>, payload: object): T {
|
|
20
|
+
return plainToInstance(cls, payload, { excludeExtraneousValues: true });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function errorsOf<T extends object>(cls: ClassConstructor<T>, payload: object): string[] {
|
|
24
|
+
return paths(validateSync(toDto(cls, payload) as object));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
describe('AddProductRequest — qty por línea', () => {
|
|
28
|
+
it('acepta solo el sku (qty ausente = 1 lo resuelve el silo)', () => {
|
|
29
|
+
expect(errorsOf(AddProductRequest, { sku: 'SKU-1' })).toEqual([]);
|
|
30
|
+
});
|
|
31
|
+
it('acepta qty explícita', () => {
|
|
32
|
+
expect(errorsOf(AddProductRequest, { sku: 'SKU-1', qty: 3 })).toEqual([]);
|
|
33
|
+
expect(toDto(AddProductRequest, { sku: 'SKU-1', qty: 3 }).qty).toBe(3);
|
|
34
|
+
});
|
|
35
|
+
it('rechaza qty menor a 1', () => {
|
|
36
|
+
expect(errorsOf(AddProductRequest, { sku: 'SKU-1', qty: 0 })).toContain('qty');
|
|
37
|
+
});
|
|
38
|
+
it('rechaza qty no entera', () => {
|
|
39
|
+
expect(errorsOf(AddProductRequest, { sku: 'SKU-1', qty: 1.5 })).toContain('qty');
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
describe('DeleteProductRequest — quitar por lineId', () => {
|
|
44
|
+
it('acepta lineId', () => {
|
|
45
|
+
expect(errorsOf(DeleteProductRequest, { lineId: 'L1' })).toEqual([]);
|
|
46
|
+
expect(toDto(DeleteProductRequest, { lineId: 'L1' }).lineId).toBe('L1');
|
|
47
|
+
});
|
|
48
|
+
it('sigue aceptando el request vacío', () => {
|
|
49
|
+
expect(errorsOf(DeleteProductRequest, {})).toEqual([]);
|
|
50
|
+
});
|
|
51
|
+
it('rechaza lineId que no es string', () => {
|
|
52
|
+
expect(errorsOf(DeleteProductRequest, { lineId: 7 })).toContain('lineId');
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
describe('QuoteRequest — financedLineId', () => {
|
|
57
|
+
const base = { downPaymentCents: 1000, termWeeks: 12 };
|
|
58
|
+
it('acepta sin financedLineId (compat)', () => {
|
|
59
|
+
expect(errorsOf(QuoteRequest, base)).toEqual([]);
|
|
60
|
+
});
|
|
61
|
+
it('acepta financedLineId', () => {
|
|
62
|
+
expect(errorsOf(QuoteRequest, { ...base, financedLineId: 'L2' })).toEqual([]);
|
|
63
|
+
expect(toDto(QuoteRequest, { ...base, financedLineId: 'L2' }).financedLineId).toBe('L2');
|
|
64
|
+
});
|
|
65
|
+
it('rechaza financedLineId vacío', () => {
|
|
66
|
+
expect(errorsOf(QuoteRequest, { ...base, financedLineId: '' })).toContain('financedLineId');
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe('CompleteSaleRequest — líneas con identificadores por componente', () => {
|
|
71
|
+
const ok = {
|
|
72
|
+
lines: [
|
|
73
|
+
{ lineId: 'L1', components: [{ sku: 'PHONE-1', identifiers: ['356938035643809'] }] },
|
|
74
|
+
{ lineId: 'L2', components: [{ sku: 'SIM-1', identifiers: ['8952140'] }, { sku: 'CASE-1', identifiers: [] }] },
|
|
75
|
+
],
|
|
76
|
+
};
|
|
77
|
+
it('acepta un request completo', () => {
|
|
78
|
+
expect(errorsOf(CompleteSaleRequest, ok)).toEqual([]);
|
|
79
|
+
const dto = toDto(CompleteSaleRequest, ok);
|
|
80
|
+
expect(dto.lines[1].components[0].identifiers).toEqual(['8952140']);
|
|
81
|
+
});
|
|
82
|
+
it('acepta lista de líneas vacía (venta solo por cantidad)', () => {
|
|
83
|
+
expect(errorsOf(CompleteSaleRequest, { lines: [] })).toEqual([]);
|
|
84
|
+
});
|
|
85
|
+
it('acepta sin lines (front sin body)', () => {
|
|
86
|
+
expect(errorsOf(CompleteSaleRequest, {})).toEqual([]);
|
|
87
|
+
});
|
|
88
|
+
it('rechaza lines que no es arreglo', () => {
|
|
89
|
+
expect(errorsOf(CompleteSaleRequest, { lines: 'L1' })).toContain('lines');
|
|
90
|
+
});
|
|
91
|
+
it('rechaza una línea sin lineId', () => {
|
|
92
|
+
expect(errorsOf(CompleteSaleRequest, { lines: [{ components: [] }] })).toContain('lines.0.lineId');
|
|
93
|
+
});
|
|
94
|
+
it('rechaza un identificador que no es string', () => {
|
|
95
|
+
const bad = { lines: [{ lineId: 'L1', components: [{ sku: 'SIM-1', identifiers: [123] }] }] };
|
|
96
|
+
expect(errorsOf(CompleteSaleRequest, bad)).toContain('lines.0.components.0.identifiers');
|
|
97
|
+
});
|
|
98
|
+
it('rechaza un componente sin sku', () => {
|
|
99
|
+
const bad = { lines: [{ lineId: 'L1', components: [{ identifiers: ['x'] }] }] };
|
|
100
|
+
expect(errorsOf(CompleteSaleRequest, bad)).toContain('lines.0.components.0.sku');
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
describe('SuggestIdentifiersQuery — prefijo mínimo 4', () => {
|
|
105
|
+
it('acepta sku y prefijo de 4', () => {
|
|
106
|
+
expect(errorsOf(SuggestIdentifiersQuery, { sku: 'SIM-1', prefix: '8952' })).toEqual([]);
|
|
107
|
+
});
|
|
108
|
+
it('rechaza prefijo corto', () => {
|
|
109
|
+
expect(errorsOf(SuggestIdentifiersQuery, { sku: 'SIM-1', prefix: '895' })).toContain('prefix');
|
|
110
|
+
});
|
|
111
|
+
it('rechaza sin sku', () => {
|
|
112
|
+
expect(errorsOf(SuggestIdentifiersQuery, { prefix: '8952' })).toContain('sku');
|
|
113
|
+
});
|
|
114
|
+
});
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import {
|
|
3
|
+
LinePaymentTypeEnum,
|
|
4
|
+
WizardLineStatusEnum,
|
|
5
|
+
type Sale,
|
|
6
|
+
type SaleLine,
|
|
7
|
+
type WizardProduct,
|
|
8
|
+
type WizardReservedLine,
|
|
9
|
+
type WizardSession,
|
|
10
|
+
} from '../../../src/retailWizard';
|
|
11
|
+
import { MdmProviderEnum, ProductCategoryEnum, TrackingModeEnum } from '../../../src/retailCatalog';
|
|
12
|
+
|
|
13
|
+
describe('enums del inventario multi-item', () => {
|
|
14
|
+
it('WizardLineStatusEnum tiene los 3 estados de la línea', () => {
|
|
15
|
+
expect(Object.values(WizardLineStatusEnum)).toEqual(['PENDING', 'RESERVED', 'RELEASING']);
|
|
16
|
+
});
|
|
17
|
+
it('LinePaymentTypeEnum distingue crédito y contado', () => {
|
|
18
|
+
expect(Object.values(LinePaymentTypeEnum)).toEqual(['CREDIT', 'CASH']);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
describe('formas de sesión, línea y venta', () => {
|
|
23
|
+
const kitLine: WizardReservedLine = {
|
|
24
|
+
lineId: 'L1',
|
|
25
|
+
sku: 'KIT-1',
|
|
26
|
+
qty: 1,
|
|
27
|
+
status: WizardLineStatusEnum.RESERVED,
|
|
28
|
+
reservationId: 'r-1',
|
|
29
|
+
expiresAt: '2026-09-23T20:30:00.000Z',
|
|
30
|
+
basePriceCents: 500000,
|
|
31
|
+
listPriceCents: 550000,
|
|
32
|
+
priceSk: '2026-09-01T00:00:00.000Z',
|
|
33
|
+
eligibleFinanciers: ['SUREKEEP'],
|
|
34
|
+
financeable: true,
|
|
35
|
+
paymentType: LinePaymentTypeEnum.CREDIT,
|
|
36
|
+
sellItemCost: 2,
|
|
37
|
+
mdmEnabled: true,
|
|
38
|
+
mdmProvider: MdmProviderEnum.TRUSTONIC,
|
|
39
|
+
components: [
|
|
40
|
+
{ sku: 'PHONE-1', qty: 1, category: ProductCategoryEnum.PHONE, trackingMode: TrackingModeEnum.IMEI },
|
|
41
|
+
{ sku: 'SIM-1', qty: 1, category: ProductCategoryEnum.SIM, trackingMode: TrackingModeEnum.SERIAL },
|
|
42
|
+
],
|
|
43
|
+
identifiers: [
|
|
44
|
+
{ sku: 'PHONE-1', identifiers: ['356938035643809'] },
|
|
45
|
+
{ sku: 'SIM-1', identifiers: ['8952140'] },
|
|
46
|
+
],
|
|
47
|
+
product: {
|
|
48
|
+
brand: 'Moto',
|
|
49
|
+
model: 'G',
|
|
50
|
+
capacity: '128GB',
|
|
51
|
+
color: 'Negro',
|
|
52
|
+
imageUrl: null,
|
|
53
|
+
tier: null,
|
|
54
|
+
category: ProductCategoryEnum.BUNDLE,
|
|
55
|
+
trackingMode: TrackingModeEnum.QUANTITY,
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const pendingLine: WizardReservedLine = {
|
|
60
|
+
lineId: 'L2',
|
|
61
|
+
sku: 'CASE-1',
|
|
62
|
+
qty: 2,
|
|
63
|
+
status: WizardLineStatusEnum.PENDING,
|
|
64
|
+
reservationId: 'r-2',
|
|
65
|
+
expiresAt: '2026-09-23T20:30:00.000Z',
|
|
66
|
+
basePriceCents: null,
|
|
67
|
+
listPriceCents: null,
|
|
68
|
+
priceSk: null,
|
|
69
|
+
eligibleFinanciers: [],
|
|
70
|
+
financeable: false,
|
|
71
|
+
paymentType: null,
|
|
72
|
+
sellItemCost: null,
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
it('la sesión acepta reservedLines y financedLineId sin tocar los campos espejo', () => {
|
|
76
|
+
const session: Pick<WizardSession, 'reservedLines' | 'financedLineId' | 'reservedSku' | 'reservedImei'> = {
|
|
77
|
+
reservedLines: [kitLine, pendingLine],
|
|
78
|
+
financedLineId: 'L1',
|
|
79
|
+
reservedSku: 'PHONE-1',
|
|
80
|
+
reservedImei: '356938035643809',
|
|
81
|
+
};
|
|
82
|
+
expect(session.reservedLines).toHaveLength(2);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('WizardProduct acepta lineId, categoría y rastreo como espejo', () => {
|
|
86
|
+
const product: WizardProduct = {
|
|
87
|
+
sku: 'PHONE-1',
|
|
88
|
+
imei: '356938035643809',
|
|
89
|
+
cashPriceCents: 500000,
|
|
90
|
+
brand: 'Moto',
|
|
91
|
+
model: 'G',
|
|
92
|
+
capacity: '128GB',
|
|
93
|
+
color: 'Negro',
|
|
94
|
+
imageUrl: null,
|
|
95
|
+
tier: 'MID',
|
|
96
|
+
eligibleFinanciers: ['SUREKEEP'],
|
|
97
|
+
lineId: 'L1',
|
|
98
|
+
category: ProductCategoryEnum.PHONE,
|
|
99
|
+
trackingMode: TrackingModeEnum.IMEI,
|
|
100
|
+
};
|
|
101
|
+
expect(product.lineId).toBe('L1');
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('la venta acepta lines, skus e inventoryReturnPending', () => {
|
|
105
|
+
const line: SaleLine = {
|
|
106
|
+
lineId: 'L1',
|
|
107
|
+
sku: 'KIT-1',
|
|
108
|
+
qty: 1,
|
|
109
|
+
basePriceCents: 500000,
|
|
110
|
+
listPriceCents: 550000,
|
|
111
|
+
priceSk: '2026-09-01T00:00:00.000Z',
|
|
112
|
+
paymentType: LinePaymentTypeEnum.CREDIT,
|
|
113
|
+
components: [
|
|
114
|
+
{ sku: 'PHONE-1', qty: 1, identifiers: ['356938035643809'] },
|
|
115
|
+
{ sku: 'SIM-1', qty: 1, identifiers: ['8952140'] },
|
|
116
|
+
],
|
|
117
|
+
};
|
|
118
|
+
const sale: Pick<Sale, 'lines' | 'skus' | 'inventoryReturnPending' | 'sku'> = {
|
|
119
|
+
lines: [line],
|
|
120
|
+
skus: ['KIT-1', 'PHONE-1', 'SIM-1'],
|
|
121
|
+
inventoryReturnPending: false,
|
|
122
|
+
sku: 'PHONE-1',
|
|
123
|
+
};
|
|
124
|
+
expect(sale.lines?.[0].components).toHaveLength(2);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
@@ -3,5 +3,10 @@ export declare enum Status {
|
|
|
3
3
|
PENDING = "PENDING",
|
|
4
4
|
PAUSED = "PAUSED",
|
|
5
5
|
CANCELLED = "CANCELLED",
|
|
6
|
-
PIN_BLOCKED = "PIN_BLOCKED"
|
|
6
|
+
PIN_BLOCKED = "PIN_BLOCKED",
|
|
7
|
+
/**
|
|
8
|
+
* Bloqueo por fraude decidido por el emisor (CP: `card.status.fraud_blocked`,
|
|
9
|
+
* `card.status = FRAUD_BLOCK`). No lo puede quitar el usuario desde la app.
|
|
10
|
+
*/
|
|
11
|
+
FRAUD_BLOCK = "FRAUD_BLOCK"
|
|
7
12
|
}
|
package/bin/card/enums/Status.js
CHANGED
|
@@ -8,4 +8,9 @@ var Status;
|
|
|
8
8
|
Status["PAUSED"] = "PAUSED";
|
|
9
9
|
Status["CANCELLED"] = "CANCELLED";
|
|
10
10
|
Status["PIN_BLOCKED"] = "PIN_BLOCKED";
|
|
11
|
+
/**
|
|
12
|
+
* Bloqueo por fraude decidido por el emisor (CP: `card.status.fraud_blocked`,
|
|
13
|
+
* `card.status = FRAUD_BLOCK`). No lo puede quitar el usuario desde la app.
|
|
14
|
+
*/
|
|
15
|
+
Status["FRAUD_BLOCK"] = "FRAUD_BLOCK";
|
|
11
16
|
})(Status || (exports.Status = Status = {}));
|
|
@@ -2,6 +2,9 @@ import { MdmLockModeEnum } from '../enums/MdmLockModeEnum';
|
|
|
2
2
|
import { MdmProviderEnum } from '../enums/MdmProviderEnum';
|
|
3
3
|
import { ProductStatusEnum } from '../enums/ProductStatusEnum';
|
|
4
4
|
import { ProductTierEnum } from '../enums/ProductTierEnum';
|
|
5
|
+
import { ProductCategoryEnum } from '../enums/ProductCategoryEnum';
|
|
6
|
+
import { TrackingModeEnum } from '../enums/TrackingModeEnum';
|
|
7
|
+
import { ProductComponent } from './ProductComponent';
|
|
5
8
|
/**
|
|
6
9
|
* Product — aggregate root del catálogo del dominio `retailCatalog`
|
|
7
10
|
* (lambda retail-catalog-business, SureKeep Fase 1 — pista Retail).
|
|
@@ -19,7 +22,8 @@ export declare class Product {
|
|
|
19
22
|
description: string;
|
|
20
23
|
specs: Record<string, unknown> | null;
|
|
21
24
|
imageUrl: string | null;
|
|
22
|
-
|
|
25
|
+
/** `null` = Sin gama. */
|
|
26
|
+
tier: ProductTierEnum | null;
|
|
23
27
|
basePriceCents: number;
|
|
24
28
|
listPriceCents: number | null;
|
|
25
29
|
eligibleFinanciers: string[];
|
|
@@ -31,4 +35,14 @@ export declare class Product {
|
|
|
31
35
|
updatedBy: string;
|
|
32
36
|
createdAt: string;
|
|
33
37
|
updatedAt: string;
|
|
38
|
+
category?: ProductCategoryEnum;
|
|
39
|
+
trackingMode?: TrackingModeEnum;
|
|
40
|
+
/** Se puede vender suelto (fuera de un kit). */
|
|
41
|
+
sellable?: boolean;
|
|
42
|
+
/** Aparece en el catálogo del flujo de venta. */
|
|
43
|
+
showInSalesFlow?: boolean;
|
|
44
|
+
/** Solo en BUNDLE. */
|
|
45
|
+
components?: ProductComponent[] | null;
|
|
46
|
+
/** Llave del registro PRICE# del que salen basePriceCents y listPriceCents. */
|
|
47
|
+
currentPriceSk?: string | null;
|
|
34
48
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
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.ProductComponent = void 0;
|
|
13
|
+
const class_validator_1 = require("class-validator");
|
|
14
|
+
const SkuPattern_1 = require("../constants/SkuPattern");
|
|
15
|
+
/** Componente de un kit (BUNDLE): qué SKU consume y cuántas piezas por kit. */
|
|
16
|
+
class ProductComponent {
|
|
17
|
+
}
|
|
18
|
+
exports.ProductComponent = ProductComponent;
|
|
19
|
+
__decorate([
|
|
20
|
+
(0, class_validator_1.Matches)(SkuPattern_1.SKU_PATTERN, { message: 'sku admite solo [A-Za-z0-9-]' }),
|
|
21
|
+
(0, class_validator_1.Length)(1, 64),
|
|
22
|
+
(0, class_validator_1.IsString)(),
|
|
23
|
+
__metadata("design:type", String)
|
|
24
|
+
], ProductComponent.prototype, "sku", void 0);
|
|
25
|
+
__decorate([
|
|
26
|
+
(0, class_validator_1.IsInt)(),
|
|
27
|
+
(0, class_validator_1.Min)(1),
|
|
28
|
+
__metadata("design:type", Number)
|
|
29
|
+
], ProductComponent.prototype, "qty", void 0);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { InventoryLensPeriodEnum } from '../../enums/InventoryLensPeriodEnum';
|
|
2
|
+
/** Query de GET /backoffice/inventory/skus/{sku} (backofficeGetInventorySku); el retailer sale del token. */
|
|
3
|
+
export declare class GetInventorySkuQuery {
|
|
4
|
+
period?: InventoryLensPeriodEnum;
|
|
5
|
+
/** Debe pertenecer al retailer del token. */
|
|
6
|
+
storeId?: string;
|
|
7
|
+
/** Tamaño de página del libro de movimientos. */
|
|
8
|
+
limit?: number;
|
|
9
|
+
nextToken?: string;
|
|
10
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
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.GetInventorySkuQuery = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
const InventoryLensPeriodEnum_1 = require("../../enums/InventoryLensPeriodEnum");
|
|
16
|
+
/** Query de GET /backoffice/inventory/skus/{sku} (backofficeGetInventorySku); el retailer sale del token. */
|
|
17
|
+
class GetInventorySkuQuery {
|
|
18
|
+
}
|
|
19
|
+
exports.GetInventorySkuQuery = GetInventorySkuQuery;
|
|
20
|
+
__decorate([
|
|
21
|
+
(0, class_validator_1.IsOptional)(),
|
|
22
|
+
(0, class_validator_1.IsEnum)(InventoryLensPeriodEnum_1.InventoryLensPeriodEnum),
|
|
23
|
+
__metadata("design:type", String)
|
|
24
|
+
], GetInventorySkuQuery.prototype, "period", void 0);
|
|
25
|
+
__decorate([
|
|
26
|
+
(0, class_validator_1.IsOptional)(),
|
|
27
|
+
(0, class_validator_1.IsString)(),
|
|
28
|
+
__metadata("design:type", String)
|
|
29
|
+
], GetInventorySkuQuery.prototype, "storeId", void 0);
|
|
30
|
+
__decorate([
|
|
31
|
+
(0, class_validator_1.IsOptional)(),
|
|
32
|
+
(0, class_transformer_1.Type)(() => Number),
|
|
33
|
+
(0, class_validator_1.IsInt)(),
|
|
34
|
+
(0, class_validator_1.Min)(1),
|
|
35
|
+
(0, class_validator_1.Max)(100),
|
|
36
|
+
__metadata("design:type", Number)
|
|
37
|
+
], GetInventorySkuQuery.prototype, "limit", void 0);
|
|
38
|
+
__decorate([
|
|
39
|
+
(0, class_validator_1.IsOptional)(),
|
|
40
|
+
(0, class_validator_1.IsString)(),
|
|
41
|
+
__metadata("design:type", String)
|
|
42
|
+
], GetInventorySkuQuery.prototype, "nextToken", void 0);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { InventoryLensFilterEnum } from '../../enums/InventoryLensFilterEnum';
|
|
2
|
+
import { InventoryLensPeriodEnum } from '../../enums/InventoryLensPeriodEnum';
|
|
2
3
|
/**
|
|
3
4
|
* Query string de `GET /backoffice/inventory/lens`. SureKeep Fase 3 — pista Retail.
|
|
4
5
|
*
|
|
@@ -10,4 +11,8 @@ import { InventoryLensFilterEnum } from '../../enums/InventoryLensFilterEnum';
|
|
|
10
11
|
*/
|
|
11
12
|
export declare class InventoryLensQuery {
|
|
12
13
|
filter: InventoryLensFilterEnum;
|
|
14
|
+
/** Solo `filter=list`: periodo de ventas y cobertura. */
|
|
15
|
+
period?: InventoryLensPeriodEnum;
|
|
16
|
+
/** Solo `filter=list`: una tienda del retailer del token; ausente = consolidado. */
|
|
17
|
+
storeId?: string;
|
|
13
18
|
}
|
|
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.InventoryLensQuery = void 0;
|
|
13
13
|
const class_validator_1 = require("class-validator");
|
|
14
14
|
const InventoryLensFilterEnum_1 = require("../../enums/InventoryLensFilterEnum");
|
|
15
|
+
const InventoryLensPeriodEnum_1 = require("../../enums/InventoryLensPeriodEnum");
|
|
15
16
|
/**
|
|
16
17
|
* Query string de `GET /backoffice/inventory/lens`. SureKeep Fase 3 — pista Retail.
|
|
17
18
|
*
|
|
@@ -28,3 +29,13 @@ __decorate([
|
|
|
28
29
|
(0, class_validator_1.IsEnum)(InventoryLensFilterEnum_1.InventoryLensFilterEnum),
|
|
29
30
|
__metadata("design:type", String)
|
|
30
31
|
], InventoryLensQuery.prototype, "filter", void 0);
|
|
32
|
+
__decorate([
|
|
33
|
+
(0, class_validator_1.IsOptional)(),
|
|
34
|
+
(0, class_validator_1.IsEnum)(InventoryLensPeriodEnum_1.InventoryLensPeriodEnum),
|
|
35
|
+
__metadata("design:type", String)
|
|
36
|
+
], InventoryLensQuery.prototype, "period", void 0);
|
|
37
|
+
__decorate([
|
|
38
|
+
(0, class_validator_1.IsOptional)(),
|
|
39
|
+
(0, class_validator_1.IsString)(),
|
|
40
|
+
__metadata("design:type", String)
|
|
41
|
+
], InventoryLensQuery.prototype, "storeId", void 0);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ReservationLineRef } from './ReservationLineRef';
|
|
2
|
+
/** Body de PUT /private/stores/{storeId}/reservations/release (privateReleaseStock). */
|
|
3
|
+
export declare class ReleaseStockRequest {
|
|
4
|
+
sessionId: string;
|
|
5
|
+
lines: ReservationLineRef[];
|
|
6
|
+
/** `true` = solo libera las reservas ya vencidas (barrido). */
|
|
7
|
+
onlyExpired: boolean;
|
|
8
|
+
}
|
|
@@ -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.ReleaseStockRequest = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
const ReservationLineRef_1 = require("./ReservationLineRef");
|
|
16
|
+
/** Body de PUT /private/stores/{storeId}/reservations/release (privateReleaseStock). */
|
|
17
|
+
class ReleaseStockRequest {
|
|
18
|
+
}
|
|
19
|
+
exports.ReleaseStockRequest = ReleaseStockRequest;
|
|
20
|
+
__decorate([
|
|
21
|
+
(0, class_validator_1.IsString)(),
|
|
22
|
+
__metadata("design:type", String)
|
|
23
|
+
], ReleaseStockRequest.prototype, "sessionId", void 0);
|
|
24
|
+
__decorate([
|
|
25
|
+
(0, class_validator_1.IsArray)(),
|
|
26
|
+
(0, class_validator_1.ArrayMinSize)(1),
|
|
27
|
+
(0, class_validator_1.ValidateNested)({ each: true }),
|
|
28
|
+
(0, class_transformer_1.Type)(() => ReservationLineRef_1.ReservationLineRef),
|
|
29
|
+
__metadata("design:type", Array)
|
|
30
|
+
], ReleaseStockRequest.prototype, "lines", void 0);
|
|
31
|
+
__decorate([
|
|
32
|
+
(0, class_validator_1.IsBoolean)(),
|
|
33
|
+
__metadata("design:type", Boolean)
|
|
34
|
+
], ReleaseStockRequest.prototype, "onlyExpired", void 0);
|