@fiado/type-kit 3.478.0 → 3.480.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/_test_/unit/retailCatalog/backofficeRequests.test.ts +4 -0
  2. package/_test_/unit/retailCatalog/catalogEnums.test.ts +1 -1
  3. package/_test_/unit/retailPromotions/constants.test.ts +1 -1
  4. package/_test_/unit/retailPromotions/skuSalePromotions.test.ts +49 -0
  5. package/bin/retailCatalog/dtos/requests/BackofficeRegisterEntryRequest.d.ts +3 -0
  6. package/bin/retailCatalog/dtos/requests/BackofficeRegisterEntryRequest.js +6 -0
  7. package/bin/retailCatalog/enums/InventoryMovementReasonEnum.d.ts +3 -2
  8. package/bin/retailCatalog/enums/InventoryMovementReasonEnum.js +2 -1
  9. package/bin/retailPromotions/constants/retailPromotionsErrorHttpStatus.js +1 -0
  10. package/bin/retailPromotions/dtos/requests/SkuSalePromotionsQuery.d.ts +5 -0
  11. package/bin/retailPromotions/dtos/requests/SkuSalePromotionsQuery.js +30 -0
  12. package/bin/retailPromotions/dtos/responses/SkuSalePromotionsResponse.d.ts +6 -0
  13. package/bin/retailPromotions/dtos/responses/SkuSalePromotionsResponse.js +2 -0
  14. package/bin/retailPromotions/enums/RetailPromotionsErrorCodeEnum.d.ts +3 -1
  15. package/bin/retailPromotions/enums/RetailPromotionsErrorCodeEnum.js +2 -0
  16. package/bin/retailPromotions/index.d.ts +2 -0
  17. package/bin/retailPromotions/index.js +2 -0
  18. package/package.json +1 -1
  19. package/src/retailCatalog/dtos/requests/BackofficeRegisterEntryRequest.ts +7 -1
  20. package/src/retailCatalog/enums/InventoryMovementReasonEnum.ts +2 -1
  21. package/src/retailPromotions/constants/retailPromotionsErrorHttpStatus.ts +1 -0
  22. package/src/retailPromotions/dtos/requests/SkuSalePromotionsQuery.ts +15 -0
  23. package/src/retailPromotions/dtos/responses/SkuSalePromotionsResponse.ts +7 -0
  24. package/src/retailPromotions/enums/RetailPromotionsErrorCodeEnum.ts +2 -0
  25. package/src/retailPromotions/index.ts +2 -0
@@ -141,6 +141,10 @@ describe('BackofficeRegisterEntryRequest (backofficeRegisterEntry)', () => {
141
141
  expect(errorsOf(BackofficeRegisterEntryRequest, { ...ok, identifiers: [' '] })).toContain('identifiers');
142
142
  expect(errorsOf(BackofficeRegisterEntryRequest, { ...ok, identifiers: ['A1', 'A1'] })).toContain('identifiers');
143
143
  });
144
+ it('acepta el motivo sobrante de conteo y rechaza motivos desconocidos', () => {
145
+ expect(errorsOf(BackofficeRegisterEntryRequest, { ...ok, reason: InventoryMovementReasonEnum.COUNT_SURPLUS })).toEqual([]);
146
+ expect(errorsOf(BackofficeRegisterEntryRequest, { ...ok, reason: 'LOST' })).toContain('reason');
147
+ });
144
148
  });
145
149
 
