@fiado/type-kit 3.567.0 → 3.568.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.
@@ -68,6 +68,11 @@ describe('SellStockRequest y ReturnStockRequest', () => {
68
68
  const bad = { ...saleLine, components: [{ sku: 'SIM-1', qty: 1, identifiers: [123] }] };
69
69
  expect(errorsOf(SellStockRequest, { sessionId: 's', retailerId: 'ret', lines: [bad] })).toContain('lines.0.components.0.identifiers');
70
70
  });
71
+ it('acepta saleId opcional', () => {
72
+ const base = { sessionId: 's', retailerId: 'ret', lines: [saleLine] };
73
+ expect(errorsOf(SellStockRequest, { ...base, saleId: 'sale-1' })).toEqual([]);
74
+ expect(errorsOf(SellStockRequest, { ...base, saleId: 123 })).toContain('saleId');
75
+ });
71
76
  it('devolución exige saleId y soldAt ISO', () => {
72
77
  const ok = { saleId: 'sale', retailerId: 'ret', soldAt: '2026-09-23T10:00:00.000Z', lines: [saleLine] };
73
78
  expect(errorsOf(ReturnStockRequest, ok)).toEqual([]);
@@ -153,4 +158,17 @@ describe('GetInventorySkuQuery', () => {
153
158
  expect(validateSync(dto)).toEqual([]);
154
159
  });
155
160
  it('rechaza limit fuera de rango', () => expect(errorsOf(GetInventorySkuQuery, { limit: '0' })).toContain('limit'));
161
+ it.each([
162
+ [true, true],
163
+ [false, false],
164
+ ['true', true],
165
+ ['false', false],
166
+ ])('convierte includeHolds %p a %p', (raw, expected) => {
167
+ const dto = plainToInstance(GetInventorySkuQuery, { includeHolds: raw });
168
+ expect(dto.includeHolds).toBe(expected);
169
+ expect(validateSync(dto)).toEqual([]);
170
+ });
171
+ it('rechaza includeHolds no booleano', () => {
172
+ expect(errorsOf(GetInventorySkuQuery, { includeHolds: 'x' })).toContain('includeHolds');
173
+ });
156
174
  });
@@ -7,4 +7,6 @@ export declare class GetInventorySkuQuery {
7
7
  /** Tamaño de página del libro de movimientos. */
8
8
  limit?: number;
9
9
  nextToken?: string;
10
+ /** `true` incluye en el libro los movimientos RESERVATION y RELEASE. */
11
+ includeHolds?: boolean;
10
12
  }
@@ -40,3 +40,9 @@ __decorate([
40
40
  (0, class_validator_1.IsString)(),
41
41
  __metadata("design:type", String)
42
42
  ], GetInventorySkuQuery.prototype, "nextToken", void 0);
43
+ __decorate([
44
+ (0, class_validator_1.IsOptional)(),
45
+ (0, class_transformer_1.Transform)(({ value }) => (value === 'true' ? true : value === 'false' ? false : value)),
46
+ (0, class_validator_1.IsBoolean)(),
47
+ __metadata("design:type", Boolean)
48
+ ], GetInventorySkuQuery.prototype, "includeHolds", void 0);
@@ -4,4 +4,6 @@ export declare class SellStockRequest {
4
4
  sessionId: string;
5
5
  retailerId: string;
6
6
  lines: StockLine[];
7
+ /** Venta a la que pertenece; liga los MOV# de la TX con ella. */
8
+ saleId?: string;
7
9
  }
@@ -32,3 +32,8 @@ __decorate([
32
32
  (0, class_transformer_1.Type)(() => StockLine_1.StockLine),
33
33
  __metadata("design:type", Array)
34
34
  ], SellStockRequest.prototype, "lines", void 0);
