@fiado/type-kit 3.611.0 → 3.612.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/gsfConnector/gsfMessages.test.ts +233 -0
- package/bin/gsfConnector/constants/GsfPatterns.d.ts +15 -0
- package/bin/gsfConnector/constants/GsfPatterns.js +18 -0
- package/bin/gsfConnector/constants/GsfPaymentOperations.d.ts +6 -0
- package/bin/gsfConnector/constants/GsfPaymentOperations.js +16 -0
- package/bin/gsfConnector/dtos/GsfAddress.d.ts +13 -0
- package/bin/gsfConnector/dtos/GsfAddress.js +81 -0
- package/bin/gsfConnector/dtos/GsfCreateCreditMessage.d.ts +17 -0
- package/bin/gsfConnector/dtos/GsfCreateCreditMessage.js +78 -0
- package/bin/gsfConnector/dtos/GsfCreditTerms.d.ts +17 -0
- package/bin/gsfConnector/dtos/GsfCreditTerms.js +71 -0
- package/bin/gsfConnector/dtos/GsfCustomer.d.ts +15 -0
- package/bin/gsfConnector/dtos/GsfCustomer.js +80 -0
- package/bin/gsfConnector/dtos/GsfExpectedState.d.ts +8 -0
- package/bin/gsfConnector/dtos/GsfExpectedState.js +38 -0
- package/bin/gsfConnector/dtos/GsfPayment.d.ts +16 -0
- package/bin/gsfConnector/dtos/GsfPayment.js +75 -0
- package/bin/gsfConnector/dtos/GsfPaymentMessage.d.ts +16 -0
- package/bin/gsfConnector/dtos/GsfPaymentMessage.js +74 -0
- package/bin/gsfConnector/dtos/GsfScheduleInstallment.d.ts +9 -0
- package/bin/gsfConnector/dtos/GsfScheduleInstallment.js +60 -0
- package/bin/gsfConnector/enums/GsfOperationEnum.d.ts +11 -0
- package/bin/gsfConnector/enums/GsfOperationEnum.js +15 -0
- package/bin/gsfConnector/enums/GsfPaymentChannelEnum.d.ts +11 -0
- package/bin/gsfConnector/enums/GsfPaymentChannelEnum.js +15 -0
- package/bin/gsfConnector/enums/GsfPaymentKindEnum.d.ts +11 -0
- package/bin/gsfConnector/enums/GsfPaymentKindEnum.js +15 -0
- package/bin/gsfConnector/enums/GsfPaymentPeriodicityEnum.d.ts +6 -0
- package/bin/gsfConnector/enums/GsfPaymentPeriodicityEnum.js +10 -0
- package/bin/gsfConnector/index.d.ts +17 -0
- package/bin/gsfConnector/index.js +37 -0
- package/bin/gsfConnector/validators/IsGsfCalendarDate.d.ts +6 -0
- package/bin/gsfConnector/validators/IsGsfCalendarDate.js +29 -0
- package/bin/gsfConnector/validators/IsGsfPaymentKindForOperation.d.ts +6 -0
- package/bin/gsfConnector/validators/IsGsfPaymentKindForOperation.js +31 -0
- package/bin/gsfConnector/validators/IsGsfPrepaymentScheduleProvided.d.ts +6 -0
- package/bin/gsfConnector/validators/IsGsfPrepaymentScheduleProvided.js +28 -0
- package/bin/index.d.ts +1 -0
- package/bin/index.js +3 -2
- package/package.json +1 -1
- package/src/gsfConnector/constants/GsfPatterns.ts +21 -0
- package/src/gsfConnector/constants/GsfPaymentOperations.ts +17 -0
- package/src/gsfConnector/dtos/GsfAddress.ts +60 -0
- package/src/gsfConnector/dtos/GsfCreateCreditMessage.ts +60 -0
- package/src/gsfConnector/dtos/GsfCreditTerms.ts +55 -0
- package/src/gsfConnector/dtos/GsfCustomer.ts +60 -0
- package/src/gsfConnector/dtos/GsfExpectedState.ts +25 -0
- package/src/gsfConnector/dtos/GsfPayment.ts +57 -0
- package/src/gsfConnector/dtos/GsfPaymentMessage.ts +58 -0
- package/src/gsfConnector/dtos/GsfScheduleInstallment.ts +41 -0
- package/src/gsfConnector/enums/GsfOperationEnum.ts +11 -0
- package/src/gsfConnector/enums/GsfPaymentChannelEnum.ts +11 -0
- package/src/gsfConnector/enums/GsfPaymentKindEnum.ts +11 -0
- package/src/gsfConnector/enums/GsfPaymentPeriodicityEnum.ts +6 -0
- package/src/gsfConnector/index.ts +24 -0
- package/src/gsfConnector/validators/IsGsfCalendarDate.ts +19 -0
- package/src/gsfConnector/validators/IsGsfPaymentKindForOperation.ts +21 -0
- package/src/gsfConnector/validators/IsGsfPrepaymentScheduleProvided.ts +18 -0
- package/src/index.ts +1 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.IsGsfPrepaymentScheduleProvided = void 0;
|
|
10
|
+
const class_validator_1 = require("class-validator");
|
|
11
|
+
const GsfOperationEnum_1 = require("../enums/GsfOperationEnum");
|
|
12
|
+
/** Un abono a capital trae la tabla recalculada: sin ella no hay contra qué comparar la reestructura de GSF. */
|
|
13
|
+
let IsGsfPrepaymentScheduleProvided = class IsGsfPrepaymentScheduleProvided {
|
|
14
|
+
validate(value, args) {
|
|
15
|
+
if (args.object.operation !== GsfOperationEnum_1.GsfOperationEnum.APPLY_PREPAYMENT) {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
const schedule = value?.schedule;
|
|
19
|
+
return Array.isArray(schedule) && schedule.length > 0;
|
|
20
|
+
}
|
|
21
|
+
defaultMessage(args) {
|
|
22
|
+
return `${args.property}.schedule es obligatorio en APPLY_PREPAYMENT`;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
exports.IsGsfPrepaymentScheduleProvided = IsGsfPrepaymentScheduleProvided;
|
|
26
|
+
exports.IsGsfPrepaymentScheduleProvided = IsGsfPrepaymentScheduleProvided = __decorate([
|
|
27
|
+
(0, class_validator_1.ValidatorConstraint)({ name: 'isGsfPrepaymentScheduleProvided', async: false })
|
|
28
|
+
], IsGsfPrepaymentScheduleProvided);
|
package/bin/index.d.ts
CHANGED
|
@@ -80,6 +80,7 @@ export * as AiEngine from './aiEngine';
|
|
|
80
80
|
export * as Sentry from './sentry';
|
|
81
81
|
export * as CreditStatements from './credit-statements';
|
|
82
82
|
export * as CirculoCredito from './circuloCredito';
|
|
83
|
+
export * as GsfConnector from './gsfConnector';
|
|
83
84
|
export * as MilestoneBusiness from './milestone-business';
|
|
84
85
|
export * as Mdm from './mdm';
|
|
85
86
|
export * as MessagesConnector from './messagesConnector';
|
package/bin/index.js
CHANGED
|
@@ -37,8 +37,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.CentralPayments = exports.Helpdesk = exports.FiadoApiResponse = exports.Auth = exports.LegalDocumentsBusiness = exports.Role = exports.STPAccount = exports.RiskProfile = exports.FraudPreventionEngine = exports.BBVARst = exports.Stp = exports.BenefitCenter = exports.FiadoIncFavorite = exports.BankAccount = exports.P2pContact = exports.CreditContract = exports.Contract = exports.ProductCatalog = exports.ContactInfo = exports.TransactionAnalytics = exports.Transaction = exports.TransactionProcessor = exports.GenericMessage = exports.EventBridgeMessage = exports.SessionActivity = exports.MessageMoments = exports.NotificationMessages = exports.ServicePayment = exports.Header = exports.Identity = exports.UserTags = exports.Group = exports.File = exports.ExchangeRate = exports.Directory = exports.Currency = exports.Country = exports.Card = exports.Authentication = exports.AppContent = exports.App = exports.Offices = exports.Places = exports.Address = exports.Beneficiary = exports.Activity = exports.Biometrics = exports.MetamapConnector = exports.Account = exports.Crypto = void 0;
|
|
40
|
-
exports.
|
|
41
|
-
exports.CustomerMessages = exports.TaskManager = exports.LoanRetailAudit = exports.Meetings = exports.Rules = exports.PdfRender = exports.DatalakeReports = exports.RewardsEligibility = exports.Rewards = exports.DynamicForm = exports.FileStorage = exports.MoneyTransfer = exports.RetailLoan = exports.Membership = exports.WebhookBusiness = exports.PeopleBusiness = exports.UserConfirmations = exports.Collection = exports.Shipping = exports.PhoneSales = exports.Onboarding = exports.Kyc = exports.LoanScoring = exports.LoanCredit = exports.LoanCollectorAssignment = exports.LoanOfferings = exports.Shortlink = exports.LoanConfig = exports.DatalakeQuery = exports.RetailIntegration = exports.RetailPromotions = exports.RetailWizard = exports.RetailCustomer = void 0;
|
|
40
|
+
exports.RetailCatalog = exports.RetailCommission = exports.RetailOrg = exports.EmailVerification = exports.NetworkConnector = exports.Modelias = exports.TotpSecurity = exports.Passport = exports.WalletFunding = exports.Remittance = exports.PlatformRbac = exports.CognitoBackofficeConnector = exports.WhatsappConnector = exports.TwilioConnector = exports.MessagesConnector = exports.Mdm = exports.MilestoneBusiness = exports.GsfConnector = exports.CirculoCredito = exports.CreditStatements = exports.Sentry = exports.AiEngine = exports.Funnel = exports.TeamsConnector = exports.PlatformErrorEvents = exports.CustomerFile = exports.CreditBackoffice = exports.CreditDashboard = exports.CreditEngine = exports.Credit = exports.ComissionBusiness = exports.UsMarketGrowthBusiness = exports.ReferralBusiness = exports.ZendeskMessaging = exports.NotificationWS = exports.Event = exports.PayrollBusiness = exports.Cnbv = exports.DirectorySetting = exports.InvoiceCollector = exports.Collector = exports.Pricelist = exports.Company = exports.Services = exports.AccountIssuanceBusiness = exports.AppSelectionData = exports.Device = exports.Observations = exports.IssuanceBusiness = exports.Blacklist = void 0;
|
|
41
|
+
exports.CustomerMessages = exports.TaskManager = exports.LoanRetailAudit = exports.Meetings = exports.Rules = exports.PdfRender = exports.DatalakeReports = exports.RewardsEligibility = exports.Rewards = exports.DynamicForm = exports.FileStorage = exports.MoneyTransfer = exports.RetailLoan = exports.Membership = exports.WebhookBusiness = exports.PeopleBusiness = exports.UserConfirmations = exports.Collection = exports.Shipping = exports.PhoneSales = exports.Onboarding = exports.Kyc = exports.LoanScoring = exports.LoanCredit = exports.LoanCollectorAssignment = exports.LoanOfferings = exports.Shortlink = exports.LoanConfig = exports.DatalakeQuery = exports.RetailIntegration = exports.RetailPromotions = exports.RetailWizard = exports.RetailCustomer = exports.RetailCards = void 0;
|
|
42
42
|
exports.Crypto = __importStar(require("./crypto"));
|
|
43
43
|
exports.Account = __importStar(require("./account"));
|
|
44
44
|
exports.MetamapConnector = __importStar(require("./metamapConnector"));
|
|
@@ -121,6 +121,7 @@ exports.AiEngine = __importStar(require("./aiEngine"));
|
|
|
121
121
|
exports.Sentry = __importStar(require("./sentry"));
|
|
122
122
|
exports.CreditStatements = __importStar(require("./credit-statements"));
|
|
123
123
|
exports.CirculoCredito = __importStar(require("./circuloCredito"));
|
|
124
|
+
exports.GsfConnector = __importStar(require("./gsfConnector"));
|
|
124
125
|
exports.MilestoneBusiness = __importStar(require("./milestone-business"));
|
|
125
126
|
exports.Mdm = __importStar(require("./mdm"));
|
|
126
127
|
exports.MessagesConnector = __importStar(require("./messagesConnector"));
|
package/package.json
CHANGED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Fecha calendario `YYYY-MM-DD`; `IsGsfCalendarDate` además rechaza días que no existen. */
|
|
2
|
+
export const GSF_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
|
|
3
|
+
|
|
4
|
+
/** Slug de la cuenta de SofomCloud: elige las credenciales del conector. */
|
|
5
|
+
export const GSF_ACCOUNT_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
6
|
+
export const GSF_ACCOUNT_MAX_LENGTH = 64;
|
|
7
|
+
|
|
8
|
+
/** RFC de persona física: 13 caracteres. GSF pide 13 en PF. */
|
|
9
|
+
export const GSF_RFC_PF_PATTERN = /^[A-ZÑ&]{4}\d{6}[A-Z0-9]{3}$/;
|
|
10
|
+
|
|
11
|
+
/** Al menos un carácter que no sea espacio. */
|
|
12
|
+
export const GSF_NOT_BLANK_PATTERN = /\S/;
|
|
13
|
+
|
|
14
|
+
/** Tope de SQS FIFO para MessageGroupId y MessageDeduplicationId. */
|
|
15
|
+
export const GSF_QUEUE_ID_MAX_LENGTH = 128;
|
|
16
|
+
|
|
17
|
+
export const GSF_MAX_CENTS = Number.MAX_SAFE_INTEGER;
|
|
18
|
+
export const GSF_MAX_INSTALLMENTS = 1000;
|
|
19
|
+
|
|
20
|
+
/** Tasa anual máxima en decimal: 100 = 10,000 %. */
|
|
21
|
+
export const GSF_MAX_ANNUAL_RATE = 100;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { GsfOperationEnum } from '../enums/GsfOperationEnum';
|
|
2
|
+
import { GsfPaymentKindEnum } from '../enums/GsfPaymentKindEnum';
|
|
3
|
+
|
|
4
|
+
export const GSF_PAYMENT_OPERATIONS = [
|
|
5
|
+
GsfOperationEnum.APPLY_PAYMENT,
|
|
6
|
+
GsfOperationEnum.APPLY_PREPAYMENT,
|
|
7
|
+
GsfOperationEnum.SETTLE_CREDIT,
|
|
8
|
+
] as const;
|
|
9
|
+
|
|
10
|
+
export type GsfPaymentOperation = (typeof GSF_PAYMENT_OPERATIONS)[number];
|
|
11
|
+
|
|
12
|
+
/** Clases de pago que admite cada operación. Una liquidación parcial viaja como `APPLY_PAYMENT`. */
|
|
13
|
+
export const GSF_PAYMENT_KINDS_BY_OPERATION: Record<GsfPaymentOperation, readonly GsfPaymentKindEnum[]> = {
|
|
14
|
+
[GsfOperationEnum.APPLY_PAYMENT]: [GsfPaymentKindEnum.INSTALLMENT, GsfPaymentKindEnum.ADVANCE, GsfPaymentKindEnum.SETTLEMENT],
|
|
15
|
+
[GsfOperationEnum.APPLY_PREPAYMENT]: [GsfPaymentKindEnum.PREPAYMENT],
|
|
16
|
+
[GsfOperationEnum.SETTLE_CREDIT]: [GsfPaymentKindEnum.SETTLEMENT],
|
|
17
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Expose } from 'class-transformer';
|
|
2
|
+
import { IsNotEmpty, IsOptional, IsString, Matches } from 'class-validator';
|
|
3
|
+
import { ZIP_CODE_MX_PATTERN } from '../../common/constants/InputPatterns';
|
|
4
|
+
import { GSF_NOT_BLANK_PATTERN } from '../constants/GsfPatterns';
|
|
5
|
+
|
|
6
|
+
/** Domicilio del cliente con nombres; el conector los traduce a los catálogos de geografía de GSF. */
|
|
7
|
+
export class GsfAddress {
|
|
8
|
+
@Expose()
|
|
9
|
+
@IsString()
|
|
10
|
+
@IsNotEmpty()
|
|
11
|
+
@Matches(GSF_NOT_BLANK_PATTERN)
|
|
12
|
+
street: string;
|
|
13
|
+
|
|
14
|
+
@Expose()
|
|
15
|
+
@IsString()
|
|
16
|
+
@IsNotEmpty()
|
|
17
|
+
@Matches(GSF_NOT_BLANK_PATTERN)
|
|
18
|
+
externalNumber: string;
|
|
19
|
+
|
|
20
|
+
@Expose()
|
|
21
|
+
@IsOptional()
|
|
22
|
+
@IsString()
|
|
23
|
+
@Matches(GSF_NOT_BLANK_PATTERN)
|
|
24
|
+
internalNumber?: string;
|
|
25
|
+
|
|
26
|
+
@Expose()
|
|
27
|
+
@IsString()
|
|
28
|
+
@IsNotEmpty()
|
|
29
|
+
@Matches(GSF_NOT_BLANK_PATTERN)
|
|
30
|
+
neighborhood: string;
|
|
31
|
+
|
|
32
|
+
@Expose()
|
|
33
|
+
@Matches(ZIP_CODE_MX_PATTERN)
|
|
34
|
+
zipCode: string;
|
|
35
|
+
|
|
36
|
+
@Expose()
|
|
37
|
+
@IsString()
|
|
38
|
+
@IsNotEmpty()
|
|
39
|
+
@Matches(GSF_NOT_BLANK_PATTERN)
|
|
40
|
+
city: string;
|
|
41
|
+
|
|
42
|
+
/** Si falta, el conector usa la ciudad. Vacío no vale: se omite. */
|
|
43
|
+
@Expose()
|
|
44
|
+
@IsOptional()
|
|
45
|
+
@IsString()
|
|
46
|
+
@Matches(GSF_NOT_BLANK_PATTERN)
|
|
47
|
+
municipality?: string;
|
|
48
|
+
|
|
49
|
+
@Expose()
|
|
50
|
+
@IsString()
|
|
51
|
+
@IsNotEmpty()
|
|
52
|
+
@Matches(GSF_NOT_BLANK_PATTERN)
|
|
53
|
+
state: string;
|
|
54
|
+
|
|
55
|
+
@Expose()
|
|
56
|
+
@IsString()
|
|
57
|
+
@IsNotEmpty()
|
|
58
|
+
@Matches(GSF_NOT_BLANK_PATTERN)
|
|
59
|
+
country: string;
|
|
60
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Expose, Type } from 'class-transformer';
|
|
2
|
+
import {
|
|
3
|
+
ArrayMinSize, ArrayUnique, Equals, IsArray, IsDefined, IsNotEmpty, IsObject, IsString, Matches, MaxLength, ValidateNested,
|
|
4
|
+
} from 'class-validator';
|
|
5
|
+
import { GsfOperationEnum } from '../enums/GsfOperationEnum';
|
|
6
|
+
import { GsfCustomer } from './GsfCustomer';
|
|
7
|
+
import { GsfCreditTerms } from './GsfCreditTerms';
|
|
8
|
+
import { GsfScheduleInstallment } from './GsfScheduleInstallment';
|
|
9
|
+
import { GSF_ACCOUNT_MAX_LENGTH, GSF_ACCOUNT_PATTERN, GSF_NOT_BLANK_PATTERN, GSF_QUEUE_ID_MAX_LENGTH } from '../constants/GsfPatterns';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Mensaje `CREATE_CREDIT` de `GsfSyncQueue.fifo`: el crédito ya está activo en el origen. MessageGroupId =
|
|
13
|
+
* `externalCreditId`, MessageDeduplicationId = `messageId`.
|
|
14
|
+
*/
|
|
15
|
+
export class GsfCreateCreditMessage {
|
|
16
|
+
@Expose()
|
|
17
|
+
@Matches(GSF_ACCOUNT_PATTERN)
|
|
18
|
+
@MaxLength(GSF_ACCOUNT_MAX_LENGTH)
|
|
19
|
+
account: string;
|
|
20
|
+
|
|
21
|
+
@Expose()
|
|
22
|
+
@Equals(GsfOperationEnum.CREATE_CREDIT)
|
|
23
|
+
operation: GsfOperationEnum.CREATE_CREDIT;
|
|
24
|
+
|
|
25
|
+
@Expose()
|
|
26
|
+
@IsString()
|
|
27
|
+
@IsNotEmpty()
|
|
28
|
+
@Matches(GSF_NOT_BLANK_PATTERN)
|
|
29
|
+
@MaxLength(GSF_QUEUE_ID_MAX_LENGTH)
|
|
30
|
+
messageId: string;
|
|
31
|
+
|
|
32
|
+
@Expose()
|
|
33
|
+
@IsString()
|
|
34
|
+
@IsNotEmpty()
|
|
35
|
+
@Matches(GSF_NOT_BLANK_PATTERN)
|
|
36
|
+
@MaxLength(GSF_QUEUE_ID_MAX_LENGTH)
|
|
37
|
+
externalCreditId: string;
|
|
38
|
+
|
|
39
|
+
@Expose()
|
|
40
|
+
@IsDefined()
|
|
41
|
+
@IsObject()
|
|
42
|
+
@ValidateNested()
|
|
43
|
+
@Type(() => GsfCustomer)
|
|
44
|
+
customer: GsfCustomer;
|
|
45
|
+
|
|
46
|
+
@Expose()
|
|
47
|
+
@IsDefined()
|
|
48
|
+
@IsObject()
|
|
49
|
+
@ValidateNested()
|
|
50
|
+
@Type(() => GsfCreditTerms)
|
|
51
|
+
terms: GsfCreditTerms;
|
|
52
|
+
|
|
53
|
+
@Expose()
|
|
54
|
+
@IsArray()
|
|
55
|
+
@ArrayMinSize(1)
|
|
56
|
+
@ArrayUnique((installment: GsfScheduleInstallment) => installment?.installmentNumber)
|
|
57
|
+
@ValidateNested({ each: true })
|
|
58
|
+
@Type(() => GsfScheduleInstallment)
|
|
59
|
+
expectedSchedule: GsfScheduleInstallment[];
|
|
60
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Expose } from 'class-transformer';
|
|
2
|
+
import { IsEnum, IsInt, IsNumber, Max, Min, Validate } from 'class-validator';
|
|
3
|
+
import { GsfPaymentPeriodicityEnum } from '../enums/GsfPaymentPeriodicityEnum';
|
|
4
|
+
import { GSF_MAX_ANNUAL_RATE, GSF_MAX_CENTS, GSF_MAX_INSTALLMENTS } from '../constants/GsfPatterns';
|
|
5
|
+
import { IsGsfCalendarDate } from '../validators/IsGsfCalendarDate';
|
|
6
|
+
|
|
7
|
+
/** Condiciones del crédito tal como quedaron firmadas. */
|
|
8
|
+
export class GsfCreditTerms {
|
|
9
|
+
/** Monto que se amortiza, comisiones financiadas incluidas. */
|
|
10
|
+
@Expose()
|
|
11
|
+
@IsInt()
|
|
12
|
+
@Min(1)
|
|
13
|
+
@Max(GSF_MAX_CENTS)
|
|
14
|
+
amountCents: number;
|
|
15
|
+
|
|
16
|
+
@Expose()
|
|
17
|
+
@IsInt()
|
|
18
|
+
@Min(1)
|
|
19
|
+
@Max(GSF_MAX_INSTALLMENTS)
|
|
20
|
+
installmentCount: number;
|
|
21
|
+
|
|
22
|
+
@Expose()
|
|
23
|
+
@IsEnum(GsfPaymentPeriodicityEnum)
|
|
24
|
+
periodicity: GsfPaymentPeriodicityEnum;
|
|
25
|
+
|
|
26
|
+
/** Tasa anual del contrato en decimal: 2.30 = 230 %. Puede ser 0 por una promoción. */
|
|
27
|
+
@Expose()
|
|
28
|
+
@IsNumber({ allowNaN: false, allowInfinity: false })
|
|
29
|
+
@Min(0)
|
|
30
|
+
@Max(GSF_MAX_ANNUAL_RATE)
|
|
31
|
+
annualRate: number;
|
|
32
|
+
|
|
33
|
+
/** Entre cuántos periodos divide el origen la tasa anual: 52 si el interés semanal es tasa / 52. */
|
|
34
|
+
@Expose()
|
|
35
|
+
@IsInt()
|
|
36
|
+
@Min(1)
|
|
37
|
+
@Max(365)
|
|
38
|
+
periodsPerYear: number;
|
|
39
|
+
|
|
40
|
+
/** IVA sobre el interés en decimal: 0.16. */
|
|
41
|
+
@Expose()
|
|
42
|
+
@IsNumber({ allowNaN: false, allowInfinity: false })
|
|
43
|
+
@Min(0)
|
|
44
|
+
@Max(1)
|
|
45
|
+
ivaRate: number;
|
|
46
|
+
|
|
47
|
+
@Expose()
|
|
48
|
+
@Validate(IsGsfCalendarDate)
|
|
49
|
+
signedOn: string;
|
|
50
|
+
|
|
51
|
+
/** Inicio del calendario de pagos. */
|
|
52
|
+
@Expose()
|
|
53
|
+
@Validate(IsGsfCalendarDate)
|
|
54
|
+
activatedOn: string;
|
|
55
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Expose, Type } from 'class-transformer';
|
|
2
|
+
import { IsDefined, IsNotEmpty, IsObject, IsOptional, IsString, Matches, MaxLength, Validate, ValidateNested } from 'class-validator';
|
|
3
|
+
import { EMAIL_MAX_LENGTH, EMAIL_PATTERN, PHONE_MX_ACCEPTED_PATTERN } from '../../common/constants/InputPatterns';
|
|
4
|
+
import { regexCurp } from '../../helpers/constans/regex';
|
|
5
|
+
import { GsfAddress } from './GsfAddress';
|
|
6
|
+
import { GSF_NOT_BLANK_PATTERN, GSF_RFC_PF_PATTERN } from '../constants/GsfPatterns';
|
|
7
|
+
import { IsGsfCalendarDate } from '../validators/IsGsfCalendarDate';
|
|
8
|
+
|
|
9
|
+
/** Cliente persona física. Lleva datos personales: nunca se loguea. */
|
|
10
|
+
export class GsfCustomer {
|
|
11
|
+
@Expose()
|
|
12
|
+
@IsString()
|
|
13
|
+
@IsNotEmpty()
|
|
14
|
+
@Matches(GSF_NOT_BLANK_PATTERN)
|
|
15
|
+
names: string;
|
|
16
|
+
|
|
17
|
+
@Expose()
|
|
18
|
+
@IsString()
|
|
19
|
+
@IsNotEmpty()
|
|
20
|
+
@Matches(GSF_NOT_BLANK_PATTERN)
|
|
21
|
+
paternalLastName: string;
|
|
22
|
+
|
|
23
|
+
@Expose()
|
|
24
|
+
@IsOptional()
|
|
25
|
+
@IsString()
|
|
26
|
+
@Matches(GSF_NOT_BLANK_PATTERN)
|
|
27
|
+
maternalLastName?: string;
|
|
28
|
+
|
|
29
|
+
@Expose()
|
|
30
|
+
@Matches(GSF_RFC_PF_PATTERN)
|
|
31
|
+
rfc: string;
|
|
32
|
+
|
|
33
|
+
/** El conector deriva de la CURP el género y el estado de nacimiento. */
|
|
34
|
+
@Expose()
|
|
35
|
+
@Matches(regexCurp)
|
|
36
|
+
curp: string;
|
|
37
|
+
|
|
38
|
+
@Expose()
|
|
39
|
+
@Validate(IsGsfCalendarDate)
|
|
40
|
+
birthDate: string;
|
|
41
|
+
|
|
42
|
+
@Expose()
|
|
43
|
+
@IsOptional()
|
|
44
|
+
@Matches(EMAIL_PATTERN)
|
|
45
|
+
@MaxLength(EMAIL_MAX_LENGTH)
|
|
46
|
+
email?: string;
|
|
47
|
+
|
|
48
|
+
/** 10 dígitos, con o sin `+52`; el conector manda los 10 dígitos. */
|
|
49
|
+
@Expose()
|
|
50
|
+
@IsOptional()
|
|
51
|
+
@Matches(PHONE_MX_ACCEPTED_PATTERN)
|
|
52
|
+
mobilePhone?: string;
|
|
53
|
+
|
|
54
|
+
@Expose()
|
|
55
|
+
@IsDefined()
|
|
56
|
+
@IsObject()
|
|
57
|
+
@ValidateNested()
|
|
58
|
+
@Type(() => GsfAddress)
|
|
59
|
+
address: GsfAddress;
|
|
60
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Expose, Type } from 'class-transformer';
|
|
2
|
+
import { ArrayMinSize, ArrayUnique, IsArray, IsInt, IsOptional, Max, Min, ValidateNested } from 'class-validator';
|
|
3
|
+
import { GsfScheduleInstallment } from './GsfScheduleInstallment';
|
|
4
|
+
import { GSF_MAX_CENTS } from '../constants/GsfPatterns';
|
|
5
|
+
|
|
6
|
+
/** Cómo debe quedar el crédito en GSF después del pago, según el origen. */
|
|
7
|
+
export class GsfExpectedState {
|
|
8
|
+
/** Capital pendiente del crédito después del pago. */
|
|
9
|
+
@Expose()
|
|
10
|
+
@IsOptional()
|
|
11
|
+
@IsInt()
|
|
12
|
+
@Min(0)
|
|
13
|
+
@Max(GSF_MAX_CENTS)
|
|
14
|
+
principalAfterCents?: number;
|
|
15
|
+
|
|
16
|
+
/** Cuotas que el pago recalculó (abono a capital), con sus importes nuevos. */
|
|
17
|
+
@Expose()
|
|
18
|
+
@IsOptional()
|
|
19
|
+
@IsArray()
|
|
20
|
+
@ArrayMinSize(1)
|
|
21
|
+
@ArrayUnique((installment: GsfScheduleInstallment) => installment?.installmentNumber)
|
|
22
|
+
@ValidateNested({ each: true })
|
|
23
|
+
@Type(() => GsfScheduleInstallment)
|
|
24
|
+
schedule?: GsfScheduleInstallment[];
|
|
25
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Expose } from 'class-transformer';
|
|
2
|
+
import { IsEnum, IsInt, IsNotEmpty, IsOptional, IsString, Matches, Max, Min, Validate } from 'class-validator';
|
|
3
|
+
import { GsfPaymentKindEnum } from '../enums/GsfPaymentKindEnum';
|
|
4
|
+
import { GsfPaymentChannelEnum } from '../enums/GsfPaymentChannelEnum';
|
|
5
|
+
import { GSF_MAX_CENTS, GSF_NOT_BLANK_PATTERN } from '../constants/GsfPatterns';
|
|
6
|
+
import { IsGsfCalendarDate } from '../validators/IsGsfCalendarDate';
|
|
7
|
+
|
|
8
|
+
/** Un pago ya aplicado en el sistema de origen. */
|
|
9
|
+
export class GsfPayment {
|
|
10
|
+
/** Id del pago en el origen: el conector no aplica dos veces el mismo. */
|
|
11
|
+
@Expose()
|
|
12
|
+
@IsString()
|
|
13
|
+
@IsNotEmpty()
|
|
14
|
+
@Matches(GSF_NOT_BLANK_PATTERN)
|
|
15
|
+
externalPaymentId: string;
|
|
16
|
+
|
|
17
|
+
@Expose()
|
|
18
|
+
@IsEnum(GsfPaymentKindEnum)
|
|
19
|
+
kind: GsfPaymentKindEnum;
|
|
20
|
+
|
|
21
|
+
@Expose()
|
|
22
|
+
@IsEnum(GsfPaymentChannelEnum)
|
|
23
|
+
channel: GsfPaymentChannelEnum;
|
|
24
|
+
|
|
25
|
+
@Expose()
|
|
26
|
+
@IsInt()
|
|
27
|
+
@Min(1)
|
|
28
|
+
@Max(GSF_MAX_CENTS)
|
|
29
|
+
amountCents: number;
|
|
30
|
+
|
|
31
|
+
/** Día del pago en la zona del origen. */
|
|
32
|
+
@Expose()
|
|
33
|
+
@Validate(IsGsfCalendarDate)
|
|
34
|
+
appliedOn: string;
|
|
35
|
+
|
|
36
|
+
/** Desglose que aplicó el origen; sirve para conciliar. */
|
|
37
|
+
@Expose()
|
|
38
|
+
@IsOptional()
|
|
39
|
+
@IsInt()
|
|
40
|
+
@Min(0)
|
|
41
|
+
@Max(GSF_MAX_CENTS)
|
|
42
|
+
capitalCents?: number;
|
|
43
|
+
|
|
44
|
+
@Expose()
|
|
45
|
+
@IsOptional()
|
|
46
|
+
@IsInt()
|
|
47
|
+
@Min(0)
|
|
48
|
+
@Max(GSF_MAX_CENTS)
|
|
49
|
+
interestCents?: number;
|
|
50
|
+
|
|
51
|
+
@Expose()
|
|
52
|
+
@IsOptional()
|
|
53
|
+
@IsInt()
|
|
54
|
+
@Min(0)
|
|
55
|
+
@Max(GSF_MAX_CENTS)
|
|
56
|
+
ivaCents?: number;
|
|
57
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Expose, Type } from 'class-transformer';
|
|
2
|
+
import {
|
|
3
|
+
IsDefined, IsIn, IsNotEmpty, IsObject, IsString, Matches, MaxLength, Validate, ValidateIf, ValidateNested,
|
|
4
|
+
} from 'class-validator';
|
|
5
|
+
import { GsfOperationEnum } from '../enums/GsfOperationEnum';
|
|
6
|
+
import { GsfPayment } from './GsfPayment';
|
|
7
|
+
import { GsfExpectedState } from './GsfExpectedState';
|
|
8
|
+
import { GSF_PAYMENT_OPERATIONS, GsfPaymentOperation } from '../constants/GsfPaymentOperations';
|
|
9
|
+
import { GSF_ACCOUNT_MAX_LENGTH, GSF_ACCOUNT_PATTERN, GSF_NOT_BLANK_PATTERN, GSF_QUEUE_ID_MAX_LENGTH } from '../constants/GsfPatterns';
|
|
10
|
+
import { IsGsfPaymentKindForOperation } from '../validators/IsGsfPaymentKindForOperation';
|
|
11
|
+
import { IsGsfPrepaymentScheduleProvided } from '../validators/IsGsfPrepaymentScheduleProvided';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Mensaje de pago de `GsfSyncQueue.fifo`: `APPLY_PAYMENT`, `APPLY_PREPAYMENT` o `SETTLE_CREDIT`. Llega
|
|
15
|
+
* después del `CREATE_CREDIT` del mismo crédito porque comparten MessageGroupId (`externalCreditId`).
|
|
16
|
+
*/
|
|
17
|
+
export class GsfPaymentMessage {
|
|
18
|
+
@Expose()
|
|
19
|
+
@Matches(GSF_ACCOUNT_PATTERN)
|
|
20
|
+
@MaxLength(GSF_ACCOUNT_MAX_LENGTH)
|
|
21
|
+
account: string;
|
|
22
|
+
|
|
23
|
+
@Expose()
|
|
24
|
+
@IsIn([...GSF_PAYMENT_OPERATIONS])
|
|
25
|
+
operation: GsfPaymentOperation;
|
|
26
|
+
|
|
27
|
+
@Expose()
|
|
28
|
+
@IsString()
|
|
29
|
+
@IsNotEmpty()
|
|
30
|
+
@Matches(GSF_NOT_BLANK_PATTERN)
|
|
31
|
+
@MaxLength(GSF_QUEUE_ID_MAX_LENGTH)
|
|
32
|
+
messageId: string;
|
|
33
|
+
|
|
34
|
+
@Expose()
|
|
35
|
+
@IsString()
|
|
36
|
+
@IsNotEmpty()
|
|
37
|
+
@Matches(GSF_NOT_BLANK_PATTERN)
|
|
38
|
+
@MaxLength(GSF_QUEUE_ID_MAX_LENGTH)
|
|
39
|
+
externalCreditId: string;
|
|
40
|
+
|
|
41
|
+
@Expose()
|
|
42
|
+
@IsDefined()
|
|
43
|
+
@IsObject()
|
|
44
|
+
@ValidateNested()
|
|
45
|
+
@Type(() => GsfPayment)
|
|
46
|
+
@Validate(IsGsfPaymentKindForOperation)
|
|
47
|
+
payment: GsfPayment;
|
|
48
|
+
|
|
49
|
+
/** Obligatorio en `APPLY_PREPAYMENT`, con la tabla recalculada. */
|
|
50
|
+
@Expose()
|
|
51
|
+
@ValidateIf((message: GsfPaymentMessage) => message.operation === GsfOperationEnum.APPLY_PREPAYMENT || message.expected != null)
|
|
52
|
+
@IsDefined()
|
|
53
|
+
@IsObject()
|
|
54
|
+
@ValidateNested()
|
|
55
|
+
@Type(() => GsfExpectedState)
|
|
56
|
+
@Validate(IsGsfPrepaymentScheduleProvided)
|
|
57
|
+
expected?: GsfExpectedState;
|
|
58
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Expose } from 'class-transformer';
|
|
2
|
+
import { IsInt, Max, Min, Validate } from 'class-validator';
|
|
3
|
+
import { GSF_MAX_CENTS, GSF_MAX_INSTALLMENTS } from '../constants/GsfPatterns';
|
|
4
|
+
import { IsGsfCalendarDate } from '../validators/IsGsfCalendarDate';
|
|
5
|
+
|
|
6
|
+
/** Una cuota como la calculó el sistema de origen; el conector la compara contra la de GSF. */
|
|
7
|
+
export class GsfScheduleInstallment {
|
|
8
|
+
@Expose()
|
|
9
|
+
@IsInt()
|
|
10
|
+
@Min(1)
|
|
11
|
+
@Max(GSF_MAX_INSTALLMENTS)
|
|
12
|
+
installmentNumber: number;
|
|
13
|
+
|
|
14
|
+
@Expose()
|
|
15
|
+
@Validate(IsGsfCalendarDate)
|
|
16
|
+
dueDate: string;
|
|
17
|
+
|
|
18
|
+
@Expose()
|
|
19
|
+
@IsInt()
|
|
20
|
+
@Min(0)
|
|
21
|
+
@Max(GSF_MAX_CENTS)
|
|
22
|
+
capitalCents: number;
|
|
23
|
+
|
|
24
|
+
@Expose()
|
|
25
|
+
@IsInt()
|
|
26
|
+
@Min(0)
|
|
27
|
+
@Max(GSF_MAX_CENTS)
|
|
28
|
+
interestCents: number;
|
|
29
|
+
|
|
30
|
+
@Expose()
|
|
31
|
+
@IsInt()
|
|
32
|
+
@Min(0)
|
|
33
|
+
@Max(GSF_MAX_CENTS)
|
|
34
|
+
ivaCents: number;
|
|
35
|
+
|
|
36
|
+
@Expose()
|
|
37
|
+
@IsInt()
|
|
38
|
+
@Min(0)
|
|
39
|
+
@Max(GSF_MAX_CENTS)
|
|
40
|
+
totalCents: number;
|
|
41
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Operación que pide un mensaje de `GsfSyncQueue.fifo`. */
|
|
2
|
+
export enum GsfOperationEnum {
|
|
3
|
+
/** Alta del cliente y del crédito ya activo, con la tabla que se espera ver en GSF. */
|
|
4
|
+
CREATE_CREDIT = 'CREATE_CREDIT',
|
|
5
|
+
/** Pago de una cuota, adelanto de cuotas o liquidación parcial. */
|
|
6
|
+
APPLY_PAYMENT = 'APPLY_PAYMENT',
|
|
7
|
+
/** Abono a capital: GSF reestructura la tabla y se compara con la esperada. */
|
|
8
|
+
APPLY_PREPAYMENT = 'APPLY_PREPAYMENT',
|
|
9
|
+
/** Pago que liquida el crédito. */
|
|
10
|
+
SETTLE_CREDIT = 'SETTLE_CREDIT',
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Por dónde entró el dinero de un pago. */
|
|
2
|
+
export enum GsfPaymentChannelEnum {
|
|
3
|
+
/** Cargo automático a la tarjeta del cliente. */
|
|
4
|
+
AUTOMATIC_CARD_CHARGE = 'AUTOMATIC_CARD_CHARGE',
|
|
5
|
+
/** Efectivo en ventanilla o caja. */
|
|
6
|
+
CASH = 'CASH',
|
|
7
|
+
/** Tarjeta en ventanilla o caja. */
|
|
8
|
+
CARD = 'CARD',
|
|
9
|
+
/** Transferencia bancaria. */
|
|
10
|
+
WIRE_TRANSFER = 'WIRE_TRANSFER',
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Para qué se aplicó un pago en el sistema de origen. */
|
|
2
|
+
export enum GsfPaymentKindEnum {
|
|
3
|
+
/** Cuota del periodo. */
|
|
4
|
+
INSTALLMENT = 'INSTALLMENT',
|
|
5
|
+
/** Cuotas futuras cubiertas tal cual: la tabla no cambia. */
|
|
6
|
+
ADVANCE = 'ADVANCE',
|
|
7
|
+
/** Abono a capital: baja las cuotas restantes. */
|
|
8
|
+
PREPAYMENT = 'PREPAYMENT',
|
|
9
|
+
/** Liquidación del crédito. */
|
|
10
|
+
SETTLEMENT = 'SETTLEMENT',
|
|
11
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Enums
|
|
2
|
+
export * from './enums/GsfOperationEnum';
|
|
3
|
+
export * from './enums/GsfPaymentKindEnum';
|
|
4
|
+
export * from './enums/GsfPaymentChannelEnum';
|
|
5
|
+
export * from './enums/GsfPaymentPeriodicityEnum';
|
|
6
|
+
|
|
7
|
+
// Constants
|
|
8
|
+
export * from './constants/GsfPatterns';
|
|
9
|
+
export * from './constants/GsfPaymentOperations';
|
|
10
|
+
|
|
11
|
+
// Validators
|
|
12
|
+
export * from './validators/IsGsfCalendarDate';
|
|
13
|
+
export * from './validators/IsGsfPaymentKindForOperation';
|
|
14
|
+
export * from './validators/IsGsfPrepaymentScheduleProvided';
|
|
15
|
+
|
|
16
|
+
// DTOs del mensaje de GsfSyncQueue.fifo
|
|
17
|
+
export * from './dtos/GsfAddress';
|
|
18
|
+
export * from './dtos/GsfCustomer';
|
|
19
|
+
export * from './dtos/GsfScheduleInstallment';
|
|
20
|
+
export * from './dtos/GsfCreditTerms';
|
|
21
|
+
export * from './dtos/GsfPayment';
|
|
22
|
+
export * from './dtos/GsfExpectedState';
|
|
23
|
+
export * from './dtos/GsfCreateCreditMessage';
|
|
24
|
+
export * from './dtos/GsfPaymentMessage';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ValidatorConstraint, ValidationArguments, ValidatorConstraintInterface } from 'class-validator';
|
|
2
|
+
import { GSF_DATE_PATTERN } from '../constants/GsfPatterns';
|
|
3
|
+
|
|
4
|
+
/** `YYYY-MM-DD` de un día que existe: rechaza `2026-02-30` o `2026-13-01`, que el patrón solo no detecta. */
|
|
5
|
+
@ValidatorConstraint({ name: 'isGsfCalendarDate', async: false })
|
|
6
|
+
export class IsGsfCalendarDate implements ValidatorConstraintInterface {
|
|
7
|
+
validate(value: unknown, _args: ValidationArguments): boolean {
|
|
8
|
+
if (typeof value !== 'string' || !GSF_DATE_PATTERN.test(value)) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
const [year, month, day] = value.split('-').map(Number);
|
|
12
|
+
const date = new Date(Date.UTC(year, month - 1, day));
|
|
13
|
+
return date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
defaultMessage(args: ValidationArguments): string {
|
|
17
|
+
return `${args.property} debe ser una fecha YYYY-MM-DD que exista`;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ValidatorConstraint, ValidationArguments, ValidatorConstraintInterface } from 'class-validator';
|
|
2
|
+
import { GSF_PAYMENT_KINDS_BY_OPERATION, GSF_PAYMENT_OPERATIONS, GsfPaymentOperation } from '../constants/GsfPaymentOperations';
|
|
3
|
+
|
|
4
|
+
/** La clase del pago tiene que corresponder a la operación del mensaje: un abono solo viaja como abono. */
|
|
5
|
+
@ValidatorConstraint({ name: 'isGsfPaymentKindForOperation', async: false })
|
|
6
|
+
export class IsGsfPaymentKindForOperation implements ValidatorConstraintInterface {
|
|
7
|
+
validate(value: unknown, args: ValidationArguments): boolean {
|
|
8
|
+
const operation = (args.object as { operation?: unknown }).operation;
|
|
9
|
+
// Sin operación válida el error ya lo marca `operation`. Se compara contra la lista para que
|
|
10
|
+
// `constructor` o `__proto__` no lean el prototipo del mapa.
|
|
11
|
+
if (!GSF_PAYMENT_OPERATIONS.includes(operation as GsfPaymentOperation)) {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
const kind = (value as { kind?: unknown } | null | undefined)?.kind;
|
|
15
|
+
return GSF_PAYMENT_KINDS_BY_OPERATION[operation as GsfPaymentOperation].includes(kind as never);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
defaultMessage(args: ValidationArguments): string {
|
|
19
|
+
return `${args.property}.kind no corresponde a la operación del mensaje`;
|
|
20
|
+
}
|
|
21
|
+
}
|