@fiado/type-kit 3.575.0 → 3.577.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/remittance/RemittanceProviderCost.test.ts +78 -0
- package/_test_/unit/retailCommission/commissionRules.test.ts +28 -0
- package/bin/remittance/dtos/RemittanceBackofficeTransaction.d.ts +8 -0
- package/bin/remittance/dtos/RemittancePayerConfig.d.ts +3 -0
- package/bin/remittance/dtos/RemittancePricing.d.ts +26 -0
- package/bin/remittance/dtos/RemittancePricing.js +53 -1
- package/bin/remittance/dtos/RemittanceProviderCost.d.ts +72 -0
- package/bin/remittance/dtos/RemittanceProviderCost.js +127 -0
- package/bin/remittance/dtos/index.d.ts +1 -0
- package/bin/remittance/dtos/index.js +1 -0
- package/bin/remittance/dtos/internal/RemittancePricingResolve.d.ts +12 -0
- package/bin/remittance/dtos/internal/RemittancePricingResolve.js +12 -0
- package/bin/remittance/dtos/internal/RemittancePricingSchedule.d.ts +4 -0
- package/bin/remittance/dtos/internal/RemittancePricingSchedule.js +11 -0
- package/bin/retailCommission/dtos/CommissionApi.d.ts +12 -0
- package/bin/retailCommission/dtos/CommissionRule.d.ts +6 -0
- package/package.json +1 -1
- package/src/remittance/dtos/RemittanceBackofficeTransaction.ts +11 -0
- package/src/remittance/dtos/RemittancePayerConfig.ts +3 -0
- package/src/remittance/dtos/RemittancePricing.ts +60 -0
- package/src/remittance/dtos/RemittanceProviderCost.ts +139 -0
- package/src/remittance/dtos/index.ts +1 -0
- package/src/remittance/dtos/internal/RemittancePricingResolve.ts +19 -0
- package/src/remittance/dtos/internal/RemittancePricingSchedule.ts +10 -0
- package/src/retailCommission/dtos/CommissionApi.ts +12 -0
- package/src/retailCommission/dtos/CommissionRule.ts +6 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
import { plainToInstance } from "class-transformer";
|
|
3
|
+
import { validateSync } from "class-validator";
|
|
4
|
+
import { ProviderCostUpdateRequest } from "../../../src/remittance/dtos/RemittanceProviderCost";
|
|
5
|
+
import { SimulatePricingRequest, UpdatePricingRequest } from "../../../src/remittance/dtos/RemittancePricing";
|
|
6
|
+
import { PricingResolveRequest } from "../../../src/remittance/dtos/internal/RemittancePricingResolve";
|
|
7
|
+
|
|
8
|
+
const errorsOf = <T extends object>(cls: new () => T, plain: object) =>
|
|
9
|
+
validateSync(plainToInstance(cls, plain), { whitelist: true, forbidNonWhitelisted: true });
|
|
10
|
+
|
|
11
|
+
describe("ProviderCostUpdateRequest", () => {
|
|
12
|
+
it("acepta grupos con tres precios, tramo y asignaciones", () => {
|
|
13
|
+
expect(errorsOf(ProviderCostUpdateRequest, {
|
|
14
|
+
costTier: 1,
|
|
15
|
+
groups: [{ groupId: "A", costsUSD: [3, 2.75, 2.6] }],
|
|
16
|
+
assignments: [
|
|
17
|
+
{ payerCode: "GCA8", receptionMethod: "CASH_PICKUP", groupId: "B" },
|
|
18
|
+
{ payerCode: "GCA12", receptionMethod: "CASH_PICKUP", groupId: null },
|
|
19
|
+
],
|
|
20
|
+
})).toHaveLength(0);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("rechaza un grupo sin los tres precios", () => {
|
|
24
|
+
expect(errorsOf(ProviderCostUpdateRequest, { groups: [{ groupId: "A", costsUSD: [3, 2.75] }] })).not.toHaveLength(0);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("rechaza ids de grupo que no son una letra mayúscula", () => {
|
|
28
|
+
expect(errorsOf(ProviderCostUpdateRequest, { groups: [{ groupId: "AB", costsUSD: [3, 2.75, 2.6] }] })).not.toHaveLength(0);
|
|
29
|
+
expect(errorsOf(ProviderCostUpdateRequest, { assignments: [{ payerCode: "GCA8", receptionMethod: "CASH_PICKUP", groupId: "b" }] })).not.toHaveLength(0);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("rechaza precios con más de dos decimales o fuera de rango", () => {
|
|
33
|
+
expect(errorsOf(ProviderCostUpdateRequest, { groups: [{ groupId: "A", costsUSD: [3.001, 2.75, 2.6] }] })).not.toHaveLength(0);
|
|
34
|
+
expect(errorsOf(ProviderCostUpdateRequest, { groups: [{ groupId: "A", costsUSD: [-1, 2.75, 2.6] }] })).not.toHaveLength(0);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("rechaza un tramo fuera de 1..3", () => {
|
|
38
|
+
expect(errorsOf(ProviderCostUpdateRequest, { costTier: 4 })).not.toHaveLength(0);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
describe("ajustes de fee por grupo", () => {
|
|
43
|
+
const tramos = [{ amountMin: 25, amountMax: null, serviceFee: 2.99, effectiveFrom: "2026-10-23" }];
|
|
44
|
+
|
|
45
|
+
it("UpdatePricingRequest acepta groupFeeAdjustments con signo", () => {
|
|
46
|
+
expect(errorsOf(UpdatePricingRequest, {
|
|
47
|
+
markupBps: 120, tramos,
|
|
48
|
+
groupFeeAdjustments: [{ groupId: "C", adjustmentUSD: 1 }, { groupId: "A", adjustmentUSD: -0.5 }],
|
|
49
|
+
})).toHaveLength(0);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("UpdatePricingRequest sigue válido sin groupFeeAdjustments", () => {
|
|
53
|
+
expect(errorsOf(UpdatePricingRequest, { markupBps: 120, tramos })).toHaveLength(0);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("SimulatePricingRequest acepta payer y método", () => {
|
|
57
|
+
expect(errorsOf(SimulatePricingRequest, {
|
|
58
|
+
corridor: "USD-GTQ", amountUSD: 200, markupBps: 120, tramos,
|
|
59
|
+
payerCode: "GCA10", receptionMethod: "CASH_PICKUP",
|
|
60
|
+
})).toHaveLength(0);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe("PricingResolveRequest", () => {
|
|
65
|
+
it("acepta payer y método opcionales", () => {
|
|
66
|
+
expect(errorsOf(PricingResolveRequest, {
|
|
67
|
+
directoryId: "8f14e45f-ceea-467f-a8f8-3c1a3f6b1d2e", corridor: "USD-GTQ", amountUSD: 200,
|
|
68
|
+
payerCode: "GCA10", receptionMethod: "ACCOUNT_CREDIT",
|
|
69
|
+
})).toHaveLength(0);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("rechaza un método que no existe", () => {
|
|
73
|
+
expect(errorsOf(PricingResolveRequest, {
|
|
74
|
+
directoryId: "8f14e45f-ceea-467f-a8f8-3c1a3f6b1d2e", corridor: "USD-GTQ", amountUSD: 200,
|
|
75
|
+
receptionMethod: "CARRIER_PIGEON",
|
|
76
|
+
})).not.toHaveLength(0);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
@@ -113,6 +113,14 @@ describe('retailCommission — regla, políticas y snapshot', () => {
|
|
|
113
113
|
expect(monthly.payTiming).toBe('MONTHLY');
|
|
114
114
|
});
|
|
115
115
|
|
|
116
|
+
it('la regla puede traer adelanto al momento, o null, o nada', () => {
|
|
117
|
+
const withAdvance: RetailCommission.CommissionRule = { ...base, payTiming: RetailCommission.CommissionPayTimingEnum.MONTHLY, onSaleAdvanceBps: 3000 };
|
|
118
|
+
const none: RetailCommission.CommissionRule = { ...base, onSaleAdvanceBps: null };
|
|
119
|
+
expect(base.onSaleAdvanceBps).toBeUndefined();
|
|
120
|
+
expect(withAdvance.onSaleAdvanceBps).toBe(3000);
|
|
121
|
+
expect(none.onSaleAdvanceBps).toBeNull();
|
|
122
|
+
});
|
|
123
|
+
|
|
116
124
|
it('el snapshot congela las reglas publicadas y las políticas', () => {
|
|
117
125
|
const snapshot: RetailCommission.CommissionRuleSetSnapshot = {
|
|
118
126
|
retailerId: 'RET-1',
|
|
@@ -276,6 +284,26 @@ describe('retailCommission — contratos de reglas y políticas', () => {
|
|
|
276
284
|
expect(view.payTiming).toBe('ON_SALE');
|
|
277
285
|
});
|
|
278
286
|
|
|
287
|
+
it('el editor manda el adelanto y el vendedor lo ve', () => {
|
|
288
|
+
const create: RetailCommission.CreateRuleRequest = { ...input, payTiming: RetailCommission.CommissionPayTimingEnum.MONTHLY, onSaleAdvanceBps: 3000 };
|
|
289
|
+
const clear: RetailCommission.CreateRuleRequest = { ...input, onSaleAdvanceBps: null };
|
|
290
|
+
const view: RetailCommission.CommissionRuleView = {
|
|
291
|
+
ruleId: 'RC-01',
|
|
292
|
+
name: create.name,
|
|
293
|
+
description: create.description,
|
|
294
|
+
levers: create.levers,
|
|
295
|
+
scope: create.scope,
|
|
296
|
+
condition: create.condition,
|
|
297
|
+
effectiveFrom: create.effectiveFrom,
|
|
298
|
+
effectiveTo: create.effectiveTo,
|
|
299
|
+
payTiming: create.payTiming,
|
|
300
|
+
onSaleAdvanceBps: create.onSaleAdvanceBps,
|
|
301
|
+
};
|
|
302
|
+
expect(input.onSaleAdvanceBps).toBeUndefined();
|
|
303
|
+
expect(clear.onSaleAdvanceBps).toBeNull();
|
|
304
|
+
expect(view.onSaleAdvanceBps).toBe(3000);
|
|
305
|
+
});
|
|
306
|
+
|
|
279
307
|
it('las políticas se guardan juntas', () => {
|
|
280
308
|
const request: RetailCommission.UpdatePoliciesRequest = {
|
|
281
309
|
clawback: { cancelacionDias: 7, devolucionDias: 7, npiM30Dias: 30 },
|
|
@@ -95,4 +95,12 @@ export declare class RemittanceBackofficeTransaction {
|
|
|
95
95
|
reconStatus?: RemittanceReconStatus;
|
|
96
96
|
/** Detalle textual de los diffs cuando reconStatus !== OK. */
|
|
97
97
|
reconDiffDetail?: string;
|
|
98
|
+
/** Costo UniTeller esperado en USD según el grupo y el tramo vigente al enviar. */
|
|
99
|
+
unitellerCostExpected?: number;
|
|
100
|
+
/** Grupo de costo del payer × método al enviar. */
|
|
101
|
+
costGroup?: string;
|
|
102
|
+
/** Tramo de volumen vigente al enviar (1..3). */
|
|
103
|
+
costTier?: number;
|
|
104
|
+
/** Ajuste del grupo que se sumó al fee de esta remesa. */
|
|
105
|
+
groupFeeAdjustment?: number;
|
|
98
106
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ReceptionMethod } from "../enums/ReceptionMethod";
|
|
2
|
+
import { CostGroupByMethod } from "./RemittanceProviderCost";
|
|
2
3
|
/**
|
|
3
4
|
* DTOs de la administración de payers desde el backoffice (v1: enabled + override de nombre).
|
|
4
5
|
* La lista de payers la dicta el catálogo UniTeller; la config es un overlay por payerCode.
|
|
@@ -18,6 +19,8 @@ export declare class RemittancePayerConfigItem {
|
|
|
18
19
|
configured: boolean;
|
|
19
20
|
/** Logo de UniTeller, solo lectura (identificación visual en la lista). */
|
|
20
21
|
logoUrl?: string;
|
|
22
|
+
/** Grupo de costo UniTeller de cada método (solo lectura aquí; se edita en Costos UniTeller). */
|
|
23
|
+
costGroupByMethod?: CostGroupByMethod;
|
|
21
24
|
}
|
|
22
25
|
/** Response de GET /backoffice/config/payers (config chica, sin paginación). */
|
|
23
26
|
export declare class RemittancePayerConfigListResponse {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { RemittanceCorridor } from "../enums/RemittanceCorridor";
|
|
2
|
+
import { ReceptionMethod } from "../enums/ReceptionMethod";
|
|
2
3
|
/**
|
|
3
4
|
* DTOs de Precio Base (Dashboard Ops · Variables Operativas §1).
|
|
4
5
|
*
|
|
@@ -20,6 +21,12 @@ export declare class PricingTier {
|
|
|
20
21
|
/** ISO date (YYYY-MM-DD) "FEE DESDE" — informativo. */
|
|
21
22
|
effectiveFrom: string;
|
|
22
23
|
}
|
|
24
|
+
/** Ajuste en USD que se suma al fee del tramo cuando el payer × método cae en ese grupo de costo. */
|
|
25
|
+
export declare class PricingGroupFeeAdjustment {
|
|
26
|
+
groupId: string;
|
|
27
|
+
/** CON SIGNO: negativo descuenta. El fee final nunca baja de 0. */
|
|
28
|
+
adjustmentUSD: number;
|
|
29
|
+
}
|
|
23
30
|
/** Body de POST /backoffice/pricing/base. */
|
|
24
31
|
export declare class CreatePricingRequest {
|
|
25
32
|
corridor: RemittanceCorridor;
|
|
@@ -29,6 +36,8 @@ export declare class CreatePricingRequest {
|
|
|
29
36
|
tramos: PricingTier[];
|
|
30
37
|
name?: string;
|
|
31
38
|
notes?: string;
|
|
39
|
+
/** Ajuste del fee por grupo de costo del payer. Ausente = conserva los actuales; [] = sin ajustes. */
|
|
40
|
+
groupFeeAdjustments?: PricingGroupFeeAdjustment[];
|
|
32
41
|
}
|
|
33
42
|
/** Body de PUT /backoffice/pricing/base/{id} (reemplazo completo; corridor/segmentId inmutables). */
|
|
34
43
|
export declare class UpdatePricingRequest {
|
|
@@ -36,6 +45,8 @@ export declare class UpdatePricingRequest {
|
|
|
36
45
|
tramos: PricingTier[];
|
|
37
46
|
name?: string;
|
|
38
47
|
notes?: string;
|
|
48
|
+
/** Ajuste del fee por grupo de costo del payer. Ausente = conserva los actuales; [] = sin ajustes. */
|
|
49
|
+
groupFeeAdjustments?: PricingGroupFeeAdjustment[];
|
|
39
50
|
}
|
|
40
51
|
/** Combinación completa (response de list/create/update). */
|
|
41
52
|
export declare class PricingCombination {
|
|
@@ -48,6 +59,8 @@ export declare class PricingCombination {
|
|
|
48
59
|
tramos: PricingTier[];
|
|
49
60
|
/** # promos activas que aplican a la combinación. 0 hasta que exista Promociones. */
|
|
50
61
|
promosCount: number;
|
|
62
|
+
/** Ajuste del fee por grupo de costo. Ausente o [] = sin ajustes. */
|
|
63
|
+
groupFeeAdjustments?: PricingGroupFeeAdjustment[];
|
|
51
64
|
name: string | null;
|
|
52
65
|
notes: string | null;
|
|
53
66
|
createdAt: string;
|
|
@@ -72,6 +85,11 @@ export declare class SimulatePricingRequest {
|
|
|
72
85
|
amountUSD: number;
|
|
73
86
|
markupBps: number;
|
|
74
87
|
tramos: PricingTier[];
|
|
88
|
+
/** Ajustes del panel (pueden no estar guardados). Solo aplican si viene payer y método. */
|
|
89
|
+
groupFeeAdjustments?: PricingGroupFeeAdjustment[];
|
|
90
|
+
/** Payer y método opcionales: con ellos la simulación suma el ajuste del grupo y calcula costo y margen. */
|
|
91
|
+
payerCode?: string;
|
|
92
|
+
receptionMethod?: ReceptionMethod;
|
|
75
93
|
}
|
|
76
94
|
export declare class SimulatePricingResponse {
|
|
77
95
|
/** ExternalQuickQuotes (vivo). */
|
|
@@ -90,6 +108,14 @@ export declare class SimulatePricingResponse {
|
|
|
90
108
|
revenueUsd: number;
|
|
91
109
|
/** ISO del quote. */
|
|
92
110
|
asOf: string;
|
|
111
|
+
/** Grupo de costo del payer × método simulado. */
|
|
112
|
+
costGroup?: string;
|
|
113
|
+
/** Ajuste del grupo ya sumado en serviceFee. */
|
|
114
|
+
groupFeeAdjustment?: number;
|
|
115
|
+
/** Costo UniTeller esperado (Exhibit A, tramo vigente del país). */
|
|
116
|
+
unitellerCostExpected?: number;
|
|
117
|
+
/** revenueUsd − unitellerCostExpected. */
|
|
118
|
+
netMarginUsd?: number;
|
|
93
119
|
}
|
|
94
120
|
/** Response de GET /backoffice/pricing/wholesale?corridor= (rb passthrough del connector). */
|
|
95
121
|
export declare class WholesaleRateResponse {
|
|
@@ -9,10 +9,12 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
9
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.WholesaleRateResponse = exports.SimulatePricingResponse = exports.SimulatePricingRequest = exports.PricingCombinationMetrics = exports.PricingListResponse = exports.PricingCombination = exports.UpdatePricingRequest = exports.CreatePricingRequest = exports.PricingTier = void 0;
|
|
12
|
+
exports.WholesaleRateResponse = exports.SimulatePricingResponse = exports.SimulatePricingRequest = exports.PricingCombinationMetrics = exports.PricingListResponse = exports.PricingCombination = exports.UpdatePricingRequest = exports.CreatePricingRequest = exports.PricingGroupFeeAdjustment = exports.PricingTier = void 0;
|
|
13
13
|
const class_transformer_1 = require("class-transformer");
|
|
14
14
|
const class_validator_1 = require("class-validator");
|
|
15
15
|
const RemittanceCorridor_1 = require("../enums/RemittanceCorridor");
|
|
16
|
+
const ReceptionMethod_1 = require("../enums/ReceptionMethod");
|
|
17
|
+
const RemittanceProviderCost_1 = require("./RemittanceProviderCost");
|
|
16
18
|
/**
|
|
17
19
|
* DTOs de Precio Base (Dashboard Ops · Variables Operativas §1).
|
|
18
20
|
*
|
|
@@ -55,6 +57,21 @@ __decorate([
|
|
|
55
57
|
(0, class_validator_1.Length)(10, 10),
|
|
56
58
|
__metadata("design:type", String)
|
|
57
59
|
], PricingTier.prototype, "effectiveFrom", void 0);
|
|
60
|
+
/** Ajuste en USD que se suma al fee del tramo cuando el payer × método cae en ese grupo de costo. */
|
|
61
|
+
class PricingGroupFeeAdjustment {
|
|
62
|
+
}
|
|
63
|
+
exports.PricingGroupFeeAdjustment = PricingGroupFeeAdjustment;
|
|
64
|
+
__decorate([
|
|
65
|
+
(0, class_validator_1.IsString)(),
|
|
66
|
+
(0, class_validator_1.Matches)(RemittanceProviderCost_1.PROVIDER_COST_GROUP_ID_PATTERN),
|
|
67
|
+
__metadata("design:type", String)
|
|
68
|
+
], PricingGroupFeeAdjustment.prototype, "groupId", void 0);
|
|
69
|
+
__decorate([
|
|
70
|
+
(0, class_validator_1.IsNumber)({ maxDecimalPlaces: 2 }),
|
|
71
|
+
(0, class_validator_1.Min)(-100),
|
|
72
|
+
(0, class_validator_1.Max)(100),
|
|
73
|
+
__metadata("design:type", Number)
|
|
74
|
+
], PricingGroupFeeAdjustment.prototype, "adjustmentUSD", void 0);
|
|
58
75
|
/** Body de POST /backoffice/pricing/base. */
|
|
59
76
|
class CreatePricingRequest {
|
|
60
77
|
}
|
|
@@ -94,6 +111,14 @@ __decorate([
|
|
|
94
111
|
(0, class_validator_1.MaxLength)(500),
|
|
95
112
|
__metadata("design:type", String)
|
|
96
113
|
], CreatePricingRequest.prototype, "notes", void 0);
|
|
114
|
+
__decorate([
|
|
115
|
+
(0, class_validator_1.IsOptional)(),
|
|
116
|
+
(0, class_validator_1.IsArray)(),
|
|
117
|
+
(0, class_validator_1.ArrayMaxSize)(10),
|
|
118
|
+
(0, class_validator_1.ValidateNested)({ each: true }),
|
|
119
|
+
(0, class_transformer_1.Type)(() => PricingGroupFeeAdjustment),
|
|
120
|
+
__metadata("design:type", Array)
|
|
121
|
+
], CreatePricingRequest.prototype, "groupFeeAdjustments", void 0);
|
|
97
122
|
/** Body de PUT /backoffice/pricing/base/{id} (reemplazo completo; corridor/segmentId inmutables). */
|
|
98
123
|
class UpdatePricingRequest {
|
|
99
124
|
}
|
|
@@ -124,6 +149,14 @@ __decorate([
|
|
|
124
149
|
(0, class_validator_1.MaxLength)(500),
|
|
125
150
|
__metadata("design:type", String)
|
|
126
151
|
], UpdatePricingRequest.prototype, "notes", void 0);
|
|
152
|
+
__decorate([
|
|
153
|
+
(0, class_validator_1.IsOptional)(),
|
|
154
|
+
(0, class_validator_1.IsArray)(),
|
|
155
|
+
(0, class_validator_1.ArrayMaxSize)(10),
|
|
156
|
+
(0, class_validator_1.ValidateNested)({ each: true }),
|
|
157
|
+
(0, class_transformer_1.Type)(() => PricingGroupFeeAdjustment),
|
|
158
|
+
__metadata("design:type", Array)
|
|
159
|
+
], UpdatePricingRequest.prototype, "groupFeeAdjustments", void 0);
|
|
127
160
|
/** Combinación completa (response de list/create/update). */
|
|
128
161
|
class PricingCombination {
|
|
129
162
|
}
|
|
@@ -163,6 +196,25 @@ __decorate([
|
|
|
163
196
|
(0, class_transformer_1.Type)(() => PricingTier),
|
|
164
197
|
__metadata("design:type", Array)
|
|
165
198
|
], SimulatePricingRequest.prototype, "tramos", void 0);
|
|
199
|
+
__decorate([
|
|
200
|
+
(0, class_validator_1.IsOptional)(),
|
|
201
|
+
(0, class_validator_1.IsArray)(),
|
|
202
|
+
(0, class_validator_1.ArrayMaxSize)(10),
|
|
203
|
+
(0, class_validator_1.ValidateNested)({ each: true }),
|
|
204
|
+
(0, class_transformer_1.Type)(() => PricingGroupFeeAdjustment),
|
|
205
|
+
__metadata("design:type", Array)
|
|
206
|
+
], SimulatePricingRequest.prototype, "groupFeeAdjustments", void 0);
|
|
207
|
+
__decorate([
|
|
208
|
+
(0, class_validator_1.IsOptional)(),
|
|
209
|
+
(0, class_validator_1.IsString)(),
|
|
210
|
+
(0, class_validator_1.Length)(1, 40),
|
|
211
|
+
__metadata("design:type", String)
|
|
212
|
+
], SimulatePricingRequest.prototype, "payerCode", void 0);
|
|
213
|
+
__decorate([
|
|
214
|
+
(0, class_validator_1.IsOptional)(),
|
|
215
|
+
(0, class_validator_1.IsEnum)(ReceptionMethod_1.ReceptionMethod),
|
|
216
|
+
__metadata("design:type", String)
|
|
217
|
+
], SimulatePricingRequest.prototype, "receptionMethod", void 0);
|
|
166
218
|
class SimulatePricingResponse {
|
|
167
219
|
}
|
|
168
220
|
exports.SimulatePricingResponse = SimulatePricingResponse;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { ReceptionMethod } from "../enums/ReceptionMethod";
|
|
2
|
+
/**
|
|
3
|
+
* DTOs de Costos UniTeller (Exhibit A del contrato): lo que UniTeller le cobra a Fiado por remesa.
|
|
4
|
+
* Por país hay grupos con un precio por tramo de volumen y un tramo vigente; cada payer × método
|
|
5
|
+
* cae en un grupo. Se guarda en RemittanceCountryConfig_GT (grupos y tramo) y en
|
|
6
|
+
* RemittancePayerConfig_GT (grupo por método). Dueño: remittance-business.
|
|
7
|
+
*/
|
|
8
|
+
/** Cantidad de tramos de volumen del Exhibit A. */
|
|
9
|
+
export declare const PROVIDER_COST_TIER_COUNT = 3;
|
|
10
|
+
/** Id de grupo: una letra mayúscula (A, B, C…). */
|
|
11
|
+
export declare const PROVIDER_COST_GROUP_ID_PATTERN: RegExp;
|
|
12
|
+
/** Grupo de costo: un precio en USD por tramo de volumen (posición 0 = tramo 1). */
|
|
13
|
+
export declare class ProviderCostGroup {
|
|
14
|
+
groupId: string;
|
|
15
|
+
costsUSD: number[];
|
|
16
|
+
}
|
|
17
|
+
/** Grupo de cada método de un payer. Método ausente = sin grupo (sin costo esperado ni ajuste de fee). */
|
|
18
|
+
export declare class CostGroupByMethod {
|
|
19
|
+
ACCOUNT_CREDIT?: string;
|
|
20
|
+
CASH_PICKUP?: string;
|
|
21
|
+
WALLET?: string;
|
|
22
|
+
}
|
|
23
|
+
/** Un payer × método del catálogo del país, con su grupo si tiene. */
|
|
24
|
+
export declare class ProviderCostAssignment {
|
|
25
|
+
payerCode: string;
|
|
26
|
+
/** Nombre efectivo del payer (override de Ops o el de UniTeller). */
|
|
27
|
+
name: string;
|
|
28
|
+
receptionMethod: ReceptionMethod;
|
|
29
|
+
/** Ausente = sin grupo. */
|
|
30
|
+
groupId?: string;
|
|
31
|
+
}
|
|
32
|
+
/** Volumen del mes calendario en curso (UTC), sin canceladas. Guía para elegir el tramo vigente. */
|
|
33
|
+
export declare class ProviderCostMonthVolume {
|
|
34
|
+
txCount: number;
|
|
35
|
+
volumeUSD: number;
|
|
36
|
+
}
|
|
37
|
+
/** Costos de un país (vista de backoffice). */
|
|
38
|
+
export declare class ProviderCostCountryItem {
|
|
39
|
+
countryISO: string;
|
|
40
|
+
name: string;
|
|
41
|
+
/** Tramo vigente 1..3; null = sin configurar. */
|
|
42
|
+
costTier: number | null;
|
|
43
|
+
groups: ProviderCostGroup[];
|
|
44
|
+
/** Todos los payer × método del catálogo del país, con o sin grupo. */
|
|
45
|
+
assignments: ProviderCostAssignment[];
|
|
46
|
+
/** Ausente si no se pudo calcular. */
|
|
47
|
+
monthVolume?: ProviderCostMonthVolume;
|
|
48
|
+
updatedAt?: string;
|
|
49
|
+
updatedBy?: string;
|
|
50
|
+
}
|
|
51
|
+
/** Response de GET /backoffice/config/provider-costs. */
|
|
52
|
+
export declare class ProviderCostListResponse {
|
|
53
|
+
/** Etiquetas de los tramos de volumen del contrato, en orden (tramo 1 primero). */
|
|
54
|
+
tierLabels: string[];
|
|
55
|
+
items: ProviderCostCountryItem[];
|
|
56
|
+
}
|
|
57
|
+
/** Cambio de grupo de un payer × método. groupId null o ausente = quitarlo de su grupo. */
|
|
58
|
+
export declare class ProviderCostAssignmentUpdate {
|
|
59
|
+
payerCode: string;
|
|
60
|
+
receptionMethod: ReceptionMethod;
|
|
61
|
+
groupId?: string | null;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Body de PUT /backoffice/config/provider-costs/{countryISO}. Todo opcional.
|
|
65
|
+
* `groups` reemplaza la lista completa; `assignments` solo toca los payer × método que trae.
|
|
66
|
+
* Response: ProviderCostCountryItem.
|
|
67
|
+
*/
|
|
68
|
+
export declare class ProviderCostUpdateRequest {
|
|
69
|
+
costTier?: number;
|
|
70
|
+
groups?: ProviderCostGroup[];
|
|
71
|
+
assignments?: ProviderCostAssignmentUpdate[];
|
|
72
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
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.ProviderCostUpdateRequest = exports.ProviderCostAssignmentUpdate = exports.ProviderCostListResponse = exports.ProviderCostCountryItem = exports.ProviderCostMonthVolume = exports.ProviderCostAssignment = exports.CostGroupByMethod = exports.ProviderCostGroup = exports.PROVIDER_COST_GROUP_ID_PATTERN = exports.PROVIDER_COST_TIER_COUNT = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
const ReceptionMethod_1 = require("../enums/ReceptionMethod");
|
|
16
|
+
/**
|
|
17
|
+
* DTOs de Costos UniTeller (Exhibit A del contrato): lo que UniTeller le cobra a Fiado por remesa.
|
|
18
|
+
* Por país hay grupos con un precio por tramo de volumen y un tramo vigente; cada payer × método
|
|
19
|
+
* cae en un grupo. Se guarda en RemittanceCountryConfig_GT (grupos y tramo) y en
|
|
20
|
+
* RemittancePayerConfig_GT (grupo por método). Dueño: remittance-business.
|
|
21
|
+
*/
|
|
22
|
+
/** Cantidad de tramos de volumen del Exhibit A. */
|
|
23
|
+
exports.PROVIDER_COST_TIER_COUNT = 3;
|
|
24
|
+
/** Id de grupo: una letra mayúscula (A, B, C…). */
|
|
25
|
+
exports.PROVIDER_COST_GROUP_ID_PATTERN = /^[A-Z]$/;
|
|
26
|
+
/** Grupo de costo: un precio en USD por tramo de volumen (posición 0 = tramo 1). */
|
|
27
|
+
class ProviderCostGroup {
|
|
28
|
+
}
|
|
29
|
+
exports.ProviderCostGroup = ProviderCostGroup;
|
|
30
|
+
__decorate([
|
|
31
|
+
(0, class_validator_1.IsString)(),
|
|
32
|
+
(0, class_validator_1.Matches)(exports.PROVIDER_COST_GROUP_ID_PATTERN),
|
|
33
|
+
__metadata("design:type", String)
|
|
34
|
+
], ProviderCostGroup.prototype, "groupId", void 0);
|
|
35
|
+
__decorate([
|
|
36
|
+
(0, class_validator_1.IsArray)(),
|
|
37
|
+
(0, class_validator_1.ArrayMinSize)(exports.PROVIDER_COST_TIER_COUNT),
|
|
38
|
+
(0, class_validator_1.ArrayMaxSize)(exports.PROVIDER_COST_TIER_COUNT),
|
|
39
|
+
(0, class_validator_1.IsNumber)({ maxDecimalPlaces: 2 }, { each: true }),
|
|
40
|
+
(0, class_validator_1.Min)(0, { each: true }),
|
|
41
|
+
(0, class_validator_1.Max)(50, { each: true }),
|
|
42
|
+
__metadata("design:type", Array)
|
|
43
|
+
], ProviderCostGroup.prototype, "costsUSD", void 0);
|
|
44
|
+
/** Grupo de cada método de un payer. Método ausente = sin grupo (sin costo esperado ni ajuste de fee). */
|
|
45
|
+
class CostGroupByMethod {
|
|
46
|
+
}
|
|
47
|
+
exports.CostGroupByMethod = CostGroupByMethod;
|
|
48
|
+
__decorate([
|
|
49
|
+
(0, class_validator_1.IsOptional)(),
|
|
50
|
+
(0, class_validator_1.Matches)(exports.PROVIDER_COST_GROUP_ID_PATTERN),
|
|
51
|
+
__metadata("design:type", String)
|
|
52
|
+
], CostGroupByMethod.prototype, "ACCOUNT_CREDIT", void 0);
|
|
53
|
+
__decorate([
|
|
54
|
+
(0, class_validator_1.IsOptional)(),
|
|
55
|
+
(0, class_validator_1.Matches)(exports.PROVIDER_COST_GROUP_ID_PATTERN),
|
|
56
|
+
__metadata("design:type", String)
|
|
57
|
+
], CostGroupByMethod.prototype, "CASH_PICKUP", void 0);
|
|
58
|
+
__decorate([
|
|
59
|
+
(0, class_validator_1.IsOptional)(),
|
|
60
|
+
(0, class_validator_1.Matches)(exports.PROVIDER_COST_GROUP_ID_PATTERN),
|
|
61
|
+
__metadata("design:type", String)
|
|
62
|
+
], CostGroupByMethod.prototype, "WALLET", void 0);
|
|
63
|
+
/** Un payer × método del catálogo del país, con su grupo si tiene. */
|
|
64
|
+
class ProviderCostAssignment {
|
|
65
|
+
}
|
|
66
|
+
exports.ProviderCostAssignment = ProviderCostAssignment;
|
|
67
|
+
/** Volumen del mes calendario en curso (UTC), sin canceladas. Guía para elegir el tramo vigente. */
|
|
68
|
+
class ProviderCostMonthVolume {
|
|
69
|
+
}
|
|
70
|
+
exports.ProviderCostMonthVolume = ProviderCostMonthVolume;
|
|
71
|
+
/** Costos de un país (vista de backoffice). */
|
|
72
|
+
class ProviderCostCountryItem {
|
|
73
|
+
}
|
|
74
|
+
exports.ProviderCostCountryItem = ProviderCostCountryItem;
|
|
75
|
+
/** Response de GET /backoffice/config/provider-costs. */
|
|
76
|
+
class ProviderCostListResponse {
|
|
77
|
+
}
|
|
78
|
+
exports.ProviderCostListResponse = ProviderCostListResponse;
|
|
79
|
+
/** Cambio de grupo de un payer × método. groupId null o ausente = quitarlo de su grupo. */
|
|
80
|
+
class ProviderCostAssignmentUpdate {
|
|
81
|
+
}
|
|
82
|
+
exports.ProviderCostAssignmentUpdate = ProviderCostAssignmentUpdate;
|
|
83
|
+
__decorate([
|
|
84
|
+
(0, class_validator_1.IsString)(),
|
|
85
|
+
(0, class_validator_1.Length)(1, 40),
|
|
86
|
+
__metadata("design:type", String)
|
|
87
|
+
], ProviderCostAssignmentUpdate.prototype, "payerCode", void 0);
|
|
88
|
+
__decorate([
|
|
89
|
+
(0, class_validator_1.IsEnum)(ReceptionMethod_1.ReceptionMethod),
|
|
90
|
+
__metadata("design:type", String)
|
|
91
|
+
], ProviderCostAssignmentUpdate.prototype, "receptionMethod", void 0);
|
|
92
|
+
__decorate([
|
|
93
|
+
(0, class_validator_1.IsOptional)(),
|
|
94
|
+
(0, class_validator_1.Matches)(exports.PROVIDER_COST_GROUP_ID_PATTERN),
|
|
95
|
+
__metadata("design:type", String)
|
|
96
|
+
], ProviderCostAssignmentUpdate.prototype, "groupId", void 0);
|
|
97
|
+
/**
|
|
98
|
+
* Body de PUT /backoffice/config/provider-costs/{countryISO}. Todo opcional.
|
|
99
|
+
* `groups` reemplaza la lista completa; `assignments` solo toca los payer × método que trae.
|
|
100
|
+
* Response: ProviderCostCountryItem.
|
|
101
|
+
*/
|
|
102
|
+
class ProviderCostUpdateRequest {
|
|
103
|
+
}
|
|
104
|
+
exports.ProviderCostUpdateRequest = ProviderCostUpdateRequest;
|
|
105
|
+
__decorate([
|
|
106
|
+
(0, class_validator_1.IsOptional)(),
|
|
107
|
+
(0, class_validator_1.IsInt)(),
|
|
108
|
+
(0, class_validator_1.Min)(1),
|
|
109
|
+
(0, class_validator_1.Max)(exports.PROVIDER_COST_TIER_COUNT),
|
|
110
|
+
__metadata("design:type", Number)
|
|
111
|
+
], ProviderCostUpdateRequest.prototype, "costTier", void 0);
|
|
112
|
+
__decorate([
|
|
113
|
+
(0, class_validator_1.IsOptional)(),
|
|
114
|
+
(0, class_validator_1.IsArray)(),
|
|
115
|
+
(0, class_validator_1.ArrayMaxSize)(10),
|
|
116
|
+
(0, class_validator_1.ValidateNested)({ each: true }),
|
|
117
|
+
(0, class_transformer_1.Type)(() => ProviderCostGroup),
|
|
118
|
+
__metadata("design:type", Array)
|
|
119
|
+
], ProviderCostUpdateRequest.prototype, "groups", void 0);
|
|
120
|
+
__decorate([
|
|
121
|
+
(0, class_validator_1.IsOptional)(),
|
|
122
|
+
(0, class_validator_1.IsArray)(),
|
|
123
|
+
(0, class_validator_1.ArrayMaxSize)(300),
|
|
124
|
+
(0, class_validator_1.ValidateNested)({ each: true }),
|
|
125
|
+
(0, class_transformer_1.Type)(() => ProviderCostAssignmentUpdate),
|
|
126
|
+
__metadata("design:type", Array)
|
|
127
|
+
], ProviderCostUpdateRequest.prototype, "assignments", void 0);
|
|
@@ -49,6 +49,7 @@ export * from "./RemittancePricingTable";
|
|
|
49
49
|
export * from "./RemittanceExceptionCatalog";
|
|
50
50
|
export * from "./RemittanceCountryConfig";
|
|
51
51
|
export * from "./RemittancePayerConfig";
|
|
52
|
+
export * from "./RemittanceProviderCost";
|
|
52
53
|
export * from "./RemittanceFavoriteItem";
|
|
53
54
|
export * from "./RemittanceFavoriteListResponse";
|
|
54
55
|
export * from "./RemittanceBackofficeCancelCloseRequest";
|
|
@@ -65,6 +65,7 @@ __exportStar(require("./RemittancePricingTable"), exports);
|
|
|
65
65
|
__exportStar(require("./RemittanceExceptionCatalog"), exports);
|
|
66
66
|
__exportStar(require("./RemittanceCountryConfig"), exports);
|
|
67
67
|
__exportStar(require("./RemittancePayerConfig"), exports);
|
|
68
|
+
__exportStar(require("./RemittanceProviderCost"), exports);
|
|
68
69
|
__exportStar(require("./RemittanceFavoriteItem"), exports);
|
|
69
70
|
__exportStar(require("./RemittanceFavoriteListResponse"), exports);
|
|
70
71
|
__exportStar(require("./RemittanceBackofficeCancelCloseRequest"), exports);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { RemittanceCorridor } from "../../enums/RemittanceCorridor";
|
|
2
|
+
import { ReceptionMethod } from "../../enums/ReceptionMethod";
|
|
2
3
|
/**
|
|
3
4
|
* Request del resolver de send-time (Fase B). El connector lo llama por cada
|
|
4
5
|
* quote/preview/pay. `code` = promo tecleada por el cliente en la app (opcional).
|
|
@@ -8,6 +9,9 @@ export declare class PricingResolveRequest {
|
|
|
8
9
|
corridor: RemittanceCorridor;
|
|
9
10
|
amountUSD: number;
|
|
10
11
|
code?: string;
|
|
12
|
+
/** Payer del beneficiario. Con receptionMethod define el grupo de costo (costo esperado y ajuste de fee). */
|
|
13
|
+
payerCode?: string;
|
|
14
|
+
receptionMethod?: ReceptionMethod;
|
|
11
15
|
}
|
|
12
16
|
/** Regla BLOCK que rechazó la tx (VALIDATION o TX_AMOUNT con acción BLOCK). */
|
|
13
17
|
export declare class PricingResolveBlocked {
|
|
@@ -32,4 +36,12 @@ export declare class PricingResolveResponse {
|
|
|
32
36
|
/** Mínimo de envío del país destino (RemittanceCountryConfig_GT). El connector rechaza montos menores. */
|
|
33
37
|
minAmountUSD: number;
|
|
34
38
|
blocked?: PricingResolveBlocked;
|
|
39
|
+
/** Grupo de costo del payer × método. Ausente = sin grupo o sin payer en el request. */
|
|
40
|
+
costGroup?: string;
|
|
41
|
+
/** Tramo de volumen vigente del país con el que se calculó el costo (1..3). */
|
|
42
|
+
costTier?: number;
|
|
43
|
+
/** Costo UniTeller esperado en USD (Exhibit A). Ausente si no hay grupo o tramo. */
|
|
44
|
+
unitellerCostExpected?: number;
|
|
45
|
+
/** Ajuste en USD del grupo que ya está sumado en `serviceFee` (antes de promos y topes). */
|
|
46
|
+
groupFeeAdjustment?: number;
|
|
35
47
|
}
|
|
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.PricingResolveResponse = exports.PricingResolveBlocked = exports.PricingResolveRequest = void 0;
|
|
13
13
|
const class_validator_1 = require("class-validator");
|
|
14
14
|
const RemittanceCorridor_1 = require("../../enums/RemittanceCorridor");
|
|
15
|
+
const ReceptionMethod_1 = require("../../enums/ReceptionMethod");
|
|
15
16
|
/**
|
|
16
17
|
* Request del resolver de send-time (Fase B). El connector lo llama por cada
|
|
17
18
|
* quote/preview/pay. `code` = promo tecleada por el cliente en la app (opcional).
|
|
@@ -38,6 +39,17 @@ __decorate([
|
|
|
38
39
|
(0, class_validator_1.Length)(3, 30),
|
|
39
40
|
__metadata("design:type", String)
|
|
40
41
|
], PricingResolveRequest.prototype, "code", void 0);
|
|
42
|
+
__decorate([
|
|
43
|
+
(0, class_validator_1.IsOptional)(),
|
|
44
|
+
(0, class_validator_1.IsString)(),
|
|
45
|
+
(0, class_validator_1.Length)(1, 40),
|
|
46
|
+
__metadata("design:type", String)
|
|
47
|
+
], PricingResolveRequest.prototype, "payerCode", void 0);
|
|
48
|
+
__decorate([
|
|
49
|
+
(0, class_validator_1.IsOptional)(),
|
|
50
|
+
(0, class_validator_1.IsEnum)(ReceptionMethod_1.ReceptionMethod),
|
|
51
|
+
__metadata("design:type", String)
|
|
52
|
+
], PricingResolveRequest.prototype, "receptionMethod", void 0);
|
|
41
53
|
/** Regla BLOCK que rechazó la tx (VALIDATION o TX_AMOUNT con acción BLOCK). */
|
|
42
54
|
class PricingResolveBlocked {
|
|
43
55
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RemittanceCorridor } from "../../enums/RemittanceCorridor";
|
|
2
2
|
import { PromotionKind } from "../../enums/PromotionKind";
|
|
3
|
+
import { ReceptionMethod } from "../../enums/ReceptionMethod";
|
|
3
4
|
/**
|
|
4
5
|
* Request del schedule de precio por corredor (Fase B — F2 app). El connector lo
|
|
5
6
|
* llama (passthrough desde benefits) para mostrarle al usuario la tabla de tramos de
|
|
@@ -8,6 +9,9 @@ import { PromotionKind } from "../../enums/PromotionKind";
|
|
|
8
9
|
export declare class PricingScheduleRequest {
|
|
9
10
|
directoryId: string;
|
|
10
11
|
corridor: RemittanceCorridor;
|
|
12
|
+
/** Payer y método elegidos: los fees de los tramos incluyen el ajuste de su grupo. Ausentes = fee base. */
|
|
13
|
+
payerCode?: string;
|
|
14
|
+
receptionMethod?: ReceptionMethod;
|
|
11
15
|
}
|
|
12
16
|
/** Un tramo del schedule. `serviceFee` YA refleja la promo automática aplicada (D5). */
|
|
13
17
|
export declare class PricingScheduleTier {
|
|
@@ -14,6 +14,7 @@ const class_transformer_1 = require("class-transformer");
|
|
|
14
14
|
const class_validator_1 = require("class-validator");
|
|
15
15
|
const RemittanceCorridor_1 = require("../../enums/RemittanceCorridor");
|
|
16
16
|
const PromotionKind_1 = require("../../enums/PromotionKind");
|
|
17
|
+
const ReceptionMethod_1 = require("../../enums/ReceptionMethod");
|
|
17
18
|
/**
|
|
18
19
|
* Request del schedule de precio por corredor (Fase B — F2 app). El connector lo
|
|
19
20
|
* llama (passthrough desde benefits) para mostrarle al usuario la tabla de tramos de
|
|
@@ -30,6 +31,16 @@ __decorate([
|
|
|
30
31
|
(0, class_validator_1.IsEnum)(RemittanceCorridor_1.RemittanceCorridor),
|
|
31
32
|
__metadata("design:type", String)
|
|
32
33
|
], PricingScheduleRequest.prototype, "corridor", void 0);
|
|
34
|
+
__decorate([
|
|
35
|
+
(0, class_validator_1.IsOptional)(),
|
|
36
|
+
(0, class_validator_1.IsString)(),
|
|
37
|
+
__metadata("design:type", String)
|
|
38
|
+
], PricingScheduleRequest.prototype, "payerCode", void 0);
|
|
39
|
+
__decorate([
|
|
40
|
+
(0, class_validator_1.IsOptional)(),
|
|
41
|
+
(0, class_validator_1.IsEnum)(ReceptionMethod_1.ReceptionMethod),
|
|
42
|
+
__metadata("design:type", String)
|
|
43
|
+
], PricingScheduleRequest.prototype, "receptionMethod", void 0);
|
|
33
44
|
/** Un tramo del schedule. `serviceFee` YA refleja la promo automática aplicada (D5). */
|
|
34
45
|
class PricingScheduleTier {
|
|
35
46
|
}
|
|
@@ -202,6 +202,12 @@ export interface CommissionRuleInput {
|
|
|
202
202
|
countBy?: CommissionCountByEnum;
|
|
203
203
|
/** Cuándo se paga lo que gana. Ausente = `ON_CUT`. */
|
|
204
204
|
payTiming?: CommissionPayTimingEnum;
|
|
205
|
+
/**
|
|
206
|
+
* Parte del bono por venta que se paga al registrar la venta, en puntos base (100–9900); el resto se
|
|
207
|
+
* paga en `payTiming`. Solo en reglas cuya única palanca es el bono por venta y con `payTiming`
|
|
208
|
+
* `ON_CUT` o `MONTHLY`. Ausente o `null` = sin adelanto.
|
|
209
|
+
*/
|
|
210
|
+
onSaleAdvanceBps?: number | null;
|
|
205
211
|
}
|
|
206
212
|
/** `POST /backoffice/commissions/rules` — la regla nace en borrador. */
|
|
207
213
|
export type CreateRuleRequest = CommissionRuleInput;
|
|
@@ -387,6 +393,12 @@ export interface CommissionRuleView {
|
|
|
387
393
|
countBy?: CommissionCountByEnum;
|
|
388
394
|
/** Cuándo se paga lo que gana. Ausente = `ON_CUT`. */
|
|
389
395
|
payTiming?: CommissionPayTimingEnum;
|
|
396
|
+
/**
|
|
397
|
+
* Parte del bono por venta que se paga al registrar la venta, en puntos base (100–9900); el resto se
|
|
398
|
+
* paga en `payTiming`. Solo en reglas cuya única palanca es el bono por venta y con `payTiming`
|
|
399
|
+
* `ON_CUT` o `MONTHLY`. Ausente o `null` = sin adelanto.
|
|
400
|
+
*/
|
|
401
|
+
onSaleAdvanceBps?: number | null;
|
|
390
402
|
}
|
|
391
403
|
/** Lo pagado en varios cortes. */
|
|
392
404
|
export interface MyCommissionsTotals {
|
|
@@ -79,6 +79,12 @@ export interface CommissionRule {
|
|
|
79
79
|
countBy?: CommissionCountByEnum;
|
|
80
80
|
/** Cuándo se paga lo que gana. Ausente = `ON_CUT`. */
|
|
81
81
|
payTiming?: CommissionPayTimingEnum;
|
|
82
|
+
/**
|
|
83
|
+
* Parte del bono por venta que se paga al registrar la venta, en puntos base (100–9900); el resto se
|
|
84
|
+
* paga en `payTiming`. Solo en reglas cuya única palanca es el bono por venta y con `payTiming`
|
|
85
|
+
* `ON_CUT` o `MONTHLY`. Ausente o `null` = sin adelanto.
|
|
86
|
+
*/
|
|
87
|
+
onSaleAdvanceBps?: number | null;
|
|
82
88
|
/** Sube en cada guardado. */
|
|
83
89
|
version: number;
|
|
84
90
|
/** La versión que está en el plan vigente. `null` si nunca se publicó. */
|
package/package.json
CHANGED
|
@@ -102,4 +102,15 @@ export class RemittanceBackofficeTransaction {
|
|
|
102
102
|
reconStatus?: RemittanceReconStatus;
|
|
103
103
|
/** Detalle textual de los diffs cuando reconStatus !== OK. */
|
|
104
104
|
reconDiffDetail?: string;
|
|
105
|
+
|
|
106
|
+
// ─── Costo esperado al enviar (Exhibit A, foto del confirm) ─────────
|
|
107
|
+
|
|
108
|
+
/** Costo UniTeller esperado en USD según el grupo y el tramo vigente al enviar. */
|
|
109
|
+
unitellerCostExpected?: number;
|
|
110
|
+
/** Grupo de costo del payer × método al enviar. */
|
|
111
|
+
costGroup?: string;
|
|
112
|
+
/** Tramo de volumen vigente al enviar (1..3). */
|
|
113
|
+
costTier?: number;
|
|
114
|
+
/** Ajuste del grupo que se sumó al fee de esta remesa. */
|
|
115
|
+
groupFeeAdjustment?: number;
|
|
105
116
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { IsBoolean, IsOptional, IsString, Length } from "class-validator";
|
|
2
2
|
import { ReceptionMethod } from "../enums/ReceptionMethod";
|
|
3
|
+
import { CostGroupByMethod } from "./RemittanceProviderCost";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* DTOs de la administración de payers desde el backoffice (v1: enabled + override de nombre).
|
|
@@ -21,6 +22,8 @@ export class RemittancePayerConfigItem {
|
|
|
21
22
|
configured!: boolean;
|
|
22
23
|
/** Logo de UniTeller, solo lectura (identificación visual en la lista). */
|
|
23
24
|
logoUrl?: string;
|
|
25
|
+
/** Grupo de costo UniTeller de cada método (solo lectura aquí; se edita en Costos UniTeller). */
|
|
26
|
+
costGroupByMethod?: CostGroupByMethod;
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
/** Response de GET /backoffice/config/payers (config chica, sin paginación). */
|
|
@@ -9,12 +9,15 @@ import {
|
|
|
9
9
|
IsOptional,
|
|
10
10
|
IsString,
|
|
11
11
|
Length,
|
|
12
|
+
Matches,
|
|
12
13
|
Max,
|
|
13
14
|
MaxLength,
|
|
14
15
|
Min,
|
|
15
16
|
ValidateNested,
|
|
16
17
|
} from "class-validator";
|
|
17
18
|
import { RemittanceCorridor } from "../enums/RemittanceCorridor";
|
|
19
|
+
import { ReceptionMethod } from "../enums/ReceptionMethod";
|
|
20
|
+
import { PROVIDER_COST_GROUP_ID_PATTERN } from "./RemittanceProviderCost";
|
|
18
21
|
|
|
19
22
|
/**
|
|
20
23
|
* DTOs de Precio Base (Dashboard Ops · Variables Operativas §1).
|
|
@@ -56,6 +59,19 @@ export class PricingTier {
|
|
|
56
59
|
effectiveFrom!: string;
|
|
57
60
|
}
|
|
58
61
|
|
|
62
|
+
/** Ajuste en USD que se suma al fee del tramo cuando el payer × método cae en ese grupo de costo. */
|
|
63
|
+
export class PricingGroupFeeAdjustment {
|
|
64
|
+
@IsString()
|
|
65
|
+
@Matches(PROVIDER_COST_GROUP_ID_PATTERN)
|
|
66
|
+
groupId!: string;
|
|
67
|
+
|
|
68
|
+
/** CON SIGNO: negativo descuenta. El fee final nunca baja de 0. */
|
|
69
|
+
@IsNumber({ maxDecimalPlaces: 2 })
|
|
70
|
+
@Min(-100)
|
|
71
|
+
@Max(100)
|
|
72
|
+
adjustmentUSD!: number;
|
|
73
|
+
}
|
|
74
|
+
|
|
59
75
|
/** Body de POST /backoffice/pricing/base. */
|
|
60
76
|
export class CreatePricingRequest {
|
|
61
77
|
@IsEnum(RemittanceCorridor)
|
|
@@ -87,6 +103,14 @@ export class CreatePricingRequest {
|
|
|
87
103
|
@IsString()
|
|
88
104
|
@MaxLength(500)
|
|
89
105
|
notes?: string;
|
|
106
|
+
|
|
107
|
+
/** Ajuste del fee por grupo de costo del payer. Ausente = conserva los actuales; [] = sin ajustes. */
|
|
108
|
+
@IsOptional()
|
|
109
|
+
@IsArray()
|
|
110
|
+
@ArrayMaxSize(10)
|
|
111
|
+
@ValidateNested({ each: true })
|
|
112
|
+
@Type(() => PricingGroupFeeAdjustment)
|
|
113
|
+
groupFeeAdjustments?: PricingGroupFeeAdjustment[];
|
|
90
114
|
}
|
|
91
115
|
|
|
92
116
|
/** Body de PUT /backoffice/pricing/base/{id} (reemplazo completo; corridor/segmentId inmutables). */
|
|
@@ -112,6 +136,14 @@ export class UpdatePricingRequest {
|
|
|
112
136
|
@IsString()
|
|
113
137
|
@MaxLength(500)
|
|
114
138
|
notes?: string;
|
|
139
|
+
|
|
140
|
+
/** Ajuste del fee por grupo de costo del payer. Ausente = conserva los actuales; [] = sin ajustes. */
|
|
141
|
+
@IsOptional()
|
|
142
|
+
@IsArray()
|
|
143
|
+
@ArrayMaxSize(10)
|
|
144
|
+
@ValidateNested({ each: true })
|
|
145
|
+
@Type(() => PricingGroupFeeAdjustment)
|
|
146
|
+
groupFeeAdjustments?: PricingGroupFeeAdjustment[];
|
|
115
147
|
}
|
|
116
148
|
|
|
117
149
|
/** Combinación completa (response de list/create/update). */
|
|
@@ -125,6 +157,8 @@ export class PricingCombination {
|
|
|
125
157
|
tramos!: PricingTier[];
|
|
126
158
|
/** # promos activas que aplican a la combinación. 0 hasta que exista Promociones. */
|
|
127
159
|
promosCount!: number;
|
|
160
|
+
/** Ajuste del fee por grupo de costo. Ausente o [] = sin ajustes. */
|
|
161
|
+
groupFeeAdjustments?: PricingGroupFeeAdjustment[];
|
|
128
162
|
name!: string | null;
|
|
129
163
|
notes!: string | null;
|
|
130
164
|
createdAt!: string;
|
|
@@ -166,6 +200,24 @@ export class SimulatePricingRequest {
|
|
|
166
200
|
@ValidateNested({ each: true })
|
|
167
201
|
@Type(() => PricingTier)
|
|
168
202
|
tramos!: PricingTier[];
|
|
203
|
+
|
|
204
|
+
/** Ajustes del panel (pueden no estar guardados). Solo aplican si viene payer y método. */
|
|
205
|
+
@IsOptional()
|
|
206
|
+
@IsArray()
|
|
207
|
+
@ArrayMaxSize(10)
|
|
208
|
+
@ValidateNested({ each: true })
|
|
209
|
+
@Type(() => PricingGroupFeeAdjustment)
|
|
210
|
+
groupFeeAdjustments?: PricingGroupFeeAdjustment[];
|
|
211
|
+
|
|
212
|
+
/** Payer y método opcionales: con ellos la simulación suma el ajuste del grupo y calcula costo y margen. */
|
|
213
|
+
@IsOptional()
|
|
214
|
+
@IsString()
|
|
215
|
+
@Length(1, 40)
|
|
216
|
+
payerCode?: string;
|
|
217
|
+
|
|
218
|
+
@IsOptional()
|
|
219
|
+
@IsEnum(ReceptionMethod)
|
|
220
|
+
receptionMethod?: ReceptionMethod;
|
|
169
221
|
}
|
|
170
222
|
|
|
171
223
|
export class SimulatePricingResponse {
|
|
@@ -185,6 +237,14 @@ export class SimulatePricingResponse {
|
|
|
185
237
|
revenueUsd!: number;
|
|
186
238
|
/** ISO del quote. */
|
|
187
239
|
asOf!: string;
|
|
240
|
+
/** Grupo de costo del payer × método simulado. */
|
|
241
|
+
costGroup?: string;
|
|
242
|
+
/** Ajuste del grupo ya sumado en serviceFee. */
|
|
243
|
+
groupFeeAdjustment?: number;
|
|
244
|
+
/** Costo UniTeller esperado (Exhibit A, tramo vigente del país). */
|
|
245
|
+
unitellerCostExpected?: number;
|
|
246
|
+
/** revenueUsd − unitellerCostExpected. */
|
|
247
|
+
netMarginUsd?: number;
|
|
188
248
|
}
|
|
189
249
|
|
|
190
250
|
/** Response de GET /backoffice/pricing/wholesale?corridor= (rb passthrough del connector). */
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { Type } from "class-transformer";
|
|
2
|
+
import {
|
|
3
|
+
ArrayMaxSize,
|
|
4
|
+
ArrayMinSize,
|
|
5
|
+
IsArray,
|
|
6
|
+
IsEnum,
|
|
7
|
+
IsInt,
|
|
8
|
+
IsNumber,
|
|
9
|
+
IsOptional,
|
|
10
|
+
IsString,
|
|
11
|
+
Length,
|
|
12
|
+
Matches,
|
|
13
|
+
Max,
|
|
14
|
+
Min,
|
|
15
|
+
ValidateNested,
|
|
16
|
+
} from "class-validator";
|
|
17
|
+
import { ReceptionMethod } from "../enums/ReceptionMethod";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* DTOs de Costos UniTeller (Exhibit A del contrato): lo que UniTeller le cobra a Fiado por remesa.
|
|
21
|
+
* Por país hay grupos con un precio por tramo de volumen y un tramo vigente; cada payer × método
|
|
22
|
+
* cae en un grupo. Se guarda en RemittanceCountryConfig_GT (grupos y tramo) y en
|
|
23
|
+
* RemittancePayerConfig_GT (grupo por método). Dueño: remittance-business.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/** Cantidad de tramos de volumen del Exhibit A. */
|
|
27
|
+
export const PROVIDER_COST_TIER_COUNT = 3;
|
|
28
|
+
|
|
29
|
+
/** Id de grupo: una letra mayúscula (A, B, C…). */
|
|
30
|
+
export const PROVIDER_COST_GROUP_ID_PATTERN = /^[A-Z]$/;
|
|
31
|
+
|
|
32
|
+
/** Grupo de costo: un precio en USD por tramo de volumen (posición 0 = tramo 1). */
|
|
33
|
+
export class ProviderCostGroup {
|
|
34
|
+
@IsString()
|
|
35
|
+
@Matches(PROVIDER_COST_GROUP_ID_PATTERN)
|
|
36
|
+
groupId!: string;
|
|
37
|
+
|
|
38
|
+
@IsArray()
|
|
39
|
+
@ArrayMinSize(PROVIDER_COST_TIER_COUNT)
|
|
40
|
+
@ArrayMaxSize(PROVIDER_COST_TIER_COUNT)
|
|
41
|
+
@IsNumber({ maxDecimalPlaces: 2 }, { each: true })
|
|
42
|
+
@Min(0, { each: true })
|
|
43
|
+
@Max(50, { each: true })
|
|
44
|
+
costsUSD!: number[];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Grupo de cada método de un payer. Método ausente = sin grupo (sin costo esperado ni ajuste de fee). */
|
|
48
|
+
export class CostGroupByMethod {
|
|
49
|
+
@IsOptional()
|
|
50
|
+
@Matches(PROVIDER_COST_GROUP_ID_PATTERN)
|
|
51
|
+
ACCOUNT_CREDIT?: string;
|
|
52
|
+
|
|
53
|
+
@IsOptional()
|
|
54
|
+
@Matches(PROVIDER_COST_GROUP_ID_PATTERN)
|
|
55
|
+
CASH_PICKUP?: string;
|
|
56
|
+
|
|
57
|
+
@IsOptional()
|
|
58
|
+
@Matches(PROVIDER_COST_GROUP_ID_PATTERN)
|
|
59
|
+
WALLET?: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Un payer × método del catálogo del país, con su grupo si tiene. */
|
|
63
|
+
export class ProviderCostAssignment {
|
|
64
|
+
payerCode!: string;
|
|
65
|
+
/** Nombre efectivo del payer (override de Ops o el de UniTeller). */
|
|
66
|
+
name!: string;
|
|
67
|
+
receptionMethod!: ReceptionMethod;
|
|
68
|
+
/** Ausente = sin grupo. */
|
|
69
|
+
groupId?: string;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Volumen del mes calendario en curso (UTC), sin canceladas. Guía para elegir el tramo vigente. */
|
|
73
|
+
export class ProviderCostMonthVolume {
|
|
74
|
+
txCount!: number;
|
|
75
|
+
volumeUSD!: number;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Costos de un país (vista de backoffice). */
|
|
79
|
+
export class ProviderCostCountryItem {
|
|
80
|
+
countryISO!: string;
|
|
81
|
+
name!: string;
|
|
82
|
+
/** Tramo vigente 1..3; null = sin configurar. */
|
|
83
|
+
costTier!: number | null;
|
|
84
|
+
groups!: ProviderCostGroup[];
|
|
85
|
+
/** Todos los payer × método del catálogo del país, con o sin grupo. */
|
|
86
|
+
assignments!: ProviderCostAssignment[];
|
|
87
|
+
/** Ausente si no se pudo calcular. */
|
|
88
|
+
monthVolume?: ProviderCostMonthVolume;
|
|
89
|
+
updatedAt?: string;
|
|
90
|
+
updatedBy?: string;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Response de GET /backoffice/config/provider-costs. */
|
|
94
|
+
export class ProviderCostListResponse {
|
|
95
|
+
/** Etiquetas de los tramos de volumen del contrato, en orden (tramo 1 primero). */
|
|
96
|
+
tierLabels!: string[];
|
|
97
|
+
items!: ProviderCostCountryItem[];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Cambio de grupo de un payer × método. groupId null o ausente = quitarlo de su grupo. */
|
|
101
|
+
export class ProviderCostAssignmentUpdate {
|
|
102
|
+
@IsString()
|
|
103
|
+
@Length(1, 40)
|
|
104
|
+
payerCode!: string;
|
|
105
|
+
|
|
106
|
+
@IsEnum(ReceptionMethod)
|
|
107
|
+
receptionMethod!: ReceptionMethod;
|
|
108
|
+
|
|
109
|
+
@IsOptional()
|
|
110
|
+
@Matches(PROVIDER_COST_GROUP_ID_PATTERN)
|
|
111
|
+
groupId?: string | null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Body de PUT /backoffice/config/provider-costs/{countryISO}. Todo opcional.
|
|
116
|
+
* `groups` reemplaza la lista completa; `assignments` solo toca los payer × método que trae.
|
|
117
|
+
* Response: ProviderCostCountryItem.
|
|
118
|
+
*/
|
|
119
|
+
export class ProviderCostUpdateRequest {
|
|
120
|
+
@IsOptional()
|
|
121
|
+
@IsInt()
|
|
122
|
+
@Min(1)
|
|
123
|
+
@Max(PROVIDER_COST_TIER_COUNT)
|
|
124
|
+
costTier?: number;
|
|
125
|
+
|
|
126
|
+
@IsOptional()
|
|
127
|
+
@IsArray()
|
|
128
|
+
@ArrayMaxSize(10)
|
|
129
|
+
@ValidateNested({ each: true })
|
|
130
|
+
@Type(() => ProviderCostGroup)
|
|
131
|
+
groups?: ProviderCostGroup[];
|
|
132
|
+
|
|
133
|
+
@IsOptional()
|
|
134
|
+
@IsArray()
|
|
135
|
+
@ArrayMaxSize(300)
|
|
136
|
+
@ValidateNested({ each: true })
|
|
137
|
+
@Type(() => ProviderCostAssignmentUpdate)
|
|
138
|
+
assignments?: ProviderCostAssignmentUpdate[];
|
|
139
|
+
}
|
|
@@ -49,6 +49,7 @@ export * from "./RemittancePricingTable";
|
|
|
49
49
|
export * from "./RemittanceExceptionCatalog";
|
|
50
50
|
export * from "./RemittanceCountryConfig";
|
|
51
51
|
export * from "./RemittancePayerConfig";
|
|
52
|
+
export * from "./RemittanceProviderCost";
|
|
52
53
|
export * from "./RemittanceFavoriteItem";
|
|
53
54
|
export * from "./RemittanceFavoriteListResponse";
|
|
54
55
|
export * from "./RemittanceBackofficeCancelCloseRequest";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { IsEnum, IsNumber, IsOptional, IsString, IsUUID, Length, Min } from "class-validator";
|
|
2
2
|
import { RemittanceCorridor } from "../../enums/RemittanceCorridor";
|
|
3
|
+
import { ReceptionMethod } from "../../enums/ReceptionMethod";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Request del resolver de send-time (Fase B). El connector lo llama por cada
|
|
@@ -20,6 +21,16 @@ export class PricingResolveRequest {
|
|
|
20
21
|
@IsString()
|
|
21
22
|
@Length(3, 30)
|
|
22
23
|
code?: string;
|
|
24
|
+
|
|
25
|
+
/** Payer del beneficiario. Con receptionMethod define el grupo de costo (costo esperado y ajuste de fee). */
|
|
26
|
+
@IsOptional()
|
|
27
|
+
@IsString()
|
|
28
|
+
@Length(1, 40)
|
|
29
|
+
payerCode?: string;
|
|
30
|
+
|
|
31
|
+
@IsOptional()
|
|
32
|
+
@IsEnum(ReceptionMethod)
|
|
33
|
+
receptionMethod?: ReceptionMethod;
|
|
23
34
|
}
|
|
24
35
|
|
|
25
36
|
/** Regla BLOCK que rechazó la tx (VALIDATION o TX_AMOUNT con acción BLOCK). */
|
|
@@ -46,4 +57,12 @@ export class PricingResolveResponse {
|
|
|
46
57
|
/** Mínimo de envío del país destino (RemittanceCountryConfig_GT). El connector rechaza montos menores. */
|
|
47
58
|
minAmountUSD!: number;
|
|
48
59
|
blocked?: PricingResolveBlocked;
|
|
60
|
+
/** Grupo de costo del payer × método. Ausente = sin grupo o sin payer en el request. */
|
|
61
|
+
costGroup?: string;
|
|
62
|
+
/** Tramo de volumen vigente del país con el que se calculó el costo (1..3). */
|
|
63
|
+
costTier?: number;
|
|
64
|
+
/** Costo UniTeller esperado en USD (Exhibit A). Ausente si no hay grupo o tramo. */
|
|
65
|
+
unitellerCostExpected?: number;
|
|
66
|
+
/** Ajuste en USD del grupo que ya está sumado en `serviceFee` (antes de promos y topes). */
|
|
67
|
+
groupFeeAdjustment?: number;
|
|
49
68
|
}
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
} from "class-validator";
|
|
13
13
|
import { RemittanceCorridor } from "../../enums/RemittanceCorridor";
|
|
14
14
|
import { PromotionKind } from "../../enums/PromotionKind";
|
|
15
|
+
import { ReceptionMethod } from "../../enums/ReceptionMethod";
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Request del schedule de precio por corredor (Fase B — F2 app). El connector lo
|
|
@@ -24,6 +25,15 @@ export class PricingScheduleRequest {
|
|
|
24
25
|
|
|
25
26
|
@IsEnum(RemittanceCorridor)
|
|
26
27
|
corridor!: RemittanceCorridor;
|
|
28
|
+
|
|
29
|
+
/** Payer y método elegidos: los fees de los tramos incluyen el ajuste de su grupo. Ausentes = fee base. */
|
|
30
|
+
@IsOptional()
|
|
31
|
+
@IsString()
|
|
32
|
+
payerCode?: string;
|
|
33
|
+
|
|
34
|
+
@IsOptional()
|
|
35
|
+
@IsEnum(ReceptionMethod)
|
|
36
|
+
receptionMethod?: ReceptionMethod;
|
|
27
37
|
}
|
|
28
38
|
|
|
29
39
|
/** Un tramo del schedule. `serviceFee` YA refleja la promo automática aplicada (D5). */
|
|
@@ -264,6 +264,12 @@ export interface CommissionRuleInput {
|
|
|
264
264
|
countBy?: CommissionCountByEnum;
|
|
265
265
|
/** Cuándo se paga lo que gana. Ausente = `ON_CUT`. */
|
|
266
266
|
payTiming?: CommissionPayTimingEnum;
|
|
267
|
+
/**
|
|
268
|
+
* Parte del bono por venta que se paga al registrar la venta, en puntos base (100–9900); el resto se
|
|
269
|
+
* paga en `payTiming`. Solo en reglas cuya única palanca es el bono por venta y con `payTiming`
|
|
270
|
+
* `ON_CUT` o `MONTHLY`. Ausente o `null` = sin adelanto.
|
|
271
|
+
*/
|
|
272
|
+
onSaleAdvanceBps?: number | null;
|
|
267
273
|
}
|
|
268
274
|
|
|
269
275
|
/** `POST /backoffice/commissions/rules` — la regla nace en borrador. */
|
|
@@ -466,6 +472,12 @@ export interface CommissionRuleView {
|
|
|
466
472
|
countBy?: CommissionCountByEnum;
|
|
467
473
|
/** Cuándo se paga lo que gana. Ausente = `ON_CUT`. */
|
|
468
474
|
payTiming?: CommissionPayTimingEnum;
|
|
475
|
+
/**
|
|
476
|
+
* Parte del bono por venta que se paga al registrar la venta, en puntos base (100–9900); el resto se
|
|
477
|
+
* paga en `payTiming`. Solo en reglas cuya única palanca es el bono por venta y con `payTiming`
|
|
478
|
+
* `ON_CUT` o `MONTHLY`. Ausente o `null` = sin adelanto.
|
|
479
|
+
*/
|
|
480
|
+
onSaleAdvanceBps?: number | null;
|
|
469
481
|
}
|
|
470
482
|
|
|
471
483
|
/** Lo pagado en varios cortes. */
|
|
@@ -88,6 +88,12 @@ export interface CommissionRule {
|
|
|
88
88
|
countBy?: CommissionCountByEnum;
|
|
89
89
|
/** Cuándo se paga lo que gana. Ausente = `ON_CUT`. */
|
|
90
90
|
payTiming?: CommissionPayTimingEnum;
|
|
91
|
+
/**
|
|
92
|
+
* Parte del bono por venta que se paga al registrar la venta, en puntos base (100–9900); el resto se
|
|
93
|
+
* paga en `payTiming`. Solo en reglas cuya única palanca es el bono por venta y con `payTiming`
|
|
94
|
+
* `ON_CUT` o `MONTHLY`. Ausente o `null` = sin adelanto.
|
|
95
|
+
*/
|
|
96
|
+
onSaleAdvanceBps?: number | null;
|
|
91
97
|
/** Sube en cada guardado. */
|
|
92
98
|
version: number;
|
|
93
99
|
/** La versión que está en el plan vigente. `null` si nunca se publicó. */
|