146
150
  describe('BackofficeRegisterAdjustmentRequest (backofficeRegisterAdjustment)', () => {
@@ -55,7 +55,7 @@ describe('retailCatalog — enums de la operación independiente', () => {
55
55
 
56
56
  it('expone el motivo de un movimiento', () => {
57
57
  expect(Object.values(RetailCatalog.InventoryMovementReasonEnum)).toEqual([
58
- 'SHRINKAGE', 'ADJUSTMENT', 'WARRANTY', 'DAMAGED_RETURN',
58
+ 'SHRINKAGE', 'ADJUSTMENT', 'WARRANTY', 'DAMAGED_RETURN', 'COUNT_SURPLUS',
59
59
  ]);
60
60
  });
61
61
  });
@@ -43,7 +43,7 @@ describe('catálogo de errores', () => {
43
43
  expect(RETAIL_PROMOTIONS_ERROR_HTTP_STATUS.CODE_NOT_FOUND).toBe(404);
44
44
  expect(RETAIL_PROMOTIONS_ERROR_HTTP_STATUS.DISCOUNT_AFTER_QUOTE).toBe(409);
45
45
  expect(RETAIL_PROMOTIONS_ERROR_HTTP_STATUS.CODE_NOT_OWNED).toBe(422);
46
- expect(Object.keys(RetailPromotionsErrorCodeEnum)).toHaveLength(28);
46
+ expect(Object.keys(RetailPromotionsErrorCodeEnum)).toHaveLength(29);
47
47
  });
48
48
 
49
49
  it('promo de regalo y de venta mandadas en el campo equivocado son 422', () => {
@@ -0,0 +1,49 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validate } from 'class-validator';
4
+ import {
5
+ RETAIL_PROMOTIONS_ERROR_HTTP_STATUS,
6
+ RetailPromotionsErrorCodeEnum,
7
+ SkuSalePromotionsQuery,
8
+ SkuSalePromotionsResponse,
9
+ } from '../../../src/retailPromotions/index';
10
+
11
+ const invalidProps = async (raw: Record<string, unknown>): Promise<string[]> => {
12
+ const errors = await validate(plainToInstance(SkuSalePromotionsQuery, raw) as object);
13
+ return errors.map((e) => e.property).sort();
14
+ };
15
+
16
+ describe('SkuSalePromotionsQuery', () => {
17
+ it('acepta sessionId y sku', async () => {
18
+ expect(await invalidProps({ sessionId: 'ses-1', sku: 'SKU-1' })).toEqual([]);
19
+ });
20
+
21
+ it('exige ambos campos', async () => {
22
+ expect(await invalidProps({})).toEqual(['sessionId', 'sku']);
23
+ });
24
+
25
+ it.each([
26
+ ['sessionId', { sessionId: '', sku: 'SKU-1' }],
27
+ ['sku', { sessionId: 'ses-1', sku: '' }],
28
+ ])('rechaza %s vacío', async (prop, raw) => {
29
+ expect(await invalidProps(raw)).toEqual([prop]);
30
+ });
31
+
32
+ it('rechaza valores que no son texto', async () => {
33
+ expect(await invalidProps({ sessionId: 1, sku: ['SKU-1'] })).toEqual(['sessionId', 'sku']);
34
+ });
35
+ });
36
+
37
+ describe('SkuSalePromotionsResponse', () => {
38
+ it('lleva el sku y sus promos evaluadas', () => {
39
+ const response: SkuSalePromotionsResponse = { sku: 'SKU-1', promotions: [] };
40
+ expect(response.promotions).toEqual([]);
41
+ });
42
+ });
43
+
44
+ describe('CATALOG_SKU_NOT_FOUND', () => {
45
+ it('es 404', () => {
46
+ expect(RetailPromotionsErrorCodeEnum.CATALOG_SKU_NOT_FOUND).toBe('CATALOG_SKU_NOT_FOUND');
47
+ expect(RETAIL_PROMOTIONS_ERROR_HTTP_STATUS.CATALOG_SKU_NOT_FOUND).toBe(404);
48
+ });
49
+ });
@@ -1,3 +1,4 @@
1
+ import { InventoryMovementReasonEnum } from '../../enums/InventoryMovementReasonEnum';
1
2
  /** Body de POST /backoffice/inventory/entries (backofficeRegisterEntry); suma al saldo de la tienda con un MOV# ENTRY. */
2
3
  export declare class BackofficeRegisterEntryRequest {
3
4
  /** Debe pertenecer al retailer del token. */
@@ -6,4 +7,6 @@ export declare class BackofficeRegisterEntryRequest {
6
7
  qty: number;
7
8
  /** IMEI o serie de cada pieza; ausente si el SKU se rastrea por cantidad. */
8
9
  identifiers?: string[];
10
+ /** Motivo de la entrada; COUNT_SURPLUS marca un sobrante de conteo. Ausente en una entrada normal. */
11
+ reason?: InventoryMovementReasonEnum;
9
12
  }
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.BackofficeRegisterEntryRequest = void 0;
13
13
  const class_validator_1 = require("class-validator");
14
14
  const SkuPattern_1 = require("../../constants/SkuPattern");
15
+ const InventoryMovementReasonEnum_1 = require("../../enums/InventoryMovementReasonEnum");
15
16
  /** Body de POST /backoffice/inventory/entries (backofficeRegisterEntry); suma al saldo de la tienda con un MOV# ENTRY. */
16
17
  class BackofficeRegisterEntryRequest {
17
18
  }
@@ -41,3 +42,8 @@ __decorate([
41
42
  (0, class_validator_1.IsString)({ each: true }),
42
43
  __metadata("design:type", Array)
43
44
  ], BackofficeRegisterEntryRequest.prototype, "identifiers", void 0);
45
+ __decorate([
46
+ (0, class_validator_1.IsOptional)(),
47
+ (0, class_validator_1.IsEnum)(InventoryMovementReasonEnum_1.InventoryMovementReasonEnum),
48
+ __metadata("design:type", String)
49
+ ], BackofficeRegisterEntryRequest.prototype, "reason", void 0);
@@ -1,7 +1,8 @@
1
- /** Motivo de un movimiento manual de inventario (MOV#): merma, ajuste, garantía o devolución dañada. */
1
+ /** Motivo de un movimiento manual de inventario (MOV#): merma, ajuste, garantía, devolución dañada o sobrante de conteo. */
2
2
  export declare enum InventoryMovementReasonEnum {
3
3
  SHRINKAGE = "SHRINKAGE",
4
4
  ADJUSTMENT = "ADJUSTMENT",
5
5
  WARRANTY = "WARRANTY",
6
- DAMAGED_RETURN = "DAMAGED_RETURN"
6
+ DAMAGED_RETURN = "DAMAGED_RETURN",
7
+ COUNT_SURPLUS = "COUNT_SURPLUS"
7
8
  }
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.InventoryMovementReasonEnum = void 0;
4
- /** Motivo de un movimiento manual de inventario (MOV#): merma, ajuste, garantía o devolución dañada. */
4
+ /** Motivo de un movimiento manual de inventario (MOV#): merma, ajuste, garantía, devolución dañada o sobrante de conteo. */
5
5
  var InventoryMovementReasonEnum;
6
6
  (function (InventoryMovementReasonEnum) {
7
7
  InventoryMovementReasonEnum["SHRINKAGE"] = "SHRINKAGE";
8
8
  InventoryMovementReasonEnum["ADJUSTMENT"] = "ADJUSTMENT";
9
9
  InventoryMovementReasonEnum["WARRANTY"] = "WARRANTY";
10
10
  InventoryMovementReasonEnum["DAMAGED_RETURN"] = "DAMAGED_RETURN";
11
+ InventoryMovementReasonEnum["COUNT_SURPLUS"] = "COUNT_SURPLUS";
11
12
  })(InventoryMovementReasonEnum || (exports.InventoryMovementReasonEnum = InventoryMovementReasonEnum = {}));
@@ -32,4 +32,5 @@ exports.RETAIL_PROMOTIONS_ERROR_HTTP_STATUS = {
32
32
  [RetailPromotionsErrorCodeEnum_1.RetailPromotionsErrorCodeEnum.PROMOTION_NOT_REVALIDATED]: 409,
33
33
  [RetailPromotionsErrorCodeEnum_1.RetailPromotionsErrorCodeEnum.SALE_PROMOTION_HOLD_CONFLICT]: 409,
34
34
  [RetailPromotionsErrorCodeEnum_1.RetailPromotionsErrorCodeEnum.INVALID_NEXT_TOKEN]: 400,
35
+ [RetailPromotionsErrorCodeEnum_1.RetailPromotionsErrorCodeEnum.CATALOG_SKU_NOT_FOUND]: 404,
35
36
  };
@@ -0,0 +1,5 @@
1
+ /** Query de publicListSkuSalePromotions; precio, tienda y cliente salen de la sesión y del catálogo. */
2
+ export declare class SkuSalePromotionsQuery {
3
+ sessionId: string;
4
+ sku: string;
5
+ }
@@ -0,0 +1,30 @@
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.SkuSalePromotionsQuery = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ /** Query de publicListSkuSalePromotions; precio, tienda y cliente salen de la sesión y del catálogo. */
16
+ class SkuSalePromotionsQuery {
17
+ }
18
+ exports.SkuSalePromotionsQuery = SkuSalePromotionsQuery;
19
+ __decorate([
20
+ (0, class_transformer_1.Expose)(),
21
+ (0, class_validator_1.IsString)(),
22
+ (0, class_validator_1.IsNotEmpty)(),
23
+ __metadata("design:type", String)
24
+ ], SkuSalePromotionsQuery.prototype, "sessionId", void 0);
25
+ __decorate([
26
+ (0, class_transformer_1.Expose)(),
27
+ (0, class_validator_1.IsString)(),
28
+ (0, class_validator_1.IsNotEmpty)(),
29
+ __metadata("design:type", String)
30
+ ], SkuSalePromotionsQuery.prototype, "sku", void 0);
@@ -0,0 +1,6 @@
1
+ import { EvaluatedSalePromotion } from './WizardSalePromotionResponses';
2
+ /** Promos que aplicarían si el SKU fuera la ancla de la sesión, con sus opciones de regalo. */
3
+ export interface SkuSalePromotionsResponse {
4
+ sku: string;
5
+ promotions: EvaluatedSalePromotion[];
6
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -40,5 +40,7 @@ export declare enum RetailPromotionsErrorCodeEnum {
40
40
  /** Otra venta ya retiene la promo. */
41
41
  SALE_PROMOTION_HOLD_CONFLICT = "SALE_PROMOTION_HOLD_CONFLICT",
42
42
  /** El token de paginación no es válido. */
43
- INVALID_NEXT_TOKEN = "INVALID_NEXT_TOKEN"
43
+ INVALID_NEXT_TOKEN = "INVALID_NEXT_TOKEN",
44
+ /** El SKU no existe en el catálogo. */
45
+ CATALOG_SKU_NOT_FOUND = "CATALOG_SKU_NOT_FOUND"
44
46
  }
@@ -45,4 +45,6 @@ var RetailPromotionsErrorCodeEnum;
45
45
  RetailPromotionsErrorCodeEnum["SALE_PROMOTION_HOLD_CONFLICT"] = "SALE_PROMOTION_HOLD_CONFLICT";
46
46
  /** El token de paginación no es válido. */
47
47
  RetailPromotionsErrorCodeEnum["INVALID_NEXT_TOKEN"] = "INVALID_NEXT_TOKEN";
48
+ /** El SKU no existe en el catálogo. */
49
+ RetailPromotionsErrorCodeEnum["CATALOG_SKU_NOT_FOUND"] = "CATALOG_SKU_NOT_FOUND";
48
50
  })(RetailPromotionsErrorCodeEnum || (exports.RetailPromotionsErrorCodeEnum = RetailPromotionsErrorCodeEnum = {}));
@@ -45,6 +45,8 @@ export * from './dtos/requests/EvaluateSalePromotionsRequest';
45
45
  export * from './dtos/requests/HoldGiftPromotionInput';
46
46
  export * from './dtos/requests/HoldSalePromotionRequest';
47
47
  export * from './dtos/requests/GetSaleCouponQuery';
48
+ export * from './dtos/requests/SkuSalePromotionsQuery';
48
49
  export * from './dtos/responses/SalePromotionCrudResponses';
49
50
  export * from './dtos/responses/DiscountCodeResponses';
50
51
  export * from './dtos/responses/WizardSalePromotionResponses';
52
+ export * from './dtos/responses/SkuSalePromotionsResponse';
@@ -65,7 +65,9 @@ __exportStar(require("./dtos/requests/EvaluateSalePromotionsRequest"), exports);
65
65
  __exportStar(require("./dtos/requests/HoldGiftPromotionInput"), exports);
66
66
  __exportStar(require("./dtos/requests/HoldSalePromotionRequest"), exports);
67
67
  __exportStar(require("./dtos/requests/GetSaleCouponQuery"), exports);
68
+ __exportStar(require("./dtos/requests/SkuSalePromotionsQuery"), exports);
68
69
  // Response DTOs
69
70
  __exportStar(require("./dtos/responses/SalePromotionCrudResponses"), exports);
70
71
  __exportStar(require("./dtos/responses/DiscountCodeResponses"), exports);
71
72
  __exportStar(require("./dtos/responses/WizardSalePromotionResponses"), exports);
73
+ __exportStar(require("./dtos/responses/SkuSalePromotionsResponse"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/type-kit",
3
- "version": "3.478.0",
3
+ "version": "3.480.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",
@@ -1,5 +1,6 @@
1
- import { ArrayMinSize, ArrayUnique, IsArray, IsInt, IsOptional, IsString, Length, Matches, Min } from 'class-validator';
1
+ import { ArrayMinSize, ArrayUnique, IsArray, IsEnum, IsInt, IsOptional, IsString, Length, Matches, Min } from 'class-validator';
2
2
  import { SKU_PATTERN } from '../../constants/SkuPattern';
3
+ import { InventoryMovementReasonEnum } from '../../enums/InventoryMovementReasonEnum';
3
4
 
4
5
  /** Body de POST /backoffice/inventory/entries (backofficeRegisterEntry); suma al saldo de la tienda con un MOV# ENTRY. */
5
6
  export class BackofficeRegisterEntryRequest {
@@ -25,4 +26,9 @@ export class BackofficeRegisterEntryRequest {
25
26
  @Matches(/^\S+$/, { each: true })
26
27
  @IsString({ each: true })
27
28
  identifiers?: string[];
29
+
30
+ /** Motivo de la entrada; COUNT_SURPLUS marca un sobrante de conteo. Ausente en una entrada normal. */
31
+ @IsOptional()
32
+ @IsEnum(InventoryMovementReasonEnum)
33
+ reason?: InventoryMovementReasonEnum;
28
34
  }
@@ -1,7 +1,8 @@
1
- /** Motivo de un movimiento manual de inventario (MOV#): merma, ajuste, garantía o devolución dañada. */
1
+ /** Motivo de un movimiento manual de inventario (MOV#): merma, ajuste, garantía, devolución dañada o sobrante de conteo. */
2
2
  export enum InventoryMovementReasonEnum {
3
3
  SHRINKAGE = 'SHRINKAGE',
4
4
  ADJUSTMENT = 'ADJUSTMENT',
5
5
  WARRANTY = 'WARRANTY',
6
6
  DAMAGED_RETURN = 'DAMAGED_RETURN',
7
+ COUNT_SURPLUS = 'COUNT_SURPLUS',
7
8
  }
@@ -30,4 +30,5 @@ export const RETAIL_PROMOTIONS_ERROR_HTTP_STATUS: Readonly<Record<C, 400 | 403 |
30
30
  [C.PROMOTION_NOT_REVALIDATED]: 409,
31
31
  [C.SALE_PROMOTION_HOLD_CONFLICT]: 409,
32
32
  [C.INVALID_NEXT_TOKEN]: 400,
33
+ [C.CATALOG_SKU_NOT_FOUND]: 404,
33
34
  };
@@ -0,0 +1,15 @@
1
+ import { Expose } from 'class-transformer';
2
+ import { IsNotEmpty, IsString } from 'class-validator';
3
+
4
+ /** Query de publicListSkuSalePromotions; precio, tienda y cliente salen de la sesión y del catálogo. */
5
+ export class SkuSalePromotionsQuery {
6
+ @Expose()
7
+ @IsString()
8
+ @IsNotEmpty()
9
+ sessionId!: string;
10
+
11
+ @Expose()
12
+ @IsString()
13
+ @IsNotEmpty()
14
+ sku!: string;
15
+ }
@@ -0,0 +1,7 @@
1
+ import { EvaluatedSalePromotion } from './WizardSalePromotionResponses';
2
+
3
+ /** Promos que aplicarían si el SKU fuera la ancla de la sesión, con sus opciones de regalo. */
4
+ export interface SkuSalePromotionsResponse {
5
+ sku: string;
6
+ promotions: EvaluatedSalePromotion[];
7
+ }
@@ -41,4 +41,6 @@ export enum RetailPromotionsErrorCodeEnum {
41
41
  SALE_PROMOTION_HOLD_CONFLICT = 'SALE_PROMOTION_HOLD_CONFLICT',
42
42
  /** El token de paginación no es válido. */
43
43
  INVALID_NEXT_TOKEN = 'INVALID_NEXT_TOKEN',
44
+ /** El SKU no existe en el catálogo. */
45
+ CATALOG_SKU_NOT_FOUND = 'CATALOG_SKU_NOT_FOUND',
44
46
  }
@@ -52,8 +52,10 @@ export * from './dtos/requests/EvaluateSalePromotionsRequest';
52
52
  export * from './dtos/requests/HoldGiftPromotionInput';
53
53
  export * from './dtos/requests/HoldSalePromotionRequest';
54
54
  export * from './dtos/requests/GetSaleCouponQuery';
55
+ export * from './dtos/requests/SkuSalePromotionsQuery';
55
56
 
56
57
  // Response DTOs
57
58
  export * from './dtos/responses/SalePromotionCrudResponses';
58
59
  export * from './dtos/responses/DiscountCodeResponses';
59
60
  export * from './dtos/responses/WizardSalePromotionResponses';
61
+ export * from './dtos/responses/SkuSalePromotionsResponse';