@fiado/type-kit 3.607.0 → 3.609.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/loanCredit/dtos/originateLoanCreditRequest.test.ts +9 -0
- package/_test_/unit/loanOfferings/promotionCategoryTierScope.test.ts +89 -0
- package/_test_/unit/retailIntegration/eventPayloadBounds.test.ts +1 -1
- package/_test_/unit/retailIntegration/eventPayloads.test.ts +53 -6
- package/_test_/unit/retailIntegration/retailSystemEnums.test.ts +2 -0
- package/bin/loanCredit/dtos/requests/OriginateLoanCreditRequest.d.ts +6 -0
- package/bin/loanCredit/dtos/requests/OriginateLoanCreditRequest.js +14 -0
- package/bin/loanOfferings/constants/promotionSkuBatch.d.ts +2 -0
- package/bin/loanOfferings/constants/promotionSkuBatch.js +5 -0
- package/bin/loanOfferings/dtos/requests/CreatePromotionRequest.d.ts +6 -0
- package/bin/loanOfferings/dtos/requests/CreatePromotionRequest.js +16 -0
- package/bin/loanOfferings/dtos/requests/ListPromotedSkusRequest.d.ts +11 -0
- package/bin/loanOfferings/dtos/requests/ListPromotedSkusRequest.js +47 -0
- package/bin/loanOfferings/dtos/requests/ListSkuPromotionsRequest.d.ts +11 -0
- package/bin/loanOfferings/dtos/requests/ListSkuPromotionsRequest.js +47 -0
- package/bin/loanOfferings/dtos/requests/PromotionSkuInput.d.ts +8 -0
- package/bin/loanOfferings/dtos/requests/PromotionSkuInput.js +37 -0
- package/bin/loanOfferings/dtos/requests/SimulateCreditPlanRequest.d.ts +6 -0
- package/bin/loanOfferings/dtos/requests/SimulateCreditPlanRequest.js +14 -0
- package/bin/loanOfferings/dtos/requests/UpdatePromotionRequest.d.ts +6 -0
- package/bin/loanOfferings/dtos/requests/UpdatePromotionRequest.js +16 -0
- package/bin/loanOfferings/dtos/responses/PromotionResponse.d.ts +6 -0
- package/bin/loanOfferings/index.d.ts +4 -0
- package/bin/loanOfferings/index.js +5 -0
- package/bin/retailIntegration/dtos/ProductEventPayload.d.ts +3 -1
- package/bin/retailIntegration/dtos/ProductEventPayload.js +8 -2
- package/bin/retailIntegration/enums/RetailMdmModeEnum.d.ts +5 -0
- package/bin/retailIntegration/enums/RetailMdmModeEnum.js +9 -0
- package/bin/retailIntegration/enums/index.d.ts +1 -0
- package/bin/retailIntegration/enums/index.js +1 -0
- package/bin/retailIntegration/index.d.ts +1 -0
- package/bin/retailIntegration/index.js +1 -0
- package/bin/retailIntegration/models/RetailSystemProduct.d.ts +4 -1
- package/bin/retailIntegration/validators/productValidators.d.ts +13 -0
- package/bin/retailIntegration/validators/productValidators.js +49 -0
- package/package.json +1 -1
- package/src/loanCredit/dtos/requests/OriginateLoanCreditRequest.ts +14 -0
- package/src/loanOfferings/constants/promotionSkuBatch.ts +2 -0
- package/src/loanOfferings/dtos/requests/CreatePromotionRequest.ts +16 -0
- package/src/loanOfferings/dtos/requests/ListPromotedSkusRequest.ts +32 -0
- package/src/loanOfferings/dtos/requests/ListSkuPromotionsRequest.ts +32 -0
- package/src/loanOfferings/dtos/requests/PromotionSkuInput.ts +21 -0
- package/src/loanOfferings/dtos/requests/SimulateCreditPlanRequest.ts +16 -1
- package/src/loanOfferings/dtos/requests/UpdatePromotionRequest.ts +16 -0
- package/src/loanOfferings/dtos/responses/PromotionResponse.ts +6 -0
- package/src/loanOfferings/index.ts +6 -0
- package/src/retailIntegration/dtos/ProductEventPayload.ts +6 -2
- package/src/retailIntegration/enums/RetailMdmModeEnum.ts +5 -0
- package/src/retailIntegration/enums/index.ts +1 -0
- package/src/retailIntegration/index.ts +1 -0
- package/src/retailIntegration/models/RetailSystemProduct.ts +4 -0
- package/src/retailIntegration/validators/productValidators.ts +35 -0
|
@@ -33,6 +33,8 @@ __exportStar(require("./enums/SegmentStatusEnum"), exports);
|
|
|
33
33
|
__exportStar(require("./enums/SegmentColorSlotEnum"), exports);
|
|
34
34
|
__exportStar(require("./enums/SegmentFilterIdEnum"), exports);
|
|
35
35
|
__exportStar(require("./enums/PrepaymentMinimumModeEnum"), exports);
|
|
36
|
+
// Constantes
|
|
37
|
+
__exportStar(require("./constants/promotionSkuBatch"), exports);
|
|
36
38
|
// Entity DTOs
|
|
37
39
|
__exportStar(require("./dtos/CreditPlan"), exports);
|
|
38
40
|
__exportStar(require("./dtos/PrepaymentMinimum"), exports);
|
|
@@ -64,6 +66,9 @@ __exportStar(require("./dtos/requests/ChangeSegmentStatusRequest"), exports);
|
|
|
64
66
|
__exportStar(require("./dtos/requests/ResolveCustomerSegmentsRequest"), exports);
|
|
65
67
|
__exportStar(require("./dtos/requests/ComputeAmortizationScheduleRequest"), exports);
|
|
66
68
|
__exportStar(require("./dtos/requests/ListSegmentCatalogQuery"), exports);
|
|
69
|
+
__exportStar(require("./dtos/requests/PromotionSkuInput"), exports);
|
|
70
|
+
__exportStar(require("./dtos/requests/ListPromotedSkusRequest"), exports);
|
|
71
|
+
__exportStar(require("./dtos/requests/ListSkuPromotionsRequest"), exports);
|
|
67
72
|
// Response DTOs
|
|
68
73
|
__exportStar(require("./dtos/responses/CreditPlanResponse"), exports);
|
|
69
74
|
__exportStar(require("./dtos/responses/FinancierResponse"), exports);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RetailCurrency, RetailFinancier, RetailMdmProvider, RetailProductCategory, RetailProductStatus, RetailProductTier, RetailSystemProduct, RetailSystemProductPrice, RetailTrackingMode } from '../models/RetailSystemProduct';
|
|
1
|
+
import type { RetailCurrency, RetailFinancier, RetailMdmMode, RetailMdmProvider, RetailProductCategory, RetailProductStatus, RetailProductTier, RetailSystemProduct, RetailSystemProductPrice, RetailTrackingMode } from '../models/RetailSystemProduct';
|
|
2
2
|
/** Precio del producto en decimales string. */
|
|
3
3
|
export declare class ProductEventPricePayload implements RetailSystemProductPrice {
|
|
4
4
|
basePrice: string;
|
|
@@ -23,5 +23,7 @@ export declare class ProductEventPayload implements RetailSystemProduct {
|
|
|
23
23
|
/** Opcional en el evento: ausente o `null` se vuelve la lista de todas las financieras. */
|
|
24
24
|
eligibleFinanciers: RetailFinancier[];
|
|
25
25
|
mdmProvider: RetailMdmProvider | null;
|
|
26
|
+
/** Opcional en el evento: ausente se vuelve `null`. */
|
|
27
|
+
mdmMode: RetailMdmMode | null;
|
|
26
28
|
status: RetailProductStatus;
|
|
27
29
|
}
|
|
@@ -16,6 +16,7 @@ const retailIntegrationLimits_1 = require("../constants/retailIntegrationLimits"
|
|
|
16
16
|
const enums_1 = require("../enums");
|
|
17
17
|
const IsIsoDateTimeWithZone_1 = require("../validators/IsIsoDateTimeWithZone");
|
|
18
18
|
const payloadValidators_1 = require("../validators/payloadValidators");
|
|
19
|
+
const productValidators_1 = require("../validators/productValidators");
|
|
19
20
|
/** Precio del producto en decimales string. */
|
|
20
21
|
class ProductEventPricePayload {
|
|
21
22
|
}
|
|
@@ -118,10 +119,15 @@ __decorate([
|
|
|
118
119
|
__metadata("design:type", Array)
|
|
119
120
|
], ProductEventPayload.prototype, "eligibleFinanciers", void 0);
|
|
120
121
|
__decorate([
|
|
121
|
-
(0, class_validator_1.
|
|
122
|
-
(0, class_validator_1.IsIn)(Object.values(enums_1.RetailMdmProviderEnum)),
|
|
122
|
+
(0, class_validator_1.Validate)(productValidators_1.MdmProviderMatchesTracking),
|
|
123
123
|
__metadata("design:type", String)
|
|
124
124
|
], ProductEventPayload.prototype, "mdmProvider", void 0);
|
|
125
|
+
__decorate([
|
|
126
|
+
(0, class_transformer_1.Expose)(),
|
|
127
|
+
(0, class_transformer_1.Transform)(({ value }) => value ?? null),
|
|
128
|
+
(0, class_validator_1.Validate)(productValidators_1.MdmModeMatchesProvider),
|
|
129
|
+
__metadata("design:type", String)
|
|
130
|
+
], ProductEventPayload.prototype, "mdmMode", void 0);
|
|
125
131
|
__decorate([
|
|
126
132
|
(0, class_validator_1.IsIn)(Object.values(enums_1.RetailProductStatusEnum)),
|
|
127
133
|
__metadata("design:type", String)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RetailMdmModeEnum = void 0;
|
|
4
|
+
/** Modo del candado MDM del equipo; mismos valores que `MdmLockModeEnum` de retailCatalog. */
|
|
5
|
+
var RetailMdmModeEnum;
|
|
6
|
+
(function (RetailMdmModeEnum) {
|
|
7
|
+
RetailMdmModeEnum["SCHEDULED"] = "SCHEDULED";
|
|
8
|
+
RetailMdmModeEnum["ONDEMAND"] = "ONDEMAND";
|
|
9
|
+
})(RetailMdmModeEnum || (exports.RetailMdmModeEnum = RetailMdmModeEnum = {}));
|
|
@@ -10,6 +10,7 @@ export * from './RetailProductTierEnum';
|
|
|
10
10
|
export * from './RetailCurrencyEnum';
|
|
11
11
|
export * from './RetailFinancierEnum';
|
|
12
12
|
export * from './RetailMdmProviderEnum';
|
|
13
|
+
export * from './RetailMdmModeEnum';
|
|
13
14
|
export * from './RetailProductStatusEnum';
|
|
14
15
|
export * from './RetailPieceStatusEnum';
|
|
15
16
|
export * from './RetailPieceReasonEnum';
|
|
@@ -26,6 +26,7 @@ __exportStar(require("./RetailProductTierEnum"), exports);
|
|
|
26
26
|
__exportStar(require("./RetailCurrencyEnum"), exports);
|
|
27
27
|
__exportStar(require("./RetailFinancierEnum"), exports);
|
|
28
28
|
__exportStar(require("./RetailMdmProviderEnum"), exports);
|
|
29
|
+
__exportStar(require("./RetailMdmModeEnum"), exports);
|
|
29
30
|
__exportStar(require("./RetailProductStatusEnum"), exports);
|
|
30
31
|
__exportStar(require("./RetailPieceStatusEnum"), exports);
|
|
31
32
|
__exportStar(require("./RetailPieceReasonEnum"), exports);
|
|
@@ -5,6 +5,7 @@ export * from './validators/IsIsoDateTimeWithZone';
|
|
|
5
5
|
export * from './validators/IsMovementsRangeValid';
|
|
6
6
|
export * from './validators/IsCalendarDate';
|
|
7
7
|
export * from './validators/saleValidators';
|
|
8
|
+
export * from './validators/productValidators';
|
|
8
9
|
export * from './dtos/RetailEventEnvelope';
|
|
9
10
|
export * from './dtos/ReceiveStoreEventRequest';
|
|
10
11
|
export * from './dtos/ReceiveRetailUserEventRequest';
|
|
@@ -21,6 +21,7 @@ __exportStar(require("./validators/IsIsoDateTimeWithZone"), exports);
|
|
|
21
21
|
__exportStar(require("./validators/IsMovementsRangeValid"), exports);
|
|
22
22
|
__exportStar(require("./validators/IsCalendarDate"), exports);
|
|
23
23
|
__exportStar(require("./validators/saleValidators"), exports);
|
|
24
|
+
__exportStar(require("./validators/productValidators"), exports);
|
|
24
25
|
__exportStar(require("./dtos/RetailEventEnvelope"), exports);
|
|
25
26
|
__exportStar(require("./dtos/ReceiveStoreEventRequest"), exports);
|
|
26
27
|
__exportStar(require("./dtos/ReceiveRetailUserEventRequest"), exports);
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { RetailCurrencyEnum, RetailFinancierEnum, RetailMdmProviderEnum, RetailProductCategoryEnum, RetailProductStatusEnum, RetailProductTierEnum, RetailTrackingModeEnum } from '../enums';
|
|
1
|
+
import { RetailCurrencyEnum, RetailFinancierEnum, RetailMdmModeEnum, RetailMdmProviderEnum, RetailProductCategoryEnum, RetailProductStatusEnum, RetailProductTierEnum, RetailTrackingModeEnum } from '../enums';
|
|
2
2
|
export type RetailProductCategory = `${RetailProductCategoryEnum}`;
|
|
3
3
|
export type RetailTrackingMode = `${RetailTrackingModeEnum}`;
|
|
4
4
|
export type RetailProductTier = `${RetailProductTierEnum}`;
|
|
5
5
|
export type RetailCurrency = `${RetailCurrencyEnum}`;
|
|
6
6
|
export type RetailFinancier = `${RetailFinancierEnum}`;
|
|
7
7
|
export type RetailMdmProvider = `${RetailMdmProviderEnum}`;
|
|
8
|
+
export type RetailMdmMode = `${RetailMdmModeEnum}`;
|
|
8
9
|
export type RetailProductStatus = `${RetailProductStatusEnum}`;
|
|
9
10
|
/** Precios como decimal en string con dos decimales. */
|
|
10
11
|
export interface RetailSystemProductPrice {
|
|
@@ -28,5 +29,7 @@ export interface RetailSystemProduct {
|
|
|
28
29
|
price: RetailSystemProductPrice;
|
|
29
30
|
eligibleFinanciers: RetailFinancier[];
|
|
30
31
|
mdmProvider: RetailMdmProvider | null;
|
|
32
|
+
/** Modo del candado; obligatorio cuando hay `mdmProvider`. */
|
|
33
|
+
mdmMode?: RetailMdmMode | null;
|
|
31
34
|
status: RetailProductStatus;
|
|
32
35
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ValidationArguments, ValidatorConstraintInterface } from 'class-validator';
|
|
2
|
+
/** Un producto rastreado por IMEI lleva MDM. */
|
|
3
|
+
export declare function requiresMdm(trackingMode: unknown): boolean;
|
|
4
|
+
/** `mdmProvider`: obligatorio con `trackingMode` IMEI y `null` en los demás productos. */
|
|
5
|
+
export declare class MdmProviderMatchesTracking implements ValidatorConstraintInterface {
|
|
6
|
+
validate(value: unknown, args: ValidationArguments): boolean;
|
|
7
|
+
defaultMessage(): string;
|
|
8
|
+
}
|
|
9
|
+
/** `mdmMode`: obligatorio con `mdmProvider` y `null` sin él; MOTOSAFE solo opera en ONDEMAND. */
|
|
10
|
+
export declare class MdmModeMatchesProvider implements ValidatorConstraintInterface {
|
|
11
|
+
validate(value: unknown, args: ValidationArguments): boolean;
|
|
12
|
+
defaultMessage(): string;
|
|
13
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.MdmModeMatchesProvider = exports.MdmProviderMatchesTracking = void 0;
|
|
10
|
+
exports.requiresMdm = requiresMdm;
|
|
11
|
+
const class_validator_1 = require("class-validator");
|
|
12
|
+
const enums_1 = require("../enums");
|
|
13
|
+
/** Un producto rastreado por IMEI lleva MDM. */
|
|
14
|
+
function requiresMdm(trackingMode) {
|
|
15
|
+
return trackingMode === enums_1.RetailTrackingModeEnum.IMEI;
|
|
16
|
+
}
|
|
17
|
+
/** `mdmProvider`: obligatorio con `trackingMode` IMEI y `null` en los demás productos. */
|
|
18
|
+
let MdmProviderMatchesTracking = class MdmProviderMatchesTracking {
|
|
19
|
+
validate(value, args) {
|
|
20
|
+
if (!requiresMdm(args.object.trackingMode))
|
|
21
|
+
return value === null;
|
|
22
|
+
return Object.values(enums_1.RetailMdmProviderEnum).includes(value);
|
|
23
|
+
}
|
|
24
|
+
defaultMessage() {
|
|
25
|
+
return 'mdmProvider es obligatorio con trackingMode IMEI y null en los demás productos';
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
exports.MdmProviderMatchesTracking = MdmProviderMatchesTracking;
|
|
29
|
+
exports.MdmProviderMatchesTracking = MdmProviderMatchesTracking = __decorate([
|
|
30
|
+
(0, class_validator_1.ValidatorConstraint)({ name: 'mdmProviderMatchesTracking', async: false })
|
|
31
|
+
], MdmProviderMatchesTracking);
|
|
32
|
+
/** `mdmMode`: obligatorio con `mdmProvider` y `null` sin él; MOTOSAFE solo opera en ONDEMAND. */
|
|
33
|
+
let MdmModeMatchesProvider = class MdmModeMatchesProvider {
|
|
34
|
+
validate(value, args) {
|
|
35
|
+
const provider = args.object.mdmProvider;
|
|
36
|
+
if (provider === null || provider === undefined)
|
|
37
|
+
return value === null;
|
|
38
|
+
if (provider === enums_1.RetailMdmProviderEnum.MOTOSAFE)
|
|
39
|
+
return value === enums_1.RetailMdmModeEnum.ONDEMAND;
|
|
40
|
+
return Object.values(enums_1.RetailMdmModeEnum).includes(value);
|
|
41
|
+
}
|
|
42
|
+
defaultMessage() {
|
|
43
|
+
return 'mdmMode es obligatorio con mdmProvider (MOTOSAFE solo ONDEMAND) y null sin él';
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
exports.MdmModeMatchesProvider = MdmModeMatchesProvider;
|
|
47
|
+
exports.MdmModeMatchesProvider = MdmModeMatchesProvider = __decorate([
|
|
48
|
+
(0, class_validator_1.ValidatorConstraint)({ name: 'mdmModeMatchesProvider', async: false })
|
|
49
|
+
], MdmModeMatchesProvider);
|
package/package.json
CHANGED
|
@@ -8,6 +8,8 @@ import {
|
|
|
8
8
|
Max,
|
|
9
9
|
Min,
|
|
10
10
|
} from 'class-validator';
|
|
11
|
+
import { ProductCategoryEnum } from '../../../retailCatalog/enums/ProductCategoryEnum';
|
|
12
|
+
import { ProductTierEnum } from '../../../retailCatalog/enums/ProductTierEnum';
|
|
11
13
|
import { ClientLevelEnum } from '../../../loanScoring/enums/ClientLevelEnum';
|
|
12
14
|
|
|
13
15
|
/**
|
|
@@ -106,4 +108,16 @@ export class OriginateLoanCreditRequest {
|
|
|
106
108
|
@IsOptional()
|
|
107
109
|
@IsString()
|
|
108
110
|
productSku?: string;
|
|
111
|
+
|
|
112
|
+
/** Tipo del equipo: resuelve promociones acotadas por tipo. */
|
|
113
|
+
@Expose()
|
|
114
|
+
@IsOptional()
|
|
115
|
+
@IsEnum(ProductCategoryEnum)
|
|
116
|
+
productCategory?: ProductCategoryEnum;
|
|
117
|
+
|
|
118
|
+
/** Gama del equipo: resuelve promociones acotadas por gama. */
|
|
119
|
+
@Expose()
|
|
120
|
+
@IsOptional()
|
|
121
|
+
@IsEnum(ProductTierEnum)
|
|
122
|
+
productTier?: ProductTierEnum;
|
|
109
123
|
}
|
|
@@ -10,6 +10,8 @@ import {
|
|
|
10
10
|
ValidateNested,
|
|
11
11
|
} from 'class-validator';
|
|
12
12
|
import { CreditPlanLevelEnum } from '../../enums/CreditPlanLevelEnum';
|
|
13
|
+
import { ProductCategoryEnum } from '../../../retailCatalog/enums/ProductCategoryEnum';
|
|
14
|
+
import { ProductTierEnum } from '../../../retailCatalog/enums/ProductTierEnum';
|
|
13
15
|
import { PromotionEffectInput } from './PromotionEffectInput';
|
|
14
16
|
|
|
15
17
|
/**
|
|
@@ -49,6 +51,20 @@ export class CreatePromotionRequest {
|
|
|
49
51
|
@IsString({ each: true })
|
|
50
52
|
productSkus?: string[] | null;
|
|
51
53
|
|
|
54
|
+
/** Tipos de producto alcanzados; ausente o `null` = todos los tipos. */
|
|
55
|
+
@Expose()
|
|
56
|
+
@IsOptional()
|
|
57
|
+
@IsArray()
|
|
58
|
+
@IsEnum(ProductCategoryEnum, { each: true })
|
|
59
|
+
productCategories?: ProductCategoryEnum[] | null;
|
|
60
|
+
|
|
61
|
+
/** Gamas alcanzadas; ausente o `null` = todas las gamas. */
|
|
62
|
+
@Expose()
|
|
63
|
+
@IsOptional()
|
|
64
|
+
@IsArray()
|
|
65
|
+
@IsEnum(ProductTierEnum, { each: true })
|
|
66
|
+
tiers?: ProductTierEnum[] | null;
|
|
67
|
+
|
|
52
68
|
/** Tiendas alcanzadas. `null` o ausente = todas. */
|
|
53
69
|
@Expose()
|
|
54
70
|
@IsOptional()
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Expose, Type } from 'class-transformer';
|
|
2
|
+
import { ArrayMaxSize, IsArray, IsEnum, IsNotEmpty, IsOptional, IsString, ValidateNested } from 'class-validator';
|
|
3
|
+
import { PROMOTION_SKU_BATCH_MAX_ITEMS } from '../../constants/promotionSkuBatch';
|
|
4
|
+
import { CreditPlanLevelEnum } from '../../enums/CreditPlanLevelEnum';
|
|
5
|
+
import { PromotionSkuInput } from './PromotionSkuInput';
|
|
6
|
+
|
|
7
|
+
/** Body de `POST /private/promotions/promoted-skus` (M2M): SKUs del lote con promoción viva para el badge; hasta 100 SKUs. */
|
|
8
|
+
export class ListPromotedSkusRequest {
|
|
9
|
+
@Expose()
|
|
10
|
+
@IsString()
|
|
11
|
+
@IsNotEmpty()
|
|
12
|
+
storeId!: string;
|
|
13
|
+
|
|
14
|
+
/** Nivel del cliente si loan-scoring ya corrió. */
|
|
15
|
+
@Expose()
|
|
16
|
+
@IsOptional()
|
|
17
|
+
@IsEnum(CreditPlanLevelEnum)
|
|
18
|
+
level?: CreditPlanLevelEnum;
|
|
19
|
+
|
|
20
|
+
/** Segmento del cliente si ya se resolvió. */
|
|
21
|
+
@Expose()
|
|
22
|
+
@IsOptional()
|
|
23
|
+
@IsString()
|
|
24
|
+
segmentId?: string;
|
|
25
|
+
|
|
26
|
+
@Expose()
|
|
27
|
+
@IsArray()
|
|
28
|
+
@ArrayMaxSize(PROMOTION_SKU_BATCH_MAX_ITEMS)
|
|
29
|
+
@ValidateNested({ each: true })
|
|
30
|
+
@Type(() => PromotionSkuInput)
|
|
31
|
+
items!: PromotionSkuInput[];
|
|
32
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Expose, Type } from 'class-transformer';
|
|
2
|
+
import { ArrayMaxSize, IsArray, IsEnum, IsNotEmpty, IsOptional, IsString, ValidateNested } from 'class-validator';
|
|
3
|
+
import { PROMOTION_SKU_BATCH_MAX_ITEMS } from '../../constants/promotionSkuBatch';
|
|
4
|
+
import { CreditPlanLevelEnum } from '../../enums/CreditPlanLevelEnum';
|
|
5
|
+
import { PromotionSkuInput } from './PromotionSkuInput';
|
|
6
|
+
|
|
7
|
+
/** Body de `POST /private/promotions/by-sku` (M2M): promociones vivas de cada SKU del lote; hasta 100 SKUs. */
|
|
8
|
+
export class ListSkuPromotionsRequest {
|
|
9
|
+
@Expose()
|
|
10
|
+
@IsString()
|
|
11
|
+
@IsNotEmpty()
|
|
12
|
+
storeId!: string;
|
|
13
|
+
|
|
14
|
+
/** Nivel del cliente si loan-scoring ya corrió. */
|
|
15
|
+
@Expose()
|
|
16
|
+
@IsOptional()
|
|
17
|
+
@IsEnum(CreditPlanLevelEnum)
|
|
18
|
+
level?: CreditPlanLevelEnum;
|
|
19
|
+
|
|
20
|
+
/** Segmento del cliente si ya se resolvió. */
|
|
21
|
+
@Expose()
|
|
22
|
+
@IsOptional()
|
|
23
|
+
@IsString()
|
|
24
|
+
segmentId?: string;
|
|
25
|
+
|
|
26
|
+
@Expose()
|
|
27
|
+
@IsArray()
|
|
28
|
+
@ArrayMaxSize(PROMOTION_SKU_BATCH_MAX_ITEMS)
|
|
29
|
+
@ValidateNested({ each: true })
|
|
30
|
+
@Type(() => PromotionSkuInput)
|
|
31
|
+
items!: PromotionSkuInput[];
|
|
32
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Expose } from 'class-transformer';
|
|
2
|
+
import { IsEnum, IsOptional, IsString } from 'class-validator';
|
|
3
|
+
import { ProductCategoryEnum } from '../../../retailCatalog/enums/ProductCategoryEnum';
|
|
4
|
+
import { ProductTierEnum } from '../../../retailCatalog/enums/ProductTierEnum';
|
|
5
|
+
|
|
6
|
+
/** Un SKU con su tipo y gama; sin ellos no cumple un alcance por tipo o por gama. */
|
|
7
|
+
export class PromotionSkuInput {
|
|
8
|
+
@Expose()
|
|
9
|
+
@IsString()
|
|
10
|
+
sku!: string;
|
|
11
|
+
|
|
12
|
+
@Expose()
|
|
13
|
+
@IsOptional()
|
|
14
|
+
@IsEnum(ProductCategoryEnum)
|
|
15
|
+
category?: ProductCategoryEnum;
|
|
16
|
+
|
|
17
|
+
@Expose()
|
|
18
|
+
@IsOptional()
|
|
19
|
+
@IsEnum(ProductTierEnum)
|
|
20
|
+
tier?: ProductTierEnum;
|
|
21
|
+
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { Expose } from 'class-transformer';
|
|
2
|
-
import { IsArray, IsInt, IsNumber, IsOptional, IsString, Max, Min } from 'class-validator';
|
|
2
|
+
import { IsArray, IsEnum, IsInt, IsNumber, IsOptional, IsString, Max, Min } from 'class-validator';
|
|
3
|
+
import { ProductCategoryEnum } from '../../../retailCatalog/enums/ProductCategoryEnum';
|
|
4
|
+
import { ProductTierEnum } from '../../../retailCatalog/enums/ProductTierEnum';
|
|
5
|
+
|
|
3
6
|
|
|
4
7
|
/**
|
|
5
8
|
* Body de POST /private/credit-plans/:planId/simulate y query de GET /credit-plans/:planId/simulator.
|
|
@@ -46,6 +49,18 @@ export class SimulateCreditPlanRequest {
|
|
|
46
49
|
@IsString()
|
|
47
50
|
productSku?: string;
|
|
48
51
|
|
|
52
|
+
/** Tipo del equipo. Sin él no se resuelven las promociones acotadas por tipo. */
|
|
53
|
+
@Expose()
|
|
54
|
+
@IsOptional()
|
|
55
|
+
@IsEnum(ProductCategoryEnum)
|
|
56
|
+
productCategory?: ProductCategoryEnum;
|
|
57
|
+
|
|
58
|
+
/** Gama del equipo. Sin ella no se resuelven las promociones acotadas por gama. */
|
|
59
|
+
@Expose()
|
|
60
|
+
@IsOptional()
|
|
61
|
+
@IsEnum(ProductTierEnum)
|
|
62
|
+
productTier?: ProductTierEnum;
|
|
63
|
+
|
|
49
64
|
/**
|
|
50
65
|
* Segmentos del cliente, los que devolvió `POST /private/segments/resolve`. Un arreglo vacío
|
|
51
66
|
* declara que el cliente no está en ninguno; ausente declara que el caller no lo consultó.
|
|
@@ -10,6 +10,8 @@ import {
|
|
|
10
10
|
ValidateNested,
|
|
11
11
|
} from 'class-validator';
|
|
12
12
|
import { CreditPlanLevelEnum } from '../../enums/CreditPlanLevelEnum';
|
|
13
|
+
import { ProductCategoryEnum } from '../../../retailCatalog/enums/ProductCategoryEnum';
|
|
14
|
+
import { ProductTierEnum } from '../../../retailCatalog/enums/ProductTierEnum';
|
|
13
15
|
import { PromotionEffectInput } from './PromotionEffectInput';
|
|
14
16
|
|
|
15
17
|
/**
|
|
@@ -52,6 +54,20 @@ export class UpdatePromotionRequest {
|
|
|
52
54
|
@IsString({ each: true })
|
|
53
55
|
productSkus?: string[] | null;
|
|
54
56
|
|
|
57
|
+
/** Tipos de producto alcanzados; ausente o `null` = todos los tipos. */
|
|
58
|
+
@Expose()
|
|
59
|
+
@IsOptional()
|
|
60
|
+
@IsArray()
|
|
61
|
+
@IsEnum(ProductCategoryEnum, { each: true })
|
|
62
|
+
productCategories?: ProductCategoryEnum[] | null;
|
|
63
|
+
|
|
64
|
+
/** Gamas alcanzadas; ausente o `null` = todas las gamas. */
|
|
65
|
+
@Expose()
|
|
66
|
+
@IsOptional()
|
|
67
|
+
@IsArray()
|
|
68
|
+
@IsEnum(ProductTierEnum, { each: true })
|
|
69
|
+
tiers?: ProductTierEnum[] | null;
|
|
70
|
+
|
|
55
71
|
/** Tiendas alcanzadas. `null` o ausente = todas. */
|
|
56
72
|
@Expose()
|
|
57
73
|
@IsOptional()
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ProductCategoryEnum } from '../../../retailCatalog/enums/ProductCategoryEnum';
|
|
2
|
+
import { ProductTierEnum } from '../../../retailCatalog/enums/ProductTierEnum';
|
|
1
3
|
import { CreditPlanLevelEnum } from '../../enums/CreditPlanLevelEnum';
|
|
2
4
|
import { PromotionEffectKindEnum } from '../../enums/PromotionEffectKindEnum';
|
|
3
5
|
import { PromotionPhaseEnum } from '../../enums/PromotionPhaseEnum';
|
|
@@ -22,6 +24,10 @@ export interface PromotionResponse {
|
|
|
22
24
|
targetLevels: CreditPlanLevelEnum[];
|
|
23
25
|
/** `null` = alcanza a todos los productos. */
|
|
24
26
|
productSkus: string[] | null;
|
|
27
|
+
/** `null` = alcanza a todos los tipos de producto. */
|
|
28
|
+
productCategories: ProductCategoryEnum[] | null;
|
|
29
|
+
/** `null` = alcanza a todas las gamas. */
|
|
30
|
+
tiers: ProductTierEnum[] | null;
|
|
25
31
|
/** `null` = alcanza a todas las tiendas. Dimensión «Tienda / canal» del alcance. */
|
|
26
32
|
storeIds: string[] | null;
|
|
27
33
|
validFrom: string | null;
|
|
@@ -18,6 +18,9 @@ export * from './enums/SegmentColorSlotEnum';
|
|
|
18
18
|
export * from './enums/SegmentFilterIdEnum';
|
|
19
19
|
export * from './enums/PrepaymentMinimumModeEnum';
|
|
20
20
|
|
|
21
|
+
// Constantes
|
|
22
|
+
export * from './constants/promotionSkuBatch';
|
|
23
|
+
|
|
21
24
|
// Entity DTOs
|
|
22
25
|
export * from './dtos/CreditPlan';
|
|
23
26
|
export * from './dtos/PrepaymentMinimum';
|
|
@@ -50,6 +53,9 @@ export * from './dtos/requests/ChangeSegmentStatusRequest';
|
|
|
50
53
|
export * from './dtos/requests/ResolveCustomerSegmentsRequest';
|
|
51
54
|
export * from './dtos/requests/ComputeAmortizationScheduleRequest';
|
|
52
55
|
export * from './dtos/requests/ListSegmentCatalogQuery';
|
|
56
|
+
export * from './dtos/requests/PromotionSkuInput';
|
|
57
|
+
export * from './dtos/requests/ListPromotedSkusRequest';
|
|
58
|
+
export * from './dtos/requests/ListSkuPromotionsRequest';
|
|
53
59
|
|
|
54
60
|
// Response DTOs
|
|
55
61
|
export * from './dtos/responses/CreditPlanResponse';
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
import {
|
|
12
12
|
RetailCurrencyEnum,
|
|
13
13
|
RetailFinancierEnum,
|
|
14
|
-
RetailMdmProviderEnum,
|
|
15
14
|
RetailProductCategoryEnum,
|
|
16
15
|
RetailProductStatusEnum,
|
|
17
16
|
RetailProductTierEnum,
|
|
@@ -20,6 +19,7 @@ import {
|
|
|
20
19
|
import type {
|
|
21
20
|
RetailCurrency,
|
|
22
21
|
RetailFinancier,
|
|
22
|
+
RetailMdmMode,
|
|
23
23
|
RetailMdmProvider,
|
|
24
24
|
RetailProductCategory,
|
|
25
25
|
RetailProductStatus,
|
|
@@ -30,6 +30,7 @@ import type {
|
|
|
30
30
|
} from '../models/RetailSystemProduct';
|
|
31
31
|
import { IsIsoDateTimeWithZone } from '../validators/IsIsoDateTimeWithZone';
|
|
32
32
|
import { isNullOrValidated } from '../validators/payloadValidators';
|
|
33
|
+
import { MdmModeMatchesProvider, MdmProviderMatchesTracking } from '../validators/productValidators';
|
|
33
34
|
|
|
34
35
|
/** Precio del producto en decimales string. */
|
|
35
36
|
export class ProductEventPricePayload implements RetailSystemProductPrice {
|
|
@@ -58,6 +59,9 @@ export class ProductEventPayload implements RetailSystemProduct {
|
|
|
58
59
|
@Expose() @Transform(({ value }) => value ?? Object.values(RetailFinancierEnum))
|
|
59
60
|
@IsOptional() @IsArray() @ArrayNotEmpty() @ArrayUnique() @ArrayMaxSize(RETAIL_ELIGIBLE_FINANCIERS_MAX) @IsIn(Object.values(RetailFinancierEnum), { each: true })
|
|
60
61
|
eligibleFinanciers!: RetailFinancier[];
|
|
61
|
-
@
|
|
62
|
+
@Validate(MdmProviderMatchesTracking) mdmProvider!: RetailMdmProvider | null;
|
|
63
|
+
/** Opcional en el evento: ausente se vuelve `null`. */
|
|
64
|
+
@Expose() @Transform(({ value }) => value ?? null)
|
|
65
|
+
@Validate(MdmModeMatchesProvider) mdmMode!: RetailMdmMode | null;
|
|
62
66
|
@IsIn(Object.values(RetailProductStatusEnum)) status!: RetailProductStatus;
|
|
63
67
|
}
|
|
@@ -10,6 +10,7 @@ export * from './RetailProductTierEnum';
|
|
|
10
10
|
export * from './RetailCurrencyEnum';
|
|
11
11
|
export * from './RetailFinancierEnum';
|
|
12
12
|
export * from './RetailMdmProviderEnum';
|
|
13
|
+
export * from './RetailMdmModeEnum';
|
|
13
14
|
export * from './RetailProductStatusEnum';
|
|
14
15
|
export * from './RetailPieceStatusEnum';
|
|
15
16
|
export * from './RetailPieceReasonEnum';
|
|
@@ -5,6 +5,7 @@ export * from './validators/IsIsoDateTimeWithZone';
|
|
|
5
5
|
export * from './validators/IsMovementsRangeValid';
|
|
6
6
|
export * from './validators/IsCalendarDate';
|
|
7
7
|
export * from './validators/saleValidators';
|
|
8
|
+
export * from './validators/productValidators';
|
|
8
9
|
export * from './dtos/RetailEventEnvelope';
|
|
9
10
|
export * from './dtos/ReceiveStoreEventRequest';
|
|
10
11
|
export * from './dtos/ReceiveRetailUserEventRequest';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
RetailCurrencyEnum,
|
|
3
3
|
RetailFinancierEnum,
|
|
4
|
+
RetailMdmModeEnum,
|
|
4
5
|
RetailMdmProviderEnum,
|
|
5
6
|
RetailProductCategoryEnum,
|
|
6
7
|
RetailProductStatusEnum,
|
|
@@ -14,6 +15,7 @@ export type RetailProductTier = `${RetailProductTierEnum}`;
|
|
|
14
15
|
export type RetailCurrency = `${RetailCurrencyEnum}`;
|
|
15
16
|
export type RetailFinancier = `${RetailFinancierEnum}`;
|
|
16
17
|
export type RetailMdmProvider = `${RetailMdmProviderEnum}`;
|
|
18
|
+
export type RetailMdmMode = `${RetailMdmModeEnum}`;
|
|
17
19
|
export type RetailProductStatus = `${RetailProductStatusEnum}`;
|
|
18
20
|
|
|
19
21
|
/** Precios como decimal en string con dos decimales. */
|
|
@@ -39,5 +41,7 @@ export interface RetailSystemProduct {
|
|
|
39
41
|
price: RetailSystemProductPrice;
|
|
40
42
|
eligibleFinanciers: RetailFinancier[];
|
|
41
43
|
mdmProvider: RetailMdmProvider | null;
|
|
44
|
+
/** Modo del candado; obligatorio cuando hay `mdmProvider`. */
|
|
45
|
+
mdmMode?: RetailMdmMode | null;
|
|
42
46
|
status: RetailProductStatus;
|
|
43
47
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ValidationArguments, ValidatorConstraint, ValidatorConstraintInterface } from 'class-validator';
|
|
2
|
+
import { RetailMdmModeEnum, RetailMdmProviderEnum, RetailTrackingModeEnum } from '../enums';
|
|
3
|
+
|
|
4
|
+
/** Un producto rastreado por IMEI lleva MDM. */
|
|
5
|
+
export function requiresMdm(trackingMode: unknown): boolean {
|
|
6
|
+
return trackingMode === RetailTrackingModeEnum.IMEI;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/** `mdmProvider`: obligatorio con `trackingMode` IMEI y `null` en los demás productos. */
|
|
10
|
+
@ValidatorConstraint({ name: 'mdmProviderMatchesTracking', async: false })
|
|
11
|
+
export class MdmProviderMatchesTracking implements ValidatorConstraintInterface {
|
|
12
|
+
validate(value: unknown, args: ValidationArguments): boolean {
|
|
13
|
+
if (!requiresMdm((args.object as { trackingMode?: unknown }).trackingMode)) return value === null;
|
|
14
|
+
return (Object.values(RetailMdmProviderEnum) as unknown[]).includes(value);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
defaultMessage(): string {
|
|
18
|
+
return 'mdmProvider es obligatorio con trackingMode IMEI y null en los demás productos';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** `mdmMode`: obligatorio con `mdmProvider` y `null` sin él; MOTOSAFE solo opera en ONDEMAND. */
|
|
23
|
+
@ValidatorConstraint({ name: 'mdmModeMatchesProvider', async: false })
|
|
24
|
+
export class MdmModeMatchesProvider implements ValidatorConstraintInterface {
|
|
25
|
+
validate(value: unknown, args: ValidationArguments): boolean {
|
|
26
|
+
const provider = (args.object as { mdmProvider?: unknown }).mdmProvider;
|
|
27
|
+
if (provider === null || provider === undefined) return value === null;
|
|
28
|
+
if (provider === RetailMdmProviderEnum.MOTOSAFE) return value === RetailMdmModeEnum.ONDEMAND;
|
|
29
|
+
return (Object.values(RetailMdmModeEnum) as unknown[]).includes(value);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
defaultMessage(): string {
|
|
33
|
+
return 'mdmMode es obligatorio con mdmProvider (MOTOSAFE solo ONDEMAND) y null sin él';
|
|
34
|
+
}
|
|
35
|
+
}
|