@mody-park-cha-raja/finance_common 4.29.0 → 4.29.1-beta.1

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/README.md CHANGED
@@ -1,18 +1,18 @@
1
- # Name
2
- ### @mody-park-cha-raja/finance_common
3
-
4
- # Synopsis
5
- Common interfaces, models, enums, and utilities for the Mody Park Cha Raja finance ecosystem
6
-
7
- # Description
8
-
9
- # Example
10
-
11
- # Install:
12
- `npm install @mody-park-cha-raja/finance_common`
13
-
14
- # Test:
15
- `npm test`
16
-
17
- #License:
18
- ISC
1
+ # Name
2
+ ### @mody-park-cha-raja/finance_common
3
+
4
+ # Synopsis
5
+ Common interfaces, models, enums, and utilities for the Mody Park Cha Raja finance ecosystem
6
+
7
+ # Description
8
+
9
+ # Example
10
+
11
+ # Install:
12
+ `npm install @mody-park-cha-raja/finance_common`
13
+
14
+ # Test:
15
+ `npm test`
16
+
17
+ #License:
18
+ ISC
package/dist/index.d.mts CHANGED
@@ -113,6 +113,7 @@ interface IDonationEntity extends IAuditColumnEntity {
113
113
  receiptNumber: string;
114
114
  flatNo: string;
115
115
  name?: string;
116
+ flatId: number;
116
117
  amount: number;
117
118
  mobileNumber?: string;
118
119
  paymentType: PaymentType;
@@ -292,11 +293,90 @@ declare class UserModel extends BaseEntityModel implements IUserEntity {
292
293
  static populateFromEntity(entity: IUserEntity): UserModel;
293
294
  }
294
295
 
296
+ interface FlatDonationLike {
297
+ flatNo: string;
298
+ amount: number;
299
+ donationYear?: number;
300
+ createdOn?: number;
301
+ createdByUser?: Nullable<{
302
+ name?: string;
303
+ }>;
304
+ updatedByUser?: Nullable<{
305
+ name?: string;
306
+ }>;
307
+ }
308
+ type FlatCollectionStatus = "Paid" | "Pending";
309
+ interface FlatCollectionEntry {
310
+ flatNumber: string;
311
+ status: FlatCollectionStatus;
312
+ amount: number;
313
+ latestDonation?: Nullable<FlatDonationLike>;
314
+ }
315
+ interface FlatParseResult {
316
+ wing?: string;
317
+ num?: string;
318
+ isSpecial: boolean;
319
+ }
320
+ interface FlatOption {
321
+ label: string;
322
+ value: string;
323
+ }
324
+ declare class FlatModel {
325
+ id: number;
326
+ wing: string;
327
+ unitNumber: string;
328
+ status: EntityStatus;
329
+ createdOn: number;
330
+ updatedOn: number;
331
+ createdBy: number;
332
+ updatedBy: number;
333
+ static populateFromEntity(entity: IFlatEntity): FlatModel;
334
+ createdByUser?: UserModel;
335
+ updatedByUser?: UserModel;
336
+ donations?: DonationModel[];
337
+ static relations: Partial<Record<EntityList, IModelRelationConfig<EntityList>>>;
338
+ static readonly FLAT_NUMBERS: readonly string[];
339
+ static readonly FLATS_BY_WING: ReadonlyMap<string, readonly string[]>;
340
+ static readonly SPECIAL_FLATS: readonly string[];
341
+ static readonly WINGS: readonly string[];
342
+ static getDonationYear(): number;
343
+ static getTotalFlats(): number;
344
+ static getWingsFromFlats(flats: ReadonlyArray<{
345
+ wing?: string | null;
346
+ }>): string[];
347
+ static getSpecialsFromFlats(flats: ReadonlyArray<{
348
+ wing?: string | null;
349
+ unitNumber: string;
350
+ }>): string[];
351
+ static getRegularFlatCount(flats: ReadonlyArray<{
352
+ wing?: string | null;
353
+ }>): number;
354
+ static getWingFlatCount(flats: ReadonlyArray<{
355
+ wing?: string | null;
356
+ }>, wing: string): number;
357
+ static getFlatOptionsFromFlats(flats: ReadonlyArray<{
358
+ wing?: string | null;
359
+ unitNumber: string;
360
+ }>, wing: string): FlatOption[];
361
+ static buildFlatNumber(wing: string, num: string): string;
362
+ static isSpecialFlat(flatNo: string, specials?: readonly string[]): boolean;
363
+ static parseFlatNumber(flatNo: string, specials?: readonly string[]): FlatParseResult;
364
+ static getFlatOptions(wing: string, specials?: readonly string[]): FlatOption[];
365
+ static getDisplayLabel(wing: string, flatNo: string, specials?: readonly string[]): string;
366
+ static computeCollectionStatus(donations: FlatDonationLike[], year: number, flats?: ReadonlyArray<{
367
+ wing?: string | null;
368
+ unitNumber: string;
369
+ }>): FlatCollectionEntry[];
370
+ static compareFlatNumbers(a: string, b: string, specials?: readonly string[]): number;
371
+ static convertNumberToWords(num: number): string;
372
+ }
373
+
295
374
  declare class DonationModel extends BaseEntityModel implements IDonationEntity {
296
375
  id: number;
297
376
  receiptNumber: string;
298
377
  flatNo: string;
299
378
  name?: string;
379
+ flatId: number;
300
380
  amount: number;
301
381
  mobileNumber?: string;
302
382
  paymentType: PaymentType;
@@ -308,6 +388,7 @@ declare class DonationModel extends BaseEntityModel implements IDonationEntity {
308
388
  updatedBy: number;
309
389
  createdByUser?: UserModel;
310
390
  updatedByUser?: UserModel;
391
+ flat?: FlatModel;
311
392
  protected constructor();
312
393
  static relations: Partial<Record<EntityList, IModelRelationConfig<EntityList>>>;
313
394
  static populateFromEntity(entity: IDonationEntity): DonationModel;
@@ -432,60 +513,6 @@ declare class FlatHistoryModel extends BaseEntityModel implements IFlatHistoryEn
432
513
  static populateFromEntity(entity: IFlatHistoryEntity): FlatHistoryModel;
433
514
  }
434
515
 
435
- interface FlatDonationLike {
436
- flatNo: string;
437
- amount: number;
438
- donationYear?: number;
439
- createdOn?: number;
440
- createdByUser?: Nullable<{
441
- name?: string;
442
- }>;
443
- updatedByUser?: Nullable<{
444
- name?: string;
445
- }>;
446
- }
447
- type FlatCollectionStatus = "Paid" | "Pending";
448
- interface FlatCollectionEntry {
449
- flatNumber: string;
450
- status: FlatCollectionStatus;
451
- amount: number;
452
- latestDonation?: Nullable<FlatDonationLike>;
453
- }
454
- interface FlatParseResult {
455
- wing?: string;
456
- num?: string;
457
- isSpecial: boolean;
458
- }
459
- interface FlatOption {
460
- label: string;
461
- value: string;
462
- }
463
- declare class FlatModel {
464
- id: number;
465
- wing: string;
466
- unitNumber: string;
467
- status: EntityStatus;
468
- createdOn: number;
469
- updatedOn: number;
470
- createdBy: number;
471
- updatedBy: number;
472
- static populateFromEntity(entity: IFlatEntity): FlatModel;
473
- static readonly FLAT_NUMBERS: readonly string[];
474
- static readonly FLATS_BY_WING: ReadonlyMap<string, readonly string[]>;
475
- static readonly SPECIAL_FLATS: readonly string[];
476
- static readonly WINGS: readonly string[];
477
- static getDonationYear(): number;
478
- static getTotalFlats(): number;
479
- static buildFlatNumber(wing: string, num: string): string;
480
- static isSpecialFlat(flatNo: string): boolean;
481
- static parseFlatNumber(flatNo: string): FlatParseResult;
482
- static getFlatOptions(wing: string): FlatOption[];
483
- static getDisplayLabel(wing: string, flatNo: string): string;
484
- static computeCollectionStatus(donations: FlatDonationLike[], year: number): FlatCollectionEntry[];
485
- static compareFlatNumbers(a: string, b: string): number;
486
- static convertNumberToWords(num: number): string;
487
- }
488
-
489
516
  declare class SponsorHistoryModel extends BaseEntityModel implements ISponsorHistoryEntity {
490
517
  id: number;
491
518
  entityId: number;
package/dist/index.d.ts CHANGED
@@ -113,6 +113,7 @@ interface IDonationEntity extends IAuditColumnEntity {
113
113
  receiptNumber: string;
114
114
  flatNo: string;
115
115
  name?: string;
116
+ flatId: number;
116
117
  amount: number;
117
118
  mobileNumber?: string;
118
119
  paymentType: PaymentType;
@@ -292,11 +293,90 @@ declare class UserModel extends BaseEntityModel implements IUserEntity {
292
293
  static populateFromEntity(entity: IUserEntity): UserModel;
293
294
  }
294
295
 
296
+ interface FlatDonationLike {
297
+ flatNo: string;
298
+ amount: number;
299
+ donationYear?: number;
300
+ createdOn?: number;
301
+ createdByUser?: Nullable<{
302
+ name?: string;
303
+ }>;
304
+ updatedByUser?: Nullable<{
305
+ name?: string;
306
+ }>;
307
+ }
308
+ type FlatCollectionStatus = "Paid" | "Pending";
309
+ interface FlatCollectionEntry {
310
+ flatNumber: string;
311
+ status: FlatCollectionStatus;
312
+ amount: number;
313
+ latestDonation?: Nullable<FlatDonationLike>;
314
+ }
315
+ interface FlatParseResult {
316
+ wing?: string;
317
+ num?: string;
318
+ isSpecial: boolean;
319
+ }
320
+ interface FlatOption {
321
+ label: string;
322
+ value: string;
323
+ }
324
+ declare class FlatModel {
325
+ id: number;
326
+ wing: string;
327
+ unitNumber: string;
328
+ status: EntityStatus;
329
+ createdOn: number;
330
+ updatedOn: number;
331
+ createdBy: number;
332
+ updatedBy: number;
333
+ static populateFromEntity(entity: IFlatEntity): FlatModel;
334
+ createdByUser?: UserModel;
335
+ updatedByUser?: UserModel;
336
+ donations?: DonationModel[];
337
+ static relations: Partial<Record<EntityList, IModelRelationConfig<EntityList>>>;
338
+ static readonly FLAT_NUMBERS: readonly string[];
339
+ static readonly FLATS_BY_WING: ReadonlyMap<string, readonly string[]>;
340
+ static readonly SPECIAL_FLATS: readonly string[];
341
+ static readonly WINGS: readonly string[];
342
+ static getDonationYear(): number;
343
+ static getTotalFlats(): number;
344
+ static getWingsFromFlats(flats: ReadonlyArray<{
345
+ wing?: string | null;
346
+ }>): string[];
347
+ static getSpecialsFromFlats(flats: ReadonlyArray<{
348
+ wing?: string | null;
349
+ unitNumber: string;
350
+ }>): string[];
351
+ static getRegularFlatCount(flats: ReadonlyArray<{
352
+ wing?: string | null;
353
+ }>): number;
354
+ static getWingFlatCount(flats: ReadonlyArray<{
355
+ wing?: string | null;
356
+ }>, wing: string): number;
357
+ static getFlatOptionsFromFlats(flats: ReadonlyArray<{
358
+ wing?: string | null;
359
+ unitNumber: string;
360
+ }>, wing: string): FlatOption[];
361
+ static buildFlatNumber(wing: string, num: string): string;
362
+ static isSpecialFlat(flatNo: string, specials?: readonly string[]): boolean;
363
+ static parseFlatNumber(flatNo: string, specials?: readonly string[]): FlatParseResult;
364
+ static getFlatOptions(wing: string, specials?: readonly string[]): FlatOption[];
365
+ static getDisplayLabel(wing: string, flatNo: string, specials?: readonly string[]): string;
366
+ static computeCollectionStatus(donations: FlatDonationLike[], year: number, flats?: ReadonlyArray<{
367
+ wing?: string | null;
368
+ unitNumber: string;
369
+ }>): FlatCollectionEntry[];
370
+ static compareFlatNumbers(a: string, b: string, specials?: readonly string[]): number;
371
+ static convertNumberToWords(num: number): string;
372
+ }
373
+
295
374
  declare class DonationModel extends BaseEntityModel implements IDonationEntity {
296
375
  id: number;
297
376
  receiptNumber: string;
298
377
  flatNo: string;
299
378
  name?: string;
379
+ flatId: number;
300
380
  amount: number;
301
381
  mobileNumber?: string;
302
382
  paymentType: PaymentType;
@@ -308,6 +388,7 @@ declare class DonationModel extends BaseEntityModel implements IDonationEntity {
308
388
  updatedBy: number;
309
389
  createdByUser?: UserModel;
310
390
  updatedByUser?: UserModel;
391
+ flat?: FlatModel;
311
392
  protected constructor();
312
393
  static relations: Partial<Record<EntityList, IModelRelationConfig<EntityList>>>;
313
394
  static populateFromEntity(entity: IDonationEntity): DonationModel;
@@ -432,60 +513,6 @@ declare class FlatHistoryModel extends BaseEntityModel implements IFlatHistoryEn
432
513
  static populateFromEntity(entity: IFlatHistoryEntity): FlatHistoryModel;
433
514
  }
434
515
 
435
- interface FlatDonationLike {
436
- flatNo: string;
437
- amount: number;
438
- donationYear?: number;
439
- createdOn?: number;
440
- createdByUser?: Nullable<{
441
- name?: string;
442
- }>;
443
- updatedByUser?: Nullable<{
444
- name?: string;
445
- }>;
446
- }
447
- type FlatCollectionStatus = "Paid" | "Pending";
448
- interface FlatCollectionEntry {
449
- flatNumber: string;
450
- status: FlatCollectionStatus;
451
- amount: number;
452
- latestDonation?: Nullable<FlatDonationLike>;
453
- }
454
- interface FlatParseResult {
455
- wing?: string;
456
- num?: string;
457
- isSpecial: boolean;
458
- }
459
- interface FlatOption {
460
- label: string;
461
- value: string;
462
- }
463
- declare class FlatModel {
464
- id: number;
465
- wing: string;
466
- unitNumber: string;
467
- status: EntityStatus;
468
- createdOn: number;
469
- updatedOn: number;
470
- createdBy: number;
471
- updatedBy: number;
472
- static populateFromEntity(entity: IFlatEntity): FlatModel;
473
- static readonly FLAT_NUMBERS: readonly string[];
474
- static readonly FLATS_BY_WING: ReadonlyMap<string, readonly string[]>;
475
- static readonly SPECIAL_FLATS: readonly string[];
476
- static readonly WINGS: readonly string[];
477
- static getDonationYear(): number;
478
- static getTotalFlats(): number;
479
- static buildFlatNumber(wing: string, num: string): string;
480
- static isSpecialFlat(flatNo: string): boolean;
481
- static parseFlatNumber(flatNo: string): FlatParseResult;
482
- static getFlatOptions(wing: string): FlatOption[];
483
- static getDisplayLabel(wing: string, flatNo: string): string;
484
- static computeCollectionStatus(donations: FlatDonationLike[], year: number): FlatCollectionEntry[];
485
- static compareFlatNumbers(a: string, b: string): number;
486
- static convertNumberToWords(num: number): string;
487
- }
488
-
489
516
  declare class SponsorHistoryModel extends BaseEntityModel implements ISponsorHistoryEntity {
490
517
  id: number;
491
518
  entityId: number;
package/dist/index.js CHANGED
@@ -778,6 +778,7 @@ var _DonationModel = class _DonationModel extends BaseEntityModel {
778
778
  this.id = 0;
779
779
  this.receiptNumber = "";
780
780
  this.flatNo = "";
781
+ this.flatId = 0;
781
782
  this.amount = 0;
782
783
  this.paymentType = "Cash" /* CASH */;
783
784
  this.status = "Active" /* ACTIVE */;
@@ -835,6 +836,12 @@ _DonationModel.relations = {
835
836
  ],
836
837
  searchProperty: "id",
837
838
  entity: "user" /* USER */
839
+ },
840
+ ["flat" /* FLAT */]: {
841
+ relationType: "ONE" /* ONE */,
842
+ mappingProperties: [{ sourceProperty: "flatId", targetProperty: "flat" }],
843
+ searchProperty: "id",
844
+ entity: "flat" /* FLAT */
838
845
  }
839
846
  };
840
847
  var DonationModel = _DonationModel;
@@ -1104,14 +1111,35 @@ var _FlatModel = class _FlatModel {
1104
1111
  static getTotalFlats() {
1105
1112
  return _FlatModel.FLAT_NUMBERS.length;
1106
1113
  }
1114
+ static getWingsFromFlats(flats) {
1115
+ return [
1116
+ ...new Set(flats.map((f) => (f.wing ?? "").trim()).filter(Boolean))
1117
+ ].sort();
1118
+ }
1119
+ static getSpecialsFromFlats(flats) {
1120
+ return flats.filter((f) => !f.wing && !!f.unitNumber).map((f) => f.unitNumber);
1121
+ }
1122
+ static getRegularFlatCount(flats) {
1123
+ return flats.filter((f) => !!f.wing).length;
1124
+ }
1125
+ static getWingFlatCount(flats, wing) {
1126
+ return flats.filter((f) => f.wing === wing).length;
1127
+ }
1128
+ static getFlatOptionsFromFlats(flats, wing) {
1129
+ const specials = _FlatModel.getSpecialsFromFlats(flats);
1130
+ return [
1131
+ ...flats.filter((f) => f.wing === wing).map((f) => ({ label: `${wing}-${f.unitNumber}`, value: f.unitNumber })),
1132
+ ...specials.map((label) => ({ label, value: label }))
1133
+ ];
1134
+ }
1107
1135
  static buildFlatNumber(wing, num) {
1108
1136
  return `${wing}-${num}`;
1109
1137
  }
1110
- static isSpecialFlat(flatNo) {
1111
- return _FlatModel.SPECIAL_FLATS.includes(flatNo);
1138
+ static isSpecialFlat(flatNo, specials) {
1139
+ return (specials ?? _FlatModel.SPECIAL_FLATS).includes(flatNo);
1112
1140
  }
1113
- static parseFlatNumber(flatNo) {
1114
- if (_FlatModel.isSpecialFlat(flatNo)) {
1141
+ static parseFlatNumber(flatNo, specials) {
1142
+ if (_FlatModel.isSpecialFlat(flatNo, specials)) {
1115
1143
  return { isSpecial: true };
1116
1144
  }
1117
1145
  const match = /^([A-Za-z])-([0-9]{1,3}[A-Za-z]?)$/.exec(flatNo);
@@ -1120,21 +1148,29 @@ var _FlatModel = class _FlatModel {
1120
1148
  }
1121
1149
  return { isSpecial: false };
1122
1150
  }
1123
- static getFlatOptions(wing) {
1151
+ static getFlatOptions(wing, specials) {
1152
+ const effectiveSpecials = specials ?? _FlatModel.SPECIAL_FLATS;
1124
1153
  const wingFlats = _FlatModel.FLATS_BY_WING.get(wing) ?? [];
1125
- const all = [...wingFlats, ..._FlatModel.SPECIAL_FLATS];
1154
+ const all = [...wingFlats, ...effectiveSpecials];
1126
1155
  return all.map((f) => ({
1127
- label: _FlatModel.isSpecialFlat(f) ? f : `${wing}-${f}`,
1156
+ label: _FlatModel.isSpecialFlat(f, effectiveSpecials) ? f : `${wing}-${f}`,
1128
1157
  value: f
1129
1158
  }));
1130
1159
  }
1131
- static getDisplayLabel(wing, flatNo) {
1160
+ static getDisplayLabel(wing, flatNo, specials) {
1132
1161
  if (!flatNo) return "";
1133
- if (_FlatModel.isSpecialFlat(flatNo)) return flatNo;
1162
+ if (_FlatModel.isSpecialFlat(flatNo, specials)) return flatNo;
1134
1163
  return `${wing}-${flatNo}`;
1135
1164
  }
1136
- static computeCollectionStatus(donations, year) {
1137
- return _FlatModel.FLAT_NUMBERS.map((flatNumber) => {
1165
+ static computeCollectionStatus(donations, year, flats) {
1166
+ let flatNumbers = _FlatModel.FLAT_NUMBERS;
1167
+ if (flats) {
1168
+ const specials = _FlatModel.getSpecialsFromFlats(flats);
1169
+ flatNumbers = flats.map(
1170
+ (f) => _FlatModel.getDisplayLabel(f.wing ?? "", f.unitNumber ?? "", specials)
1171
+ );
1172
+ }
1173
+ return flatNumbers.map((flatNumber) => {
1138
1174
  const flatDonations = donations.filter(
1139
1175
  (d) => d.donationYear === year && d.flatNo === flatNumber
1140
1176
  );
@@ -1146,17 +1182,18 @@ var _FlatModel = class _FlatModel {
1146
1182
  return { flatNumber, status, amount, latestDonation };
1147
1183
  });
1148
1184
  }
1149
- static compareFlatNumbers(a, b) {
1150
- const isA = _FlatModel.isSpecialFlat(a);
1151
- const isB = _FlatModel.isSpecialFlat(b);
1185
+ static compareFlatNumbers(a, b, specials) {
1186
+ const isA = _FlatModel.isSpecialFlat(a, specials);
1187
+ const isB = _FlatModel.isSpecialFlat(b, specials);
1152
1188
  if (isA || isB) {
1153
1189
  if (isA && isB) {
1154
- return _FlatModel.SPECIAL_FLATS.indexOf(a) - _FlatModel.SPECIAL_FLATS.indexOf(b);
1190
+ const effectiveSpecials = specials ?? _FlatModel.SPECIAL_FLATS;
1191
+ return effectiveSpecials.indexOf(a) - effectiveSpecials.indexOf(b);
1155
1192
  }
1156
1193
  return isA ? 1 : -1;
1157
1194
  }
1158
- const pa = _FlatModel.parseFlatNumber(a);
1159
- const pb = _FlatModel.parseFlatNumber(b);
1195
+ const pa = _FlatModel.parseFlatNumber(a, specials);
1196
+ const pb = _FlatModel.parseFlatNumber(b, specials);
1160
1197
  if (!pa.wing || !pa.num || !pb.wing || !pb.num) {
1161
1198
  return a < b ? -1 : a > b ? 1 : 0;
1162
1199
  }
@@ -1180,6 +1217,25 @@ var _FlatModel = class _FlatModel {
1180
1217
  return convertNumberToWords(num);
1181
1218
  }
1182
1219
  };
1220
+ _FlatModel.relations = {
1221
+ ["user" /* USER */]: {
1222
+ relationType: "ONE" /* ONE */,
1223
+ mappingProperties: [
1224
+ { sourceProperty: "createdBy", targetProperty: "createdByUser" },
1225
+ { sourceProperty: "updatedBy", targetProperty: "updatedByUser" }
1226
+ ],
1227
+ searchProperty: "id",
1228
+ entity: "user" /* USER */
1229
+ },
1230
+ ["donation" /* DONATION */]: {
1231
+ relationType: "MANY" /* MANY */,
1232
+ mappingProperties: [
1233
+ { sourceProperty: "id", targetProperty: "donations" }
1234
+ ],
1235
+ searchProperty: "flatId",
1236
+ entity: "donation" /* DONATION */
1237
+ }
1238
+ };
1183
1239
  _FlatModel.FLAT_NUMBERS = FLAT_NUMBERS;
1184
1240
  _FlatModel.FLATS_BY_WING = FLATS_BY_WING;
1185
1241
  _FlatModel.SPECIAL_FLATS = SPECIAL_FLATS;