@fiado/type-kit 3.645.0 → 3.646.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.
Files changed (35) hide show
  1. package/_test_/unit/collection/authorizeCollectionMovementRequest.test.ts +15 -0
  2. package/_test_/unit/collection/costCenter.test.ts +54 -0
  3. package/_test_/unit/collection/disburseRequest.test.ts +15 -0
  4. package/_test_/unit/reconciliation/reconciliationRequests.test.ts +15 -0
  5. package/_test_/unit/transaction/transactionCreateRequestM8.test.ts +21 -6
  6. package/bin/collection/dtos/AuthorizeCollectionMovementRequest.d.ts +9 -0
  7. package/bin/collection/dtos/AuthorizeCollectionMovementRequest.js +6 -0
  8. package/bin/collection/dtos/CollectionProductConfigDto.d.ts +2 -0
  9. package/bin/collection/dtos/CollectionProductConfigDto.js +6 -0
  10. package/bin/collection/dtos/DisburseRequest.d.ts +5 -0
  11. package/bin/collection/dtos/DisburseRequest.js +6 -0
  12. package/bin/collection/dtos/UpsertProductConfigRequest.d.ts +2 -0
  13. package/bin/collection/dtos/UpsertProductConfigRequest.js +6 -0
  14. package/bin/reconciliation/dtos/ReconciliationDefinition.d.ts +2 -0
  15. package/bin/reconciliation/dtos/requests/ReconciliationFeedRequests.d.ts +5 -0
  16. package/bin/reconciliation/dtos/requests/ReconciliationFeedRequests.js +9 -0
  17. package/bin/transaction/constants/costCenter.d.ts +5 -0
  18. package/bin/transaction/constants/costCenter.js +8 -0
  19. package/bin/transaction/dtos/TransactionCreateRequest.d.ts +5 -2
  20. package/bin/transaction/dtos/TransactionCreateRequest.js +1 -1
  21. package/bin/transaction/index.d.ts +1 -0
  22. package/bin/transaction/index.js +2 -0
  23. package/bin/transactionProcessor/dtos/AuthorizeBonusRequest.d.ts +2 -0
  24. package/bin/transactionProcessor/dtos/AuthorizeBonusRequest.js +6 -0
  25. package/package.json +1 -1
  26. package/src/collection/dtos/AuthorizeCollectionMovementRequest.ts +10 -1
  27. package/src/collection/dtos/CollectionProductConfigDto.ts +3 -1
  28. package/src/collection/dtos/DisburseRequest.ts +6 -0
  29. package/src/collection/dtos/UpsertProductConfigRequest.ts +3 -1
  30. package/src/reconciliation/dtos/ReconciliationDefinition.ts +2 -0
  31. package/src/reconciliation/dtos/requests/ReconciliationFeedRequests.ts +14 -2
  32. package/src/transaction/constants/costCenter.ts +5 -0
  33. package/src/transaction/dtos/TransactionCreateRequest.ts +5 -2
  34. package/src/transaction/index.ts +3 -0
  35. package/src/transactionProcessor/dtos/AuthorizeBonusRequest.ts +7 -1
@@ -31,3 +31,18 @@ describe('AuthorizeCollectionMovementRequest.tenantId', () => {
31
31
  expect(await invalidProperties({ ...VALID, tenantId: 42 })).toEqual(['tenantId']);
32
32
  });
33
33
  });
