@fiado/type-kit 3.576.0 → 3.578.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/retailWizard/customerTableShapes.test.ts +22 -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/retailCustomer/dtos/requests/UpsertCustomerFromKycRequest.d.ts +2 -0
- package/bin/retailCustomer/dtos/requests/UpsertCustomerFromKycRequest.js +6 -0
- package/bin/retailWizard/dtos/responses/BackofficeCustomerTableResponse.d.ts +18 -5
- 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/retailCustomer/dtos/requests/UpsertCustomerFromKycRequest.ts +6 -0
- package/src/retailWizard/dtos/responses/BackofficeCustomerTableResponse.ts +19 -5
|
@@ -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
|
+
});
|
|
@@ -12,9 +12,12 @@ describe('BackofficeCustomerTableResponse', () => {
|
|
|
12
12
|
to: '2026-10-07T18:00:00.000Z',
|
|
13
13
|
nextToken: 'abc',
|
|
14
14
|
sources: { sales: SellerTableSourceStatusEnum.OK, credit: SellerTableSourceStatusEnum.UNAVAILABLE },
|
|
15
|
+
counts: { withSales: 1, accountOnly: 1 },
|
|
15
16
|
items: [
|
|
16
17
|
{
|
|
17
18
|
retailCustomerId: 'RC-1',
|
|
19
|
+
accountOnly: false,
|
|
20
|
+
originStoreId: 'ST-1',
|
|
18
21
|
name: 'Ana',
|
|
19
22
|
phone: null,
|
|
20
23
|
purchaseCount: 2,
|
|
@@ -28,9 +31,28 @@ describe('BackofficeCustomerTableResponse', () => {
|
|
|
28
31
|
skLevel: ClientLevelEnum.GOLD,
|
|
29
32
|
activeCreditsCount: null,
|
|
30
33
|
},
|
|
34
|
+
{
|
|
35
|
+
retailCustomerId: 'RC-2',
|
|
36
|
+
accountOnly: true,
|
|
37
|
+
originStoreId: 'ST-1',
|
|
38
|
+
name: 'Luz',
|
|
39
|
+
phone: null,
|
|
40
|
+
purchaseCount: 0,
|
|
41
|
+
totalSpentCents: 0,
|
|
42
|
+
averageTicketCents: null,
|
|
43
|
+
firstPurchaseAt: null,
|
|
44
|
+
lastPurchaseAt: null,
|
|
45
|
+
lastStoreName: null,
|
|
46
|
+
favoriteStoreId: null,
|
|
47
|
+
favoriteStoreName: null,
|
|
48
|
+
skLevel: null,
|
|
49
|
+
activeCreditsCount: null,
|
|
50
|
+
},
|
|
31
51
|
],
|
|
32
52
|
};
|
|
33
53
|
expect(response.items[0].skLevel).toBe('GOLD');
|
|
34
54
|
expect(response.sources.credit).toBe('UNAVAILABLE');
|
|
55
|
+
expect(response.items[1].accountOnly).toBe(true);
|
|
56
|
+
expect(response.counts.accountOnly).toBe(1);
|
|
35
57
|
});
|
|
36
58
|
});
|
|
@@ -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
|
}
|
|
@@ -10,6 +10,8 @@ import { RetailKycStatusEnum } from '../../enums/RetailKycStatusEnum';
|
|
|
10
10
|
export declare class UpsertCustomerFromKycRequest {
|
|
11
11
|
/** Tienda de alta/origen — del JWT del vendedor dueño de la sesión del wizard (F1 §3.5). */
|
|
12
12
|
originStoreId: string;
|
|
13
|
+
/** Cadena de la tienda de alta; el wizard la manda desde la sesión. */
|
|
14
|
+
retailerId?: string;
|
|
13
15
|
/** Nombre partido por convención Fiado (F1 §3.5) — lo entrega el OCR del INE, NO se deriva de un string. */
|
|
14
16
|
names: string;
|
|
15
17
|
paternalLastName: string;
|
|
@@ -30,6 +30,12 @@ __decorate([
|
|
|
30
30
|
(0, class_validator_1.IsString)(),
|
|
31
31
|
__metadata("design:type", String)
|
|
32
32
|
], UpsertCustomerFromKycRequest.prototype, "originStoreId", void 0);
|
|
33
|
+
__decorate([
|
|
34
|
+
(0, class_transformer_1.Expose)(),
|
|
35
|
+
(0, class_validator_1.IsOptional)(),
|
|
36
|
+
(0, class_validator_1.IsString)(),
|
|
37
|
+
__metadata("design:type", String)
|
|
38
|
+
], UpsertCustomerFromKycRequest.prototype, "retailerId", void 0);
|
|
33
39
|
__decorate([
|
|
34
40
|
(0, class_transformer_1.Expose)(),
|
|
35
41
|
(0, class_validator_1.IsString)(),
|
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
import type { ClientLevelEnum } from '../../../loanScoring/enums/ClientLevelEnum';
|
|
2
2
|
import type { SellerTableSourceStatusEnum } from '../../enums/SellerTableSourceStatusEnum';
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* Una fila de la tabla de Clientes: un cliente del padrón de la cadena con sus compras en la ventana
|
|
5
|
+
* (sin canceladas) y su crédito SK. `accountOnly` = abrió cuenta y no tiene ninguna compra en la cadena.
|
|
6
|
+
*/
|
|
4
7
|
export interface CustomerTableRow {
|
|
5
8
|
retailCustomerId: string;
|
|
9
|
+
accountOnly: boolean;
|
|
10
|
+
/** Tienda donde se dio de alta; `null` si el padrón no la tiene. */
|
|
11
|
+
originStoreId: string | null;
|
|
6
12
|
name: string | null;
|
|
7
13
|
phone: string | null;
|
|
8
14
|
purchaseCount: number;
|
|
9
15
|
/** Precio de lo comprado (en crédito, el precio del equipo, no el enganche). */
|
|
10
16
|
totalSpentCents: number;
|
|
11
17
|
averageTicketCents: number | null;
|
|
12
|
-
|
|
13
|
-
|
|
18
|
+
/** `null` en un cliente «solo cuenta». */
|
|
19
|
+
firstPurchaseAt: string | null;
|
|
20
|
+
lastPurchaseAt: string | null;
|
|
14
21
|
lastStoreName: string | null;
|
|
15
22
|
/** Tienda con más compras; en empate, la de la compra más reciente. */
|
|
16
23
|
favoriteStoreId: string | null;
|
|
@@ -25,14 +32,20 @@ export interface CustomerTableSources {
|
|
|
25
32
|
sales: SellerTableSourceStatusEnum.OK;
|
|
26
33
|
credit: SellerTableSourceStatusEnum;
|
|
27
34
|
}
|
|
35
|
+
/** Clientes del padrón leídos en la página, antes del filtro `customerType`; el front los suma por página. */
|
|
36
|
+
export interface CustomerTableCounts {
|
|
37
|
+
withSales: number;
|
|
38
|
+
accountOnly: number;
|
|
39
|
+
}
|
|
28
40
|
/**
|
|
29
|
-
* `GET /backoffice/customers/table?from&to&limit&nextToken&storeId&sellerId&value` — tabla
|
|
30
|
-
* del Portal Admin VL, paginada por
|
|
41
|
+
* `GET /backoffice/customers/table?from&to&limit&nextToken&storeId&sellerId&customerType&value` — tabla
|
|
42
|
+
* de Clientes del Portal Admin VL, paginada sobre el padrón por alta descendente. `from` en `null` es «Todo».
|
|
31
43
|
*/
|
|
32
44
|
export interface BackofficeCustomerTableResponse {
|
|
33
45
|
from: string | null;
|
|
34
46
|
to: string;
|
|
35
47
|
nextToken: string | null;
|
|
36
48
|
sources: CustomerTableSources;
|
|
49
|
+
counts: CustomerTableCounts;
|
|
37
50
|
items: CustomerTableRow[];
|
|
38
51
|
}
|
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). */
|
|
@@ -27,6 +27,12 @@ export class UpsertCustomerFromKycRequest {
|
|
|
27
27
|
@IsString()
|
|
28
28
|
originStoreId!: string;
|
|
29
29
|
|
|
30
|
+
/** Cadena de la tienda de alta; el wizard la manda desde la sesión. */
|
|
31
|
+
@Expose()
|
|
32
|
+
@IsOptional()
|
|
33
|
+
@IsString()
|
|
34
|
+
retailerId?: string;
|
|
35
|
+
|
|
30
36
|
/** Nombre partido por convención Fiado (F1 §3.5) — lo entrega el OCR del INE, NO se deriva de un string. */
|
|
31
37
|
@Expose()
|
|
32
38
|
@IsString()
|
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
import type { ClientLevelEnum } from '../../../loanScoring/enums/ClientLevelEnum';
|
|
2
2
|
import type { SellerTableSourceStatusEnum } from '../../enums/SellerTableSourceStatusEnum';
|
|
3
3
|
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* Una fila de la tabla de Clientes: un cliente del padrón de la cadena con sus compras en la ventana
|
|
6
|
+
* (sin canceladas) y su crédito SK. `accountOnly` = abrió cuenta y no tiene ninguna compra en la cadena.
|
|
7
|
+
*/
|
|
5
8
|
export interface CustomerTableRow {
|
|
6
9
|
retailCustomerId: string;
|
|
10
|
+
accountOnly: boolean;
|
|
11
|
+
/** Tienda donde se dio de alta; `null` si el padrón no la tiene. */
|
|
12
|
+
originStoreId: string | null;
|
|
7
13
|
name: string | null;
|
|
8
14
|
phone: string | null;
|
|
9
15
|
purchaseCount: number;
|
|
10
16
|
/** Precio de lo comprado (en crédito, el precio del equipo, no el enganche). */
|
|
11
17
|
totalSpentCents: number;
|
|
12
18
|
averageTicketCents: number | null;
|
|
13
|
-
|
|
14
|
-
|
|
19
|
+
/** `null` en un cliente «solo cuenta». */
|
|
20
|
+
firstPurchaseAt: string | null;
|
|
21
|
+
lastPurchaseAt: string | null;
|
|
15
22
|
lastStoreName: string | null;
|
|
16
23
|
/** Tienda con más compras; en empate, la de la compra más reciente. */
|
|
17
24
|
favoriteStoreId: string | null;
|
|
@@ -28,14 +35,21 @@ export interface CustomerTableSources {
|
|
|
28
35
|
credit: SellerTableSourceStatusEnum;
|
|
29
36
|
}
|
|
30
37
|
|
|
38
|
+
/** Clientes del padrón leídos en la página, antes del filtro `customerType`; el front los suma por página. */
|
|
39
|
+
export interface CustomerTableCounts {
|
|
40
|
+
withSales: number;
|
|
41
|
+
accountOnly: number;
|
|
42
|
+
}
|
|
43
|
+
|
|
31
44
|
/**
|
|
32
|
-
* `GET /backoffice/customers/table?from&to&limit&nextToken&storeId&sellerId&value` — tabla
|
|
33
|
-
* del Portal Admin VL, paginada por
|
|
45
|
+
* `GET /backoffice/customers/table?from&to&limit&nextToken&storeId&sellerId&customerType&value` — tabla
|
|
46
|
+
* de Clientes del Portal Admin VL, paginada sobre el padrón por alta descendente. `from` en `null` es «Todo».
|
|
34
47
|
*/
|
|
35
48
|
export interface BackofficeCustomerTableResponse {
|
|
36
49
|
from: string | null;
|
|
37
50
|
to: string;
|
|
38
51
|
nextToken: string | null;
|
|
39
52
|
sources: CustomerTableSources;
|
|
53
|
+
counts: CustomerTableCounts;
|
|
40
54
|
items: CustomerTableRow[];
|
|
41
55
|
}
|