@fiado/type-kit 3.565.0 → 3.567.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/retailCustomer/customerReferralContract.test.ts +8 -0
- package/_test_/unit/retailPromotions/referralWizardContracts.test.ts +119 -0
- package/_test_/unit/retailPromotions/salePromotionPaymentCheck.test.ts +5 -2
- package/_test_/unit/retailWizard/backofficeCustomerReferrals.test.ts +13 -0
- package/_test_/unit/retailWizard/promotionM2mRequests.test.ts +10 -0
- package/bin/retailCustomer/dtos/requests/CreateCustomerReferralsRequest.d.ts +2 -0
- package/bin/retailCustomer/dtos/requests/CreateCustomerReferralsRequest.js +7 -0
- package/bin/retailPromotions/dtos/requests/CheckSalePromotionPaymentRequest.d.ts +3 -2
- package/bin/retailPromotions/dtos/requests/CheckSalePromotionPaymentRequest.js +2 -1
- package/bin/retailPromotions/dtos/requests/EvaluateSalePromotionsRequest.d.ts +2 -0
- package/bin/retailPromotions/dtos/requests/EvaluateSalePromotionsRequest.js +7 -0
- package/bin/retailPromotions/dtos/requests/ListLiveReferralPromotionsQuery.d.ts +10 -0
- package/bin/retailPromotions/dtos/requests/ListLiveReferralPromotionsQuery.js +38 -0
- package/bin/retailPromotions/dtos/responses/LiveReferralPromotionsResponse.d.ts +24 -0
- package/bin/retailPromotions/dtos/responses/LiveReferralPromotionsResponse.js +2 -0
- package/bin/retailPromotions/dtos/responses/WizardSalePromotionResponses.d.ts +13 -0
- package/bin/retailPromotions/index.d.ts +2 -0
- package/bin/retailPromotions/index.js +2 -0
- package/bin/retailWizard/dtos/responses/BackofficeCustomerReferralsResponse.d.ts +2 -0
- package/bin/retailWizard/dtos/responses/PrivateWizardSessionResponse.d.ts +4 -0
- package/package.json +1 -1
- package/src/retailCustomer/dtos/requests/CreateCustomerReferralsRequest.ts +7 -0
- package/src/retailPromotions/dtos/requests/CheckSalePromotionPaymentRequest.ts +5 -3
- package/src/retailPromotions/dtos/requests/EvaluateSalePromotionsRequest.ts +7 -0
- package/src/retailPromotions/dtos/requests/ListLiveReferralPromotionsQuery.ts +24 -0
- package/src/retailPromotions/dtos/responses/LiveReferralPromotionsResponse.ts +26 -0
- package/src/retailPromotions/dtos/responses/WizardSalePromotionResponses.ts +15 -0
- package/src/retailPromotions/index.ts +2 -0
- package/src/retailWizard/dtos/responses/BackofficeCustomerReferralsResponse.ts +2 -0
- package/src/retailWizard/dtos/responses/PrivateWizardSessionResponse.ts +4 -0
|
@@ -61,6 +61,7 @@ describe('enums de referidos', () => {
|
|
|
61
61
|
|
|
62
62
|
const SALE_BATCH = {
|
|
63
63
|
source: 'SALE',
|
|
64
|
+
retailerId: 'r-1',
|
|
64
65
|
storeId: 'st-1',
|
|
65
66
|
wizardSessionId: 'ws-1',
|
|
66
67
|
capturedBy: 'seller-1',
|
|
@@ -98,6 +99,13 @@ describe('CreateCustomerReferralsRequest', () => {
|
|
|
98
99
|
expect(errorsOf(CreateCustomerReferralsRequest, { ...SALE_BATCH, capturedBy: ' ' })).toContain('capturedBy');
|
|
99
100
|
});
|
|
100
101
|
|
|
102
|
+
it('exige la cadena de captura, también desde el cajón', () => {
|
|
103
|
+
const { retailerId: _retailerId, ...noRetailer } = SALE_BATCH;
|
|
104
|
+
expect(errorsOf(CreateCustomerReferralsRequest, noRetailer)).toEqual(['retailerId']);
|
|
105
|
+
expect(errorsOf(CreateCustomerReferralsRequest, { ...noRetailer, source: 'BACKOFFICE' })).toEqual(['retailerId']);
|
|
106
|
+
expect(errorsOf(CreateCustomerReferralsRequest, { ...SALE_BATCH, retailerId: ' ' })).toEqual(['retailerId']);
|
|
107
|
+
});
|
|
108
|
+
|
|
101
109
|
it('rechaza un origen fuera del catálogo', () => {
|
|
102
110
|
expect(errorsOf(CreateCustomerReferralsRequest, { ...SALE_BATCH, source: 'WEB' })).toContain('source');
|
|
103
111
|
});
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { plainToInstance } from 'class-transformer';
|
|
3
|
+
import { validateSync } from 'class-validator';
|
|
4
|
+
import { RetailPromotions } from '../../../src/index';
|
|
5
|
+
import {
|
|
6
|
+
EvaluateSalePromotionsRequest,
|
|
7
|
+
ListLiveReferralPromotionsQuery,
|
|
8
|
+
ReferralPromotionChannelEnum,
|
|
9
|
+
ReferralRewardTypeEnum,
|
|
10
|
+
ReferralTriggerEnum,
|
|
11
|
+
} from '../../../src/retailPromotions/index';
|
|
12
|
+
import type {
|
|
13
|
+
EvaluateSalePromotionsResponse,
|
|
14
|
+
ListLiveReferralPromotionsResponse,
|
|
15
|
+
} from '../../../src/retailPromotions/index';
|
|
16
|
+
|
|
17
|
+
type Dto = new () => object;
|
|
18
|
+
|
|
19
|
+
const errorsOf = (dtoClass: Dto, raw: Record<string, unknown>): string[] =>
|
|
20
|
+
validateSync(plainToInstance(dtoClass, raw, { excludeExtraneousValues: true }) as object).map((e) => e.property);
|
|
21
|
+
|
|
22
|
+
describe('EvaluateSalePromotionsRequest con teléfono', () => {
|
|
23
|
+
it('acepta el teléfono del cliente o su ausencia', () => {
|
|
24
|
+
expect(errorsOf(EvaluateSalePromotionsRequest, { sessionId: 's1', phone: '5512345678' })).toEqual([]);
|
|
25
|
+
expect(errorsOf(EvaluateSalePromotionsRequest, { sessionId: 's1' })).toEqual([]);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('rechaza el teléfono vacío o no texto', () => {
|
|
29
|
+
expect(errorsOf(EvaluateSalePromotionsRequest, { sessionId: 's1', phone: '' })).toEqual(['phone']);
|
|
30
|
+
expect(errorsOf(EvaluateSalePromotionsRequest, { sessionId: 's1', phone: 5512345678 })).toEqual(['phone']);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe('EvaluateSalePromotionsResponse con referredBy', () => {
|
|
35
|
+
it('trae solo el nombre de quien recomendó y lo que gana el recomendado', () => {
|
|
36
|
+
const response: EvaluateSalePromotionsResponse = {
|
|
37
|
+
promotions: [],
|
|
38
|
+
discountCode: null,
|
|
39
|
+
referredBy: {
|
|
40
|
+
name: 'María Fernanda',
|
|
41
|
+
rewards: [
|
|
42
|
+
{
|
|
43
|
+
promotionId: 'promo_1',
|
|
44
|
+
promotionName: 'Gama alta · ganan los dos',
|
|
45
|
+
reward: {
|
|
46
|
+
type: ReferralRewardTypeEnum.SALE_DISCOUNT,
|
|
47
|
+
amountCents: null,
|
|
48
|
+
percentBps: 1000,
|
|
49
|
+
maxAmountCents: null,
|
|
50
|
+
coupon: null,
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
expect(response.referredBy?.rewards?.[0].reward.percentBps).toBe(1000);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('referredBy es opcional', () => {
|
|
60
|
+
const response: EvaluateSalePromotionsResponse = { promotions: [], discountCode: null };
|
|
61
|
+
expect(response.referredBy).toBeUndefined();
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
describe('ListLiveReferralPromotionsQuery', () => {
|
|
66
|
+
it('acepta sesión sola o con canal y evento', () => {
|
|
67
|
+
expect(errorsOf(ListLiveReferralPromotionsQuery, { sessionId: 's1' })).toEqual([]);
|
|
68
|
+
expect(
|
|
69
|
+
errorsOf(ListLiveReferralPromotionsQuery, {
|
|
70
|
+
sessionId: 's1',
|
|
71
|
+
channel: ReferralPromotionChannelEnum.CREDIT,
|
|
72
|
+
trigger: ReferralTriggerEnum.ACCOUNT_OPENED,
|
|
73
|
+
}),
|
|
74
|
+
).toEqual([]);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('exige la sesión', () => {
|
|
78
|
+
expect(errorsOf(ListLiveReferralPromotionsQuery, {})).toEqual(['sessionId']);
|
|
79
|
+
expect(errorsOf(ListLiveReferralPromotionsQuery, { sessionId: '' })).toEqual(['sessionId']);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('rechaza canal o evento fuera del catálogo', () => {
|
|
83
|
+
expect(errorsOf(ListLiveReferralPromotionsQuery, { sessionId: 's1', channel: 'WALLET' })).toEqual(['channel']);
|
|
84
|
+
expect(errorsOf(ListLiveReferralPromotionsQuery, { sessionId: 's1', trigger: 'SIGNUP' })).toEqual(['trigger']);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('sale por el index raíz', () => {
|
|
88
|
+
expect(new RetailPromotions.ListLiveReferralPromotionsQuery()).toBeInstanceOf(ListLiveReferralPromotionsQuery);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe('ListLiveReferralPromotionsResponse', () => {
|
|
93
|
+
it('trae «tú ganas» y «tu amigo gana» por promo', () => {
|
|
94
|
+
const response: ListLiveReferralPromotionsResponse = {
|
|
95
|
+
items: [
|
|
96
|
+
{
|
|
97
|
+
promotionId: 'promo_1',
|
|
98
|
+
version: 2,
|
|
99
|
+
name: 'Abre tu cuenta · ganan los dos',
|
|
100
|
+
customerText: 'Cuando tu amigo abra su cuenta Fiado',
|
|
101
|
+
channel: ReferralPromotionChannelEnum.SALE,
|
|
102
|
+
trigger: ReferralTriggerEnum.ACCOUNT_OPENED,
|
|
103
|
+
purchaseNumber: null,
|
|
104
|
+
installmentStreak: null,
|
|
105
|
+
validUntil: '2026-11-17T23:59:59.000Z',
|
|
106
|
+
referrerReward: {
|
|
107
|
+
type: ReferralRewardTypeEnum.FIXED_BONUS,
|
|
108
|
+
amountCents: 15000,
|
|
109
|
+
percentBps: null,
|
|
110
|
+
maxAmountCents: null,
|
|
111
|
+
coupon: null,
|
|
112
|
+
},
|
|
113
|
+
referredReward: null,
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
};
|
|
117
|
+
expect(response.items[0].referrerReward.amountCents).toBe(15000);
|
|
118
|
+
});
|
|
119
|
+
});
|
|
@@ -12,9 +12,12 @@ describe('CheckSalePromotionPaymentRequest', () => {
|
|
|
12
12
|
expect(await errorsOf({ method })).toEqual([]);
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
-
it('rechaza un medio fuera del enum
|
|
15
|
+
it('rechaza un medio fuera del enum', async () => {
|
|
16
16
|
expect(await errorsOf({ method: 'BITCOIN' })).toEqual(['method']);
|
|
17
|
-
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('sin medio es válido: se revisa contra la forma de pago de la sesión', async () => {
|
|
20
|
+
expect(await errorsOf({})).toEqual([]);
|
|
18
21
|
});
|
|
19
22
|
|
|
20
23
|
it('el detalle del 422 nombra la promo y los medios que acepta', () => {
|
|
@@ -45,6 +45,19 @@ describe('BackofficeCustomerReferralsResponse', () => {
|
|
|
45
45
|
expect(response.referrals[0].capture.source).toBe('SALE');
|
|
46
46
|
});
|
|
47
47
|
|
|
48
|
+
it('acepta el nombre visible de quien capturó, opcional y nullable', () => {
|
|
49
|
+
const named: BackofficeCustomerReferral = {
|
|
50
|
+
...referral,
|
|
51
|
+
capture: { ...referral.capture, capturedByName: 'Laura Méndez (Admin SK)' },
|
|
52
|
+
};
|
|
53
|
+
const unresolved: BackofficeCustomerReferral = { ...referral, capture: { ...referral.capture, capturedByName: null } };
|
|
54
|
+
expect([named.capture.capturedByName, unresolved.capture.capturedByName, referral.capture.capturedByName]).toEqual([
|
|
55
|
+
'Laura Méndez (Admin SK)',
|
|
56
|
+
null,
|
|
57
|
+
undefined,
|
|
58
|
+
]);
|
|
59
|
+
});
|
|
60
|
+
|
|
48
61
|
it('suma premios por referido y el bloque «llegó recomendado por» en la tanda B', () => {
|
|
49
62
|
const response: BackofficeCustomerReferralsResponse = {
|
|
50
63
|
referrals: [{ ...referral, rewards: [{ ...reward, role: ReferralRoleEnum.REFERRER }] }],
|
|
@@ -256,5 +256,15 @@ describe('respuestas de los M2M de Promociones', () => {
|
|
|
256
256
|
undefined,
|
|
257
257
|
]);
|
|
258
258
|
expect(asString).toBeDefined();
|
|
259
|
+
|
|
260
|
+
const referred: PrivateWizardSessionResponse = { ...base, customerPhone: '5512345678', customerPurchaseNumber: 2 };
|
|
261
|
+
// @ts-expect-error el número de compra es numérico
|
|
262
|
+
const purchaseAsString: PrivateWizardSessionResponse = { ...base, customerPurchaseNumber: '2' };
|
|
263
|
+
expect([referred.customerPhone, referred.customerPurchaseNumber, base.customerPurchaseNumber]).toEqual([
|
|
264
|
+
'5512345678',
|
|
265
|
+
2,
|
|
266
|
+
undefined,
|
|
267
|
+
]);
|
|
268
|
+
expect(purchaseAsString).toBeDefined();
|
|
259
269
|
});
|
|
260
270
|
});
|
|
@@ -8,6 +8,8 @@ export declare class CustomerReferralInput {
|
|
|
8
8
|
/** Body de `privateCreateCustomerReferrals`: lote de referidos de un cliente. */
|
|
9
9
|
export declare class CreateCustomerReferralsRequest {
|
|
10
10
|
source: ReferralSourceEnum;
|
|
11
|
+
/** Cadena donde se captura el referido; «gana el primero» busca por cadena + teléfono. */
|
|
12
|
+
retailerId: string;
|
|
11
13
|
/** Tienda de captura; obligatoria en venta y apertura. */
|
|
12
14
|
storeId?: string;
|
|
13
15
|
wizardSessionId?: string;
|
|
@@ -52,6 +52,13 @@ __decorate([
|
|
|
52
52
|
(0, class_validator_1.IsEnum)(ReferralSourceEnum_1.ReferralSourceEnum),
|
|
53
53
|
__metadata("design:type", String)
|
|
54
54
|
], CreateCustomerReferralsRequest.prototype, "source", void 0);
|
|
55
|
+
__decorate([
|
|
56
|
+
(0, class_transformer_1.Expose)(),
|
|
57
|
+
(0, Trim_1.Trim)(),
|
|
58
|
+
(0, class_validator_1.IsString)(),
|
|
59
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
60
|
+
__metadata("design:type", String)
|
|
61
|
+
], CreateCustomerReferralsRequest.prototype, "retailerId", void 0);
|
|
55
62
|
__decorate([
|
|
56
63
|
(0, class_transformer_1.Expose)(),
|
|
57
64
|
(0, class_validator_1.ValidateIf)((o) => o.source !== ReferralSourceEnum_1.ReferralSourceEnum.BACKOFFICE || o.storeId !== undefined),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { SalePaymentMethodEnum } from '../../../retailWizard/enums/SalePaymentMethodEnum';
|
|
2
|
-
/** Body de `POST /private/sessions/{sessionId}/sale-promotion/payment-check` (M2M)
|
|
2
|
+
/** Body de `POST /private/sessions/{sessionId}/sale-promotion/payment-check` (M2M). */
|
|
3
3
|
export declare class CheckSalePromotionPaymentRequest {
|
|
4
|
-
|
|
4
|
+
/** Medio del cobro de contado; ausente = se valida contra la forma de pago de la sesión (enganche o cierre a crédito). */
|
|
5
|
+
method?: SalePaymentMethodEnum;
|
|
5
6
|
}
|
|
@@ -13,12 +13,13 @@ exports.CheckSalePromotionPaymentRequest = void 0;
|
|
|
13
13
|
const class_transformer_1 = require("class-transformer");
|
|
14
14
|
const class_validator_1 = require("class-validator");
|
|
15
15
|
const SalePaymentMethodEnum_1 = require("../../../retailWizard/enums/SalePaymentMethodEnum");
|
|
16
|
-
/** Body de `POST /private/sessions/{sessionId}/sale-promotion/payment-check` (M2M)
|
|
16
|
+
/** Body de `POST /private/sessions/{sessionId}/sale-promotion/payment-check` (M2M). */
|
|
17
17
|
class CheckSalePromotionPaymentRequest {
|
|
18
18
|
}
|
|
19
19
|
exports.CheckSalePromotionPaymentRequest = CheckSalePromotionPaymentRequest;
|
|
20
20
|
__decorate([
|
|
21
21
|
(0, class_transformer_1.Expose)(),
|
|
22
|
+
(0, class_validator_1.IsOptional)(),
|
|
22
23
|
(0, class_validator_1.IsEnum)(SalePaymentMethodEnum_1.SalePaymentMethodEnum),
|
|
23
24
|
__metadata("design:type", String)
|
|
24
25
|
], CheckSalePromotionPaymentRequest.prototype, "method", void 0);
|
|
@@ -29,3 +29,10 @@ __decorate([
|
|
|
29
29
|
(0, class_validator_1.IsNotEmpty)(),
|
|
30
30
|
__metadata("design:type", String)
|
|
31
31
|
], EvaluateSalePromotionsRequest.prototype, "discountCode", void 0);
|
|
32
|
+
__decorate([
|
|
33
|
+
(0, class_transformer_1.Expose)(),
|
|
34
|
+
(0, class_validator_1.IsOptional)(),
|
|
35
|
+
(0, class_validator_1.IsString)(),
|
|
36
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
37
|
+
__metadata("design:type", String)
|
|
38
|
+
], EvaluateSalePromotionsRequest.prototype, "phone", void 0);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ReferralPromotionChannelEnum } from '../../enums/ReferralPromotionChannelEnum';
|
|
2
|
+
import { ReferralTriggerEnum } from '../../enums/ReferralTriggerEnum';
|
|
3
|
+
/** Query de las promos de referido vigentes del paso Referidos; la tienda sale de la sesión. */
|
|
4
|
+
export declare class ListLiveReferralPromotionsQuery {
|
|
5
|
+
sessionId: string;
|
|
6
|
+
/** Sin canal: venta y crédito. */
|
|
7
|
+
channel?: ReferralPromotionChannelEnum;
|
|
8
|
+
/** `ACCOUNT_OPENED` en una apertura sin venta: solo las que se ganan al abrir cuenta. */
|
|
9
|
+
trigger?: ReferralTriggerEnum;
|
|
10
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
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.ListLiveReferralPromotionsQuery = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
const ReferralPromotionChannelEnum_1 = require("../../enums/ReferralPromotionChannelEnum");
|
|
16
|
+
const ReferralTriggerEnum_1 = require("../../enums/ReferralTriggerEnum");
|
|
17
|
+
/** Query de las promos de referido vigentes del paso Referidos; la tienda sale de la sesión. */
|
|
18
|
+
class ListLiveReferralPromotionsQuery {
|
|
19
|
+
}
|
|
20
|
+
exports.ListLiveReferralPromotionsQuery = ListLiveReferralPromotionsQuery;
|
|
21
|
+
__decorate([
|
|
22
|
+
(0, class_transformer_1.Expose)(),
|
|
23
|
+
(0, class_validator_1.IsString)(),
|
|
24
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
25
|
+
__metadata("design:type", String)
|
|
26
|
+
], ListLiveReferralPromotionsQuery.prototype, "sessionId", void 0);
|
|
27
|
+
__decorate([
|
|
28
|
+
(0, class_transformer_1.Expose)(),
|
|
29
|
+
(0, class_validator_1.IsOptional)(),
|
|
30
|
+
(0, class_validator_1.IsEnum)(ReferralPromotionChannelEnum_1.ReferralPromotionChannelEnum),
|
|
31
|
+
__metadata("design:type", String)
|
|
32
|
+
], ListLiveReferralPromotionsQuery.prototype, "channel", void 0);
|
|
33
|
+
__decorate([
|
|
34
|
+
(0, class_transformer_1.Expose)(),
|
|
35
|
+
(0, class_validator_1.IsOptional)(),
|
|
36
|
+
(0, class_validator_1.IsEnum)(ReferralTriggerEnum_1.ReferralTriggerEnum),
|
|
37
|
+
__metadata("design:type", String)
|
|
38
|
+
], ListLiveReferralPromotionsQuery.prototype, "trigger", void 0);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ReferralPromotionChannelEnum } from '../../enums/ReferralPromotionChannelEnum';
|
|
2
|
+
import { ReferralTriggerEnum } from '../../enums/ReferralTriggerEnum';
|
|
3
|
+
import { ReferralReward } from '../ReferralPromotion';
|
|
4
|
+
/** Promo de referido vigente para el paso Referidos: «tú ganas» y «tu amigo gana». */
|
|
5
|
+
export interface LiveReferralPromotionItem {
|
|
6
|
+
promotionId: string;
|
|
7
|
+
version: number;
|
|
8
|
+
name: string;
|
|
9
|
+
customerText: string;
|
|
10
|
+
channel: ReferralPromotionChannelEnum;
|
|
11
|
+
trigger: ReferralTriggerEnum;
|
|
12
|
+
/** Solo en `NTH_PURCHASE`. */
|
|
13
|
+
purchaseNumber: number | null;
|
|
14
|
+
/** Solo en `INSTALLMENT_STREAK`. */
|
|
15
|
+
installmentStreak: number | null;
|
|
16
|
+
/** Fin de vigencia; `null` = sin fecha de fin. */
|
|
17
|
+
validUntil: string | null;
|
|
18
|
+
referrerReward: ReferralReward;
|
|
19
|
+
/** `null` = el recomendado no gana nada. */
|
|
20
|
+
referredReward: ReferralReward | null;
|
|
21
|
+
}
|
|
22
|
+
export interface ListLiveReferralPromotionsResponse {
|
|
23
|
+
items: LiveReferralPromotionItem[];
|
|
24
|
+
}
|
|
@@ -9,6 +9,7 @@ import { SaleCouponAvailabilityEnum } from '../../enums/SaleCouponAvailabilityEn
|
|
|
9
9
|
import { SalePromotionKindEnum } from '../../enums/SalePromotionKindEnum';
|
|
10
10
|
import { SalePromotionLeverEnum } from '../../enums/SalePromotionLeverEnum';
|
|
11
11
|
import { DiscountValue } from '../DiscountValue';
|
|
12
|
+
import { ReferralReward } from '../ReferralPromotion';
|
|
12
13
|
import { LinePromotionDiscount } from '../LinePromotionDiscount';
|
|
13
14
|
import { SalePromotionLevers, SalePromotionScope } from '../SalePromotionLevers';
|
|
14
15
|
/** Condiciones del cliente que pide la promo; solo vienen las que aplican. */
|
|
@@ -91,9 +92,21 @@ export interface EvaluatedDiscountCode {
|
|
|
91
92
|
lines: LinePromotionDiscount[];
|
|
92
93
|
totalDiscountCents: number;
|
|
93
94
|
}
|
|
95
|
+
/** Lo que gana el recomendado en una promo de referido vigente. */
|
|
96
|
+
export interface EvaluatedReferredReward {
|
|
97
|
+
promotionId: string;
|
|
98
|
+
promotionName: string;
|
|
99
|
+
reward: ReferralReward;
|
|
100
|
+
}
|
|
101
|
+
/** Quién recomendó al cliente; solo viene si alguna promo vigente le da algo al recomendado. */
|
|
102
|
+
export interface EvaluatedReferredBy {
|
|
103
|
+
name: string;
|
|
104
|
+
rewards?: EvaluatedReferredReward[];
|
|
105
|
+
}
|
|
94
106
|
export interface EvaluateSalePromotionsResponse {
|
|
95
107
|
promotions: EvaluatedSalePromotion[];
|
|
96
108
|
discountCode: EvaluatedDiscountCode | null;
|
|
109
|
+
referredBy?: EvaluatedReferredBy | null;
|
|
97
110
|
}
|
|
98
111
|
/** Promo de regalo del teléfono que quedó apartada. */
|
|
99
112
|
export interface HeldGiftPromotion {
|
|
@@ -63,6 +63,7 @@ export * from './dtos/requests/SkuSalePromotionsQuery';
|
|
|
63
63
|
export * from './dtos/requests/ActiveSalePromotionsBySkusRequest';
|
|
64
64
|
export * from './dtos/requests/CheckSalePromotionPaymentRequest';
|
|
65
65
|
export * from './dtos/requests/GetReferralRewardsByPhonesRequest';
|
|
66
|
+
export * from './dtos/requests/ListLiveReferralPromotionsQuery';
|
|
66
67
|
export * from './dtos/responses/SalePromotionCrudResponses';
|
|
67
68
|
export * from './dtos/responses/DiscountCodeResponses';
|
|
68
69
|
export * from './dtos/responses/WizardSalePromotionResponses';
|
|
@@ -72,3 +73,4 @@ export * from './dtos/responses/ActiveSalePromotionsBySkusResponse';
|
|
|
72
73
|
export * from './dtos/responses/WelcomeBonusPromotionResponse';
|
|
73
74
|
export * from './dtos/responses/SalePromotionPaymentCheckResponses';
|
|
74
75
|
export * from './dtos/responses/ReferralRewardsByPhonesResponses';
|
|
76
|
+
export * from './dtos/responses/LiveReferralPromotionsResponse';
|
|
@@ -84,6 +84,7 @@ __exportStar(require("./dtos/requests/SkuSalePromotionsQuery"), exports);
|
|
|
84
84
|
__exportStar(require("./dtos/requests/ActiveSalePromotionsBySkusRequest"), exports);
|
|
85
85
|
__exportStar(require("./dtos/requests/CheckSalePromotionPaymentRequest"), exports);
|
|
86
86
|
__exportStar(require("./dtos/requests/GetReferralRewardsByPhonesRequest"), exports);
|
|
87
|
+
__exportStar(require("./dtos/requests/ListLiveReferralPromotionsQuery"), exports);
|
|
87
88
|
// Response DTOs
|
|
88
89
|
__exportStar(require("./dtos/responses/SalePromotionCrudResponses"), exports);
|
|
89
90
|
__exportStar(require("./dtos/responses/DiscountCodeResponses"), exports);
|
|
@@ -94,3 +95,4 @@ __exportStar(require("./dtos/responses/ActiveSalePromotionsBySkusResponse"), exp
|
|
|
94
95
|
__exportStar(require("./dtos/responses/WelcomeBonusPromotionResponse"), exports);
|
|
95
96
|
__exportStar(require("./dtos/responses/SalePromotionPaymentCheckResponses"), exports);
|
|
96
97
|
__exportStar(require("./dtos/responses/ReferralRewardsByPhonesResponses"), exports);
|
|
98
|
+
__exportStar(require("./dtos/responses/LiveReferralPromotionsResponse"), exports);
|
|
@@ -26,6 +26,8 @@ export interface BackofficeReferralCapture {
|
|
|
26
26
|
/** Solo en `OPENING`. */
|
|
27
27
|
accountOpeningSessionId: string | null;
|
|
28
28
|
capturedBy: string;
|
|
29
|
+
/** Nombre visible de quien capturó; `null` si no se resolvió. */
|
|
30
|
+
capturedByName?: string | null;
|
|
29
31
|
capturedAt: string;
|
|
30
32
|
}
|
|
31
33
|
/** Referido del cliente en el cajón. */
|
|
@@ -34,4 +34,8 @@ export interface PrivateWizardSessionResponse {
|
|
|
34
34
|
payment?: WizardPayment | null;
|
|
35
35
|
/** Valor efectivo del flag SPLIT_FINANCING_ENABLED del wizard. */
|
|
36
36
|
splitFinancingEnabled?: boolean;
|
|
37
|
+
/** Teléfono del cliente de la sesión, 10 dígitos. */
|
|
38
|
+
customerPhone?: string;
|
|
39
|
+
/** Número de compra que sería esta venta en la cadena: 1 + ventas previas no canceladas. */
|
|
40
|
+
customerPurchaseNumber?: number;
|
|
37
41
|
}
|
package/package.json
CHANGED
|
@@ -46,6 +46,13 @@ export class CreateCustomerReferralsRequest {
|
|
|
46
46
|
@IsEnum(ReferralSourceEnum)
|
|
47
47
|
source!: ReferralSourceEnum;
|
|
48
48
|
|
|
49
|
+
/** Cadena donde se captura el referido; «gana el primero» busca por cadena + teléfono. */
|
|
50
|
+
@Expose()
|
|
51
|
+
@Trim()
|
|
52
|
+
@IsString()
|
|
53
|
+
@IsNotEmpty()
|
|
54
|
+
retailerId!: string;
|
|
55
|
+
|
|
49
56
|
/** Tienda de captura; obligatoria en venta y apertura. */
|
|
50
57
|
@Expose()
|
|
51
58
|
@ValidateIf((o: CreateCustomerReferralsRequest) => o.source !== ReferralSourceEnum.BACKOFFICE || o.storeId !== undefined)
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { Expose } from 'class-transformer';
|
|
2
|
-
import { IsEnum } from 'class-validator';
|
|
2
|
+
import { IsEnum, IsOptional } from 'class-validator';
|
|
3
3
|
import { SalePaymentMethodEnum } from '../../../retailWizard/enums/SalePaymentMethodEnum';
|
|
4
4
|
|
|
5
|
-
/** Body de `POST /private/sessions/{sessionId}/sale-promotion/payment-check` (M2M)
|
|
5
|
+
/** Body de `POST /private/sessions/{sessionId}/sale-promotion/payment-check` (M2M). */
|
|
6
6
|
export class CheckSalePromotionPaymentRequest {
|
|
7
|
+
/** Medio del cobro de contado; ausente = se valida contra la forma de pago de la sesión (enganche o cierre a crédito). */
|
|
7
8
|
@Expose()
|
|
9
|
+
@IsOptional()
|
|
8
10
|
@IsEnum(SalePaymentMethodEnum)
|
|
9
|
-
method
|
|
11
|
+
method?: SalePaymentMethodEnum;
|
|
10
12
|
}
|
|
@@ -13,4 +13,11 @@ export class EvaluateSalePromotionsRequest {
|
|
|
13
13
|
@IsString()
|
|
14
14
|
@IsNotEmpty()
|
|
15
15
|
discountCode?: string | null;
|
|
16
|
+
|
|
17
|
+
/** Teléfono del cliente de la venta; con él se sabe si llegó recomendado. */
|
|
18
|
+
@Expose()
|
|
19
|
+
@IsOptional()
|
|
20
|
+
@IsString()
|
|
21
|
+
@IsNotEmpty()
|
|
22
|
+
phone?: string;
|
|
16
23
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Expose } from 'class-transformer';
|
|
2
|
+
import { IsEnum, IsNotEmpty, IsOptional, IsString } from 'class-validator';
|
|
3
|
+
import { ReferralPromotionChannelEnum } from '../../enums/ReferralPromotionChannelEnum';
|
|
4
|
+
import { ReferralTriggerEnum } from '../../enums/ReferralTriggerEnum';
|
|
5
|
+
|
|
6
|
+
/** Query de las promos de referido vigentes del paso Referidos; la tienda sale de la sesión. */
|
|
7
|
+
export class ListLiveReferralPromotionsQuery {
|
|
8
|
+
@Expose()
|
|
9
|
+
@IsString()
|
|
10
|
+
@IsNotEmpty()
|
|
11
|
+
sessionId!: string;
|
|
12
|
+
|
|
13
|
+
/** Sin canal: venta y crédito. */
|
|
14
|
+
@Expose()
|
|
15
|
+
@IsOptional()
|
|
16
|
+
@IsEnum(ReferralPromotionChannelEnum)
|
|
17
|
+
channel?: ReferralPromotionChannelEnum;
|
|
18
|
+
|
|
19
|
+
/** `ACCOUNT_OPENED` en una apertura sin venta: solo las que se ganan al abrir cuenta. */
|
|
20
|
+
@Expose()
|
|
21
|
+
@IsOptional()
|
|
22
|
+
@IsEnum(ReferralTriggerEnum)
|
|
23
|
+
trigger?: ReferralTriggerEnum;
|
|
24
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ReferralPromotionChannelEnum } from '../../enums/ReferralPromotionChannelEnum';
|
|
2
|
+
import { ReferralTriggerEnum } from '../../enums/ReferralTriggerEnum';
|
|
3
|
+
import { ReferralReward } from '../ReferralPromotion';
|
|
4
|
+
|
|
5
|
+
/** Promo de referido vigente para el paso Referidos: «tú ganas» y «tu amigo gana». */
|
|
6
|
+
export interface LiveReferralPromotionItem {
|
|
7
|
+
promotionId: string;
|
|
8
|
+
version: number;
|
|
9
|
+
name: string;
|
|
10
|
+
customerText: string;
|
|
11
|
+
channel: ReferralPromotionChannelEnum;
|
|
12
|
+
trigger: ReferralTriggerEnum;
|
|
13
|
+
/** Solo en `NTH_PURCHASE`. */
|
|
14
|
+
purchaseNumber: number | null;
|
|
15
|
+
/** Solo en `INSTALLMENT_STREAK`. */
|
|
16
|
+
installmentStreak: number | null;
|
|
17
|
+
/** Fin de vigencia; `null` = sin fecha de fin. */
|
|
18
|
+
validUntil: string | null;
|
|
19
|
+
referrerReward: ReferralReward;
|
|
20
|
+
/** `null` = el recomendado no gana nada. */
|
|
21
|
+
referredReward: ReferralReward | null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface ListLiveReferralPromotionsResponse {
|
|
25
|
+
items: LiveReferralPromotionItem[];
|
|
26
|
+
}
|
|
@@ -9,6 +9,7 @@ import { SaleCouponAvailabilityEnum } from '../../enums/SaleCouponAvailabilityEn
|
|
|
9
9
|
import { SalePromotionKindEnum } from '../../enums/SalePromotionKindEnum';
|
|
10
10
|
import { SalePromotionLeverEnum } from '../../enums/SalePromotionLeverEnum';
|
|
11
11
|
import { DiscountValue } from '../DiscountValue';
|
|
12
|
+
import { ReferralReward } from '../ReferralPromotion';
|
|
12
13
|
import { LinePromotionDiscount } from '../LinePromotionDiscount';
|
|
13
14
|
import { SalePromotionLevers, SalePromotionScope } from '../SalePromotionLevers';
|
|
14
15
|
|
|
@@ -99,9 +100,23 @@ export interface EvaluatedDiscountCode {
|
|
|
99
100
|
totalDiscountCents: number;
|
|
100
101
|
}
|
|
101
102
|
|
|
103
|
+
/** Lo que gana el recomendado en una promo de referido vigente. */
|
|
104
|
+
export interface EvaluatedReferredReward {
|
|
105
|
+
promotionId: string;
|
|
106
|
+
promotionName: string;
|
|
107
|
+
reward: ReferralReward;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Quién recomendó al cliente; solo viene si alguna promo vigente le da algo al recomendado. */
|
|
111
|
+
export interface EvaluatedReferredBy {
|
|
112
|
+
name: string;
|
|
113
|
+
rewards?: EvaluatedReferredReward[];
|
|
114
|
+
}
|
|
115
|
+
|
|
102
116
|
export interface EvaluateSalePromotionsResponse {
|
|
103
117
|
promotions: EvaluatedSalePromotion[];
|
|
104
118
|
discountCode: EvaluatedDiscountCode | null;
|
|
119
|
+
referredBy?: EvaluatedReferredBy | null;
|
|
105
120
|
}
|
|
106
121
|
|
|
107
122
|
/** Promo de regalo del teléfono que quedó apartada. */
|
|
@@ -72,6 +72,7 @@ export * from './dtos/requests/SkuSalePromotionsQuery';
|
|
|
72
72
|
export * from './dtos/requests/ActiveSalePromotionsBySkusRequest';
|
|
73
73
|
export * from './dtos/requests/CheckSalePromotionPaymentRequest';
|
|
74
74
|
export * from './dtos/requests/GetReferralRewardsByPhonesRequest';
|
|
75
|
+
export * from './dtos/requests/ListLiveReferralPromotionsQuery';
|
|
75
76
|
|
|
76
77
|
// Response DTOs
|
|
77
78
|
export * from './dtos/responses/SalePromotionCrudResponses';
|
|
@@ -83,3 +84,4 @@ export * from './dtos/responses/ActiveSalePromotionsBySkusResponse';
|
|
|
83
84
|
export * from './dtos/responses/WelcomeBonusPromotionResponse';
|
|
84
85
|
export * from './dtos/responses/SalePromotionPaymentCheckResponses';
|
|
85
86
|
export * from './dtos/responses/ReferralRewardsByPhonesResponses';
|
|
87
|
+
export * from './dtos/responses/LiveReferralPromotionsResponse';
|
|
@@ -28,6 +28,8 @@ export interface BackofficeReferralCapture {
|
|
|
28
28
|
/** Solo en `OPENING`. */
|
|
29
29
|
accountOpeningSessionId: string | null;
|
|
30
30
|
capturedBy: string;
|
|
31
|
+
/** Nombre visible de quien capturó; `null` si no se resolvió. */
|
|
32
|
+
capturedByName?: string | null;
|
|
31
33
|
capturedAt: string;
|
|
32
34
|
}
|
|
33
35
|
|
|
@@ -35,4 +35,8 @@ export interface PrivateWizardSessionResponse {
|
|
|
35
35
|
payment?: WizardPayment | null;
|
|
36
36
|
/** Valor efectivo del flag SPLIT_FINANCING_ENABLED del wizard. */
|
|
37
37
|
splitFinancingEnabled?: boolean;
|
|
38
|
+
/** Teléfono del cliente de la sesión, 10 dígitos. */
|
|
39
|
+
customerPhone?: string;
|
|
40
|
+
/** Número de compra que sería esta venta en la cadena: 1 + ventas previas no canceladas. */
|
|
41
|
+
customerPurchaseNumber?: number;
|
|
38
42
|
}
|