@tomei/rental 0.17.1 → 0.19.0-staging.2

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@tomei/rental",
3
- "version": "0.17.1",
3
+ "version": "0.19.0-staging.2",
4
4
  "description": "Tomei Rental Package",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -57,13 +57,15 @@
57
57
  "access": "public"
58
58
  },
59
59
  "peerDependencies": {
60
- "@tomei/activity-history": "^0.2.23",
60
+ "@tomei/activity-history": "^0.4.1",
61
61
  "@tomei/config": "^0.3.21",
62
- "@tomei/general": "^0.21.3",
63
- "@tomei/sso": "^0.51.6",
64
- "luxon": "^3.5.0",
62
+ "@tomei/finance": "^0.11.7-staging.4",
63
+ "@tomei/general": "^0.21.7",
64
+ "@tomei/sso": "^0.60.4",
65
+ "@tomei/stock": "^0.18.1",
66
+ "luxon": "^3.6.1",
65
67
  "reflect-metadata": "^0.2.2",
66
- "sequelize": "^6.37.5",
68
+ "sequelize": "^6.37.7",
67
69
  "sequelize-typescript": "^2.1.6"
68
70
  },
69
71
  "lint-staged": {
@@ -71,5 +73,8 @@
71
73
  "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
72
74
  "eslint \"{src,apps,libs,test}/**/*.ts\" --fix"
73
75
  ]
76
+ },
77
+ "overrides": {
78
+ "glob": "^9.0.0"
74
79
  }
75
80
  }
@@ -0,0 +1,7 @@
1
+ // Import all item classes that Rental might reference
2
+ import { StockInventory } from '@tomei/stock';
3
+
4
+ // Create and export the mapping
5
+ export const ItemClassMap = {
6
+ StockInventory,
7
+ };
@@ -0,0 +1,3 @@
1
+ import { ItemClassMap } from './ItemClassMap';
2
+
3
+ export { ItemClassMap };
@@ -9,7 +9,7 @@ import * as rentalDb from '../../database';
9
9
  import { QueryTypes, where } from 'sequelize';
10
10
  import { IResponseAgreementSignature } from '../../interfaces/response-hirer-signature-attr.interface';
11
11
  import { AgreementHistoryRepository } from '../agreement-history/agreement-history.repository';
12
- import { IAgreementHistoryAttr } from 'interfaces/agreement-history-attr.interface';
12
+ import { IAgreementHistoryAttr } from '../../interfaces/agreement-history-attr.interface';
13
13
  import { ActionEnum, Activity } from '@tomei/activity-history';
14
14
 
