@fiado/type-kit 3.363.0 → 3.365.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/loanOfferings/promotionRequests.test.ts +62 -0
- package/bin/loanCredit/dtos/requests/OriginateLoanCreditRequest.d.ts +8 -0
- package/bin/loanCredit/dtos/requests/OriginateLoanCreditRequest.js +12 -0
- package/bin/loanOfferings/dtos/PromotionEffect.d.ts +15 -0
- package/bin/loanOfferings/dtos/PromotionEffect.js +2 -0
- package/bin/loanOfferings/dtos/requests/ChangePromotionStatusRequest.d.ts +10 -0
- package/bin/loanOfferings/dtos/requests/ChangePromotionStatusRequest.js +34 -0
- package/bin/loanOfferings/dtos/requests/CreatePromotionRequest.d.ts +26 -0
- package/bin/loanOfferings/dtos/requests/CreatePromotionRequest.js +84 -0
- package/bin/loanOfferings/dtos/requests/PromotionEffectInput.d.ts +15 -0
- package/bin/loanOfferings/dtos/requests/PromotionEffectInput.js +46 -0
- package/bin/loanOfferings/dtos/requests/SimulateCreditPlanRequest.d.ts +8 -0
- package/bin/loanOfferings/dtos/requests/SimulateCreditPlanRequest.js +16 -0
- package/bin/loanOfferings/dtos/requests/UpdatePromotionRequest.d.ts +20 -0
- package/bin/loanOfferings/dtos/requests/UpdatePromotionRequest.js +89 -0
- package/bin/loanOfferings/dtos/responses/PromotionLogEntryResponse.d.ts +17 -0
- package/bin/loanOfferings/dtos/responses/PromotionLogEntryResponse.js +2 -0
- package/bin/loanOfferings/dtos/responses/PromotionResponse.d.ts +44 -0
- package/bin/loanOfferings/dtos/responses/PromotionResponse.js +2 -0
- package/bin/loanOfferings/dtos/responses/SimulationResultResponse.d.ts +18 -0
- package/bin/loanOfferings/enums/PromotionEffectKindEnum.d.ts +12 -0
- package/bin/loanOfferings/enums/PromotionEffectKindEnum.js +16 -0
- package/bin/loanOfferings/enums/PromotionLogEventEnum.d.ts +12 -0
- package/bin/loanOfferings/enums/PromotionLogEventEnum.js +16 -0
- package/bin/loanOfferings/enums/PromotionPhaseEnum.d.ts +11 -0
- package/bin/loanOfferings/enums/PromotionPhaseEnum.js +15 -0
- package/bin/loanOfferings/enums/PromotionStatusEnum.d.ts +12 -0
- package/bin/loanOfferings/enums/PromotionStatusEnum.js +16 -0
- package/bin/loanOfferings/index.d.ts +11 -0
- package/bin/loanOfferings/index.js +11 -0
- package/bin/retailCustomer/dtos/responses/Customer360Response.d.ts +20 -1
- package/bin/retailCustomer/dtos/responses/CustomerResponse.d.ts +6 -0
- package/package.json +1 -1
- package/src/loanCredit/dtos/requests/OriginateLoanCreditRequest.ts +16 -0
- package/src/loanOfferings/dtos/PromotionEffect.ts +15 -0
- package/src/loanOfferings/dtos/requests/ChangePromotionStatusRequest.ts +19 -0
- package/src/loanOfferings/dtos/requests/CreatePromotionRequest.ts +77 -0
- package/src/loanOfferings/dtos/requests/PromotionEffectInput.ts +33 -0
- package/src/loanOfferings/dtos/requests/SimulateCreditPlanRequest.ts +17 -1
- package/src/loanOfferings/dtos/requests/UpdatePromotionRequest.ts +76 -0
- package/src/loanOfferings/dtos/responses/PromotionLogEntryResponse.ts +18 -0
- package/src/loanOfferings/dtos/responses/PromotionResponse.ts +45 -0
- package/src/loanOfferings/dtos/responses/SimulationResultResponse.ts +20 -0
- package/src/loanOfferings/enums/PromotionEffectKindEnum.ts +12 -0
- package/src/loanOfferings/enums/PromotionLogEventEnum.ts +12 -0
- package/src/loanOfferings/enums/PromotionPhaseEnum.ts +11 -0
- package/src/loanOfferings/enums/PromotionStatusEnum.ts +12 -0
- package/src/loanOfferings/index.ts +11 -0
- package/src/retailCustomer/dtos/responses/Customer360Response.ts +21 -1
- package/src/retailCustomer/dtos/responses/CustomerResponse.ts +6 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PromotionLogEventEnum = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Evento de la bitácora de promociones (`<T>LoanPromotionLog_GT`), que alimenta el tab «Auditoría».
|
|
6
|
+
* @enum {string}
|
|
7
|
+
*/
|
|
8
|
+
var PromotionLogEventEnum;
|
|
9
|
+
(function (PromotionLogEventEnum) {
|
|
10
|
+
PromotionLogEventEnum["CREATE"] = "CREATE";
|
|
11
|
+
PromotionLogEventEnum["PUBLISH"] = "PUBLISH";
|
|
12
|
+
PromotionLogEventEnum["PAUSE"] = "PAUSE";
|
|
13
|
+
PromotionLogEventEnum["RESUME"] = "RESUME";
|
|
14
|
+
PromotionLogEventEnum["EXPIRE"] = "EXPIRE";
|
|
15
|
+
PromotionLogEventEnum["UPDATE"] = "UPDATE";
|
|
16
|
+
})(PromotionLogEventEnum || (exports.PromotionLogEventEnum = PromotionLogEventEnum = {}));
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fase de vigencia de una promoción PUBLICADA, derivada de `validFrom`/`validUntil` contra hoy.
|
|
3
|
+
* No se persiste — así no hace falta un cron que mueva estados a medianoche. `null` cuando el
|
|
4
|
+
* estado persistido no es `PUBLISHED`.
|
|
5
|
+
* @enum {string}
|
|
6
|
+
*/
|
|
7
|
+
export declare enum PromotionPhaseEnum {
|
|
8
|
+
SCHEDULED = "SCHEDULED",
|
|
9
|
+
ACTIVE = "ACTIVE",
|
|
10
|
+
EXPIRED = "EXPIRED"
|
|
11
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PromotionPhaseEnum = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Fase de vigencia de una promoción PUBLICADA, derivada de `validFrom`/`validUntil` contra hoy.
|
|
6
|
+
* No se persiste — así no hace falta un cron que mueva estados a medianoche. `null` cuando el
|
|
7
|
+
* estado persistido no es `PUBLISHED`.
|
|
8
|
+
* @enum {string}
|
|
9
|
+
*/
|
|
10
|
+
var PromotionPhaseEnum;
|
|
11
|
+
(function (PromotionPhaseEnum) {
|
|
12
|
+
PromotionPhaseEnum["SCHEDULED"] = "SCHEDULED";
|
|
13
|
+
PromotionPhaseEnum["ACTIVE"] = "ACTIVE";
|
|
14
|
+
PromotionPhaseEnum["EXPIRED"] = "EXPIRED";
|
|
15
|
+
})(PromotionPhaseEnum || (exports.PromotionPhaseEnum = PromotionPhaseEnum = {}));
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Estado PERSISTIDO de una promoción del motor (portal-admin-sk-promociones).
|
|
3
|
+
* `EXPIRED` es terminal. La «fase» que ve el operador (programada / activa / vencida) NO se guarda:
|
|
4
|
+
* se deriva de las fechas — ver `PromotionPhaseEnum`.
|
|
5
|
+
* @enum {string}
|
|
6
|
+
*/
|
|
7
|
+
export declare enum PromotionStatusEnum {
|
|
8
|
+
DRAFT = "DRAFT",
|
|
9
|
+
PUBLISHED = "PUBLISHED",
|
|
10
|
+
PAUSED = "PAUSED",
|
|
11
|
+
EXPIRED = "EXPIRED"
|
|
12
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PromotionStatusEnum = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Estado PERSISTIDO de una promoción del motor (portal-admin-sk-promociones).
|
|
6
|
+
* `EXPIRED` es terminal. La «fase» que ve el operador (programada / activa / vencida) NO se guarda:
|
|
7
|
+
* se deriva de las fechas — ver `PromotionPhaseEnum`.
|
|
8
|
+
* @enum {string}
|
|
9
|
+
*/
|
|
10
|
+
var PromotionStatusEnum;
|
|
11
|
+
(function (PromotionStatusEnum) {
|
|
12
|
+
PromotionStatusEnum["DRAFT"] = "DRAFT";
|
|
13
|
+
PromotionStatusEnum["PUBLISHED"] = "PUBLISHED";
|
|
14
|
+
PromotionStatusEnum["PAUSED"] = "PAUSED";
|
|
15
|
+
PromotionStatusEnum["EXPIRED"] = "EXPIRED";
|
|
16
|
+
})(PromotionStatusEnum || (exports.PromotionStatusEnum = PromotionStatusEnum = {}));
|
|
@@ -4,9 +4,14 @@ export * from './enums/ProductTierEnum';
|
|
|
4
4
|
export * from './enums/CreditPlanStatusEnum';
|
|
5
5
|
export * from './enums/FinancierTypeEnum';
|
|
6
6
|
export * from './enums/FinancierStatusEnum';
|
|
7
|
+
export * from './enums/PromotionStatusEnum';
|
|
8
|
+
export * from './enums/PromotionEffectKindEnum';
|
|
9
|
+
export * from './enums/PromotionPhaseEnum';
|
|
10
|
+
export * from './enums/PromotionLogEventEnum';
|
|
7
11
|
export * from './dtos/CreditPlan';
|
|
8
12
|
export * from './dtos/Financier';
|
|
9
13
|
export * from './dtos/RetailerCreditPlan';
|
|
14
|
+
export * from './dtos/PromotionEffect';
|
|
10
15
|
export * from './dtos/requests/CreateCreditPlanRequest';
|
|
11
16
|
export * from './dtos/requests/UpdateCreditPlanRequest';
|
|
12
17
|
export * from './dtos/requests/ChangeCreditPlanStatusRequest';
|
|
@@ -15,7 +20,13 @@ export * from './dtos/requests/CreateFinancierRequest';
|
|
|
15
20
|
export * from './dtos/requests/UpdateFinancierRequest';
|
|
16
21
|
export * from './dtos/requests/ChangeFinancierStatusRequest';
|
|
17
22
|
export * from './dtos/requests/ReorderFinancierRequest';
|
|
23
|
+
export * from './dtos/requests/PromotionEffectInput';
|
|
24
|
+
export * from './dtos/requests/CreatePromotionRequest';
|
|
25
|
+
export * from './dtos/requests/UpdatePromotionRequest';
|
|
26
|
+
export * from './dtos/requests/ChangePromotionStatusRequest';
|
|
18
27
|
export * from './dtos/responses/CreditPlanResponse';
|
|
19
28
|
export * from './dtos/responses/FinancierResponse';
|
|
20
29
|
export * from './dtos/responses/RetailerCreditPlanResponse';
|
|
21
30
|
export * from './dtos/responses/SimulationResultResponse';
|
|
31
|
+
export * from './dtos/responses/PromotionResponse';
|
|
32
|
+
export * from './dtos/responses/PromotionLogEntryResponse';
|
|
@@ -21,10 +21,15 @@ __exportStar(require("./enums/ProductTierEnum"), exports);
|
|
|
21
21
|
__exportStar(require("./enums/CreditPlanStatusEnum"), exports);
|
|
22
22
|
__exportStar(require("./enums/FinancierTypeEnum"), exports);
|
|
23
23
|
__exportStar(require("./enums/FinancierStatusEnum"), exports);
|
|
24
|
+
__exportStar(require("./enums/PromotionStatusEnum"), exports);
|
|
25
|
+
__exportStar(require("./enums/PromotionEffectKindEnum"), exports);
|
|
26
|
+
__exportStar(require("./enums/PromotionPhaseEnum"), exports);
|
|
27
|
+
__exportStar(require("./enums/PromotionLogEventEnum"), exports);
|
|
24
28
|
// Entity DTOs
|
|
25
29
|
__exportStar(require("./dtos/CreditPlan"), exports);
|
|
26
30
|
__exportStar(require("./dtos/Financier"), exports);
|
|
27
31
|
__exportStar(require("./dtos/RetailerCreditPlan"), exports);
|
|
32
|
+
__exportStar(require("./dtos/PromotionEffect"), exports);
|
|
28
33
|
// Request DTOs
|
|
29
34
|
__exportStar(require("./dtos/requests/CreateCreditPlanRequest"), exports);
|
|
30
35
|
__exportStar(require("./dtos/requests/UpdateCreditPlanRequest"), exports);
|
|
@@ -34,8 +39,14 @@ __exportStar(require("./dtos/requests/CreateFinancierRequest"), exports);
|
|
|
34
39
|
__exportStar(require("./dtos/requests/UpdateFinancierRequest"), exports);
|
|
35
40
|
__exportStar(require("./dtos/requests/ChangeFinancierStatusRequest"), exports);
|
|
36
41
|
__exportStar(require("./dtos/requests/ReorderFinancierRequest"), exports);
|
|
42
|
+
__exportStar(require("./dtos/requests/PromotionEffectInput"), exports);
|
|
43
|
+
__exportStar(require("./dtos/requests/CreatePromotionRequest"), exports);
|
|
44
|
+
__exportStar(require("./dtos/requests/UpdatePromotionRequest"), exports);
|
|
45
|
+
__exportStar(require("./dtos/requests/ChangePromotionStatusRequest"), exports);
|
|
37
46
|
// Response DTOs
|
|
38
47
|
__exportStar(require("./dtos/responses/CreditPlanResponse"), exports);
|
|
39
48
|
__exportStar(require("./dtos/responses/FinancierResponse"), exports);
|
|
40
49
|
__exportStar(require("./dtos/responses/RetailerCreditPlanResponse"), exports);
|
|
41
50
|
__exportStar(require("./dtos/responses/SimulationResultResponse"), exports);
|
|
51
|
+
__exportStar(require("./dtos/responses/PromotionResponse"), exports);
|
|
52
|
+
__exportStar(require("./dtos/responses/PromotionLogEntryResponse"), exports);
|
|
@@ -1,9 +1,26 @@
|
|
|
1
|
+
import { Status } from '../../../card/enums/Status';
|
|
2
|
+
import { VirtualOrPhysical } from '../../../card/enums/VirtualOrPhysical';
|
|
1
3
|
import { CustomerResponse } from './CustomerResponse';
|
|
2
4
|
/** Resumen de wallet (nivel N1/N2 + saldo) para el Cliente 360. */
|
|
3
5
|
export interface Customer360Wallet {
|
|
4
6
|
accountLevel: 1 | 2 | null;
|
|
5
7
|
clabe: string | null;
|
|
6
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Saldo en centavos, o `null` cuando la fuente no lo trajo. Era `number` a secas y eso obligaba
|
|
10
|
+
* a mandar `0` por un bloque ilegible, indistinguible de un saldo cero real.
|
|
11
|
+
*/
|
|
12
|
+
balanceCents: number | null;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Tarjeta del cliente para el Cliente 360. Los campos espejan lo que devuelve `CardResponse` de
|
|
16
|
+
* `fiado-card-business`; `issued` en `false` deja los demás en `null` (no hay tarjeta que describir).
|
|
17
|
+
*/
|
|
18
|
+
export interface Customer360Card {
|
|
19
|
+
issued: boolean;
|
|
20
|
+
/** Últimos dígitos del PAN, tal como los nombra `CardResponse.panLastDigit`. */
|
|
21
|
+
panLastDigit: string | null;
|
|
22
|
+
status: Status | null;
|
|
23
|
+
virtualOrPhysical: VirtualOrPhysical | null;
|
|
7
24
|
}
|
|
8
25
|
/** Ítem de compra en el historial del Cliente 360 (del GSI customerId-soldAt). */
|
|
9
26
|
export interface Customer360Purchase {
|
|
@@ -28,6 +45,8 @@ export interface Customer360Prospect {
|
|
|
28
45
|
export interface Customer360Response {
|
|
29
46
|
customer: CustomerResponse;
|
|
30
47
|
wallet: Customer360Wallet;
|
|
48
|
+
/** Tarjeta del cliente. Opcional: los consumidores que no la piden siguen compilando igual. */
|
|
49
|
+
card?: Customer360Card;
|
|
31
50
|
purchases: Customer360Purchase[];
|
|
32
51
|
prospects: Customer360Prospect[];
|
|
33
52
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { KycReview } from '../KycReview';
|
|
1
2
|
import { RetailAddress } from '../RetailAddress';
|
|
2
3
|
import { AccountStatusEnum } from '../../enums/AccountStatusEnum';
|
|
3
4
|
import { KycModalityEnum } from '../../enums/KycModalityEnum';
|
|
@@ -44,6 +45,11 @@ export interface CustomerResponse {
|
|
|
44
45
|
kycStatus: RetailKycStatusEnum;
|
|
45
46
|
kycModality: KycModalityEnum | null;
|
|
46
47
|
kycScore: number | null;
|
|
48
|
+
/**
|
|
49
|
+
* Veredicto manual del oficial de Cumplimiento (D21), ya persistido en el cliente. Ausente
|
|
50
|
+
* mientras nadie resolvió el KYC a mano — opcional para no romper a los consumidores actuales.
|
|
51
|
+
*/
|
|
52
|
+
kycReview?: KycReview;
|
|
47
53
|
metamapVerificationId: string | null;
|
|
48
54
|
pldFlag: boolean;
|
|
49
55
|
notes: string | null;
|
package/package.json
CHANGED
|
@@ -81,4 +81,20 @@ export class OriginateLoanCreditRequest {
|
|
|
81
81
|
@IsOptional()
|
|
82
82
|
@IsString()
|
|
83
83
|
imei?: string;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Tienda donde se vende. El motor la persiste y la reenvía al simulador del catálogo en cada
|
|
87
|
+
* cotización — al RE-cotizar el wizard no la vuelve a mandar, así que sin guardarla la venta
|
|
88
|
+
* perdería su promoción a mitad del paso 06.
|
|
89
|
+
*/
|
|
90
|
+
@Expose()
|
|
91
|
+
@IsOptional()
|
|
92
|
+
@IsString()
|
|
93
|
+
storeId?: string;
|
|
94
|
+
|
|
95
|
+
/** SKU del equipo, por el mismo motivo que `storeId`: resuelve promociones acotadas por producto. */
|
|
96
|
+
@Expose()
|
|
97
|
+
@IsOptional()
|
|
98
|
+
@IsString()
|
|
99
|
+
productSku?: string;
|
|
84
100
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Palanca que la promoción aplica sobre el plan de crédito. Al menos una clave debe venir presente
|
|
3
|
+
* (el lambda rechaza el efecto vacío con 422). Montos en **cents**; porcentajes y TNA en decimal,
|
|
4
|
+
* igual que `CreditPlan`.
|
|
5
|
+
*/
|
|
6
|
+
export interface PromotionEffect {
|
|
7
|
+
/** Delta NEGATIVO sobre el enganche mínimo del plan (`-0.20` = veinte puntos menos). */
|
|
8
|
+
downPaymentDeltaPct: number | null;
|
|
9
|
+
/** Bono que se abona a la tarjeta PCF al activar el crédito. */
|
|
10
|
+
pcfBonusCents: number | null;
|
|
11
|
+
/** TNA que reemplaza a la del plan, siempre hacia abajo (`1.80` = 180% en vez de 200%). */
|
|
12
|
+
tnaOverride: number | null;
|
|
13
|
+
/** Techo de monto financiable que reemplaza al del plan. */
|
|
14
|
+
maxAmountOverrideCents: number | null;
|
|
15
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Expose } from 'class-transformer';
|
|
2
|
+
import { IsEnum, IsOptional, IsString } from 'class-validator';
|
|
3
|
+
import { PromotionStatusEnum } from '../../enums/PromotionStatusEnum';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Body de PUT /promotions/:promotionId/status — publicar, pausar, reanudar o vencer.
|
|
7
|
+
* Transiciones válidas: `DRAFT→PUBLISHED`, `PUBLISHED⇄PAUSED`, `PUBLISHED|PAUSED→EXPIRED`.
|
|
8
|
+
* `reason` acompaña la pausa y queda en la bitácora.
|
|
9
|
+
*/
|
|
10
|
+
export class ChangePromotionStatusRequest {
|
|
11
|
+
@Expose()
|
|
12
|
+
@IsEnum(PromotionStatusEnum)
|
|
13
|
+
status!: PromotionStatusEnum;
|
|
14
|
+
|
|
15
|
+
@Expose()
|
|
16
|
+
@IsOptional()
|
|
17
|
+
@IsString()
|
|
18
|
+
reason?: string | null;
|
|
19
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Expose, Type } from 'class-transformer';
|
|
2
|
+
import {
|
|
3
|
+
ArrayNotEmpty,
|
|
4
|
+
IsArray,
|
|
5
|
+
IsEnum,
|
|
6
|
+
IsInt,
|
|
7
|
+
IsISO8601,
|
|
8
|
+
IsOptional,
|
|
9
|
+
IsString,
|
|
10
|
+
ValidateNested,
|
|
11
|
+
} from 'class-validator';
|
|
12
|
+
import { CreditPlanLevelEnum } from '../../enums/CreditPlanLevelEnum';
|
|
13
|
+
import { PromotionEffectInput } from './PromotionEffectInput';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Body de POST /promotions — alta de una promoción del motor.
|
|
17
|
+
* Nace en `DRAFT`: el estado, `promotionId`, `version`, los contadores de consumo y la auditoría
|
|
18
|
+
* los asigna el lambda y NO viajan en el request. `budgetMaxCents` ausente/`null` = sin tope.
|
|
19
|
+
*/
|
|
20
|
+
export class CreatePromotionRequest {
|
|
21
|
+
@Expose()
|
|
22
|
+
@IsString()
|
|
23
|
+
name!: string;
|
|
24
|
+
|
|
25
|
+
@Expose()
|
|
26
|
+
@IsString()
|
|
27
|
+
description!: string;
|
|
28
|
+
|
|
29
|
+
@Expose()
|
|
30
|
+
@ValidateNested()
|
|
31
|
+
@Type(() => PromotionEffectInput)
|
|
32
|
+
effect!: PromotionEffectInput;
|
|
33
|
+
|
|
34
|
+
/** Segmento de clientes al que apunta la promoción. */
|
|
35
|
+
@Expose()
|
|
36
|
+
@IsString()
|
|
37
|
+
segmentId!: string;
|
|
38
|
+
|
|
39
|
+
@Expose()
|
|
40
|
+
@IsArray()
|
|
41
|
+
@ArrayNotEmpty()
|
|
42
|
+
@IsEnum(CreditPlanLevelEnum, { each: true })
|
|
43
|
+
targetLevels!: CreditPlanLevelEnum[];
|
|
44
|
+
|
|
45
|
+
/** SKUs alcanzados; ausente o `null` = todos los productos. */
|
|
46
|
+
@Expose()
|
|
47
|
+
@IsOptional()
|
|
48
|
+
@IsArray()
|
|
49
|
+
@IsString({ each: true })
|
|
50
|
+
productSkus?: string[] | null;
|
|
51
|
+
|
|
52
|
+
/** Tiendas alcanzadas. `null` o ausente = todas. */
|
|
53
|
+
@Expose()
|
|
54
|
+
@IsOptional()
|
|
55
|
+
@IsArray()
|
|
56
|
+
@IsString({ each: true })
|
|
57
|
+
storeIds?: string[] | null;
|
|
58
|
+
|
|
59
|
+
@Expose()
|
|
60
|
+
@IsOptional()
|
|
61
|
+
@IsISO8601()
|
|
62
|
+
validFrom?: string | null;
|
|
63
|
+
|
|
64
|
+
@Expose()
|
|
65
|
+
@IsOptional()
|
|
66
|
+
@IsISO8601()
|
|
67
|
+
validUntil?: string | null;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Tope de presupuesto en cents; `null` = sin tope. El signo lo valida el lambda (422): un
|
|
71
|
+
* presupuesto negativo es un request bien formado que el negocio rechaza.
|
|
72
|
+
*/
|
|
73
|
+
@Expose()
|
|
74
|
+
@IsOptional()
|
|
75
|
+
@IsInt()
|
|
76
|
+
budgetMaxCents?: number | null;
|
|
77
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Expose } from 'class-transformer';
|
|
2
|
+
import { IsInt, IsNumber, IsOptional } from 'class-validator';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Efecto de la promoción tal como viaja en el body (alta y edición). Acá se valida solo la FORMA
|
|
6
|
+
* (que sea número o entero). Las cotas de negocio — rango de cada palanca y que venga al menos una
|
|
7
|
+
* clave — las valida el lambda con 422: son reglas del negocio sobre un body bien formado.
|
|
8
|
+
*/
|
|
9
|
+
export class PromotionEffectInput {
|
|
10
|
+
/** Delta NEGATIVO sobre el enganche mínimo (`-0.20` = veinte puntos menos); rango [-1, 0]. */
|
|
11
|
+
@Expose()
|
|
12
|
+
@IsOptional()
|
|
13
|
+
@IsNumber()
|
|
14
|
+
downPaymentDeltaPct?: number | null;
|
|
15
|
+
|
|
16
|
+
/** Bono a la tarjeta PCF, en cents. */
|
|
17
|
+
@Expose()
|
|
18
|
+
@IsOptional()
|
|
19
|
+
@IsInt()
|
|
20
|
+
pcfBonusCents?: number | null;
|
|
21
|
+
|
|
22
|
+
/** TNA que reemplaza a la del plan, hacia abajo (`1.80` = 180%); rango [0, 2.60]. */
|
|
23
|
+
@Expose()
|
|
24
|
+
@IsOptional()
|
|
25
|
+
@IsNumber()
|
|
26
|
+
tnaOverride?: number | null;
|
|
27
|
+
|
|
28
|
+
/** Techo de monto financiable que reemplaza al del plan, en cents. */
|
|
29
|
+
@Expose()
|
|
30
|
+
@IsOptional()
|
|
31
|
+
@IsInt()
|
|
32
|
+
maxAmountOverrideCents?: number | null;
|
|
33
|
+
}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { Expose } from 'class-transformer';
|
|
2
|
-
import { IsInt, IsNumber, IsOptional, Max, Min } from 'class-validator';
|
|
2
|
+
import { IsInt, IsNumber, IsOptional, IsString, Max, Min } from 'class-validator';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Body de POST /private/credit-plans/:planId/simulate y query de GET /credit-plans/:planId/simulator.
|
|
6
6
|
* Entradas del simulador de cuota (flow 06 §6.1.4). `productPriceCents` en cents; `downPaymentPct`
|
|
7
7
|
* decimal sobre 1. `customerSciScore` opcional: si viene, se valida contra el rango SCI del plan.
|
|
8
|
+
*
|
|
9
|
+
* `storeId` y `productSku` describen DÓNDE y QUÉ se está vendiendo: con ellos el simulador resuelve
|
|
10
|
+
* qué promoción aplica. Sin ellos, las promociones acotadas a una tienda o a un SKU quedan fuera —
|
|
11
|
+
* el simulador no adivina, y dar un beneficio que no corresponde es peor que no darlo.
|
|
8
12
|
*/
|
|
9
13
|
export class SimulateCreditPlanRequest {
|
|
10
14
|
@Expose()
|
|
@@ -29,4 +33,16 @@ export class SimulateCreditPlanRequest {
|
|
|
29
33
|
@Min(0)
|
|
30
34
|
@Max(100)
|
|
31
35
|
customerSciScore?: number;
|
|
36
|
+
|
|
37
|
+
/** Tienda donde se vende. Sin él no se resuelven las promociones acotadas por tienda. */
|
|
38
|
+
@Expose()
|
|
39
|
+
@IsOptional()
|
|
40
|
+
@IsString()
|
|
41
|
+
storeId?: string;
|
|
42
|
+
|
|
43
|
+
/** SKU del equipo. Sin él no se resuelven las promociones acotadas por producto. */
|
|
44
|
+
@Expose()
|
|
45
|
+
@IsOptional()
|
|
46
|
+
@IsString()
|
|
47
|
+
productSku?: string;
|
|
32
48
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Expose, Type } from 'class-transformer';
|
|
2
|
+
import {
|
|
3
|
+
ArrayNotEmpty,
|
|
4
|
+
IsArray,
|
|
5
|
+
IsEnum,
|
|
6
|
+
IsInt,
|
|
7
|
+
IsISO8601,
|
|
8
|
+
IsOptional,
|
|
9
|
+
IsString,
|
|
10
|
+
ValidateNested,
|
|
11
|
+
} from 'class-validator';
|
|
12
|
+
import { CreditPlanLevelEnum } from '../../enums/CreditPlanLevelEnum';
|
|
13
|
+
import { PromotionEffectInput } from './PromotionEffectInput';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Body de PUT /promotions/:promotionId — edición parcial (todos los campos opcionales).
|
|
17
|
+
* Solo se admite sobre `DRAFT` y `PUBLISHED`, y sube `version`. El cambio de estado va por su
|
|
18
|
+
* endpoint dedicado. `effect` se reemplaza entero cuando viene, no se mergea clave a clave.
|
|
19
|
+
*/
|
|
20
|
+
export class UpdatePromotionRequest {
|
|
21
|
+
@Expose()
|
|
22
|
+
@IsOptional()
|
|
23
|
+
@IsString()
|
|
24
|
+
name?: string;
|
|
25
|
+
|
|
26
|
+
@Expose()
|
|
27
|
+
@IsOptional()
|
|
28
|
+
@IsString()
|
|
29
|
+
description?: string;
|
|
30
|
+
|
|
31
|
+
@Expose()
|
|
32
|
+
@IsOptional()
|
|
33
|
+
@ValidateNested()
|
|
34
|
+
@Type(() => PromotionEffectInput)
|
|
35
|
+
effect?: PromotionEffectInput;
|
|
36
|
+
|
|
37
|
+
@Expose()
|
|
38
|
+
@IsOptional()
|
|
39
|
+
@IsString()
|
|
40
|
+
segmentId?: string;
|
|
41
|
+
|
|
42
|
+
@Expose()
|
|
43
|
+
@IsOptional()
|
|
44
|
+
@IsArray()
|
|
45
|
+
@ArrayNotEmpty()
|
|
46
|
+
@IsEnum(CreditPlanLevelEnum, { each: true })
|
|
47
|
+
targetLevels?: CreditPlanLevelEnum[];
|
|
48
|
+
|
|
49
|
+
@Expose()
|
|
50
|
+
@IsOptional()
|
|
51
|
+
@IsArray()
|
|
52
|
+
@IsString({ each: true })
|
|
53
|
+
productSkus?: string[] | null;
|
|
54
|
+
|
|
55
|
+
/** Tiendas alcanzadas. `null` o ausente = todas. */
|
|
56
|
+
@Expose()
|
|
57
|
+
@IsOptional()
|
|
58
|
+
@IsArray()
|
|
59
|
+
@IsString({ each: true })
|
|
60
|
+
storeIds?: string[] | null;
|
|
61
|
+
|
|
62
|
+
@Expose()
|
|
63
|
+
@IsOptional()
|
|
64
|
+
@IsISO8601()
|
|
65
|
+
validFrom?: string | null;
|
|
66
|
+
|
|
67
|
+
@Expose()
|
|
68
|
+
@IsOptional()
|
|
69
|
+
@IsISO8601()
|
|
70
|
+
validUntil?: string | null;
|
|
71
|
+
|
|
72
|
+
@Expose()
|
|
73
|
+
@IsOptional()
|
|
74
|
+
@IsInt()
|
|
75
|
+
budgetMaxCents?: number | null;
|
|
76
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { PromotionLogEventEnum } from '../../enums/PromotionLogEventEnum';
|
|
2
|
+
import { PromotionStatusEnum } from '../../enums/PromotionStatusEnum';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Fila del tab «Auditoría»: un evento de la bitácora de promociones.
|
|
6
|
+
* `fromStatus` es `null` en el alta; `reason` solo viene cargado en la pausa.
|
|
7
|
+
*/
|
|
8
|
+
export interface PromotionLogEntryResponse {
|
|
9
|
+
promotionId: string;
|
|
10
|
+
promotionName: string;
|
|
11
|
+
event: PromotionLogEventEnum;
|
|
12
|
+
occurredAt: string;
|
|
13
|
+
performedBy: string;
|
|
14
|
+
fromStatus: PromotionStatusEnum | null;
|
|
15
|
+
toStatus: PromotionStatusEnum | null;
|
|
16
|
+
reason: string | null;
|
|
17
|
+
version: number;
|
|
18
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { CreditPlanLevelEnum } from '../../enums/CreditPlanLevelEnum';
|
|
2
|
+
import { PromotionEffectKindEnum } from '../../enums/PromotionEffectKindEnum';
|
|
3
|
+
import { PromotionPhaseEnum } from '../../enums/PromotionPhaseEnum';
|
|
4
|
+
import { PromotionStatusEnum } from '../../enums/PromotionStatusEnum';
|
|
5
|
+
import { PromotionEffect } from '../PromotionEffect';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Shape de salida de una promoción (GET / POST / PUT de /promotions).
|
|
9
|
+
* Montos en cents; porcentajes y TNA en decimal.
|
|
10
|
+
*
|
|
11
|
+
* `effectKind` y `phase` son DERIVADOS y no viven en la tabla: el primero sale de las claves de
|
|
12
|
+
* `effect`, el segundo de las fechas contra hoy y solo cuando el estado es `PUBLISHED`.
|
|
13
|
+
*/
|
|
14
|
+
export interface PromotionResponse {
|
|
15
|
+
promotionId: string;
|
|
16
|
+
name: string;
|
|
17
|
+
description: string;
|
|
18
|
+
effect: PromotionEffect;
|
|
19
|
+
/** Derivado de las claves de `effect`; `COMBO` si hay dos o más, `null` si no hay ninguna. */
|
|
20
|
+
effectKind: PromotionEffectKindEnum | null;
|
|
21
|
+
segmentId: string;
|
|
22
|
+
targetLevels: CreditPlanLevelEnum[];
|
|
23
|
+
/** `null` = alcanza a todos los productos. */
|
|
24
|
+
productSkus: string[] | null;
|
|
25
|
+
/** `null` = alcanza a todas las tiendas. Dimensión «Tienda / canal» del alcance. */
|
|
26
|
+
storeIds: string[] | null;
|
|
27
|
+
validFrom: string | null;
|
|
28
|
+
validUntil: string | null;
|
|
29
|
+
status: PromotionStatusEnum;
|
|
30
|
+
/** Fase de vigencia derivada; `null` cuando el estado no es `PUBLISHED`. */
|
|
31
|
+
phase: PromotionPhaseEnum | null;
|
|
32
|
+
/** Tope de presupuesto; `null` = sin tope. */
|
|
33
|
+
budgetMaxCents: number | null;
|
|
34
|
+
budgetConsumedCents: number;
|
|
35
|
+
creditsGenerated: number;
|
|
36
|
+
version: number;
|
|
37
|
+
pausedAt: string | null;
|
|
38
|
+
pauseReason: string | null;
|
|
39
|
+
publishedAt: string | null;
|
|
40
|
+
publishedBy: string | null;
|
|
41
|
+
createdBy: string;
|
|
42
|
+
updatedBy: string;
|
|
43
|
+
createdAt: string;
|
|
44
|
+
updatedAt: string;
|
|
45
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { PromotionEffectKindEnum } from '../../enums/PromotionEffectKindEnum';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Un renglón de la tabla de amortización (M2 §3.3). Todos los montos en cents.
|
|
3
5
|
*/
|
|
@@ -14,6 +16,19 @@ export interface AmortizationRowResponse {
|
|
|
14
16
|
remainingBalanceCents: number;
|
|
15
17
|
}
|
|
16
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Promoción que el simulador aplicó a esta cotización. Sin este bloque la cuota cambia y nadie
|
|
21
|
+
* puede explicar por qué: es lo que hace auditable la regla de que gana una sola promoción.
|
|
22
|
+
*/
|
|
23
|
+
export interface AppliedPromotionResponse {
|
|
24
|
+
promotionId: string;
|
|
25
|
+
name: string;
|
|
26
|
+
/** Versión de la promoción al cotizar — el operador la edita y sube. */
|
|
27
|
+
version: number;
|
|
28
|
+
/** Palancas del plan que la promoción pisó. */
|
|
29
|
+
appliedEffects: PromotionEffectKindEnum[];
|
|
30
|
+
}
|
|
31
|
+
|
|
17
32
|
/**
|
|
18
33
|
* Resultado del simulador de cuota (POST /private/credit-plans/:planId/simulate,
|
|
19
34
|
* GET /credit-plans/:planId/simulator). Amortización francesa + IVA 16% + comisión de apertura + CAT.
|
|
@@ -42,4 +57,9 @@ export interface SimulationResultResponse {
|
|
|
42
57
|
/** Costo Anual Total (decimal, ej. 2.87 = 287%). Metodología estándar CONDUSEF (supuesto). */
|
|
43
58
|
catAnnual: number;
|
|
44
59
|
schedule: AmortizationRowResponse[];
|
|
60
|
+
/**
|
|
61
|
+
* Promoción aplicada, o `null` si ninguna alcanzaba a esta venta. Los montos de arriba YA la
|
|
62
|
+
* incluyen: es el porqué de la cuota, no un extra a sumar.
|
|
63
|
+
*/
|
|
64
|
+
appliedPromotion: AppliedPromotionResponse | null;
|
|
45
65
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Naturaleza del efecto de una promoción, DERIVADA de las claves presentes en `effect`.
|
|
3
|
+
* `COMBO` cuando hay dos o más claves. No se persiste: se calcula al responder.
|
|
4
|
+
* @enum {string}
|
|
5
|
+
*/
|
|
6
|
+
export enum PromotionEffectKindEnum {
|
|
7
|
+
DOWN_PAYMENT_DELTA = 'DOWN_PAYMENT_DELTA',
|
|
8
|
+
PCF_BONUS = 'PCF_BONUS',
|
|
9
|
+
TNA_OVERRIDE = 'TNA_OVERRIDE',
|
|
10
|
+
MAX_AMOUNT_OVERRIDE = 'MAX_AMOUNT_OVERRIDE',
|
|
11
|
+
COMBO = 'COMBO',
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evento de la bitácora de promociones (`<T>LoanPromotionLog_GT`), que alimenta el tab «Auditoría».
|
|
3
|
+
* @enum {string}
|
|
4
|
+
*/
|
|
5
|
+
export enum PromotionLogEventEnum {
|
|
6
|
+
CREATE = 'CREATE',
|
|
7
|
+
PUBLISH = 'PUBLISH',
|
|
8
|
+
PAUSE = 'PAUSE',
|
|
9
|
+
RESUME = 'RESUME',
|
|
10
|
+
EXPIRE = 'EXPIRE',
|
|
11
|
+
UPDATE = 'UPDATE',
|
|
12
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fase de vigencia de una promoción PUBLICADA, derivada de `validFrom`/`validUntil` contra hoy.
|
|
3
|
+
* No se persiste — así no hace falta un cron que mueva estados a medianoche. `null` cuando el
|
|
4
|
+
* estado persistido no es `PUBLISHED`.
|
|
5
|
+
* @enum {string}
|
|
6
|
+
*/
|
|
7
|
+
export enum PromotionPhaseEnum {
|
|
8
|
+
SCHEDULED = 'SCHEDULED',
|
|
9
|
+
ACTIVE = 'ACTIVE',
|
|
10
|
+
EXPIRED = 'EXPIRED',
|
|
11
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Estado PERSISTIDO de una promoción del motor (portal-admin-sk-promociones).
|
|
3
|
+
* `EXPIRED` es terminal. La «fase» que ve el operador (programada / activa / vencida) NO se guarda:
|
|
4
|
+
* se deriva de las fechas — ver `PromotionPhaseEnum`.
|
|
5
|
+
* @enum {string}
|
|
6
|
+
*/
|
|
7
|
+
export enum PromotionStatusEnum {
|
|
8
|
+
DRAFT = 'DRAFT',
|
|
9
|
+
PUBLISHED = 'PUBLISHED',
|
|
10
|
+
PAUSED = 'PAUSED',
|
|
11
|
+
EXPIRED = 'EXPIRED',
|
|
12
|
+
}
|