35
+ __decorate([
36
+ (0, class_validator_1.IsOptional)(),
37
+ (0, class_validator_1.IsString)(),
38
+ __metadata("design:type", String)
39
+ ], SellStockRequest.prototype, "saleId", void 0);
@@ -18,6 +18,15 @@ export interface InventoryMovementEntry {
18
18
  reason?: InventoryMovementReasonEnum;
19
19
  /** Id del MOV#, para ligar un ajuste con reversesMovementId. */
20
20
  movementId?: string;
21
+ /** Traspaso al que pertenece el movimiento, si es uno. */
22
+ transferId?: string;
23
+ /** Venta a la que pertenece el movimiento, si es una. */
24
+ saleId?: string;
25
+ }
26
+ /** Unidades apartadas (BALANCE#.reserved) del SKU en una tienda. */
27
+ export interface InventoryStoreReserved {
28
+ storeId: string;
29
+ reserved: number;
21
30
  }
22
31
  /** Pieza de una tienda; status AVAILABLE, SOLD o DAMAGED. */
23
32
  export interface InventoryPieceEntry {
@@ -37,6 +46,7 @@ export interface GetInventorySkuResponse {
37
46
  nextToken: string | null;
38
47
  /** Vacío si el SKU se rastrea por cantidad. */
39
48
  piecesByStore: InventoryStorePieces[];
49
+ reservedByStore: InventoryStoreReserved[];
40
50
  currentPrice: SkuPriceEntry | null;
41
51
  /** Promos de venta vigentes del SKU; `null` si retail-promotions no respondió. */
42
52
  promotions?: ActiveSalePromotionSummary[] | null;
@@ -85,6 +85,8 @@ export interface InventoryLensStoreStock {
85
85
  storeId: string;
86
86
  stock: number;
87
87
  sold: number;
88
+ /** Unidades apartadas (BALANCE#.reserved). */
89
+ reserved: number;
88
90
  }
89
91
  /** Alertas de una fila del modo lista. */
90
92
  export interface InventoryLensAlerts {
@@ -110,6 +112,8 @@ export interface InventoryLensListItem {
110
112
  storesWithStock: number;
111
113
  storesTotal: number;
112
114
  byStore: InventoryLensStoreStock[];
115
+ /** Suma de `reserved` de todas las tiendas. */
116
+ reservedTotal: number;
113
117
  soldPeriod: number;
114
118
  coverage: InventoryLensCoverage;
115
119
  alerts: InventoryLensAlerts;
@@ -6,6 +6,7 @@ export declare class InventorySaleAppliedMessage extends SellStockRequest {
6
6
  /** La cola es compartida entre silos; el tenant elige las tablas. */
7
7
  tenantId: string;
8
8
  storeId: string;
9
+ /** El ValidateIf anula el @IsOptional que hereda de SellStockRequest: aquí saleId es obligatorio. */
9
10
  saleId: string;
10
11
  /** Fecha de la venta; fecha el DAY# y el MOV#. */
11
12
  soldAt: string;
@@ -32,6 +32,7 @@ __decorate([
32
32
  __metadata("design:type", String)
33
33
  ], InventorySaleAppliedMessage.prototype, "storeId", void 0);
34
34
  __decorate([
35
+ (0, class_validator_1.ValidateIf)(() => true),
35
36
  (0, class_validator_1.IsString)(),
36
37
  (0, class_validator_1.IsNotEmpty)(),
37
38
  __metadata("design:type", String)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/type-kit",
3
- "version": "3.567.0",
3
+ "version": "3.568.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",
@@ -1,5 +1,5 @@
1
- import { Type } from 'class-transformer';
2
- import { IsEnum, IsInt, IsOptional, IsString, Max, Min } from 'class-validator';
1
+ import { Transform, Type } from 'class-transformer';
2
+ import { IsBoolean, IsEnum, IsInt, IsOptional, IsString, Max, Min } from 'class-validator';
3
3
  import { InventoryLensPeriodEnum } from '../../enums/InventoryLensPeriodEnum';
4
4
 
5
5
  /** Query de GET /backoffice/inventory/skus/{sku} (backofficeGetInventorySku); el retailer sale del token. */
@@ -24,4 +24,10 @@ export class GetInventorySkuQuery {
24
24
  @IsOptional()
25
25
  @IsString()
26
26
  nextToken?: string;
27
+
28
+ /** `true` incluye en el libro los movimientos RESERVATION y RELEASE. */
29
+ @IsOptional()
30
+ @Transform(({ value }) => (value === 'true' ? true : value === 'false' ? false : value))
31
+ @IsBoolean()
32
+ includeHolds?: boolean;
27
33
  }
@@ -1,5 +1,5 @@
1
1
  import { Type } from 'class-transformer';
2
- import { ArrayMinSize, IsArray, IsString, ValidateNested } from 'class-validator';
2
+ import { ArrayMinSize, IsArray, IsOptional, IsString, ValidateNested } from 'class-validator';
3
3
  import { StockLine } from './StockLine';
4
4
 
5
5
  /** Body de PUT /private/stores/{storeId}/sales (privateSellStock); una TX de venta. */
@@ -15,4 +15,9 @@ export class SellStockRequest {
15
15
  @ValidateNested({ each: true })
16
16
  @Type(() => StockLine)
17
17
  lines!: StockLine[];
18
+
19
+ /** Venta a la que pertenece; liga los MOV# de la TX con ella. */
20
+ @IsOptional()
21
+ @IsString()
22
+ saleId?: string;
18
23
  }
@@ -19,6 +19,16 @@ export interface InventoryMovementEntry {
19
19
  reason?: InventoryMovementReasonEnum;
20
20
  /** Id del MOV#, para ligar un ajuste con reversesMovementId. */
21
21
  movementId?: string;
22
+ /** Traspaso al que pertenece el movimiento, si es uno. */
23
+ transferId?: string;
24
+ /** Venta a la que pertenece el movimiento, si es una. */
25
+ saleId?: string;
26
+ }
27
+
28
+ /** Unidades apartadas (BALANCE#.reserved) del SKU en una tienda. */
29
+ export interface InventoryStoreReserved {
30
+ storeId: string;
31
+ reserved: number;
22
32
  }
23
33
 
24
34
  /** Pieza de una tienda; status AVAILABLE, SOLD o DAMAGED. */
@@ -41,6 +51,7 @@ export interface GetInventorySkuResponse {
41
51
  nextToken: string | null;
42
52
  /** Vacío si el SKU se rastrea por cantidad. */
43
53
  piecesByStore: InventoryStorePieces[];
54
+ reservedByStore: InventoryStoreReserved[];
44
55
  currentPrice: SkuPriceEntry | null;
45
56
  /** Promos de venta vigentes del SKU; `null` si retail-promotions no respondió. */
46
57
  promotions?: ActiveSalePromotionSummary[] | null;
@@ -97,6 +97,8 @@ export interface InventoryLensStoreStock {
97
97
  storeId: string;
98
98
  stock: number;
99
99
  sold: number;
100
+ /** Unidades apartadas (BALANCE#.reserved). */
101
+ reserved: number;
100
102
  }
101
103
 
102
104
  /** Alertas de una fila del modo lista. */
@@ -125,6 +127,8 @@ export interface InventoryLensListItem {
125
127
  storesWithStock: number;
126
128
  storesTotal: number;
127
129
  byStore: InventoryLensStoreStock[];
130
+ /** Suma de `reserved` de todas las tiendas. */
131
+ reservedTotal: number;
128
132
  soldPeriod: number;
129
133
  coverage: InventoryLensCoverage;
130
134
  alerts: InventoryLensAlerts;
@@ -1,4 +1,4 @@
1
- import { Equals, IsISO8601, IsNotEmpty, IsString } from 'class-validator';
1
+ import { Equals, IsISO8601, IsNotEmpty, IsString, ValidateIf } from 'class-validator';
2
2
  import { InventoryInboundMessageTypeEnum } from '../enums/InventoryInboundMessageTypeEnum';
3
3
  import { SellStockRequest } from '../dtos/requests/SellStockRequest';
4
4
 
@@ -16,6 +16,8 @@ export class InventorySaleAppliedMessage extends SellStockRequest {
16
16
  @IsNotEmpty()
17
17
  storeId!: string;
18
18
 
19
+ /** El ValidateIf anula el @IsOptional que hereda de SellStockRequest: aquí saleId es obligatorio. */
20
+ @ValidateIf(() => true)
19
21
  @IsString()
20
22
  @IsNotEmpty()
21
23
  saleId!: string;