@tomei/rental 0.17.7 → 0.17.9-dev.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/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@tomei/rental",
3
- "version": "0.17.7",
3
+ "version": "0.17.9-dev.1",
4
4
  "description": "Tomei Rental Package",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
7
7
  "start:dev": "tsc -w",
8
- "build": "tsc",
8
+ "build": "tsc -p tsconfig.build.json",
9
9
  "prepare": "husky install",
10
10
  "format": "prettier --write \"src/**/*.ts\"",
11
11
  "lint": "npx eslint . --fix",
@@ -59,13 +59,13 @@
59
59
  "peerDependencies": {
60
60
  "@tomei/activity-history": "^0.4.1",
61
61
  "@tomei/config": "^0.3.21",
62
- "@tomei/finance": "^0.11.7-staging.12",
63
- "@tomei/general": "^0.21.7",
64
- "@tomei/sso": "^0.60.4",
65
- "@tomei/stock": "^0.18.1",
66
- "luxon": "^3.6.1",
62
+ "@tomei/finance": "^0.11.7-staging.4",
63
+ "@tomei/general": "^0.21.3",
64
+ "@tomei/sso": "^0.64.0-dev.2",
65
+ "@tomei/stock": "^0.18.0",
66
+ "luxon": "^3.5.0",
67
67
  "reflect-metadata": "^0.2.2",
68
- "sequelize": "^6.37.7",
68
+ "sequelize": "^6.37.5",
69
69
  "sequelize-typescript": "^2.1.6"
70
70
  },
71
71
  "lint-staged": {
@@ -73,8 +73,5 @@
73
73
  "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
74
74
  "eslint \"{src,apps,libs,test}/**/*.ts\" --fix"
75
75
  ]
76
- },
77
- "overrides": {
78
- "glob": "^9.0.0"
79
76
  }
80
77
  }