15
15
  export class Agreement extends ObjectBase {
@@ -22,6 +22,8 @@ import { AgreementSignatureRepository } from '../agreement-signature/agreement-s
22
22
  import { AgreementSignatureStatusEnum } from '../../enum/agreement-signature-status.enum';
23
23
  import { HirerTypeEnum } from '../../enum/hirer-type.enum';
24
24
  import { AgreementHistoryRepository } from '../agreement-history/agreement-history.repository';
25
+ import { DocType, Document, IAccountSystem } from '@tomei/finance';
26
+ import { ItemClassMap } from '../../ClassMappings/ItemClassMap';
25
27
 
26
28
  export class Rental extends ObjectBase {
27
29
  ObjectId: string;
@@ -40,6 +42,8 @@ export class Rental extends ObjectBase {
40
42
  AgreementNo: string;
41
43
  AccountType: RentalAccountTypeEnum;
42
44
  JointHirers: JointHirer[] = [];
45
+ Invoices: Document[] = [];
46
+ Item: any;
43
47
  protected _Status: RentalStatusEnum | string;
44
48
  protected _EscheatmentYN: string = 'N';
45
49
  protected _CreatedById: string;
@@ -1132,4 +1136,226 @@ export class Rental extends ObjectBase {
1132
1136
  throw error;
1133
1137
  }
1134
1138
  }
1139
+
1140
+ public toJSON(): IRentalAttr {
1141
+ return {
1142
+ RentalId: this.RentalId,
1143
+ CustomerId: this.CustomerId,
1144
+ CustomerType: this.CustomerType,
1145
+ ItemId: this.ItemId,
1146
+ ItemType: this.ItemType,
1147
+ PriceId: this.PriceId,
1148
+ StartDateTime: this.StartDateTime,
1149
+ EndDateTime: this.EndDateTime,
1150
+ Status: this.Status,
1151
+ CancelRemarks: this.CancelRemarks,
1152
+ TerminateRemarks: this.TerminateRemarks,
1153
+ EscheatmentYN: this.EscheatmentYN,
1154
+ AgreementNo: this.AgreementNo,
1155
+ AccountType: this.AccountType,
1156
+ CreatedById: this.CreatedById,
1157
+ CreatedAt: this.CreatedAt,
1158
+ UpdatedById: this.UpdatedById,
1159
+ UpdatedAt: this.UpdatedAt,
1160
+ };
1161
+ }
1162
+
1163
+ public async getInvoices(
1164
+ loginUser: LoginUser,
1165
+ dbTransaction: any,
1166
+ accountingSystem?: IAccountSystem,
1167
+ ) {
1168
+ try {
1169
+ // Part 1: Privilege Checking
1170
+ // Call loginUser.checkPrivileges() by passing:
1171
+ // SystemCode: <get_from_app_config>
1172
+ // PrivilegeCode: "RENTAL_VIEW_INVOICE"
1173
+ const systemCode =
1174
+ ApplicationConfig.getComponentConfigValue('system-code');
1175
+ const isPrivileged = loginUser.checkPrivileges(
1176
+ systemCode,
1177
+ 'RENTAL_VIEW_INVOICE',
1178
+ );
1179
+
1180
+ if (!isPrivileged) {
1181
+ throw new ClassError(
1182
+ 'Rental',
1183
+ 'RentalErrMsg01',
1184
+ "You do not have 'RENTAL_VIEW_INVOICE' privilege.",
1185
+ );
1186
+ }
1187
+
1188
+ // Part 2: Validation
1189
+ // Make sure this._ObjectId exists, if not throw new ClassError by passing
1190
+ if (!this.ObjectId) {
1191
+ throw new ClassError(
1192
+ 'Rental',
1193
+ 'RentalErrMsg01',
1194
+ 'ObjectId is missing.',
1195
+ );
1196
+ }
1197
+
1198
+ // Part 3: Check Existing Invoices
1199
+ if (this.Invoices.length > 0) {
1200
+ return this.Invoices;
1201
+ }
1202
+
1203
+ // Part 4: Retrieve Invoices and Returns
1204
+ const search = {
1205
+ DocType: DocType.INVOICE,
1206
+ RelatedObjectId: this.ObjectId,
1207
+ RelatedObjectType: this.ObjectType,
1208
+ };
1209
+
1210
+ const documents = await Document.findAll(
1211
+ loginUser,
1212
+ dbTransaction,
1213
+ undefined,
1214
+ undefined,
1215
+ search,
1216
+ undefined,
1217
+ accountingSystem,
1218
+ );
1219
+
1220
+ this.Invoices = documents.rows.map((doc) => {
1221
+ const document = new Document(dbTransaction, doc);
1222
+ return document;
1223
+ });
1224
+
1225
+ return this.Invoices;
1226
+ } catch (error) {
1227
+ throw error;
1228
+ }
1229
+ }
1230
+
1231
+ public async getItem(dbTransaction: any): Promise<any> {
1232
+ if (this.Item) {
1233
+ return this.Item;
1234
+ } else {
1235
+ const ItemClass = ItemClassMap[this.ItemType];
1236
+
1237
+ if (!ItemClass || typeof ItemClass.init !== 'function') {
1238
+ throw new Error(`Invalid or unregistered ItemType: ${this.ItemType}`);
1239
+ }
1240
+
1241
+ ItemClass._Repo = ItemClass._Repo || ItemClass.getRepo();
1242
+
1243
+ if (!ItemClass._Repo) {
1244
+ throw new Error(
1245
+ `ItemType ${this.ItemType} does not have a repository.`,
1246
+ );
1247
+ }
1248
+
1249
+ const itemInstance = await ItemClass.init(this.ItemId, dbTransaction);
1250
+
1251
+ if (!itemInstance) {
1252
+ throw new Error(`${this.ItemType} not found with ID ${this.ItemId}`);
1253
+ }
1254
+ this.Item = itemInstance;
1255
+
1256
+ // Make sure item has setAvailable method
1257
+ if (typeof this.Item.setAvailable !== 'function') {
1258
+ throw new Error(`${this.ItemType} does not implement setAvailable()`);
1259
+ }
1260
+ return this.Item;
1261
+ }
1262
+ }
1263
+
1264
+ public async cancel(
1265
+ loginUser: LoginUser,
1266
+ dbTransaction: any,
1267
+ remarks: string,
1268
+ ): Promise<Rental> {
1269
+ try {
1270
+ // Part 1: Privilege Checking
1271
+ const systemCode =
1272
+ ApplicationConfig.getComponentConfigValue('system-code');
1273
+ const isPrivileged = await loginUser.checkPrivileges(
1274
+ systemCode,
1275
+ 'RENTAL_CANCEL',
1276
+ );
1277
+
1278
+ if (!isPrivileged) {
1279
+ throw new ClassError(
1280
+ 'Rental',
1281
+ 'RentalErrMsg01',
1282
+ "You do not have 'RENTAL_CANCEL' privilege.",
1283
+ );
1284
+ }
1285
+
1286
+ // Part 2: Validation
1287
+ if (!this.ObjectId) {
1288
+ throw new ClassError(
1289
+ 'Rental',
1290
+ 'RentalErrMsg01',
1291
+ 'Rental not found. Rental Id is empty.',
1292
+ );
1293
+ }
1294
+
1295
+ if (
1296
+ this.Status === RentalStatusEnum.ACTIVE ||
1297
+ this.Status === RentalStatusEnum.SUSPENDED
1298
+ ) {
1299
+ throw new ClassError(
1300
+ 'Rental',
1301
+ 'RentalErrMsg01',
1302
+ `Rental already ${this.Status}, please do termination process.`,
1303
+ );
1304
+ }
1305
+
1306
+ if (!remarks) {
1307
+ throw new ClassError(
1308
+ 'Rental',
1309
+ 'RentalErrMsg01',
1310
+ 'Cancellation remarks is required.',
1311
+ );
1312
+ }
1313
+
1314
+ // Part 3: Capture Record Info Before Changes
1315
+ const entityValueBefore = this.toJSON();
1316
+
1317
+ // Part 4: Update Rental Status and Remarks
1318
+ this._Status = RentalStatusEnum.CANCELLED;
1319
+ this.CancelRemarks = remarks;
1320
+ this._UpdatedById = loginUser.ObjectId;
1321
+ this._UpdatedAt = new Date();
1322
+
1323
+ // Part 5: Update Rental Record
1324
+ await Rental._Repo.update(
1325
+ {
1326
+ Status: this.Status,
1327
+ CancelRemarks: this.CancelRemarks,
1328
+ UpdatedById: this.UpdatedById,
1329
+ UpdatedAt: this.UpdatedAt,
1330
+ },
1331
+ {
1332
+ where: {
1333
+ RentalId: this.RentalId,
1334
+ },
1335
+ transaction: dbTransaction,
1336
+ },
1337
+ );
1338
+
1339
+ // Part 6: Mark Item as Available
1340
+ const item = await this.getItem(dbTransaction);
1341
+
1342
+ await item.setAvailable(loginUser, dbTransaction);
1343
+
1344
+ // Part 7: Capture Record Info After Changes
1345
+ const entityValueAfter = this.toJSON();
1346
+ // Part 8: Record Activity
1347
+ const activity = new Activity();
1348
+ activity.ActivityId = activity.createId();
1349
+ activity.Action = ActionEnum.UPDATE;
1350
+ activity.Description = 'Rental Cancellation';
1351
+ activity.EntityType = this.ObjectType;
1352
+ activity.EntityId = this.ObjectId;
1353
+ activity.EntityValueBefore = JSON.stringify(entityValueBefore);
1354
+ activity.EntityValueAfter = JSON.stringify(entityValueAfter);
1355
+ await activity.create(loginUser.ObjectId, dbTransaction);
1356
+ return this;
1357
+ } catch (error) {
1358
+ throw error;
1359
+ }
1360
+ }
1135
1361
  }
package/src/index.ts CHANGED
@@ -12,6 +12,7 @@ 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';
15
16
  import * as rentalDb from './database';
16
17
  export * from './interfaces';
17
18
  export * from './models';
@@ -33,4 +34,5 @@ export {
33
34
  AgreementSignatureRepository,
34
35
  AgreementHistory,
35
36
  AgreementHistoryRepository,
37
+ ItemClassMap,
36
38
  };