34
+
35
+ describe('AuthorizeCollectionMovementRequest.costCenterId', () => {
36
+ it('es opcional', async () => {
37
+ expect(await invalidProperties(VALID)).toEqual([]);
38
+ });
39
+
40
+ it('acepta el centro de costo del producto', async () => {
41
+ expect(await invalidProperties({ ...VALID, costCenterId: 'SK-COBRANZA' })).toEqual([]);
42
+ });
43
+
44
+ it('rechaza costCenterId vacío o no string', async () => {
45
+ expect(await invalidProperties({ ...VALID, costCenterId: '' })).toEqual(['costCenterId']);
46
+ expect(await invalidProperties({ ...VALID, costCenterId: 42 })).toEqual(['costCenterId']);
47
+ });
48
+ });
@@ -0,0 +1,54 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validate } from 'class-validator';
4
+ import { CollectionProductConfigDto, UpsertProductConfigRequest } from '../../../src/collection/index';
5
+ import { AuthorizeBonusRequest } from '../../../src/transactionProcessor/index';
6
+
7
+ async function invalidProperties<T extends object>(cls: new () => T, body: Record<string, unknown>): Promise<string[]> {
8
+ return (await validate(plainToInstance(cls, body) as object)).map((e) => e.property);
9
+ }
10
+
11
+ const UPSERT = {
12
+ sources: [{ order: 1, wallet: 'MXN', currency: 'MXN', mechanism: 'MXN_DIRECT', provider: 'wallet' }],
13
+ allowPartial: false,
14
+ retryPolicy: { maxAttempts: 3, backoffSeconds: 60 },
15
+ reportTargets: [],
16
+ };
17
+
18
+ const CONFIG = {
19
+ ...UPSERT,
20
+ tenantId: 'surekeep',
21
+ productId: 'loan',
22
+ version: 1,
23
+ createdBy: 'system',
24
+ updatedBy: 'system',
25
+ };
26
+
27
+ const BONUS = {
28
+ idempotencyKey: 'bonus-1',
29
+ productCatalogId: 'cat-1',
30
+ amount: 50,
31
+ directoryId: 'dir-1',
32
+ concept: 'Bono SureKeep',
33
+ };
34
+
35
+ describe.each([
36
+ ['CollectionProductConfigDto', CollectionProductConfigDto, CONFIG],
37
+ ['UpsertProductConfigRequest', UpsertProductConfigRequest, UPSERT],
38
+ ['AuthorizeBonusRequest', AuthorizeBonusRequest, BONUS],
39
+ ] as const)('%s.costCenterId', (_name, cls, valid) => {
40
+ const klass = cls as unknown as new () => object;
41
+
42
+ it('es opcional', async () => {
43
+ expect(await invalidProperties(klass, valid)).toEqual([]);
44
+ });
45
+
46
+ it('acepta un centro de costo', async () => {
47
+ expect(await invalidProperties(klass, { ...valid, costCenterId: 'SK-COBRANZA' })).toEqual([]);
48
+ });
49
+
50
+ it('rechaza vacío o no string', async () => {
51
+ expect(await invalidProperties(klass, { ...valid, costCenterId: '' })).toEqual(['costCenterId']);
52
+ expect(await invalidProperties(klass, { ...valid, costCenterId: 3 })).toEqual(['costCenterId']);
53
+ });
54
+ });
@@ -130,3 +130,18 @@ describe('DisburseResponse', () => {
130
130
  expect(await validate(plainToInstance(DisburseResponse, { transactionId: null }) as object)).toHaveLength(0);
131
131
  });
132
132
  });
133
+
134
+ describe('DisburseRequest.costCenterId', () => {
135
+ it('es opcional', async () => {
136
+ expect(await invalidProperties(VALID)).toEqual([]);
137
+ });
138
+
139
+ it('acepta el centro de costo de quien dispersa', async () => {
140
+ expect(await invalidProperties({ ...VALID, costCenterId: 'SK-BONOS' })).toEqual([]);
141
+ });
142
+
143
+ it('rechaza vacío o no string', async () => {
144
+ expect(await invalidProperties({ ...VALID, costCenterId: '' })).toEqual(['costCenterId']);
145
+ expect(await invalidProperties({ ...VALID, costCenterId: 9 })).toEqual(['costCenterId']);
146
+ });
147
+ });
@@ -206,6 +206,21 @@ describe('feed genérico de los dueños', () => {
206
206
  );
207
207
  });
208
208
 