@@ -101,8 +101,6 @@ export class Agreement extends ObjectBase {
101
101
  rental_AgreementSignature hs
102
102
  WHERE
103
103
  hs.AgreementNo = '${agreementNo}'
104
- ORDER BY
105
- hs.CreatedAt ASC
106
104
  `;
107
105
 
108
106
  const db = rentalDb.getConnection();
@@ -3,7 +3,7 @@ import { LoginUser } from '@tomei/sso';
3
3
  import { ActionEnum, Activity } from '@tomei/activity-history';
4
4
  import { IHirerChangeRequestRemoveHirerAttr } from '../../interfaces/hirer-change-request-remove-hirer-attr.interface';
5
5
  import { HirerChangeRequestRemoveHirerRepository } from './hirer-change-request-remove-hirer.repository';
6
- import { JointHirer } from 'components/joint-hirer/joint-hirer';
6
+ import { JointHirer } from '../../components/joint-hirer/joint-hirer';
7
7
 
8
8
  export class HirerChangeRequestRemoveHirer
9
9
  extends ObjectBase
@@ -4,8 +4,6 @@ import { IJointHirerAttr } from '../../interfaces/joint-hirer-attr.interface';
4
4
  import { ApplicationConfig } from '@tomei/config';
5
5
  import { LoginUser } from '@tomei/sso';
6
6
  import { ActionEnum, Activity } from '@tomei/activity-history';
7
- import { Rental } from '../rental/rental';
8
- import { RentalAccountTypeEnum } from '../../enum/account-type.enum';
9
7
 
10
8
  export class JointHirer extends ObjectBase {
11
9
  ObjectId: string;
@@ -20,7 +18,6 @@ export class JointHirer extends ObjectBase {
20
18
  CreatedAt: Date;
21
19
  UpdatedById: string;
22
20
  UpdatedAt: Date;
23
- private _Rental: Rental;
24
21
 
25
22
  get HirerId(): string {
26
23
  return this.ObjectId;
@@ -149,16 +146,6 @@ export class JointHirer extends ObjectBase {
149
146
 
150
147
  await activity.create(loginUser.ObjectId, dbTransaction);
151
148
 
152
- //update the AccountType
153
- const rental = await this.getRental(dbTransaction);
154
- const totalIds = await rental.getCustomerIds(loginUser, dbTransaction);
155
-
156
- if (totalIds.length > 1 && rental.AccountType === 'Single') {
157
- await rental.update(loginUser, dbTransaction, {
158
- AccountType: RentalAccountTypeEnum.JOINT,
159
- });
160
- }
161
-
162
149
  return this;
163
150
  } catch (error) {
164
151
  throw error;
@@ -167,20 +154,6 @@ export class JointHirer extends ObjectBase {
167
154
 
168
155
  public async remove(loginUser: LoginUser, dbTransaction?: any) {
169
156
  try {
170
- //Make sure this.HirerId exists
171
- if (!this.HirerId) {
172
- throw new ClassError(
173
- 'JointHirer',
174
- 'JointHirerErrMsg02',
175
- 'HirerId is required to remove Joint Hirer.',
176
- );
177
- }
178
-
179
- //Make sure this.Status is not "Inactive"
180
- if (this.Status === 'Inactive') {
181
- return this;
182
- }
183
-
184
157
  //Mark Joint Hirer as Inactive
185
158
  const entityValueBefore: IJointHirerAttr = this.toJSON();
186
159
  this.Status = 'Inactive'; // Set status to 'Inactive' instead of deleting the record
@@ -208,45 +181,9 @@ export class JointHirer extends ObjectBase {
208
181
 
209
182
  await activity.create(loginUser.ObjectId, dbTransaction);
210
183
 
211
- //update the AccountType
212
- const rental = await this.getRental(dbTransaction);
213
- const totalIds = await rental.getCustomerIds(loginUser, dbTransaction);
214
-
215
- if (totalIds.length === 1 && rental.AccountType === 'Joint') {
216
- await rental.update(loginUser, dbTransaction, {
217
- AccountType: RentalAccountTypeEnum.SINGLE,
218
- });
219
- }
220
-
221
184
  return this;
222
185
  } catch (error) {
223
186
  throw error;
224
187
  }
225
188
  }
226
-
227
- private async getRental(dbTransaction?: any) {
228
- if (this._Rental) {
229
- return this._Rental;
230
- }
231
-
232
- if (!this.RentalId) {
233
- throw new ClassError(
234
- 'JointHirer',
235
- 'JointHirerErrMsg04',
236
- 'RentalId is empty.',
237
- );
238
- }
239
-
240
- this._Rental = await Rental.init(dbTransaction, this.RentalId);
241
-
242
- if (!this._Rental) {
243
- throw new ClassError(
244
- 'JointHirer',
245
- 'JointHirerErrMsg05',
246
- 'Rental not found.',
247
- );
248
- }
249
-
250
- return this._Rental;
251
- }
252
189
  }
@@ -3,7 +3,7 @@ import { RentalStatusEnum } from '../../enum/rental-status.enum';
3
3
  import { RentalRepository } from './rental.repository';
4
4
  import { ClassError, ObjectBase } from '@tomei/general';
5
5
  import { ApplicationConfig } from '@tomei/config';
6
- import { LoginUser } from '@tomei/sso';
6
+ import { AuthContext, LoginUser } from '@tomei/sso';
7
7
  import { RentalPrice } from '../rental-price/rental-price';
8
8
  import { Op, QueryTypes } from 'sequelize';
9
9
  import { ActionEnum, Activity } from '@tomei/activity-history';
@@ -132,7 +132,7 @@ export class Rental extends ObjectBase {
132
132
  throw new ClassError(
133
133
  'Rental',
134
134
  'RentalErrMsg00',
135
- 'Failed To Initialize Rental',
135
+ 'Failed To Initialize Price',
136
136
  );
137
137
  }
138
138
  }
@@ -212,7 +212,7 @@ export class Rental extends ObjectBase {
212
212
  PartyId: this.CustomerId,
213
213
  PartyType: 'Customer',
214
214
  SignatureStatus: AgreementSignatureStatusEnum.PENDING,
215
- SignedAt: null,
215
+ SignedAt: new Date(),
216
216
  VerificationMethod:
217
217
  AgreementSignatureVerificationMethodEnum.FINGERPRINT,
218
218
  VerificationJustification: '',
@@ -236,7 +236,7 @@ export class Rental extends ObjectBase {
236
236
  PartyId: jointHirer.CustomerId,
237
237
  PartyType: 'Customer',
238
238
  SignatureStatus: AgreementSignatureStatusEnum.PENDING,
239
- SignedAt: null,
239
+ SignedAt: new Date(),
240
240
  VerificationMethod:
241
241
  AgreementSignatureVerificationMethodEnum.FINGERPRINT,
242
242
  VerificationJustification: '',
@@ -365,7 +365,7 @@ export class Rental extends ObjectBase {
365
365
  }
366
366
 
367
367
  public static async findAll(
368
- loginUser: LoginUser,
368
+ authContext: AuthContext,
369
369
  dbTransaction: any,
370
370
  page?: number,
371
371
  row?: number,
@@ -375,17 +375,19 @@ export class Rental extends ObjectBase {
375
375
  const systemCode =
376
376
  await ApplicationConfig.getComponentConfigValue('system-code');
377
377
 
378
- const isPrivileged = await loginUser.checkPrivileges(
379
- systemCode,
380
- 'Rental - View',
381
- );
382
-
383
- if (!isPrivileged) {
384
- throw new ClassError(
385
- 'Rental',
386
- 'RentalErrMsg01',
387
- "You do not have 'Rental - View' privilege.",
378
+ if ('loginUser' in authContext) {
379
+ const isPrivileged = await authContext.loginUser.checkPrivileges(
380
+ systemCode,
381
+ 'Rental - View',
388
382
  );
383
+
384
+ if (!isPrivileged) {
385
+ throw new ClassError(
386
+ 'Rental',
387
+ 'RentalErrMsg01',
388
+ "You do not have 'Rental - View' privilege.",
389
+ );
390
+ }
389
391
  }
390
392
 
391
393
  const queryObj: any = {};
@@ -805,7 +807,6 @@ export class Rental extends ObjectBase {
805
807
  const options: any = {
806
808
  where: {
807
809
  RentalId: this.RentalId,
808
- Status: 'Active',
809
810
  },
810
811
  transaction: dbTransaction,
811
812
  };
@@ -1339,17 +1340,6 @@ export class Rental extends ObjectBase {
1339
1340
  );
1340
1341
  }
1341
1342
 
1342
- if (
1343
- this.Status === RentalStatusEnum.ACTIVE ||
1344
- this.Status === RentalStatusEnum.SUSPENDED
1345
- ) {
1346
- throw new ClassError(
1347
- 'Rental',
1348
- 'RentalErrMsg01',
1349
- `Rental already ${this.Status}, please do termination process.`,
1350
- );
1351
- }
1352
-
1353
1343
  if (!remarks) {
1354
1344
  throw new ClassError(
1355
1345
  'Rental',
@@ -1405,70 +1395,4 @@ export class Rental extends ObjectBase {
1405
1395
  throw error;
1406
1396
  }
1407
1397
  }
1408
-
1409
- public async update(
1410
- loginUser: LoginUser,
1411
- dbTransaction: any,
1412
- updates: Partial<IRentalAttr>,
1413
- ): Promise<Rental> {
1414
- try {
1415
- // Part 1: Privilege Checking
1416
- const systemCode =
1417
- ApplicationConfig.getComponentConfigValue('system-code');
1418
- const isPrivileged = await loginUser.checkPrivileges(
1419
- systemCode,
1420
- 'RENTAL_UPDATE',
1421
- );
1422
-
1423
- if (!isPrivileged) {
1424
- throw new ClassError(
1425
- 'Rental',
1426
- 'RentalErrMsg01',
1427
- "You do not have 'RENTAL_UPDATE' privilege.",
1428
- );
1429
- }
1430
-
1431
- // Part 2: Validation
1432
- if (!this.ObjectId) {
1433
- throw new ClassError(
1434
- 'Rental',
1435
- 'RentalErrMsg01',
1436
- 'Rental not found. Rental Id is empty.',
1437
- );
1438
- }
1439
-
1440
- // Part 3: Capture Record Info Before Changes
1441
- const entityValueBefore = this.toJSON();
1442
-
1443
- // Part 4: Update Rental Record
1444
- await Rental._Repo.update(updates, {
1445
- where: {
1446
- RentalId: this.RentalId,
1447
- },
1448
- transaction: dbTransaction,
1449
- });
1450
-
1451
- // Part 5: Update object instance properties and capture after changes
1452
- Object.assign(this, updates);
1453
- this._UpdatedById = loginUser.ObjectId;
1454
- this._UpdatedAt = new Date();
1455
-
1456
- const entityValueAfter = this.toJSON();
1457
-
1458
- // Part 6: Record Activity
1459
- const activity = new Activity();
1460
- activity.ActivityId = activity.createId();
1461
- activity.Action = ActionEnum.UPDATE;
1462
- activity.Description = 'Update Rental';
1463
- activity.EntityType = this.ObjectType;
1464
- activity.EntityId = this.ObjectId;
1465
- activity.EntityValueBefore = JSON.stringify(entityValueBefore);
1466
- activity.EntityValueAfter = JSON.stringify(entityValueAfter);
1467
- await activity.create(loginUser.ObjectId, dbTransaction);
1468
-
1469
- return this;
1470
- } catch (error) {
1471
- throw error;
1472
- }
1473
- }
1474
1398
  }
@@ -227,8 +227,16 @@ export class RentalHirerChangeRequest
227
227
  }
228
228
  const rental = await Rental.init(dbTransaction, this.RentalId);
229
229
 
230
+ // 2.2 Only allow for joint account
231
+ if (rental.AccountType !== RentalAccountTypeEnum.JOINT) {
232
+ throw new ClassError(
233
+ 'HirerChangeRequest',
234
+ 'HirerChangeRequestErrMsg03',
235
+ 'Only Rental with Joint Account Type Allowed.',
236
+ );
237
+ }
238
+
230
239
  // 2.3 only allow for rental account where its joint hirer not maximum yet (at this step you've retrieve the number of joint hirer)
231
- rental.AccountType = RentalAccountTypeEnum.JOINT;
232
240
  const jointHirers = await rental.getJointHirers(dbTransaction);
233
241
 
234
242
  if (this.Type === HirerChangeRequestTypeEnum.ADD) {
@@ -245,6 +253,18 @@ export class RentalHirerChangeRequest
245
253
  );
246
254
  }
247
255
  }
256
+ // For Remove type, we don't need to check the max joint hirer length
257
+ // but we need to ensure that there is at least one joint hirer left after removal
258
+ if (
259
+ this.Type == HirerChangeRequestTypeEnum.REMOVE &&
260
+ jointHirers?.length <= 1
261
+ ) {
262
+ throw new ClassError(
263
+ 'HirerChangeRequest',
264
+ 'HirerChangeRequestErrMsg05',
265
+ 'Cannot remove the last joint hirer.',
266
+ );
267
+ }
248
268
 
249
269
  // 2.4 avoid duplicate request, call this.checkForDuplicate() private method, this method will ensure no record with same RentalId and same Type and Status is not "Completed" or "Cancelled"
250
270
  await this.checkForDuplicate(dbTransaction);
@@ -445,7 +465,6 @@ export class RentalHirerChangeRequest
445
465
  }
446
466
 
447
467
  // 2. Prepare all signature data (main + joint) in one go
448
- this.Rental.AccountType = RentalAccountTypeEnum.JOINT;
449
468
  const jointHirers = await this.Rental.getJointHirers(dbTransaction);
450
469
 
451
470
  // Main hirer signature
@@ -455,32 +474,23 @@ export class RentalHirerChangeRequest
455
474
  mainSignature.HirerType = HirerChangeRequestHirerRoleEnum.MAIN;
456
475
  mainSignature.Method = 'Upload';
457
476
 
458
- // Joint hirer signatures - only if there are joint hirers
459
- let jointSignatures = [];
460
- if (jointHirers.length > 0) {
461
- const jointSignaturePromises = jointHirers.map(async (jointHirer) => {
462
- const signature = await HirerChangeRequestSignature.init();
463
- signature.RequestId = this.RequestId;
464
- signature.JointHirerId = jointHirer.HirerId;
465
- signature.HirerType = HirerChangeRequestHirerRoleEnum.JOINT;
466
- signature.Method = 'Upload';
467
- return signature;
468
- });
477
+ // Joint hirer signatures
478
+ const jointSignaturePromises = jointHirers.map(async (jointHirer) => {
479
+ const signature = await HirerChangeRequestSignature.init();
480
+ signature.RequestId = this.RequestId;
481
+ signature.JointHirerId = jointHirer.HirerId;
482
+ signature.HirerType = HirerChangeRequestHirerRoleEnum.JOINT;
483
+ signature.Method = 'Upload';
484
+ return signature;
485
+ });
469
486
 
470
- jointSignatures = await Promise.all(jointSignaturePromises);
471
- }
487
+ const jointSignatures = await Promise.all(jointSignaturePromises);
472
488
 
473
489
  // 3. Create all signatures in parallel
474
- const signaturesToCreate = [
490
+ await Promise.all([
475
491
  mainSignature.create(loginUser, dbTransaction),
476
- ];
477
- if (jointSignatures.length > 0) {
478
- signaturesToCreate.push(
479
- ...jointSignatures.map((sig) => sig.create(loginUser, dbTransaction)),
480
- );
481
- }
482
-
483
- await Promise.all(signaturesToCreate);
492
+ ...jointSignatures.map((sig) => sig.create(loginUser, dbTransaction)),
493
+ ]);
484
494
 
485
495
  this.Signatures = [mainSignature, ...jointSignatures];
486
496
  } catch (error) {
package/src/index.ts CHANGED
@@ -12,7 +12,6 @@ import { AgreementSignature } from './components/agreement-signature/agreement-s
12
12
  import { AgreementSignatureRepository } from './components/agreement-signature/agreement-signature.repository';
13
13
  import { AgreementHistory } from './components/agreement-history/agreement-history';
14
14
  import { AgreementHistoryRepository } from './components/agreement-history/agreement-history.repository';
15
- import { ItemClassMap } from './ClassMappings/ItemClassMap';
16
15
  import { RentalHirerChangeRequest } from './components/rental-hirer-change-request/rental-hirer-change-request';
17
16
  import { RentalHirerChangeRequestRepository } from './components/rental-hirer-change-request/rental-hirer-change-request.repository';
18
17
  import { HirerChangeRequestSignature } from './components/hirer-change-request-signature/hirer-change-request-signature';
@@ -21,6 +20,7 @@ import { HirerChangeRequestNewHirer } from './components/hirer-change-request-ne
21
20
  import { HirerChangeRequestNewHirerRepository } from './components/hirer-change-request-new-hirer/hirer-change-request-new-hirer.repository';
22
21
  import { HirerChangeRequestRemoveHirer } from './components/hirer-change-request-remove-hirer/hirer-change-request-remove-hirer';
23
22
  import { HirerChangeRequestRemoveHirerRepository } from './components/hirer-change-request-remove-hirer/hirer-change-request-remove-hirer.repository';
23
+ import { ItemClassMap } from './ClassMappings/ItemClassMap';
24
24
  import * as rentalDb from './database';
25
25
  export * from './interfaces';
26
26
  export * from './models';
@@ -42,7 +42,6 @@ export {
42
42
  AgreementSignatureRepository,
43
43
  AgreementHistory,
44
44
  AgreementHistoryRepository,
45
- ItemClassMap,
46
45
  RentalHirerChangeRequest,
47
46
  RentalHirerChangeRequestRepository,
48
47
  HirerChangeRequestSignature,
@@ -51,4 +50,5 @@ export {
51
50
  HirerChangeRequestNewHirerRepository,
52
51
  HirerChangeRequestRemoveHirer,
53
52
  HirerChangeRequestRemoveHirerRepository,
53
+ ItemClassMap,
54
54
  };
@@ -7,7 +7,7 @@ import {
7
7
  BelongsTo,
8
8
  } from 'sequelize-typescript';
9
9
  import { RentalHirerChangeRequestModel } from './rental-hirer-change-request.entity';
10
- import { IHirerChangeRequestNewHirerAttr } from 'interfaces/hirer-change-request-new-hirer-attr.interface';
10
+ import { IHirerChangeRequestNewHirerAttr } from '../interfaces/hirer-change-request-new-hirer-attr.interface';
11
11
 
12
12
  @Table({
13
13
  tableName: 'hirerChangeRequest_NewHirer',
@@ -8,7 +8,7 @@ import {
8
8
  } from 'sequelize-typescript';
9
9
  import { RentalHirerChangeRequestModel } from './rental-hirer-change-request.entity';
10
10
  import { JointHirerModel } from './joint-hirer.entity';
11
- import { IHirerChangeRequestRemoveHirerAttr } from 'interfaces/hirer-change-request-remove-hirer-attr.interface';
11
+ import { IHirerChangeRequestRemoveHirerAttr } from '../interfaces/hirer-change-request-remove-hirer-attr.interface';
12
12
 
13
13
  @Table({
14
14
  tableName: 'hirerChangeRequest_RemoveHirer',
@@ -10,7 +10,7 @@ import {
10
10
  } from 'sequelize-typescript';
11
11
  import { RentalHirerChangeRequestModel } from './rental-hirer-change-request.entity';
12
12
  import { HirerChangeRequestHirerRoleEnum } from '../enum/rental-hirer-change-request-hirer-role';
13
- import { IHirerChangeRequestSignatureAttr } from 'interfaces/hirer-change-request-signature-attr.interface';
13
+ import { IHirerChangeRequestSignatureAttr } from '../interfaces/hirer-change-request-signature-attr.interface';
14
14
 
15
15
  @Table({
16
16
  tableName: 'hirerChangeRequest_Signature',
@@ -45,7 +45,7 @@ export class JointHirerModel extends Model {
45
45
  type: DataType.STRING(20),
46
46
  defaultValue: 'Active',
47
47
  })
48
- Status: string; // Default status
48
+ Status: string = 'Active'; // Default status
49
49
 
50
50
  @Column({
51
51
  allowNull: false,
@@ -1,6 +1,11 @@
1
1
  {
2
2
  "extends": "./tsconfig.json",
3
- "include": ["**/*.ts"],
4
- "exclude": ["node_modules", "__tests__", "dist", "**/*spec.ts"]
3
+ "include": ["src/**/*"],
4
+ "exclude": [
5
+ "node_modules",
6
+ "__tests__",
7
+ "./dist",
8
+ "**/*spec.ts",
9
+ "./dist/**/*"
10
+ ]
5
11
  }
6
-
package/tsconfig.json CHANGED
@@ -7,18 +7,16 @@
7
7
  "experimentalDecorators": true,
8
8
  "allowSyntheticDefaultImports": true,
9
9
  "moduleResolution": "node",
10
- "target": "es6",
10
+ "target": "es2017",
11
11
  "sourceMap": true,
12
- "outDir": "dist",
13
- "baseUrl": "./src",
14
- "rootDir": "./",
12
+ "outDir": "./dist",
13
+ "baseUrl": "./",
15
14
  "incremental": true,
16
15
  "skipLibCheck": true,
16
+ "strictNullChecks": false,
17
17
  "noImplicitAny": false,
18
18
  "strictBindCallApply": false,
19
19
  "forceConsistentCasingInFileNames": false,
20
- "noFallthroughCasesInSwitch": false,
21
- "strictNullChecks": false,
22
- },
23
- "exclude": ["node_modules", "dist"]
20
+ "noFallthroughCasesInSwitch": false
21
+ }
24
22
  }