209
+ it('costCenterIds es opcional y llega como csv del query', () => {
210
+ const base = { tenantId: 'surekeep', from: '2026-10-19T06:00:00.000Z', to: '2026-10-26T05:59:59.999Z' };
211
+ expect(errorsOf(PrivateListReconciliationFeedQuery, base)).toEqual([]);
212
+ expect(errorsOf(PrivateListReconciliationFeedQuery, { ...base, costCenterIds: 'SK-COBRANZA, SK-BONOS' })).toEqual([]);
213
+ const dto = plainToInstance(PrivateListReconciliationFeedQuery, { ...base, costCenterIds: 'SK-COBRANZA, SK-BONOS' }, { excludeExtraneousValues: true });
214
+ expect(dto.costCenterIds).toEqual(['SK-COBRANZA', 'SK-BONOS']);
215
+ expect(errorsOf(PrivateListReconciliationFeedQuery, { ...base, costCenterIds: ['SK-COBRANZA'] })).toEqual([]);
216
+ });
217
+
218
+ it('costCenterIds rechaza elementos vacíos', () => {
219
+ const base = { tenantId: 'surekeep', from: '2026-10-19T06:00:00.000Z', to: '2026-10-26T05:59:59.999Z' };
220
+ expect(errorsOf(PrivateListReconciliationFeedQuery, { ...base, costCenterIds: 'SK-COBRANZA,' })).toContain('costCenterIds');
221
+ expect(errorsOf(PrivateListReconciliationFeedQuery, { ...base, costCenterIds: '' })).toContain('costCenterIds');
222
+ });
223
+
209
224
  it('el registro por recordId pide tenant y el servicio que llama; el actor es opcional', () => {
210
225
  expect(errorsOf(PrivateGetReconciliationFeedRecordQuery, { tenantId: 'surekeep', author: 'reconciliation-engine-business' })).toEqual(
211
226
  [],
@@ -1,27 +1,42 @@
1
1
  import 'reflect-metadata';
2
2
  import { plainToInstance } from 'class-transformer';
3
3
  import { validateSync } from 'class-validator';
4
- import { TransactionCreateRequest } from '../../../src/transaction';
4
+ import { TransactionCreateRequest, UNASSIGNED_COST_CENTER_ID } from '../../../src/transaction';
5
5
 
6
6
  function errorPropsOf(payload: Record<string, unknown>): string[] {
7
7
  return validateSync(plainToInstance(TransactionCreateRequest, payload)).map((e) => e.property);
8
8
  }
9
9
 
10
- describe('TransactionCreateRequest · executionId y tenant SOFOM', () => {
10
+ describe('TransactionCreateRequest · executionId y centro de costo', () => {
11
11
  it('ambos son opcionales', () => {
12
12
  const props = errorPropsOf({});
13
13
  expect(props).not.toContain('executionId');
14
- expect(props).not.toContain('sofomTenantId');
14
+ expect(props).not.toContain('costCenterId');
15
15
  });
16
16
 
17
17
  it('acepta strings no vacíos', () => {
18
- const props = errorPropsOf({ executionId: 'exec-1', sofomTenantId: 'surekeep' });
18
+ const props = errorPropsOf({ executionId: 'exec-1', costCenterId: 'SK-COBRANZA' });
19
19
  expect(props).not.toContain('executionId');
20
- expect(props).not.toContain('sofomTenantId');
20
+ expect(props).not.toContain('costCenterId');
21
+ });
22
+
23
+ it('acepta el centro de costo sin asignar', () => {
24
+ expect(errorPropsOf({ costCenterId: UNASSIGNED_COST_CENTER_ID })).not.toContain('costCenterId');
21
25
  });
22
26
 
23
27
  it('rechaza tipos que no son string o vacíos', () => {
24
28
  expect(errorPropsOf({ executionId: 12 })).toContain('executionId');
25
- expect(errorPropsOf({ sofomTenantId: '' })).toContain('sofomTenantId');
29
+ expect(errorPropsOf({ costCenterId: '' })).toContain('costCenterId');
30
+ expect(errorPropsOf({ costCenterId: 7 })).toContain('costCenterId');
31
+ });
32
+
33
+ it('ya no declara el tenant SOFOM', () => {
34
+ expect(errorPropsOf({ sofomTenantId: '' })).not.toContain('sofomTenantId');
35
+ });
36
+ });
37
+
38
+ describe('UNASSIGNED_COST_CENTER_ID', () => {
39
+ it('es UNASSIGNED', () => {
40
+ expect(UNASSIGNED_COST_CENTER_ID).toBe('UNASSIGNED');
26
41
  });
27
42
  });
@@ -11,7 +11,16 @@ export declare class AuthorizeCollectionMovementRequest {
11
11
  intentId?: string;
12
12
  chargeId?: string;
13
13
  holdTxId?: string;
14
+ /**
15
+ * Tenant SOFOM del intento de cobro. Se conserva por compatibilidad con transaction-processor; el
16
+ * ledger ya no lo usa: la pertenencia contable del movimiento viaja en `costCenterId`.
17
+ */
14
18
  tenantId?: string;
19
+ /**
20
+ * Centro de costo del producto cobrado, tomado de su configuración en el motor. El processor lo
21
+ * escribe en la transacción del ledger; ausente, queda como `UNASSIGNED`.
22
+ */
23
+ costCenterId?: string;
15
24
  /**
16
25
  * Tarifa con la que se registra el cobro. Presente, el movimiento deja además una transacción
17
26
  * Fiado: asiento contable, historial visible para el cliente y comisión declarada. Ausente, el
@@ -63,6 +63,12 @@ __decorate([
63
63
  (0, class_validator_1.IsNotEmpty)(),
64
64
  __metadata("design:type", String)
65
65
  ], AuthorizeCollectionMovementRequest.prototype, "tenantId", void 0);
66
+ __decorate([
67
+ (0, class_validator_1.IsOptional)(),
68
+ (0, class_validator_1.IsString)(),
69
+ (0, class_validator_1.IsNotEmpty)(),
70
+ __metadata("design:type", String)
71
+ ], AuthorizeCollectionMovementRequest.prototype, "costCenterId", void 0);
66
72
  __decorate([
67
73
  (0, class_validator_1.IsOptional)(),
68
74
  (0, class_validator_1.ValidateNested)(),
@@ -17,6 +17,8 @@ export declare class CollectionProductConfigDto {
17
17
  allowPartial: boolean;
18
18
  retryPolicy: RetryPolicyDto;
19
19
  reportTargets: string[];
20
+ /** Centro de costo con el que el ledger registra los cobros de este producto. */
21
+ costCenterId?: string;
20
22
  createdBy: string;
21
23
  updatedBy: string;
22
24
  }
@@ -58,6 +58,12 @@ __decorate([
58
58
  (0, class_validator_1.IsString)({ each: true }),
59
59
  __metadata("design:type", Array)
60
60
  ], CollectionProductConfigDto.prototype, "reportTargets", void 0);
61
+ __decorate([
62
+ (0, class_validator_1.IsOptional)(),
63
+ (0, class_validator_1.IsString)(),
64
+ (0, class_validator_1.IsNotEmpty)(),
65
+ __metadata("design:type", String)
66
+ ], CollectionProductConfigDto.prototype, "costCenterId", void 0);
61
67
  __decorate([
62
68
  (0, class_validator_1.IsString)(),
63
69
  __metadata("design:type", String)
@@ -18,6 +18,11 @@ export declare class DisburseRequest {
18
18
  concept: string;
19
19
  /** Id del llamador para rastreo: asiento, crédito. */
20
20
  reference?: string;
21
+ /**
22
+ * Centro de costo de la dispersión, tomado de la configuración de quien dispersa. El motor lo
23
+ * reenvía al processor en `AuthorizeBonusRequest.costCenterId`; ausente, el ledger escribe `UNASSIGNED`.
24
+ */
25
+ costCenterId?: string;
21
26
  /** Datos de la recarga. Obligatorio si `disbursementType` es `MEX_REWARD_TOPUP`; en otros tipos se ignora. */
22
27
  topup?: DisburseTopupDetail;
23
28
  }
@@ -64,6 +64,12 @@ __decorate([
64
64
  (0, class_validator_1.IsString)(),
65
65
  __metadata("design:type", String)
66
66
  ], DisburseRequest.prototype, "reference", void 0);
67
+ __decorate([
68
+ (0, class_validator_1.IsOptional)(),
69
+ (0, class_validator_1.IsString)(),
70
+ (0, class_validator_1.IsNotEmpty)(),
71
+ __metadata("design:type", String)
72
+ ], DisburseRequest.prototype, "costCenterId", void 0);
67
73
  __decorate([
68
74
  (0, class_validator_1.ValidateIf)((o) => o.disbursementType === DisbursementType_1.DisbursementType.MEX_REWARD_TOPUP),
69
75
  (0, class_validator_1.IsDefined)(),
@@ -9,4 +9,6 @@ export declare class UpsertProductConfigRequest {
9
9
  allowPartial: boolean;
10
10
  retryPolicy: RetryPolicyDto;
11
11
  reportTargets: string[];
12
+ /** Centro de costo con el que el ledger registra los cobros de este producto. */
13
+ costCenterId?: string;
12
14
  }
@@ -41,3 +41,9 @@ __decorate([
41
41
  (0, class_validator_1.IsString)({ each: true }),
42
42
  __metadata("design:type", Array)
43
43
  ], UpsertProductConfigRequest.prototype, "reportTargets", void 0);
44
+ __decorate([
45
+ (0, class_validator_1.IsOptional)(),
46
+ (0, class_validator_1.IsString)(),
47
+ (0, class_validator_1.IsNotEmpty)(),
48
+ __metadata("design:type", String)
49
+ ], UpsertProductConfigRequest.prototype, "costCenterId", void 0);
@@ -11,6 +11,8 @@ export interface ReconciliationDefinitionSource {
11
11
  domain: ReconciliationFeedOwnerEnum;
12
12
  concept: ReconciliationFeedConceptEnum;
13
13
  partName?: string;
14
+ /** Centros de costo del ledger que pertenecen al tenant; el feed solo devuelve esos. */
15
+ costCenterIds?: string[];
14
16
  }
15
17
  /** Cuenta de FSA cuyo EdC lee una definición BANK_STATEMENT. */
16
18
  export interface ReconciliationDefinitionBankAccountView {
@@ -13,6 +13,11 @@ export declare class PrivateListReconciliationFeedQuery {
13
13
  from: string;
14
14
  to: string;
15
15
  cursor?: string;
16
+ /**
17
+ * Centros de costo del tenant, en csv (`a,b`). El dueño del feed filtra por ellos; sin la
18
+ * lista responde vacío, nunca el ledger completo.
19
+ */
20
+ costCenterIds?: string[];
16
21
  }
17
22
  /** Query de privateGetReconciliationFeedRecord; `author` y `actor` van al registro de acceso del dueño. */
18
23
  export declare class PrivateGetReconciliationFeedRecordQuery {
@@ -53,6 +53,15 @@ __decorate([
53
53
  (0, reconciliationRequestDecorators_1.PageToken)(),
54
54
  __metadata("design:type", String)
55
55
  ], PrivateListReconciliationFeedQuery.prototype, "cursor", void 0);
56
+ __decorate([
57
+ (0, class_transformer_1.Expose)(),
58
+ (0, class_validator_1.IsOptional)(),
59
+ (0, class_transformer_1.Transform)(({ value }) => (typeof value === 'string' ? value.split(',').map((id) => id.trim()) : value)),
60
+ (0, class_validator_1.IsArray)(),
61
+ (0, class_validator_1.IsString)({ each: true }),
62
+ (0, class_validator_1.IsNotEmpty)({ each: true }),
63
+ __metadata("design:type", Array)
64
+ ], PrivateListReconciliationFeedQuery.prototype, "costCenterIds", void 0);
56
65
  /** Query de privateGetReconciliationFeedRecord; `author` y `actor` van al registro de acceso del dueño. */
57
66
  class PrivateGetReconciliationFeedRecordQuery {
58
67
  }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Centro de costo de una transacción que llegó sin uno. El ledger lo escribe siempre, así que las
3
+ * transacciones sin dueño contable quedan agrupadas aquí en lugar de perderse del índice.
4
+ */
5
+ export declare const UNASSIGNED_COST_CENTER_ID = "UNASSIGNED";
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UNASSIGNED_COST_CENTER_ID = void 0;
4
+ /**
5
+ * Centro de costo de una transacción que llegó sin uno. El ledger lo escribe siempre, así que las
6
+ * transacciones sin dueño contable quedan agrupadas aquí en lugar de perderse del índice.
7
+ */
8
+ exports.UNASSIGNED_COST_CENTER_ID = 'UNASSIGNED';
@@ -56,6 +56,9 @@ export declare class TransactionCreateRequest {
56
56
  domFolio?: string;
57
57
  /** Intento del motor de cobro que originó el cargo; en cobranza es igual al `attemptId`. */
58
58
  executionId?: string;
59
- /** Tenant SOFOM dueño del cobro; `tenantId` del ledger sigue siendo `FIADO`. */
60
- sofomTenantId?: string;
59
+ /**
60
+ * Centro de costo contable de la transacción; con él se reparte el ledger entre dueños y
61
+ * conciliaciones. Si no llega, el ledger escribe `UNASSIGNED_COST_CENTER_ID`.
62
+ */
63
+ costCenterId?: string;
61
64
  }
@@ -211,4 +211,4 @@ __decorate([
211
211
  (0, class_validator_1.IsNotEmpty)(),
212
212
  (0, class_validator_1.IsOptional)(),
213
213
  __metadata("design:type", String)
214
- ], TransactionCreateRequest.prototype, "sofomTenantId", void 0);
214
+ ], TransactionCreateRequest.prototype, "costCenterId", void 0);
@@ -36,6 +36,7 @@ export * from './dtos/internal/ProviderTransactionReversalRequest';
36
36
  export * from './dtos/internal/ProviderTransactionReversalResponse';
37
37
  export * from './dtos/internal/ProviderTransactionCompletionRequest';
38
38
  export * from './dtos/internal/ProviderTransactionCompletionResponse';
39
+ export * from './constants/costCenter';
39
40
  export * from './enums/OperationEnum';
40
41
  export * from './enums/TransactionSourceEnum';
41
42
  export * from './enums/TransactionStatusEnum';
@@ -53,6 +53,8 @@ __exportStar(require("./dtos/internal/ProviderTransactionReversalRequest"), expo
53
53
  __exportStar(require("./dtos/internal/ProviderTransactionReversalResponse"), exports);
54
54
  __exportStar(require("./dtos/internal/ProviderTransactionCompletionRequest"), exports);
55
55
  __exportStar(require("./dtos/internal/ProviderTransactionCompletionResponse"), exports);
56
+ //constants
57
+ __exportStar(require("./constants/costCenter"), exports);
56
58
  //enums
57
59
  __exportStar(require("./enums/OperationEnum"), exports);
58
60
  __exportStar(require("./enums/TransactionSourceEnum"), exports);
@@ -15,5 +15,7 @@ export declare class AuthorizeBonusRequest {
15
15
  directoryId: string;
16
16
  /** Lo que el cliente ve como descripción de su movimiento. */
17
17
  concept: string;
18
+ /** Centro de costo del bono en el ledger; ausente, el processor escribe `UNASSIGNED`. */
19
+ costCenterId?: string;
18
20
  }
19
21
  export default AuthorizeBonusRequest;
@@ -47,4 +47,10 @@ __decorate([
47
47
  (0, class_validator_1.MaxLength)(120),
48
48
  __metadata("design:type", String)
49
49
  ], AuthorizeBonusRequest.prototype, "concept", void 0);
50
+ __decorate([
51
+ (0, class_validator_1.IsOptional)(),
52
+ (0, class_validator_1.IsString)(),
53
+ (0, class_validator_1.IsNotEmpty)(),
54
+ __metadata("design:type", String)
55
+ ], AuthorizeBonusRequest.prototype, "costCenterId", void 0);
50
56
  exports.default = AuthorizeBonusRequest;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/type-kit",
3
- "version": "3.645.0",
3
+ "version": "3.646.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",
@@ -14,9 +14,18 @@ export class AuthorizeCollectionMovementRequest {
14
14
  @IsOptional() @IsString() intentId?: string;
15
15
  @IsOptional() @IsString() chargeId?: string;
16
16
  @IsOptional() @IsString() holdTxId?: string;
17
- // Tenant SOFOM del intento de cobro; transaction-processor lo asienta como `sofomTenantId`.
17
+ /**
18
+ * Tenant SOFOM del intento de cobro. Se conserva por compatibilidad con transaction-processor; el
19
+ * ledger ya no lo usa: la pertenencia contable del movimiento viaja en `costCenterId`.
20
+ */
18
21
  @IsOptional() @IsString() @IsNotEmpty() tenantId?: string;
19
22
 
23
+ /**
24
+ * Centro de costo del producto cobrado, tomado de su configuración en el motor. El processor lo
25
+ * escribe en la transacción del ledger; ausente, queda como `UNASSIGNED`.
26
+ */
27
+ @IsOptional() @IsString() @IsNotEmpty() costCenterId?: string;
28
+
20
29
  /**
21
30
  * Tarifa con la que se registra el cobro. Presente, el movimiento deja además una transacción
22
31
  * Fiado: asiento contable, historial visible para el cliente y comisión declarada. Ausente, el
@@ -1,4 +1,4 @@
1
- import { IsString, IsInt, IsArray, IsBoolean, ValidateNested } from 'class-validator';
1
+ import { IsString, IsInt, IsArray, IsBoolean, IsNotEmpty, IsOptional, ValidateNested } from 'class-validator';
2
2
  import { Type } from 'class-transformer';
3
3
  import { CollectionSourceDto } from './CollectionSourceDto';
4
4
  import { RetryPolicyDto } from './RetryPolicyDto';
@@ -20,6 +20,8 @@ export class CollectionProductConfigDto {
20
20
  @IsBoolean() allowPartial!: boolean;
21
21
  @ValidateNested() @Type(() => RetryPolicyDto) retryPolicy!: RetryPolicyDto;
22
22
  @IsArray() @IsString({ each: true }) reportTargets!: string[];
23
+ /** Centro de costo con el que el ledger registra los cobros de este producto. */
24
+ @IsOptional() @IsString() @IsNotEmpty() costCenterId?: string;
23
25
  @IsString() createdBy!: string;
24
26
  @IsString() updatedBy!: string;
25
27
  }
@@ -30,6 +30,12 @@ export class DisburseRequest {
30
30
  /** Id del llamador para rastreo: asiento, crédito. */
31
31
  @IsOptional() @IsString() reference?: string;
32
32
 
33
+ /**
34
+ * Centro de costo de la dispersión, tomado de la configuración de quien dispersa. El motor lo
35
+ * reenvía al processor en `AuthorizeBonusRequest.costCenterId`; ausente, el ledger escribe `UNASSIGNED`.
36
+ */
37
+ @IsOptional() @IsString() @IsNotEmpty() costCenterId?: string;
38
+
33
39
  /** Datos de la recarga. Obligatorio si `disbursementType` es `MEX_REWARD_TOPUP`; en otros tipos se ignora. */
34
40
  @ValidateIf((o: DisburseRequest) => o.disbursementType === DisbursementType.MEX_REWARD_TOPUP)
35
41
  @IsDefined()
@@ -1,4 +1,4 @@
1
- import { IsString, IsArray, IsBoolean, ValidateNested } from 'class-validator';
1
+ import { IsString, IsArray, IsBoolean, IsNotEmpty, IsOptional, ValidateNested } from 'class-validator';
2
2
  import { Type } from 'class-transformer';
3
3
  import { CollectionSourceDto } from './CollectionSourceDto';
4
4
  import { RetryPolicyDto } from './RetryPolicyDto';
@@ -12,4 +12,6 @@ export class UpsertProductConfigRequest {
12
12
  @IsBoolean() allowPartial!: boolean;
13
13
  @ValidateNested() @Type(() => RetryPolicyDto) retryPolicy!: RetryPolicyDto;
14
14
  @IsArray() @IsString({ each: true }) reportTargets!: string[];
15
+ /** Centro de costo con el que el ledger registra los cobros de este producto. */
16
+ @IsOptional() @IsString() @IsNotEmpty() costCenterId?: string;
15
17
  }
@@ -12,6 +12,8 @@ export interface ReconciliationDefinitionSource {
12
12
  domain: ReconciliationFeedOwnerEnum;
13
13
  concept: ReconciliationFeedConceptEnum;
14
14
  partName?: string;
15
+ /** Centros de costo del ledger que pertenecen al tenant; el feed solo devuelve esos. */
16
+ costCenterIds?: string[];
15
17
  }
16
18
 
17
19
  /** Cuenta de FSA cuyo EdC lee una definición BANK_STATEMENT. */
@@ -1,5 +1,5 @@
1
- import { Expose } from 'class-transformer';
2
- import { IsEnum, IsISO8601 } from 'class-validator';
1
+ import { Expose, Transform } from 'class-transformer';
2
+ import { IsArray, IsEnum, IsISO8601, IsNotEmpty, IsOptional, IsString } from 'class-validator';
3
3
  import { ReconciliationFeedConceptEnum } from '../../enums/ReconciliationFeedConceptEnum';
4
4
  import { OptionalEmail, PageToken, RequiredId } from './reconciliationRequestDecorators';
5
5
 
@@ -31,6 +31,18 @@ export class PrivateListReconciliationFeedQuery {
31
31
 
32
32
  @PageToken()
33
33
  cursor?: string;
34
+
35
+ /**
36
+ * Centros de costo del tenant, en csv (`a,b`). El dueño del feed filtra por ellos; sin la
37
+ * lista responde vacío, nunca el ledger completo.
38
+ */
39
+ @Expose()
40
+ @IsOptional()
41
+ @Transform(({ value }) => (typeof value === 'string' ? value.split(',').map((id) => id.trim()) : value))
42
+ @IsArray()
43
+ @IsString({ each: true })
44
+ @IsNotEmpty({ each: true })
45
+ costCenterIds?: string[];
34
46
  }
35
47
 
36
48
  /** Query de privateGetReconciliationFeedRecord; `author` y `actor` van al registro de acceso del dueño. */
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Centro de costo de una transacción que llegó sin uno. El ledger lo escribe siempre, así que las
3
+ * transacciones sin dueño contable quedan agrupadas aquí en lugar de perderse del índice.
4
+ */
5
+ export const UNASSIGNED_COST_CENTER_ID = 'UNASSIGNED';
@@ -173,9 +173,12 @@ export class TransactionCreateRequest {
173
173
  @IsOptional()
174
174
  executionId?: string;
175
175
 
176
- /** Tenant SOFOM dueño del cobro; `tenantId` del ledger sigue siendo `FIADO`. */
176
+ /**
177
+ * Centro de costo contable de la transacción; con él se reparte el ledger entre dueños y
178
+ * conciliaciones. Si no llega, el ledger escribe `UNASSIGNED_COST_CENTER_ID`.
179
+ */
177
180
  @IsString()
178
181
  @IsNotEmpty()
179
182
  @IsOptional()
180
- sofomTenantId?: string;
183
+ costCenterId?: string;
181
184
  }
@@ -40,6 +40,9 @@ export * from './dtos/internal/ProviderTransactionCompletionRequest';
40
40
  export * from './dtos/internal/ProviderTransactionCompletionResponse';
41
41
 
42
42
 
43
+ //constants
44
+ export * from './constants/costCenter';
45
+
43
46
  //enums
44
47
  export * from './enums/OperationEnum';
45
48
  export * from './enums/TransactionSourceEnum';
@@ -1,4 +1,4 @@
1
- import { IsNotEmpty, IsNumber, IsPositive, IsString, MaxLength } from "class-validator";
1
+ import { IsNotEmpty, IsNumber, IsOptional, IsPositive, IsString, MaxLength } from "class-validator";
2
2
 
3
3
  /**
4
4
  * Acreditación de un bono a la wallet PagoConfiado de una persona.
@@ -31,6 +31,12 @@ export class AuthorizeBonusRequest {
31
31
  @IsString()
32
32
  @MaxLength(120)
33
33
  concept: string;
34
+
35
+ /** Centro de costo del bono en el ledger; ausente, el processor escribe `UNASSIGNED`. */
36
+ @IsOptional()
37
+ @IsString()
38
+ @IsNotEmpty()
39
+ costCenterId?: string;
34
40
  }
35
41
 
36
42
  export default AuthorizeBonusRequest;