@tomei/rental 0.17.3-dev.5 → 0.17.3-dev.7

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 (353) hide show
  1. package/.commitlintrc.json +22 -22
  2. package/.gitlab-ci.yml +16 -16
  3. package/.husky/commit-msg +9 -9
  4. package/.husky/pre-commit +7 -7
  5. package/.prettierrc +4 -4
  6. package/Jenkinsfile +51 -51
  7. package/README.md +8 -8
  8. package/dist/ClassMappings/ItemClassMap.d.ts +4 -0
  9. package/dist/ClassMappings/ItemClassMap.js +8 -0
  10. package/dist/ClassMappings/ItemClassMap.js.map +1 -0
  11. package/dist/ClassMappings/index.d.ts +2 -0
  12. package/dist/ClassMappings/index.js +6 -0
  13. package/dist/ClassMappings/index.js.map +1 -0
  14. package/dist/components/agreement/agreement.d.ts +27 -0
  15. package/dist/components/agreement/agreement.js +120 -0
  16. package/dist/components/agreement/agreement.js.map +1 -0
  17. package/dist/components/agreement/agreement.repository.d.ts +8 -0
  18. package/dist/components/agreement/agreement.repository.js +52 -0
  19. package/dist/components/agreement/agreement.repository.js.map +1 -0
  20. package/dist/components/agreement-history/agreement-history.d.ts +17 -0
  21. package/dist/components/agreement-history/agreement-history.js +40 -0
  22. package/dist/components/agreement-history/agreement-history.js.map +1 -0
  23. package/dist/components/agreement-history/agreement-history.repository.d.ts +8 -0
  24. package/dist/components/agreement-history/agreement-history.repository.js +52 -0
  25. package/dist/components/agreement-history/agreement-history.repository.js.map +1 -0
  26. package/dist/components/agreement-signature/agreement-signature.d.ts +27 -0
  27. package/dist/components/agreement-signature/agreement-signature.js +99 -0
  28. package/dist/components/agreement-signature/agreement-signature.js.map +1 -0
  29. package/dist/components/agreement-signature/agreement-signature.repository.d.ts +8 -0
  30. package/dist/components/agreement-signature/agreement-signature.repository.js +53 -0
  31. package/dist/components/agreement-signature/agreement-signature.repository.js.map +1 -0
  32. package/dist/components/booking/booking.d.ts +46 -0
  33. package/dist/components/booking/booking.js +289 -0
  34. package/dist/components/booking/booking.js.map +1 -0
  35. package/dist/components/booking/booking.repository.d.ts +8 -0
  36. package/dist/components/booking/booking.repository.js +52 -0
  37. package/dist/components/booking/booking.repository.js.map +1 -0
  38. package/dist/components/hirer-change-request-new-hirer/hirer-change-request-new-hirer.d.ts +32 -0
  39. package/dist/components/hirer-change-request-new-hirer/hirer-change-request-new-hirer.js +106 -0
  40. package/dist/components/hirer-change-request-new-hirer/hirer-change-request-new-hirer.js.map +1 -0
  41. package/dist/components/hirer-change-request-new-hirer/hirer-change-request-new-hirer.repository.d.ts +9 -0
  42. package/dist/components/hirer-change-request-new-hirer/hirer-change-request-new-hirer.repository.js +62 -0
  43. package/dist/components/hirer-change-request-new-hirer/hirer-change-request-new-hirer.repository.js.map +1 -0
  44. package/dist/components/hirer-change-request-remove-hirer/hirer-change-request-remove-hirer.d.ts +22 -0
  45. package/dist/components/hirer-change-request-remove-hirer/hirer-change-request-remove-hirer.js +89 -0
  46. package/dist/components/hirer-change-request-remove-hirer/hirer-change-request-remove-hirer.js.map +1 -0
  47. package/dist/components/hirer-change-request-remove-hirer/hirer-change-request-remove-hirer.repository.d.ts +9 -0
  48. package/dist/components/hirer-change-request-remove-hirer/hirer-change-request-remove-hirer.repository.js +63 -0
  49. package/dist/components/hirer-change-request-remove-hirer/hirer-change-request-remove-hirer.repository.js.map +1 -0
  50. package/dist/components/hirer-change-request-signature/hirer-change-request-signature.d.ts +30 -0
  51. package/dist/components/hirer-change-request-signature/hirer-change-request-signature.js +208 -0
  52. package/dist/components/hirer-change-request-signature/hirer-change-request-signature.js.map +1 -0
  53. package/dist/components/hirer-change-request-signature/hirer-change-request-signature.repository.d.ts +9 -0
  54. package/dist/components/hirer-change-request-signature/hirer-change-request-signature.repository.js +63 -0
  55. package/dist/components/hirer-change-request-signature/hirer-change-request-signature.repository.js.map +1 -0
  56. package/dist/components/joint-hirer/joint-hirer.d.ts +26 -0
  57. package/dist/components/joint-hirer/joint-hirer.js +137 -0
  58. package/dist/components/joint-hirer/joint-hirer.js.map +1 -0
  59. package/dist/components/joint-hirer/joint-hirer.repository.d.ts +8 -0
  60. package/dist/components/joint-hirer/joint-hirer.repository.js +52 -0
  61. package/dist/components/joint-hirer/joint-hirer.repository.js.map +1 -0
  62. package/dist/components/rental/rental.d.ts +72 -0
  63. package/dist/components/rental/rental.js +844 -0
  64. package/dist/components/rental/rental.js.map +1 -0
  65. package/dist/components/rental/rental.repository.d.ts +8 -0
  66. package/dist/components/rental/rental.repository.js +52 -0
  67. package/dist/components/rental/rental.repository.js.map +1 -0
  68. package/dist/components/rental-hirer-change-request/rental-hirer-change-request.d.ts +71 -0
  69. package/dist/components/rental-hirer-change-request/rental-hirer-change-request.js +531 -0
  70. package/dist/components/rental-hirer-change-request/rental-hirer-change-request.js.map +1 -0
  71. package/dist/components/rental-hirer-change-request/rental-hirer-change-request.repository.d.ts +9 -0
  72. package/dist/components/rental-hirer-change-request/rental-hirer-change-request.repository.js +62 -0
  73. package/dist/components/rental-hirer-change-request/rental-hirer-change-request.repository.js.map +1 -0
  74. package/dist/components/rental-price/rental-price.d.ts +18 -0
  75. package/dist/components/rental-price/rental-price.js +66 -0
  76. package/dist/components/rental-price/rental-price.js.map +1 -0
  77. package/dist/components/rental-price/rental-price.repository.d.ts +8 -0
  78. package/dist/components/rental-price/rental-price.repository.js +52 -0
  79. package/dist/components/rental-price/rental-price.repository.js.map +1 -0
  80. package/dist/database.d.ts +4 -0
  81. package/dist/database.js +37 -0
  82. package/dist/database.js.map +1 -0
  83. package/dist/enum/account-type.enum.d.ts +4 -0
  84. package/dist/enum/account-type.enum.js +9 -0
  85. package/dist/enum/account-type.enum.js.map +1 -0
  86. package/dist/enum/aggrement-status.enum.d.ts +5 -0
  87. package/dist/enum/aggrement-status.enum.js +10 -0
  88. package/dist/enum/aggrement-status.enum.js.map +1 -0
  89. package/dist/enum/agreement-signature-status.enum.d.ts +4 -0
  90. package/dist/enum/agreement-signature-status.enum.js +9 -0
  91. package/dist/enum/agreement-signature-status.enum.js.map +1 -0
  92. package/dist/enum/agreement-signature-verification-method.enum.d.ts +4 -0
  93. package/dist/enum/agreement-signature-verification-method.enum.js +9 -0
  94. package/dist/enum/agreement-signature-verification-method.enum.js.map +1 -0
  95. package/dist/enum/booking.enum.d.ts +5 -0
  96. package/dist/enum/booking.enum.js +10 -0
  97. package/dist/enum/booking.enum.js.map +1 -0
  98. package/dist/enum/hirer-type.enum.d.ts +4 -0
  99. package/dist/enum/hirer-type.enum.js +9 -0
  100. package/dist/enum/hirer-type.enum.js.map +1 -0
  101. package/dist/enum/index.d.ts +11 -0
  102. package/dist/enum/index.js +24 -0
  103. package/dist/enum/index.js.map +1 -0
  104. package/dist/enum/rental-hirer-change-request-hirer-role.d.ts +4 -0
  105. package/dist/enum/rental-hirer-change-request-hirer-role.js +9 -0
  106. package/dist/enum/rental-hirer-change-request-hirer-role.js.map +1 -0
  107. package/dist/enum/rental-hirer-change-request-status.d.ts +7 -0
  108. package/dist/enum/rental-hirer-change-request-status.js +12 -0
  109. package/dist/enum/rental-hirer-change-request-status.js.map +1 -0
  110. package/dist/enum/rental-hirer-change-request-type.d.ts +4 -0
  111. package/dist/enum/rental-hirer-change-request-type.js +9 -0
  112. package/dist/enum/rental-hirer-change-request-type.js.map +1 -0
  113. package/dist/enum/rental-status.enum.d.ts +9 -0
  114. package/dist/enum/rental-status.enum.js +14 -0
  115. package/dist/enum/rental-status.enum.js.map +1 -0
  116. package/dist/index.d.ts +28 -1
  117. package/dist/index.js +52 -1
  118. package/dist/index.js.map +1 -1
  119. package/dist/interfaces/agreemeent-signature-attr.interface.d.ts +14 -0
  120. package/dist/interfaces/agreemeent-signature-attr.interface.js +3 -0
  121. package/dist/interfaces/agreemeent-signature-attr.interface.js.map +1 -0
  122. package/dist/interfaces/agreement-attr.interface.d.ts +7 -0
  123. package/dist/{src/interfaces/hirer-signature-attr.interface.js → interfaces/agreement-attr.interface.js} +1 -1
  124. package/dist/interfaces/agreement-attr.interface.js.map +1 -0
  125. package/dist/interfaces/agreement-history-attr.interface.d.ts +7 -0
  126. package/dist/interfaces/agreement-history-attr.interface.js +3 -0
  127. package/dist/interfaces/agreement-history-attr.interface.js.map +1 -0
  128. package/dist/interfaces/booking-attr.interface.d.ts +18 -0
  129. package/dist/interfaces/booking-attr.interface.js +3 -0
  130. package/dist/interfaces/booking-attr.interface.js.map +1 -0
  131. package/dist/interfaces/booking-find-all-search-attr.interface.d.ts +12 -0
  132. package/dist/interfaces/booking-find-all-search-attr.interface.js +3 -0
  133. package/dist/interfaces/booking-find-all-search-attr.interface.js.map +1 -0
  134. package/dist/interfaces/hirer-change-request-new-hirer-attr.interface.d.ts +15 -0
  135. package/dist/interfaces/hirer-change-request-new-hirer-attr.interface.js +3 -0
  136. package/dist/interfaces/hirer-change-request-new-hirer-attr.interface.js.map +1 -0
  137. package/dist/interfaces/hirer-change-request-remove-hirer-attr.interface.d.ts +5 -0
  138. package/dist/interfaces/hirer-change-request-remove-hirer-attr.interface.js +3 -0
  139. package/dist/interfaces/hirer-change-request-remove-hirer-attr.interface.js.map +1 -0
  140. package/dist/interfaces/hirer-change-request-signature-attr.interface.d.ts +14 -0
  141. package/dist/interfaces/hirer-change-request-signature-attr.interface.js +3 -0
  142. package/dist/interfaces/hirer-change-request-signature-attr.interface.js.map +1 -0
  143. package/dist/interfaces/index.d.ts +14 -0
  144. package/dist/interfaces/index.js +3 -0
  145. package/dist/interfaces/index.js.map +1 -0
  146. package/dist/interfaces/joint-hirer-attr.interface.d.ts +11 -0
  147. package/dist/interfaces/joint-hirer-attr.interface.js +3 -0
  148. package/dist/interfaces/joint-hirer-attr.interface.js.map +1 -0
  149. package/dist/interfaces/rental-attr.interface.d.ts +24 -0
  150. package/dist/interfaces/rental-attr.interface.js +3 -0
  151. package/dist/interfaces/rental-attr.interface.js.map +1 -0
  152. package/dist/interfaces/rental-find-all-search-attr.interface.d.ts +10 -0
  153. package/dist/interfaces/rental-find-all-search-attr.interface.js +3 -0
  154. package/dist/interfaces/rental-find-all-search-attr.interface.js.map +1 -0
  155. package/dist/interfaces/rental-hirer-change-request.attr.interface.d.ts +16 -0
  156. package/dist/interfaces/rental-hirer-change-request.attr.interface.js +3 -0
  157. package/dist/interfaces/rental-hirer-change-request.attr.interface.js.map +1 -0
  158. package/dist/interfaces/rental-hirer-change-request.update.interface.d.ts +4 -0
  159. package/dist/interfaces/rental-hirer-change-request.update.interface.js +3 -0
  160. package/dist/interfaces/rental-hirer-change-request.update.interface.js.map +1 -0
  161. package/dist/interfaces/rental-price-attr.interface.d.ts +7 -0
  162. package/dist/interfaces/rental-price-attr.interface.js +3 -0
  163. package/dist/interfaces/rental-price-attr.interface.js.map +1 -0
  164. package/dist/interfaces/response-hirer-signature-attr.interface.d.ts +14 -0
  165. package/dist/interfaces/response-hirer-signature-attr.interface.js +3 -0
  166. package/dist/interfaces/response-hirer-signature-attr.interface.js.map +1 -0
  167. package/dist/models/agreement-history.entity.d.ts +10 -0
  168. package/dist/models/agreement-history.entity.js +65 -0
  169. package/dist/models/agreement-history.entity.js.map +1 -0
  170. package/dist/models/agreement-signature.entity.d.ts +22 -0
  171. package/dist/{src/models/hirer-signature.entity.js → models/agreement-signature.entity.js} +29 -6
  172. package/dist/models/agreement-signature.entity.js.map +1 -0
  173. package/dist/models/agreement.entity.d.ts +14 -0
  174. package/dist/models/agreement.entity.js +70 -0
  175. package/dist/models/agreement.entity.js.map +1 -0
  176. package/dist/models/booking.entity.d.ts +21 -0
  177. package/dist/models/booking.entity.js +128 -0
  178. package/dist/models/booking.entity.js.map +1 -0
  179. package/dist/models/hirer-change-request-new-hirer.entity.d.ts +19 -0
  180. package/dist/models/hirer-change-request-new-hirer.entity.js +121 -0
  181. package/dist/models/hirer-change-request-new-hirer.entity.js.map +1 -0
  182. package/dist/models/hirer-change-request-remove-hirer.entity.d.ts +11 -0
  183. package/dist/models/hirer-change-request-remove-hirer.entity.js +57 -0
  184. package/dist/models/hirer-change-request-remove-hirer.entity.js.map +1 -0
  185. package/dist/models/hirer-change-request-signature.entity.d.ts +18 -0
  186. package/dist/models/hirer-change-request-signature.entity.js +101 -0
  187. package/dist/models/hirer-change-request-signature.entity.js.map +1 -0
  188. package/dist/models/index.d.ts +12 -0
  189. package/dist/models/index.js +26 -0
  190. package/dist/models/index.js.map +1 -0
  191. package/dist/models/joint-hirer.entity.d.ts +14 -0
  192. package/dist/models/joint-hirer.entity.js +91 -0
  193. package/dist/models/joint-hirer.entity.js.map +1 -0
  194. package/dist/models/rental-hirer-change-request.entity.d.ts +22 -0
  195. package/dist/models/rental-hirer-change-request.entity.js +108 -0
  196. package/dist/models/rental-hirer-change-request.entity.js.map +1 -0
  197. package/dist/models/rental-price.entity.d.ts +8 -0
  198. package/dist/models/rental-price.entity.js +59 -0
  199. package/dist/models/rental-price.entity.js.map +1 -0
  200. package/dist/models/rental.entity.d.ts +29 -0
  201. package/dist/models/rental.entity.js +160 -0
  202. package/dist/models/rental.entity.js.map +1 -0
  203. package/dist/src/components/agreement/agreement.d.ts +1 -1
  204. package/dist/src/components/agreement/agreement.js +77 -94
  205. package/dist/src/components/agreement/agreement.js.map +1 -1
  206. package/dist/src/components/agreement/agreement.repository.js +35 -50
  207. package/dist/src/components/agreement/agreement.repository.js.map +1 -1
  208. package/dist/src/components/agreement-history/agreement-history.js +10 -21
  209. package/dist/src/components/agreement-history/agreement-history.js.map +1 -1
  210. package/dist/src/components/agreement-history/agreement-history.repository.js +35 -50
  211. package/dist/src/components/agreement-history/agreement-history.repository.js.map +1 -1
  212. package/dist/src/components/agreement-signature/agreement-signature.js +57 -70
  213. package/dist/src/components/agreement-signature/agreement-signature.js.map +1 -1
  214. package/dist/src/components/agreement-signature/agreement-signature.repository.js +36 -51
  215. package/dist/src/components/agreement-signature/agreement-signature.repository.js.map +1 -1
  216. package/dist/src/components/booking/booking.js +206 -231
  217. package/dist/src/components/booking/booking.js.map +1 -1
  218. package/dist/src/components/booking/booking.repository.js +35 -50
  219. package/dist/src/components/booking/booking.repository.js.map +1 -1
  220. package/dist/src/components/hirer-change-request-new-hirer/hirer-change-request-new-hirer.js +47 -62
  221. package/dist/src/components/hirer-change-request-new-hirer/hirer-change-request-new-hirer.js.map +1 -1
  222. package/dist/src/components/hirer-change-request-new-hirer/hirer-change-request-new-hirer.repository.js +46 -63
  223. package/dist/src/components/hirer-change-request-new-hirer/hirer-change-request-new-hirer.repository.js.map +1 -1
  224. package/dist/src/components/hirer-change-request-remove-hirer/hirer-change-request-remove-hirer.js +49 -64
  225. package/dist/src/components/hirer-change-request-remove-hirer/hirer-change-request-remove-hirer.js.map +1 -1
  226. package/dist/src/components/hirer-change-request-remove-hirer/hirer-change-request-remove-hirer.repository.js +47 -64
  227. package/dist/src/components/hirer-change-request-remove-hirer/hirer-change-request-remove-hirer.repository.js.map +1 -1
  228. package/dist/src/components/hirer-change-request-signature/hirer-change-request-signature.js +150 -167
  229. package/dist/src/components/hirer-change-request-signature/hirer-change-request-signature.js.map +1 -1
  230. package/dist/src/components/hirer-change-request-signature/hirer-change-request-signature.repository.js +47 -64
  231. package/dist/src/components/hirer-change-request-signature/hirer-change-request-signature.repository.js.map +1 -1
  232. package/dist/src/components/joint-hirer/joint-hirer.js +82 -97
  233. package/dist/src/components/joint-hirer/joint-hirer.js.map +1 -1
  234. package/dist/src/components/joint-hirer/joint-hirer.repository.js +35 -50
  235. package/dist/src/components/joint-hirer/joint-hirer.repository.js.map +1 -1
  236. package/dist/src/components/rental/rental.d.ts +2 -2
  237. package/dist/src/components/rental/rental.js +566 -595
  238. package/dist/src/components/rental/rental.js.map +1 -1
  239. package/dist/src/components/rental/rental.repository.js +35 -50
  240. package/dist/src/components/rental/rental.repository.js.map +1 -1
  241. package/dist/src/components/rental-hirer-change-request/rental-hirer-change-request.js +416 -455
  242. package/dist/src/components/rental-hirer-change-request/rental-hirer-change-request.js.map +1 -1
  243. package/dist/src/components/rental-hirer-change-request/rental-hirer-change-request.repository.js +46 -63
  244. package/dist/src/components/rental-hirer-change-request/rental-hirer-change-request.repository.js.map +1 -1
  245. package/dist/src/components/rental-price/rental-price.js +33 -46
  246. package/dist/src/components/rental-price/rental-price.js.map +1 -1
  247. package/dist/src/components/rental-price/rental-price.repository.js +35 -50
  248. package/dist/src/components/rental-price/rental-price.repository.js.map +1 -1
  249. package/dist/src/models/hirer-change-request-new-hirer.entity.d.ts +1 -1
  250. package/dist/src/models/hirer-change-request-remove-hirer.entity.d.ts +1 -1
  251. package/dist/src/models/hirer-change-request-signature.entity.d.ts +1 -1
  252. package/dist/tsconfig.build.tsbuildinfo +1 -0
  253. package/dist/tsconfig.tsbuildinfo +1 -1
  254. package/eslint.config.mjs +58 -58
  255. package/jest.config.js +10 -10
  256. package/migrations/20250529092130-add-status-to-joint-hirer.js +19 -19
  257. package/migrations/agreement-signature-table-migration.js +76 -64
  258. package/migrations/booking-table-migration.js +79 -79
  259. package/migrations/hirer-change-request-new-hirer-migration.js +72 -72
  260. package/migrations/hirer-change-request-remove-hirer-migration.js +39 -39
  261. package/migrations/hirer-change-request-signature-migration.js +65 -65
  262. package/migrations/joint-hirer-table-migration.js +52 -52
  263. package/migrations/rental-aggreement-history-migration.js +41 -41
  264. package/migrations/rental-aggrement-table-migration.js +30 -30
  265. package/migrations/rental-hirer-change-request-migrations.js +64 -64
  266. package/migrations/rental-price-table-migration.js +32 -32
  267. package/migrations/rental-table-migrations.js +96 -96
  268. package/package.json +77 -75
  269. package/sonar-project.properties +12 -12
  270. package/src/ClassMappings/ItemClassMap.ts +7 -0
  271. package/src/ClassMappings/index.ts +3 -0
  272. package/src/components/agreement/agreement.repository.ts +54 -54
  273. package/src/components/agreement/agreement.ts +185 -185
  274. package/src/components/agreement-history/agreement-history.repository.ts +54 -54
  275. package/src/components/agreement-history/agreement-history.ts +57 -57
  276. package/src/components/agreement-signature/agreement-signature.repository.ts +55 -55
  277. package/src/components/agreement-signature/agreement-signature.ts +143 -143
  278. package/src/components/booking/booking.repository.ts +51 -51
  279. package/src/components/booking/booking.ts +492 -492
  280. package/src/components/hirer-change-request-new-hirer/hirer-change-request-new-hirer.repository.ts +64 -64
  281. package/src/components/hirer-change-request-new-hirer/hirer-change-request-new-hirer.ts +153 -153
  282. package/src/components/hirer-change-request-remove-hirer/hirer-change-request-remove-hirer.repository.ts +65 -65
  283. package/src/components/hirer-change-request-remove-hirer/hirer-change-request-remove-hirer.ts +134 -134
  284. package/src/components/hirer-change-request-signature/hirer-change-request-signature.repository.ts +65 -65
  285. package/src/components/hirer-change-request-signature/hirer-change-request-signature.ts +272 -272
  286. package/src/components/joint-hirer/joint-hirer.repository.ts +54 -54
  287. package/src/components/joint-hirer/joint-hirer.ts +189 -189
  288. package/src/components/rental/rental.repository.ts +51 -51
  289. package/src/components/rental/rental.ts +1401 -1167
  290. package/src/components/rental-hirer-change-request/rental-hirer-change-request.repository.ts +64 -64
  291. package/src/components/rental-hirer-change-request/rental-hirer-change-request.ts +917 -917
  292. package/src/components/rental-price/rental-price.repository.ts +54 -54
  293. package/src/components/rental-price/rental-price.ts +100 -100
  294. package/src/database.ts +39 -39
  295. package/src/enum/account-type.enum.ts +4 -4
  296. package/src/enum/agreement-signature-status.enum.ts +4 -4
  297. package/src/enum/agreement-signature-verification-method.enum.ts +4 -0
  298. package/src/enum/booking.enum.ts +5 -5
  299. package/src/enum/hirer-type.enum.ts +4 -4
  300. package/src/enum/index.ts +23 -21
  301. package/src/enum/rental-hirer-change-request-hirer-role.ts +4 -4
  302. package/src/enum/rental-hirer-change-request-status.ts +7 -7
  303. package/src/enum/rental-hirer-change-request-type.ts +4 -4
  304. package/src/enum/rental-status.enum.ts +39 -39
  305. package/src/index.ts +54 -52
  306. package/src/interfaces/agreemeent-signature-attr.interface.ts +15 -15
  307. package/src/interfaces/agreement-attr.interface.ts +7 -7
  308. package/src/interfaces/agreement-history-attr.interface.ts +7 -7
  309. package/src/interfaces/booking-attr.interface.ts +19 -19
  310. package/src/interfaces/booking-find-all-search-attr.interface.ts +12 -12
  311. package/src/interfaces/hirer-change-request-new-hirer-attr.interface.ts +15 -15
  312. package/src/interfaces/hirer-change-request-remove-hirer-attr.interface.ts +5 -5
  313. package/src/interfaces/hirer-change-request-signature-attr.interface.ts +15 -15
  314. package/src/interfaces/index.ts +29 -29
  315. package/src/interfaces/joint-hirer-attr.interface.ts +11 -11
  316. package/src/interfaces/rental-attr.interface.ts +25 -25
  317. package/src/interfaces/rental-find-all-search-attr.interface.ts +11 -11
  318. package/src/interfaces/rental-hirer-change-request.attr.interface.ts +17 -17
  319. package/src/interfaces/rental-hirer-change-request.update.interface.ts +4 -4
  320. package/src/interfaces/rental-price-attr.interface.ts +7 -7
  321. package/src/interfaces/response-hirer-signature-attr.interface.ts +15 -15
  322. package/src/models/agreement-history.entity.ts +51 -51
  323. package/src/models/agreement-signature.entity.ts +105 -86
  324. package/src/models/agreement.entity.ts +47 -47
  325. package/src/models/booking.entity.ts +105 -105
  326. package/src/models/hirer-change-request-new-hirer.entity.ts +102 -102
  327. package/src/models/hirer-change-request-remove-hirer.entity.ts +47 -47
  328. package/src/models/hirer-change-request-signature.entity.ts +86 -86
  329. package/src/models/index.ts +25 -25
  330. package/src/models/joint-hirer.entity.ts +70 -70
  331. package/src/models/rental-price.entity.ts +38 -38
  332. package/src/models/rental.entity.ts +133 -133
  333. package/tsconfig.build.json +11 -6
  334. package/tsconfig.json +22 -24
  335. package/dist/src/components/agreement-signature/hirer-signature.d.ts +0 -27
  336. package/dist/src/components/agreement-signature/hirer-signature.js +0 -112
  337. package/dist/src/components/agreement-signature/hirer-signature.js.map +0 -1
  338. package/dist/src/components/agreement-signature/hirer-signature.repository.d.ts +0 -8
  339. package/dist/src/components/agreement-signature/hirer-signature.repository.js +0 -67
  340. package/dist/src/components/agreement-signature/hirer-signature.repository.js.map +0 -1
  341. package/dist/src/components/hirer-signature/hirer-signature.d.ts +0 -27
  342. package/dist/src/components/hirer-signature/hirer-signature.js +0 -112
  343. package/dist/src/components/hirer-signature/hirer-signature.js.map +0 -1
  344. package/dist/src/components/hirer-signature/hirer-signature.repository.d.ts +0 -8
  345. package/dist/src/components/hirer-signature/hirer-signature.repository.js +0 -67
  346. package/dist/src/components/hirer-signature/hirer-signature.repository.js.map +0 -1
  347. package/dist/src/enum/hirer-signature-status.enum.d.ts +0 -4
  348. package/dist/src/enum/hirer-signature-status.enum.js +0 -9
  349. package/dist/src/enum/hirer-signature-status.enum.js.map +0 -1
  350. package/dist/src/interfaces/hirer-signature-attr.interface.d.ts +0 -14
  351. package/dist/src/interfaces/hirer-signature-attr.interface.js.map +0 -1
  352. package/dist/src/models/hirer-signature.entity.d.ts +0 -16
  353. package/dist/src/models/hirer-signature.entity.js.map +0 -1
@@ -1,1167 +1,1401 @@
1
- import { IRentalAttr } from '../../interfaces/rental-attr.interface';
2
- import { RentalStatusEnum } from '../../enum/rental-status.enum';
3
- import { RentalRepository } from './rental.repository';
4
- import { ClassError, ObjectBase } from '@tomei/general';
5
- import { ApplicationConfig } from '@tomei/config';
6
- import { LoginUser } from '@tomei/sso';
7
- import { RentalPrice } from '../rental-price/rental-price';
8
- import { Op, QueryTypes } from 'sequelize';
9
- import { ActionEnum, Activity } from '@tomei/activity-history';
10
- import { IRentalFindAllSearchAttr } from '../../interfaces/rental-find-all-search-attr.interface';
11
- import { RentalAccountTypeEnum } from '../../enum/account-type.enum';
12
- import { JointHirer } from '../joint-hirer/joint-hirer';
13
- import { JointHirerModel } from '../../models/joint-hirer.entity';
14
- import { AgreementRepository } from '../agreement/agreement.repository';
15
- import * as rentalDb from '../../database';
16
- import { RentalModel } from '../../models/rental.entity';
17
- import { JointHirerRepository } from '../joint-hirer/joint-hirer.repository';
18
- import { AgreementModel } from '../../models';
19
- import { Agreement } from '../agreement/agreement';
20
- import { AggrementStatusEnum } from '../../enum/aggrement-status.enum';
21
- import { AgreementSignatureRepository } from '../agreement-signature/agreement-signature.repository';
22
- import { AgreementSignatureStatusEnum } from '../../enum/agreement-signature-status.enum';
23
- import { HirerTypeEnum } from '../../enum/hirer-type.enum';
24
- import { AgreementHistoryRepository } from '../agreement-history/agreement-history.repository';
25
-
26
- export class Rental extends ObjectBase {
27
- ObjectId: string;
28
- ObjectName: string;
29
- ObjectType = 'Rental';
30
- TableName: string;
31
- CustomerId: string;
32
- CustomerType: string;
33
- ItemId: string;
34
- ItemType: string;
35
- PriceId: string;
36
- StartDateTime: Date;
37
- EndDateTime: Date;
38
- CancelRemarks: string;
39
- TerminateRemarks: string;
40
- AgreementNo: string;
41
- AccountType: RentalAccountTypeEnum;
42
- JointHirers: JointHirer[] = [];
43
- protected _Status: RentalStatusEnum | string;
44
- protected _EscheatmentYN: string = 'N';
45
- protected _CreatedById: string;
46
- protected _CreatedAt: Date;
47
- protected _UpdatedById: string;
48
- protected _UpdatedAt: Date;
49
- protected static _Repo = new RentalRepository();
50
- protected static _AgreementRepo = new AgreementRepository();
51
- protected static _JointHirerRepo = new JointHirerRepository();
52
- protected static _AgreementSignatureRepo = new AgreementSignatureRepository();
53
- protected static _AgreementHistoryRepo = new AgreementHistoryRepository();
54
-
55
- get RentalId(): string {
56
- return this.ObjectId;
57
- }
58
-
59
- set RentalId(value: string) {
60
- this.ObjectId = value;
61
- }
62
-
63
- get Status(): RentalStatusEnum | string {
64
- return this._Status;
65
- }
66
-
67
- get EscheatmentYN(): string {
68
- return this._EscheatmentYN;
69
- }
70
-
71
- get CreatedById(): string {
72
- return this._CreatedById;
73
- }
74
-
75
- get CreatedAt(): Date {
76
- return this._CreatedAt;
77
- }
78
-
79
- get UpdatedById(): string {
80
- return this._UpdatedById;
81
- }
82
-
83
- get UpdatedAt(): Date {
84
- return this._UpdatedAt;
85
- }
86
-
87
- private setTerminated() {
88
- this._Status = RentalStatusEnum.TERMINATED;
89
- }
90
-
91
- protected constructor(rentalAttr?: IRentalAttr) {
92
- super();
93
- if (rentalAttr) {
94
- this.RentalId = rentalAttr.RentalId;
95
- this.CustomerId = rentalAttr.CustomerId;
96
- this.CustomerType = rentalAttr.CustomerType;
97
- this.ItemId = rentalAttr.ItemId;
98
- this.ItemType = rentalAttr.ItemType;
99
- this.PriceId = rentalAttr.PriceId;
100
- this.StartDateTime = rentalAttr.StartDateTime;
101
- this.EndDateTime = rentalAttr.EndDateTime;
102
- this.CancelRemarks = rentalAttr.CancelRemarks;
103
- this.TerminateRemarks = rentalAttr.TerminateRemarks;
104
- this.AgreementNo = rentalAttr.AgreementNo;
105
- this.AccountType = rentalAttr.AccountType;
106
- this._Status = rentalAttr.Status;
107
- this._EscheatmentYN = rentalAttr.EscheatmentYN;
108
- this._CreatedById = rentalAttr.CreatedById;
109
- this._CreatedAt = rentalAttr.CreatedAt;
110
- this._UpdatedById = rentalAttr.UpdatedById;
111
- this._UpdatedAt = rentalAttr.UpdatedAt;
112
- }
113
- }
114
-
115
- public static async init(dbTransaction?: any, rentalId?: string) {
116
- try {
117
- if (rentalId) {
118
- const rental = await Rental._Repo.findByPk(rentalId, dbTransaction);
119
- if (rental) {
120
- return new Rental(rental);
121
- } else {
122
- throw new ClassError('Rental', 'RentalErrMsg00', 'Rental Not Found');
123
- }
124
- }
125
- return new Rental();
126
- } catch (error) {
127
- throw new ClassError(
128
- 'Rental',
129
- 'RentalErrMsg00',
130
- 'Failed To Initialize Price',
131
- );
132
- }
133
- }
134
-
135
- /**
136
- * Create a new Rental record.
137
- * @param {RentalPrice} rentalPrice - The rental pricing information.
138
- * @param {LoginUser} loginUser - The user initiating the creation.
139
- * @param {any} [dbTransaction] - Optional database transaction for atomic operations.
140
- * @throws {ClassError} Throws an error if:
141
- * 1. loginUser does not have 'Rental - Create' privilege.
142
- * 2. Rental item is not available at the current date.
143
- * @returns {Promise<any>} A Promise resolving to the created rental record.
144
- */
145
- public async create(
146
- rentalPrice: RentalPrice,
147
- loginUser: LoginUser,
148
- jointHirers?: JointHirer[],
149
- dbTransaction?: any,
150
- ): Promise<any> {
151
- try {
152
- /*Part 1: Check Privilege*/
153
- const systemCode =
154
- ApplicationConfig.getComponentConfigValue('system-code');
155
- const isPrivileged = await loginUser.checkPrivileges(
156
- systemCode,
157
- 'Rental - Create',
158
- );
159
-
160
- if (!isPrivileged) {
161
- throw new ClassError(
162
- 'Rental',
163
- 'RentalErrMsg01',
164
- "You do not have 'Rental - Create' privilege.",
165
- );
166
- }
167
-
168
- /*Part 2: Make Sure Rental Item Available*/
169
- const isItemAvailable = await Rental.isItemAvailable(
170
- this.ItemId,
171
- this.ItemType,
172
- this.StartDateTime,
173
- this.EndDateTime,
174
- dbTransaction,
175
- );
176
-
177
- if (!isItemAvailable) {
178
- throw new ClassError(
179
- 'Rental',
180
- 'RentalErrMsg02',
181
- 'Rental Item is not available at current date.',
182
- );
183
- }
184
-
185
- // Part 3: Create Rental Agreement Record
186
- // Call Rental._AgreementRepo create method by passing:
187
- // AgreementNo: this.AgreementNo
188
- // Status: "Not Generated"
189
- // dbTransaction
190
- await Rental._AgreementRepo.create(
191
- {
192
- AgreementNo: this.AgreementNo,
193
- Status: 'Not Generated',
194
- },
195
- {
196
- transaction: dbTransaction,
197
- },
198
- );
199
-
200
- //Create a record into rental_AgreementSignature table
201
- //Create the main customer's signature record
202
- await Rental._AgreementSignatureRepo.create(
203
- {
204
- SignatureId: this.createId(),
205
- AgreementNo: this.AgreementNo,
206
- Party: HirerTypeEnum.PRIMARY,
207
- PartyId: this.CustomerId,
208
- PartyType: 'Customer',
209
- SignatureStatus: AgreementSignatureStatusEnum.PENDING,
210
- SignedAt: new Date(),
211
- CreatedById: loginUser.ObjectId,
212
- CreatedAt: new Date(),
213
- UpdatedById: loginUser.ObjectId,
214
- UpdatedAt: new Date(),
215
- },
216
- { transaction: dbTransaction },
217
- );
218
-
219
- // Create signatures record for joint hirers if any
220
- if (jointHirers && jointHirers.length > 0) {
221
- for (const jointHirer of jointHirers) {
222
- await Rental._AgreementSignatureRepo.create(
223
- {
224
- SignatureId: this.createId(),
225
- AgreementNo: this.AgreementNo,
226
- Party: HirerTypeEnum.JOINT,
227
- PartyId: jointHirer.CustomerId,
228
- PartyType: 'Customer',
229
- SignatureStatus: AgreementSignatureStatusEnum.PENDING,
230
- SignedAt: new Date(),
231
- CreatedById: loginUser.ObjectId,
232
- CreatedAt: new Date(),
233
- UpdatedById: loginUser.ObjectId,
234
- UpdatedAt: new Date(),
235
- },
236
- { transaction: dbTransaction },
237
- );
238
- }
239
- }
240
-
241
- /*Part 4: Insert Rental & The Agreed Rental Price*/
242
- if (!rentalPrice.PriceId) {
243
- const rentalPriceData = await rentalPrice.create(
244
- loginUser,
245
- dbTransaction,
246
- );
247
- this.PriceId = rentalPriceData.PriceId;
248
- } else {
249
- this.PriceId = rentalPrice.PriceId;
250
- }
251
- this.RentalId = this.createId();
252
- // if (!this.Status) {
253
- this._Status = RentalStatusEnum.PENDING_SIGNING;
254
- // }
255
- this._CreatedById = loginUser.ObjectId;
256
- this._UpdatedById = loginUser.ObjectId;
257
- this._CreatedAt = new Date();
258
- this._UpdatedAt = new Date();
259
-
260
- const data = {
261
- RentalId: this.RentalId,
262
- CustomerId: this.CustomerId,
263
- CustomerType: this.CustomerType,
264
- ItemId: this.ItemId,
265
- ItemType: this.ItemType,
266
- PriceId: this.PriceId,
267
- StartDateTime: this.StartDateTime,
268
- EndDateTime: this.EndDateTime,
269
- CancelRemarks: this.CancelRemarks,
270
- TerminateRemarks: this.TerminateRemarks,
271
- AgreementNo: this.AgreementNo,
272
- AccountType: this.AccountType,
273
- Status: this.Status,
274
- EscheatmentYN: this.EscheatmentYN,
275
- CreatedById: this.CreatedById,
276
- CreatedAt: this.CreatedAt,
277
- UpdatedById: this.UpdatedById,
278
- UpdatedAt: this.UpdatedAt,
279
- };
280
-
281
- await Rental._Repo.create(data, {
282
- transaction: dbTransaction,
283
- });
284
-
285
- //For every data inside Param.jointHirers, update the rentalId and call jointHirer.create
286
- if (jointHirers) {
287
- for (let i = 0; i < jointHirers.length; i++) {
288
- jointHirers[i].RentalId = this.RentalId;
289
- await jointHirers[i].create(loginUser, dbTransaction);
290
- this.JointHirers.push(jointHirers[i]);
291
- }
292
- }
293
-
294
- /*Part 5: Record Create Rental Activity*/
295
- const activity = new Activity();
296
- activity.ActivityId = activity.createId();
297
- activity.Action = ActionEnum.CREATE;
298
- activity.Description = 'Add Rental';
299
- activity.EntityType = 'Rental';
300
- activity.EntityId = this.RentalId;
301
- activity.EntityValueBefore = JSON.stringify({});
302
- activity.EntityValueAfter = JSON.stringify(data);
303
- await activity.create(loginUser.ObjectId, dbTransaction);
304
-
305
- /*Part 6: Return Result*/
306
- return this;
307
- } catch (error) {
308
- throw error;
309
- }
310
- }
311
-
312
- public static async isItemAvailable(
313
- itemId: string,
314
- itemType: string,
315
- startDateTime: Date,
316
- endDateTime: Date,
317
- dbTransaction?: any,
318
- ) {
319
- try {
320
- const rental = await Rental._Repo.findOne({
321
- where: {
322
- ItemId: itemId,
323
- ItemType: itemType,
324
- StartDateTime: {
325
- [Op.lte]: endDateTime,
326
- },
327
- EndDateTime: {
328
- [Op.gte]: startDateTime,
329
- },
330
- },
331
- transaction: dbTransaction,
332
- });
333
-
334
- if (!rental) {
335
- // No rental found → item is available
336
- return true;
337
- }
338
-
339
- if (
340
- rental.Status === RentalStatusEnum.TERMINATED ||
341
- rental.Status === RentalStatusEnum.CANCELLED
342
- ) {
343
- // Rental found but status is Terminated or Cancelled → item is available
344
- return true;
345
- }
346
-
347
- // Rental exists and is active → item is not available
348
- return false;
349
- } catch (error) {
350
- throw error;
351
- }
352
- }
353
-
354
- public static async findAll(
355
- loginUser: LoginUser,
356
- dbTransaction: any,
357
- page?: number,
358
- row?: number,
359
- search?: IRentalFindAllSearchAttr,
360
- ) {
361
- try {
362
- const systemCode =
363
- await ApplicationConfig.getComponentConfigValue('system-code');
364
-
365
- const isPrivileged = await loginUser.checkPrivileges(
366
- systemCode,
367
- 'Rental - View',
368
- );
369
-
370
- if (!isPrivileged) {
371
- throw new ClassError(
372
- 'Rental',
373
- 'RentalErrMsg01',
374
- "You do not have 'Rental - View' privilege.",
375
- );
376
- }
377
-
378
- const queryObj: any = {};
379
-
380
- let options: any = {
381
- transaction: dbTransaction,
382
- order: [['CreatedAt', 'DESC']],
383
- };
384
-
385
- if (page && row) {
386
- options = {
387
- ...options,
388
- limit: row,
389
- offset: row * (page - 1),
390
- };
391
- }
392
-
393
- if (search) {
394
- Object.entries(search).forEach(([key, value]) => {
395
- if (key === 'StartDateTime') {
396
- queryObj[key] = {
397
- [Op.gte]: value,
398
- };
399
- } else if (key === 'EndDateTime') {
400
- queryObj[key] = {
401
- [Op.lte]: value,
402
- };
403
- } else if (key === 'CustomerId') {
404
- queryObj[key] = {
405
- [Op.substring]: value,
406
- };
407
-
408
- options.include = [
409
- {
410
- model: JointHirerModel,
411
- required: false,
412
- where: {
413
- CustomerId: {
414
- [Op.substring]: value,
415
- },
416
- },
417
- },
418
- ];
419
- } else {
420
- queryObj[key] = {
421
- [Op.substring]: value,
422
- };
423
- }
424
- });
425
- if (options?.include?.length > 1) {
426
- options.include.push({
427
- model: AgreementModel,
428
- required: false,
429
- });
430
- } else {
431
- options.include = [
432
- {
433
- model: AgreementModel,
434
- required: false,
435
- },
436
- ];
437
- }
438
-
439
- options = {
440
- ...options,
441
- where: queryObj,
442
- };
443
- }
444
-
445
- return await Rental._Repo.findAndCountAll(options);
446
- } catch (err) {
447
- throw err;
448
- }
449
- }
450
-
451
- public static async checkActiveByItemId(
452
- loginUser: LoginUser,
453
- itemId: string,
454
- itemType: string,
455
- dbTransaction?: any,
456
- ) {
457
- try {
458
- const systemCode =
459
- await ApplicationConfig.getComponentConfigValue('system-code');
460
-
461
- const isPrivileged = await loginUser.checkPrivileges(
462
- systemCode,
463
- 'Rental - View',
464
- );
465
-
466
- if (!isPrivileged) {
467
- throw new ClassError(
468
- 'Rental',
469
- 'RentalErrMsg01',
470
- "You do not have 'Rental - View' privilege.",
471
- );
472
- }
473
-
474
- const queryObj: any = {
475
- ItemId: itemId,
476
- ItemType: itemType,
477
- Status: RentalStatusEnum.ACTIVE,
478
- };
479
-
480
- const options: any = {
481
- transaction: dbTransaction,
482
- where: queryObj,
483
- };
484
-
485
- const rental = await Rental._Repo.findOne(options);
486
-
487
- if (rental) {
488
- return true;
489
- } else {
490
- return false;
491
- }
492
- } catch (err) {
493
- throw err;
494
- }
495
- }
496
-
497
- /**
498
- * Sets the StartDateTime property of the Rental class as custom setter.
499
- * @param {Date} startDateTime - The start date and time of the rental.
500
- * @throws {ClassError} Throws an error if:
501
- * 1. startDateTime is a past date.
502
- * 2. startDateTime is more than the EndDateTime.
503
- * @returns {void}
504
- */
505
- setStartDateTime(startDateTime: Date): void {
506
- const startDateTimeObject = new Date(startDateTime);
507
- startDateTimeObject.setHours(0, 0, 0, 0);
508
-
509
- /*Part 1: Make Sure Future Date Time*/
510
- if (startDateTimeObject < new Date(new Date().setHours(0, 0, 0, 0))) {
511
- throw new ClassError(
512
- 'Rental',
513
- 'RentalErrMsg02',
514
- 'StartDateTime cannot be a past datetime.',
515
- );
516
- }
517
-
518
- /*Part 2: Make Sure Less Than End Date Time*/
519
- if (this.EndDateTime && startDateTimeObject > this.EndDateTime) {
520
- throw new ClassError(
521
- 'Rental',
522
- 'RentalErrMsg03',
523
- 'StartDateTime cannot be more than EndDateTime.',
524
- );
525
- }
526
-
527
- /*Part 3: Set Status Whether Reserved or Active*/
528
- if (startDateTimeObject > new Date(new Date().setHours(0, 0, 0, 0))) {
529
- this._Status = RentalStatusEnum.RESERVED;
530
- } else {
531
- this._Status = RentalStatusEnum.ACTIVE;
532
- }
533
- }
534
-
535
- public async periodEndProcess(
536
- loginUser: LoginUser,
537
- dbTransaction: any,
538
- stockInventory: any,
539
- ) {
540
- try {
541
- // Privilege Checking
542
- const systemCode =
543
- await ApplicationConfig.getComponentConfigValue('system-code');
544
-
545
- const isPrivileged = await loginUser.checkPrivileges(
546
- systemCode,
547
- 'Rental – PeriodEndProcess',
548
- );
549
-
550
- if (!isPrivileged) {
551
- throw new ClassError(
552
- 'Rental',
553
- 'RentalErrMsg04',
554
- "You do not have 'Rental - PeriodEndProcess' privilege.",
555
- );
556
- }
557
-
558
- // Validate Existing Rental
559
- if (this.AgreementNo === undefined || this.AgreementNo === null) {
560
- throw new ClassError(
561
- 'Rental',
562
- 'RentalErrMsg05',
563
- 'Rental must be existing rental.',
564
- );
565
- }
566
-
567
- // Validate Rental End Period
568
- if (this.EndDateTime === new Date(new Date().setHours(0, 0, 0, 0))) {
569
- throw new ClassError(
570
- 'Rental',
571
- 'RentalErrMsg06',
572
- 'Rental period is not ending today.',
573
- );
574
- }
575
-
576
- // Mark Rental Item as Available
577
- await stockInventory.setAvailable(loginUser, dbTransaction);
578
-
579
- // Capture Record Info Before Changes
580
- const entityValueBefore = {
581
- RentalId: this.RentalId,
582
- CustomerId: this.CustomerId,
583
- CustomerType: this.CustomerType,
584
- ItemId: this.ItemId,
585
- ItemType: this.ItemType,
586
- PriceId: this.PriceId,
587
- StartDateTime: this.StartDateTime,
588
- EndDateTime: this.EndDateTime,
589
- CancelRemarks: this.CancelRemarks,
590
- TerminateRemarks: this.TerminateRemarks,
591
- AgreementNo: this.AgreementNo,
592
- AccountType: this.AccountType,
593
- Status: this.Status,
594
- EscheatmentYN: this.EscheatmentYN,
595
- CreatedById: this.CreatedById,
596
- CreatedAt: this.CreatedAt,
597
- UpdatedById: this.UpdatedById,
598
- UpdatedAt: this.UpdatedAt,
599
- };
600
-
601
- // Mark Rental as Terminated and Capture Updater Info
602
- this.setTerminated();
603
- this._UpdatedById = loginUser.ObjectId;
604
- this._UpdatedAt = new Date();
605
-
606
- // Capture Record Info after Changes
607
- const entityValueAfter = {
608
- RentalId: this.RentalId,
609
- CustomerId: this.CustomerId,
610
- CustomerType: this.CustomerType,
611
- ItemId: this.ItemId,
612
- ItemType: this.ItemType,
613
- PriceId: this.PriceId,
614
- StartDateTime: this.StartDateTime,
615
- EndDateTime: this.EndDateTime,
616
- CancelRemarks: this.CancelRemarks,
617
- TerminateRemarks: this.TerminateRemarks,
618
- AgreementNo: this.AgreementNo,
619
- AccountType: this.AccountType,
620
- Status: this.Status,
621
- EscheatmentYN: this.EscheatmentYN,
622
- CreatedById: this.CreatedById,
623
- CreatedAt: this.CreatedAt,
624
- UpdatedById: this.UpdatedById,
625
- UpdatedAt: this.UpdatedAt,
626
- };
627
-
628
- // Record the Update Activity
629
- const activity = new Activity();
630
- activity.ActivityId = activity.createId();
631
- activity.Action = ActionEnum.UPDATE;
632
- activity.Description = 'Set Rental as Terminated';
633
- activity.EntityType = 'Rental';
634
- activity.EntityId = this.RentalId;
635
- activity.EntityValueBefore = JSON.stringify(entityValueBefore);
636
- activity.EntityValueAfter = JSON.stringify(entityValueAfter);
637
- await activity.create(loginUser.ObjectId, dbTransaction);
638
-
639
- return this;
640
- } catch (err) {
641
- throw err;
642
- }
643
- }
644
-
645
- async getCustomerActiveRentals(
646
- loginUser: LoginUser,
647
- dbTransaction: any,
648
- CustomerId: string,
649
- ): Promise<IRentalAttr[]> {
650
- try {
651
- // Part 1: Privilege Checking
652
- // Call loginUser.checkPrivileges() by passing:
653
- // SystemCode: <get_from_app_config>
654
- // PrivilegeCode: "RENTAL_VIEW"
655
- const systemCode =
656
- ApplicationConfig.getComponentConfigValue('system-code');
657
- const isPrivileged = loginUser.checkPrivileges(systemCode, 'RENTAL_VIEW');
658
-
659
- if (!isPrivileged) {
660
- throw new ClassError(
661
- 'Rental',
662
- 'RentalErrMsg01',
663
- "You do not have 'Rental - View' privilege.",
664
- );
665
- }
666
-
667
- // Part 2: Retrieve Rentals and Returns
668
- // Call Rental._Repo findAll method by passing:
669
- // where:
670
- // Status: "Active"
671
- // [Op.OR]:
672
- // CustomerId: Params.CustomerId
673
- // '$JointHirers.CustomerId$': Params.CustomerId
674
- // include:
675
- // model: JointHirerModel
676
- // attributes: []
677
- const query = `
678
- SELECT
679
- r.*
680
- FROM
681
- rental_Rental r
682
- LEFT JOIN
683
- rental_JointHirer jh ON r.RentalId = jh.RentalId
684
- WHERE
685
- r.Status = 'Active'
686
- AND (
687
- r.CustomerId = '${CustomerId}'
688
- OR jh.CustomerId = '${CustomerId}'
689
- )
690
- GROUP BY
691
- r.RentalId
692
- `;
693
- const db = rentalDb.getConnection();
694
- const result = await db.query(query, {
695
- type: QueryTypes.SELECT,
696
- transaction: dbTransaction,
697
- model: RentalModel,
698
- mapToModel: true,
699
- });
700
-
701
- // Format the returned records
702
- const records: IRentalAttr[] = result.map((record: RentalModel) => {
703
- return {
704
- RentalId: record.RentalId,
705
- CustomerId: record.CustomerId,
706
- CustomerType: record.CustomerType,
707
- ItemId: record.ItemId,
708
- ItemType: record.ItemType,
709
- PriceId: record.PriceId,
710
- StartDateTime: record.StartDateTime,
711
- EndDateTime: record.EndDateTime,
712
- CancelRemarks: record.CancelRemarks,
713
- TerminateRemarks: record.TerminateRemarks,
714
- AgreementNo: record.AgreementNo,
715
- AccountType: record.AccountType,
716
- Status: record.Status,
717
- EscheatmentYN: record.EscheatmentYN,
718
- CreatedById: record.CreatedById,
719
- CreatedAt: record.CreatedAt,
720
- UpdatedById: record.UpdatedById,
721
- UpdatedAt: record.UpdatedAt,
722
- };
723
- });
724
- // Return the returned records.
725
- return records;
726
- } catch (error) {
727
- throw error;
728
- }
729
- }
730
-
731
- async getJointHirers(dbTransaction: any) {
732
- try {
733
- if (!this.RentalId) {
734
- throw new ClassError('Rental', 'RentalErrMsg01', 'RentalId is missing');
735
- }
736
- if (this.AccountType !== RentalAccountTypeEnum.JOINT) {
737
- throw new ClassError(
738
- 'Rental',
739
- 'RentalErrMsg07',
740
- 'This rental does not have joint hirers.',
741
- );
742
- }
743
-
744
- const jointHirers = await Rental._JointHirerRepo.findAll({
745
- where: {
746
- RentalId: this.RentalId,
747
- },
748
- transaction: dbTransaction,
749
- });
750
- // Map the jointHirers to JointHirer instances
751
- const jointHirerInstances = Promise.all(
752
- jointHirers.map(async (hirer: JointHirerModel) => {
753
- return await JointHirer.init(hirer.HirerId, dbTransaction);
754
- }),
755
- );
756
- return jointHirerInstances;
757
- } catch (error) {
758
- console.error('Error in getJointHirers:', error);
759
- throw error;
760
- }
761
- }
762
-
763
- async getCustomerIds(loginUser: LoginUser, dbTransaction: any) {
764
- try {
765
- // Part 1: Privilege Checking
766
- // Call loginUser.checkPrivileges() by passing:
767
- // SystemCode: <get_from_app_config>
768
- // PrivilegeCode: "RENTAL_VIEW"
769
- const systemCode =
770
- ApplicationConfig.getComponentConfigValue('system-code');
771
- const isPrivileged = loginUser.checkPrivileges(systemCode, 'RENTAL_VIEW');
772
-
773
- if (!isPrivileged) {
774
- throw new ClassError(
775
- 'Rental',
776
- 'RentalErrMsg01',
777
- "You do not have 'Rental - View' privilege.",
778
- );
779
- }
780
-
781
- // Part 2: Validation
782
- // Make sure this.RentalId exists, if not throw new ClassError by passing
783
- if (!this.RentalId) {
784
- throw new ClassError('Rental', 'RentalErrMsg01', 'RentalId is missing');
785
- }
786
-
787
- //Part 3: Retrieve Listing and Returns
788
- // 3.1 Call Rental._JointHirerRepo findAll method by passing:
789
- // where:
790
- // RentalId: this.RentalId
791
- // dbTransaction
792
- const options: any = {
793
- where: {
794
- RentalId: this.RentalId,
795
- },
796
- transaction: dbTransaction,
797
- };
798
-
799
- const joinHirers = await Rental._JointHirerRepo.findAll(options);
800
-
801
- // 3.2 Create a new array variable and set its value to joint hirer and Rental.CustomerId
802
- // array translated to only CustomerId. Then, append this.CustomerId to the array.
803
- const customerIds: string[] = [this.CustomerId];
804
- for (let i = 0; i < joinHirers.length; i++) {
805
- const jointHirer = joinHirers[i];
806
- customerIds.push(jointHirer.CustomerId);
807
- }
808
-
809
- // 3.3 Return the array.
810
- return customerIds;
811
- } catch (error) {
812
- throw error;
813
- }
814
- }
815
-
816
- async signAgreement(
817
- loginUser: LoginUser,
818
- party: string,
819
- PartyId: string,
820
- PartyType: string,
821
- dbTransaction: any,
822
- statusAfterSign?: RentalStatusEnum | string,
823
- ) {
824
- try {
825
- // Part 1: Privilege Checking
826
- // Call loginUser.checkPrivileges() by passing:
827
- // SystemCode: <get_from_app_config>
828
- // PrivilegeCode: "RENTAL_SIGN"
829
- const systemCode =
830
- ApplicationConfig.getComponentConfigValue('system-code');
831
- const isPrivileged = loginUser.checkPrivileges(systemCode, 'RENTAL_SIGN');
832
-
833
- if (!isPrivileged) {
834
- throw new ClassError(
835
- 'Rental',
836
- 'RentalErrMsg01',
837
- "You do not have 'RENTAL_SIGN' privilege.",
838
- );
839
- }
840
-
841
- // Part 2: Validation
842
- // Make sure this.Status is "Pending Signing" and agreementStatus is "Generated", if not throw new ClassError
843
- const agreement = await Agreement.init(this.AgreementNo, dbTransaction);
844
- if (
845
- this.Status !== RentalStatusEnum.PENDING_SIGNING &&
846
- agreement.Status !== AggrementStatusEnum.GENERATED
847
- ) {
848
- throw new ClassError(
849
- 'Rental',
850
- 'RentalErrMsg01',
851
- 'Rental is not ready to be signed yet.',
852
- );
853
- }
854
-
855
- //Make sure CustomerId inside the listing and SignatureStatus is "Pending"
856
- const signatureList = await Agreement.getSignatureList(
857
- loginUser,
858
- this.AgreementNo,
859
- dbTransaction,
860
- );
861
- const customerSignature = signatureList.find(
862
- (sig) =>
863
- sig.PartyId === PartyId &&
864
- sig.PartyType === PartyType &&
865
- sig.Party === party &&
866
- sig.SignatureStatus === AgreementSignatureStatusEnum.PENDING,
867
- );
868
-
869
- if (!customerSignature) {
870
- throw new ClassError(
871
- 'Rental',
872
- 'RentalErrMsg01',
873
- 'Signature is not pending.',
874
- );
875
- }
876
-
877
- //Update rental_AgreementSignature
878
- const signaturePayload = {
879
- SignatureStatus: AgreementSignatureStatusEnum.SIGNED,
880
- SignedAt: new Date(),
881
- UpdatedById: loginUser.ObjectId,
882
- UpdatedAt: new Date(),
883
- };
884
-
885
- await Rental._AgreementSignatureRepo.update(signaturePayload, {
886
- where: {
887
- AgreementNo: this.AgreementNo,
888
- Party: party,
889
- PartyId: PartyId,
890
- PartyType: PartyType,
891
- },
892
- transaction: dbTransaction,
893
- });
894
-
895
- const signatureActivity = new Activity();
896
- signatureActivity.ActivityId = signatureActivity.createId();
897
- signatureActivity.Action = ActionEnum.UPDATE;
898
- signatureActivity.Description = 'Update hirer signature';
899
- signatureActivity.EntityType = 'AgreementSignature';
900
- signatureActivity.EntityId = this.AgreementNo;
901
- signatureActivity.EntityValueBefore = JSON.stringify(customerSignature);
902
- signatureActivity.EntityValueAfter = JSON.stringify(signaturePayload);
903
- await signatureActivity.create(loginUser.ObjectId, dbTransaction);
904
-
905
- const updatedSignatureList = await Agreement.getSignatureList(
906
- loginUser,
907
- this.AgreementNo,
908
- dbTransaction,
909
- );
910
-
911
- const pendingSignatures = updatedSignatureList.filter(
912
- (sig) => sig.SignatureStatus === 'Pending',
913
- );
914
- if (pendingSignatures.length > 0) {
915
- return;
916
- }
917
-
918
- //Part 3: Update Agreement Status
919
- // 3.1 Set EntityValueBefore to current agreement instance.
920
- const entityValueAgreementBefore = {
921
- AgreementNo: agreement.AgreementNo,
922
- Status: agreement.Status,
923
- DateSigned: agreement.DateSigned,
924
- };
925
-
926
- // 3.2 Set below agreement attributes:
927
- // DateSigned: current date & time
928
- // Status: "Signed"
929
- const payload = {
930
- DateSigned: new Date(),
931
- Status: AggrementStatusEnum.SIGNED,
932
- };
933
-
934
- // 3.3 Call Rental._AgreementRepo update()
935
- await Rental._AgreementRepo.update(payload, {
936
- where: {
937
- AgreementNo: this.AgreementNo,
938
- },
939
- transaction: dbTransaction,
940
- });
941
-
942
- const entityValueAgreementAfter = {
943
- entityValueAgreementBefore,
944
- ...payload,
945
- };
946
-
947
- // Part 4: Record Update Agreement Activity
948
- const activity = new Activity();
949
- activity.ActivityId = activity.createId();
950
- activity.Action = ActionEnum.UPDATE;
951
- activity.Description = 'Update agreement';
952
- activity.EntityType = 'RentalAgreement';
953
- activity.EntityId = this.AgreementNo;
954
- activity.EntityValueBefore = JSON.stringify(entityValueAgreementBefore);
955
- activity.EntityValueAfter = JSON.stringify(entityValueAgreementAfter);
956
- await activity.create(loginUser.ObjectId, dbTransaction);
957
-
958
- // Part 5: Update Rental Status
959
- // 5.1 Set EntityValueBefore to current rental instance.
960
- const entityValueRentalBefore = {
961
- RentalId: this.RentalId,
962
- CustomerId: this.CustomerId,
963
- CustomerType: this.CustomerType,
964
- ItemId: this.ItemId,
965
- ItemType: this.ItemType,
966
- PriceId: this.PriceId,
967
- StartDateTime: this.StartDateTime,
968
- EndDateTime: this.EndDateTime,
969
- CancelRemarks: this.CancelRemarks,
970
- TerminateRemarks: this.TerminateRemarks,
971
- AgreementNo: this.AgreementNo,
972
- AccountType: this.AccountType,
973
- Status: this.Status,
974
- EscheatmentYN: this.EscheatmentYN,
975
- CreatedById: this.CreatedById,
976
- CreatedAt: this.CreatedAt,
977
- UpdatedById: this.UpdatedById,
978
- UpdatedAt: this.UpdatedAt,
979
- };
980
- // 5.2: Set below rental attributes:
981
- // Status: "Pending Key Collection"
982
- // UpdatedById: loginUser.ObjectId
983
- // UpdatedAt: current date & time
984
-
985
- this._Status = statusAfterSign
986
- ? statusAfterSign
987
- : RentalStatusEnum.ACTIVE;
988
-
989
- const payloadRental = {
990
- Status: this._Status,
991
- UpdatedById: loginUser.ObjectId,
992
- UpdatedAt: new Date(),
993
- };
994
-
995
- // 5.3: Call Rental._Repo update() method by passing:
996
- // populate rental instance attributes
997
- // dbTransaction
998
- await Rental._Repo.update(payloadRental, {
999
- where: {
1000
- RentalId: this.RentalId,
1001
- },
1002
- transaction: dbTransaction,
1003
- });
1004
-
1005
- const entityValueRentalAfter = {
1006
- entityValueRentalBefore,
1007
- ...payloadRental,
1008
- };
1009
-
1010
- // Part 6: Record Update Agreement Activity
1011
- const rentalActivity = new Activity();
1012
- rentalActivity.ActivityId = activity.createId();
1013
- rentalActivity.Action = ActionEnum.UPDATE;
1014
- rentalActivity.Description = 'Sign rental agreement';
1015
- rentalActivity.EntityType = 'Rental';
1016
- rentalActivity.EntityId = this.RentalId;
1017
- rentalActivity.EntityValueBefore = JSON.stringify(
1018
- entityValueRentalBefore,
1019
- );
1020
- rentalActivity.EntityValueAfter = JSON.stringify(entityValueRentalAfter);
1021
- await rentalActivity.create(loginUser.ObjectId, dbTransaction);
1022
- } catch (error) {
1023
- throw error;
1024
- }
1025
- }
1026
-
1027
- async generateAgreement(
1028
- loginUser: LoginUser,
1029
- dbTransaction: any,
1030
- MediaId: string,
1031
- ) {
1032
- //This method will generate a new rental agreement.
1033
- try {
1034
- // Part 1: Privilege Checking
1035
- // Call loginUser.checkPrivileges() by passing:
1036
- // SystemCode: "<get_from_app_config>"
1037
- // PrivilegeCode: "RENTAL_AGREEMENT_CREATE"
1038
-
1039
- const systemCode =
1040
- ApplicationConfig.getComponentConfigValue('system-code');
1041
- const isPrivileged = loginUser.checkPrivileges(
1042
- systemCode,
1043
- 'RENTAL_AGREEMENT_CREATE',
1044
- );
1045
-
1046
- if (!isPrivileged) {
1047
- throw new ClassError(
1048
- 'Rental',
1049
- 'RentalErrMsg01',
1050
- "You do not have 'RENTAL_AGREEMENT_CREATE' privilege.",
1051
- );
1052
- }
1053
-
1054
- // Part 2: Validation
1055
- // Instantiate existing RentalAgreement by passing:
1056
- // dbTransaction
1057
- // AgreementNo: this.AgreementNo
1058
- // Make sure Params.MediaId exists, if not throw new ClassError by passing:
1059
- // Classname: "Rental"
1060
- // MessageCode: "RentalErrMsg0X"
1061
- // Message: "MediaId is required."
1062
- const agreement = await Agreement.init(this.AgreementNo, dbTransaction);
1063
- if (!MediaId) {
1064
- throw new ClassError(
1065
- 'Rental',
1066
- 'RentalErrMsg0X',
1067
- 'MediaId is required.',
1068
- );
1069
- }
1070
-
1071
- // Part 3: Update Agreement Record
1072
- // Set EntityValueBefore to the agreement instance.
1073
- // Set below agreement attributes:
1074
- // Status: "Generated"
1075
- // MediaId: Params.MediaId
1076
-
1077
- const EntityValueBefore = agreement;
1078
- agreement.Status = AggrementStatusEnum.GENERATED;
1079
- agreement.MediaId = MediaId;
1080
-
1081
- // Call Rental._AgreementRepo update method by passing:
1082
- // Status: agreement.Status
1083
- // MediaId: agreement.MediaId
1084
- // dbTransaction
1085
-
1086
- await Rental._AgreementRepo.update(
1087
- {
1088
- Status: agreement.Status,
1089
- MediaId: agreement.MediaId,
1090
- },
1091
- {
1092
- where: {
1093
- AgreementNo: this.AgreementNo,
1094
- },
1095
- transaction: dbTransaction,
1096
- },
1097
- );
1098
-
1099
- // Part 4: Record Update Agreement Activity
1100
- // Initialise EntityValueAfter variable and set to agreement instance
1101
- const EntityValueAfter = agreement;
1102
- // Instantiate new activity from Activity class, call createId() method, then set:
1103
- const activity = new Activity();
1104
- // Action: ActionEnum.UPDATE
1105
- // Description: "Generate agreement."
1106
- // EntityType: "RentalAgreement"
1107
- // EntityId: this.AgreementNo
1108
- // EntityValueBefore: EntityValueBefore
1109
- // EntityValueAfter: EntityValueAfter
1110
- activity.ActivityId = activity.createId();
1111
- activity.Action = ActionEnum.UPDATE;
1112
- activity.Description = 'Generate agreement.';
1113
- activity.EntityType = 'RentalAgreement';
1114
- activity.EntityId = this.AgreementNo;
1115
- activity.EntityValueBefore = JSON.stringify(EntityValueBefore);
1116
- activity.EntityValueAfter = JSON.stringify(EntityValueAfter);
1117
-
1118
- // Call new activity create method by passing:
1119
- // dbTransaction
1120
- // userId: loginUser.ObjectId
1121
- await activity.create(loginUser.ObjectId, dbTransaction);
1122
-
1123
- // Part 5: Add Record To Agreement History Table
1124
- // Make sure there is a private static readonly _AgreementHistoryRepo variable.
1125
- // Set newRecord to an object with below key-value:
1126
- // AgreementNo: this.AgreementNo
1127
- // MediaId: params.MediaId
1128
- // ActivityCompleted: "Agreement Generated"
1129
- // CreatedAt: Current Timestamp
1130
- // Use _AgreementHistoryRepo.create() method and pass newRecord and dbTransaction.
1131
- const agreementHistory = await Rental._AgreementHistoryRepo.create(
1132
- {
1133
- AgreementNo: this.AgreementNo,
1134
- MediaId,
1135
- ActivityCompleted: 'Agreement Generated',
1136
- CreatedAt: new Date(),
1137
- },
1138
- { transaction: dbTransaction },
1139
- );
1140
-
1141
- // Part 6: Record Agreement History Activity
1142
- // Initialise EntityValueAfter variable and set to newRecord from previous part.
1143
- // Instantiate new activity from Activity class, call createId() method, then set:
1144
- // Action: ActionEnum.CREATE
1145
- // Description: "Generate agreement."
1146
- // EntityType: "RentalAgreementHistory"
1147
- // EntityId: HistoryId from previous part.
1148
- // EntityValueBefore: empty object.
1149
- // EntityValueAfter: EntityValueAfter
1150
- // Call new activity create method by passing:
1151
- // dbTransaction
1152
- // userId: loginUser.ObjectId
1153
- const entityValueAfter = agreementHistory.get({ plain: true });
1154
- const activityHistory = new Activity();
1155
- activityHistory.ActivityId = activityHistory.createId();
1156
- activityHistory.Action = ActionEnum.CREATE;
1157
- activityHistory.Description = 'Generate agreement.';
1158
- activityHistory.EntityType = 'RentalAgreementHistory';
1159
- activityHistory.EntityId = agreementHistory.HistoryId.toString();
1160
- activityHistory.EntityValueBefore = JSON.stringify({});
1161
- activityHistory.EntityValueAfter = JSON.stringify(entityValueAfter);
1162
- await activityHistory.create(loginUser.ObjectId, dbTransaction);
1163
- } catch (error) {
1164
- throw error;
1165
- }
1166
- }
1167
- }
1
+ import { IRentalAttr } from '../../interfaces/rental-attr.interface';
2
+ import { RentalStatusEnum } from '../../enum/rental-status.enum';
3
+ import { RentalRepository } from './rental.repository';
4
+ import { ClassError, ObjectBase } from '@tomei/general';
5
+ import { ApplicationConfig } from '@tomei/config';
6
+ import { AuthContext, LoginUser } from '@tomei/sso';
7
+ import { RentalPrice } from '../rental-price/rental-price';
8
+ import { Op, QueryTypes } from 'sequelize';
9
+ import { ActionEnum, Activity } from '@tomei/activity-history';
10
+ import { IRentalFindAllSearchAttr } from '../../interfaces/rental-find-all-search-attr.interface';
11
+ import { RentalAccountTypeEnum } from '../../enum/account-type.enum';
12
+ import { JointHirer } from '../joint-hirer/joint-hirer';
13
+ import { JointHirerModel } from '../../models/joint-hirer.entity';
14
+ import { AgreementRepository } from '../agreement/agreement.repository';
15
+ import * as rentalDb from '../../database';
16
+ import { RentalModel } from '../../models/rental.entity';
17
+ import { JointHirerRepository } from '../joint-hirer/joint-hirer.repository';
18
+ import { AgreementModel } from '../../models';
19
+ import { Agreement } from '../agreement/agreement';
20
+ import { AggrementStatusEnum } from '../../enum/aggrement-status.enum';
21
+ import { AgreementSignatureRepository } from '../agreement-signature/agreement-signature.repository';
22
+ import { AgreementSignatureStatusEnum } from '../../enum/agreement-signature-status.enum';
23
+ import { HirerTypeEnum } from '../../enum/hirer-type.enum';
24
+ import { AgreementHistoryRepository } from '../agreement-history/agreement-history.repository';
25
+ import { DocType, Document, IAccountSystem } from '@tomei/finance';
26
+ import { ItemClassMap } from '../../ClassMappings/ItemClassMap';
27
+ import { AgreementSignatureVerificationMethodEnum } from '../../enum/agreement-signature-verification-method.enum';
28
+
29
+ export class Rental extends ObjectBase {
30
+ ObjectId: string;
31
+ ObjectName: string;
32
+ ObjectType = 'Rental';
33
+ TableName: string;
34
+ CustomerId: string;
35
+ CustomerType: string;
36
+ ItemId: string;
37
+ ItemType: string;
38
+ PriceId: string;
39
+ StartDateTime: Date;
40
+ EndDateTime: Date;
41
+ CancelRemarks: string;
42
+ TerminateRemarks: string;
43
+ AgreementNo: string;
44
+ AccountType: RentalAccountTypeEnum;
45
+ JointHirers: JointHirer[] = [];
46
+ Invoices: Document[] = [];
47
+ Item: any;
48
+ protected _Status: RentalStatusEnum | string;
49
+ protected _EscheatmentYN: string = 'N';
50
+ protected _CreatedById: string;
51
+ protected _CreatedAt: Date;
52
+ protected _UpdatedById: string;
53
+ protected _UpdatedAt: Date;
54
+ protected static _Repo = new RentalRepository();
55
+ protected static _AgreementRepo = new AgreementRepository();
56
+ protected static _JointHirerRepo = new JointHirerRepository();
57
+ protected static _AgreementSignatureRepo = new AgreementSignatureRepository();
58
+ protected static _AgreementHistoryRepo = new AgreementHistoryRepository();
59
+
60
+ get RentalId(): string {
61
+ return this.ObjectId;
62
+ }
63
+
64
+ set RentalId(value: string) {
65
+ this.ObjectId = value;
66
+ }
67
+
68
+ get Status(): RentalStatusEnum | string {
69
+ return this._Status;
70
+ }
71
+
72
+ get EscheatmentYN(): string {
73
+ return this._EscheatmentYN;
74
+ }
75
+
76
+ get CreatedById(): string {
77
+ return this._CreatedById;
78
+ }
79
+
80
+ get CreatedAt(): Date {
81
+ return this._CreatedAt;
82
+ }
83
+
84
+ get UpdatedById(): string {
85
+ return this._UpdatedById;
86
+ }
87
+
88
+ get UpdatedAt(): Date {
89
+ return this._UpdatedAt;
90
+ }
91
+
92
+ private setTerminated() {
93
+ this._Status = RentalStatusEnum.TERMINATED;
94
+ }
95
+
96
+ protected constructor(rentalAttr?: IRentalAttr) {
97
+ super();
98
+ if (rentalAttr) {
99
+ this.RentalId = rentalAttr.RentalId;
100
+ this.CustomerId = rentalAttr.CustomerId;
101
+ this.CustomerType = rentalAttr.CustomerType;
102
+ this.ItemId = rentalAttr.ItemId;
103
+ this.ItemType = rentalAttr.ItemType;
104
+ this.PriceId = rentalAttr.PriceId;
105
+ this.StartDateTime = rentalAttr.StartDateTime;
106
+ this.EndDateTime = rentalAttr.EndDateTime;
107
+ this.CancelRemarks = rentalAttr.CancelRemarks;
108
+ this.TerminateRemarks = rentalAttr.TerminateRemarks;
109
+ this.AgreementNo = rentalAttr.AgreementNo;
110
+ this.AccountType = rentalAttr.AccountType;
111
+ this._Status = rentalAttr.Status;
112
+ this._EscheatmentYN = rentalAttr.EscheatmentYN;
113
+ this._CreatedById = rentalAttr.CreatedById;
114
+ this._CreatedAt = rentalAttr.CreatedAt;
115
+ this._UpdatedById = rentalAttr.UpdatedById;
116
+ this._UpdatedAt = rentalAttr.UpdatedAt;
117
+ }
118
+ }
119
+
120
+ public static async init(dbTransaction?: any, rentalId?: string) {
121
+ try {
122
+ if (rentalId) {
123
+ const rental = await Rental._Repo.findByPk(rentalId, dbTransaction);
124
+ if (rental) {
125
+ return new Rental(rental);
126
+ } else {
127
+ throw new ClassError('Rental', 'RentalErrMsg00', 'Rental Not Found');
128
+ }
129
+ }
130
+ return new Rental();
131
+ } catch (error) {
132
+ throw new ClassError(
133
+ 'Rental',
134
+ 'RentalErrMsg00',
135
+ 'Failed To Initialize Price',
136
+ );
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Create a new Rental record.
142
+ * @param {RentalPrice} rentalPrice - The rental pricing information.
143
+ * @param {LoginUser} loginUser - The user initiating the creation.
144
+ * @param {any} [dbTransaction] - Optional database transaction for atomic operations.
145
+ * @throws {ClassError} Throws an error if:
146
+ * 1. loginUser does not have 'Rental - Create' privilege.
147
+ * 2. Rental item is not available at the current date.
148
+ * @returns {Promise<any>} A Promise resolving to the created rental record.
149
+ */
150
+ public async create(
151
+ rentalPrice: RentalPrice,
152
+ loginUser: LoginUser,
153
+ jointHirers?: JointHirer[],
154
+ dbTransaction?: any,
155
+ ): Promise<any> {
156
+ try {
157
+ /*Part 1: Check Privilege*/
158
+ const systemCode =
159
+ ApplicationConfig.getComponentConfigValue('system-code');
160
+ const isPrivileged = await loginUser.checkPrivileges(
161
+ systemCode,
162
+ 'Rental - Create',
163
+ );
164
+
165
+ if (!isPrivileged) {
166
+ throw new ClassError(
167
+ 'Rental',
168
+ 'RentalErrMsg01',
169
+ "You do not have 'Rental - Create' privilege.",
170
+ );
171
+ }
172
+
173
+ /*Part 2: Make Sure Rental Item Available*/
174
+ const isItemAvailable = await Rental.isItemAvailable(
175
+ this.ItemId,
176
+ this.ItemType,
177
+ this.StartDateTime,
178
+ this.EndDateTime,
179
+ dbTransaction,
180
+ );
181
+
182
+ if (!isItemAvailable) {
183
+ throw new ClassError(
184
+ 'Rental',
185
+ 'RentalErrMsg02',
186
+ 'Rental Item is not available at current date.',
187
+ );
188
+ }
189
+
190
+ // Part 3: Create Rental Agreement Record
191
+ // Call Rental._AgreementRepo create method by passing:
192
+ // AgreementNo: this.AgreementNo
193
+ // Status: "Not Generated"
194
+ // dbTransaction
195
+ await Rental._AgreementRepo.create(
196
+ {
197
+ AgreementNo: this.AgreementNo,
198
+ Status: 'Not Generated',
199
+ },
200
+ {
201
+ transaction: dbTransaction,
202
+ },
203
+ );
204
+
205
+ //Create a record into rental_AgreementSignature table
206
+ //Create the main customer's signature record
207
+ await Rental._AgreementSignatureRepo.create(
208
+ {
209
+ SignatureId: this.createId(),
210
+ AgreementNo: this.AgreementNo,
211
+ Party: HirerTypeEnum.PRIMARY,
212
+ PartyId: this.CustomerId,
213
+ PartyType: 'Customer',
214
+ SignatureStatus: AgreementSignatureStatusEnum.PENDING,
215
+ SignedAt: new Date(),
216
+ CreatedById: loginUser.ObjectId,
217
+ CreatedAt: new Date(),
218
+ UpdatedById: loginUser.ObjectId,
219
+ UpdatedAt: new Date(),
220
+ },
221
+ { transaction: dbTransaction },
222
+ );
223
+
224
+ // Create signatures record for joint hirers if any
225
+ if (jointHirers && jointHirers.length > 0) {
226
+ for (const jointHirer of jointHirers) {
227
+ await Rental._AgreementSignatureRepo.create(
228
+ {
229
+ SignatureId: this.createId(),
230
+ AgreementNo: this.AgreementNo,
231
+ Party: HirerTypeEnum.JOINT,
232
+ PartyId: jointHirer.CustomerId,
233
+ PartyType: 'Customer',
234
+ SignatureStatus: AgreementSignatureStatusEnum.PENDING,
235
+ SignedAt: new Date(),
236
+ CreatedById: loginUser.ObjectId,
237
+ CreatedAt: new Date(),
238
+ UpdatedById: loginUser.ObjectId,
239
+ UpdatedAt: new Date(),
240
+ },
241
+ { transaction: dbTransaction },
242
+ );
243
+ }
244
+ }
245
+
246
+ /*Part 4: Insert Rental & The Agreed Rental Price*/
247
+ if (!rentalPrice.PriceId) {
248
+ const rentalPriceData = await rentalPrice.create(
249
+ loginUser,
250
+ dbTransaction,
251
+ );
252
+ this.PriceId = rentalPriceData.PriceId;
253
+ } else {
254
+ this.PriceId = rentalPrice.PriceId;
255
+ }
256
+ this.RentalId = this.createId();
257
+ // if (!this.Status) {
258
+ this._Status = RentalStatusEnum.PENDING_SIGNING;
259
+ // }
260
+ this._CreatedById = loginUser.ObjectId;
261
+ this._UpdatedById = loginUser.ObjectId;
262
+ this._CreatedAt = new Date();
263
+ this._UpdatedAt = new Date();
264
+
265
+ const data = {
266
+ RentalId: this.RentalId,
267
+ CustomerId: this.CustomerId,
268
+ CustomerType: this.CustomerType,
269
+ ItemId: this.ItemId,
270
+ ItemType: this.ItemType,
271
+ PriceId: this.PriceId,
272
+ StartDateTime: this.StartDateTime,
273
+ EndDateTime: this.EndDateTime,
274
+ CancelRemarks: this.CancelRemarks,
275
+ TerminateRemarks: this.TerminateRemarks,
276
+ AgreementNo: this.AgreementNo,
277
+ AccountType: this.AccountType,
278
+ Status: this.Status,
279
+ EscheatmentYN: this.EscheatmentYN,
280
+ CreatedById: this.CreatedById,
281
+ CreatedAt: this.CreatedAt,
282
+ UpdatedById: this.UpdatedById,
283
+ UpdatedAt: this.UpdatedAt,
284
+ };
285
+
286
+ await Rental._Repo.create(data, {
287
+ transaction: dbTransaction,
288
+ });
289
+
290
+ //For every data inside Param.jointHirers, update the rentalId and call jointHirer.create
291
+ if (jointHirers) {
292
+ for (let i = 0; i < jointHirers.length; i++) {
293
+ jointHirers[i].RentalId = this.RentalId;
294
+ await jointHirers[i].create(loginUser, dbTransaction);
295
+ this.JointHirers.push(jointHirers[i]);
296
+ }
297
+ }
298
+
299
+ /*Part 5: Record Create Rental Activity*/
300
+ const activity = new Activity();
301
+ activity.ActivityId = activity.createId();
302
+ activity.Action = ActionEnum.CREATE;
303
+ activity.Description = 'Add Rental';
304
+ activity.EntityType = 'Rental';
305
+ activity.EntityId = this.RentalId;
306
+ activity.EntityValueBefore = JSON.stringify({});
307
+ activity.EntityValueAfter = JSON.stringify(data);
308
+ await activity.create(loginUser.ObjectId, dbTransaction);
309
+
310
+ /*Part 6: Return Result*/
311
+ return this;
312
+ } catch (error) {
313
+ throw error;
314
+ }
315
+ }
316
+
317
+ public static async isItemAvailable(
318
+ itemId: string,
319
+ itemType: string,
320
+ startDateTime: Date,
321
+ endDateTime: Date,
322
+ dbTransaction?: any,
323
+ ) {
324
+ try {
325
+ const rental = await Rental._Repo.findOne({
326
+ where: {
327
+ ItemId: itemId,
328
+ ItemType: itemType,
329
+ StartDateTime: {
330
+ [Op.lte]: endDateTime,
331
+ },
332
+ EndDateTime: {
333
+ [Op.gte]: startDateTime,
334
+ },
335
+ },
336
+ transaction: dbTransaction,
337
+ });
338
+
339
+ if (!rental) {
340
+ // No rental found item is available
341
+ return true;
342
+ }
343
+
344
+ if (
345
+ rental.Status === RentalStatusEnum.TERMINATED ||
346
+ rental.Status === RentalStatusEnum.CANCELLED
347
+ ) {
348
+ // Rental found but status is Terminated or Cancelled → item is available
349
+ return true;
350
+ }
351
+
352
+ // Rental exists and is active → item is not available
353
+ return false;
354
+ } catch (error) {
355
+ throw error;
356
+ }
357
+ }
358
+
359
+ public static async findAll(
360
+ authContext: AuthContext,
361
+ dbTransaction: any,
362
+ page?: number,
363
+ row?: number,
364
+ search?: IRentalFindAllSearchAttr,
365
+ ) {
366
+ try {
367
+ const systemCode =
368
+ await ApplicationConfig.getComponentConfigValue('system-code');
369
+
370
+ if ('loginUser' in authContext) {
371
+ const isPrivileged = await authContext.loginUser.checkPrivileges(
372
+ systemCode,
373
+ 'Rental - View',
374
+ );
375
+
376
+ if (!isPrivileged) {
377
+ throw new ClassError(
378
+ 'Rental',
379
+ 'RentalErrMsg01',
380
+ "You do not have 'Rental - View' privilege.",
381
+ );
382
+ }
383
+ }
384
+
385
+ const queryObj: any = {};
386
+
387
+ let options: any = {
388
+ transaction: dbTransaction,
389
+ order: [['CreatedAt', 'DESC']],
390
+ };
391
+
392
+ if (page && row) {
393
+ options = {
394
+ ...options,
395
+ limit: row,
396
+ offset: row * (page - 1),
397
+ };
398
+ }
399
+
400
+ if (search) {
401
+ Object.entries(search).forEach(([key, value]) => {
402
+ if (key === 'StartDateTime') {
403
+ queryObj[key] = {
404
+ [Op.gte]: value,
405
+ };
406
+ } else if (key === 'EndDateTime') {
407
+ queryObj[key] = {
408
+ [Op.lte]: value,
409
+ };
410
+ } else if (key === 'CustomerId') {
411
+ queryObj[key] = {
412
+ [Op.substring]: value,
413
+ };
414
+
415
+ options.include = [
416
+ {
417
+ model: JointHirerModel,
418
+ required: false,
419
+ where: {
420
+ CustomerId: {
421
+ [Op.substring]: value,
422
+ },
423
+ },
424
+ },
425
+ ];
426
+ } else {
427
+ queryObj[key] = {
428
+ [Op.substring]: value,
429
+ };
430
+ }
431
+ });
432
+ if (options?.include?.length > 1) {
433
+ options.include.push({
434
+ model: AgreementModel,
435
+ required: false,
436
+ });
437
+ } else {
438
+ options.include = [
439
+ {
440
+ model: AgreementModel,
441
+ required: false,
442
+ },
443
+ ];
444
+ }
445
+
446
+ options = {
447
+ ...options,
448
+ where: queryObj,
449
+ };
450
+ }
451
+
452
+ return await Rental._Repo.findAndCountAll(options);
453
+ } catch (err) {
454
+ throw err;
455
+ }
456
+ }
457
+
458
+ public static async checkActiveByItemId(
459
+ loginUser: LoginUser,
460
+ itemId: string,
461
+ itemType: string,
462
+ dbTransaction?: any,
463
+ ) {
464
+ try {
465
+ const systemCode =
466
+ await ApplicationConfig.getComponentConfigValue('system-code');
467
+
468
+ const isPrivileged = await loginUser.checkPrivileges(
469
+ systemCode,
470
+ 'Rental - View',
471
+ );
472
+
473
+ if (!isPrivileged) {
474
+ throw new ClassError(
475
+ 'Rental',
476
+ 'RentalErrMsg01',
477
+ "You do not have 'Rental - View' privilege.",
478
+ );
479
+ }
480
+
481
+ const queryObj: any = {
482
+ ItemId: itemId,
483
+ ItemType: itemType,
484
+ Status: RentalStatusEnum.ACTIVE,
485
+ };
486
+
487
+ const options: any = {
488
+ transaction: dbTransaction,
489
+ where: queryObj,
490
+ };
491
+
492
+ const rental = await Rental._Repo.findOne(options);
493
+
494
+ if (rental) {
495
+ return true;
496
+ } else {
497
+ return false;
498
+ }
499
+ } catch (err) {
500
+ throw err;
501
+ }
502
+ }
503
+
504
+ /**
505
+ * Sets the StartDateTime property of the Rental class as custom setter.
506
+ * @param {Date} startDateTime - The start date and time of the rental.
507
+ * @throws {ClassError} Throws an error if:
508
+ * 1. startDateTime is a past date.
509
+ * 2. startDateTime is more than the EndDateTime.
510
+ * @returns {void}
511
+ */
512
+ setStartDateTime(startDateTime: Date): void {
513
+ const startDateTimeObject = new Date(startDateTime);
514
+ startDateTimeObject.setHours(0, 0, 0, 0);
515
+
516
+ /*Part 1: Make Sure Future Date Time*/
517
+ if (startDateTimeObject < new Date(new Date().setHours(0, 0, 0, 0))) {
518
+ throw new ClassError(
519
+ 'Rental',
520
+ 'RentalErrMsg02',
521
+ 'StartDateTime cannot be a past datetime.',
522
+ );
523
+ }
524
+
525
+ /*Part 2: Make Sure Less Than End Date Time*/
526
+ if (this.EndDateTime && startDateTimeObject > this.EndDateTime) {
527
+ throw new ClassError(
528
+ 'Rental',
529
+ 'RentalErrMsg03',
530
+ 'StartDateTime cannot be more than EndDateTime.',
531
+ );
532
+ }
533
+
534
+ /*Part 3: Set Status Whether Reserved or Active*/
535
+ if (startDateTimeObject > new Date(new Date().setHours(0, 0, 0, 0))) {
536
+ this._Status = RentalStatusEnum.RESERVED;
537
+ } else {
538
+ this._Status = RentalStatusEnum.ACTIVE;
539
+ }
540
+ }
541
+
542
+ public async periodEndProcess(
543
+ loginUser: LoginUser,
544
+ dbTransaction: any,
545
+ stockInventory: any,
546
+ ) {
547
+ try {
548
+ // Privilege Checking
549
+ const systemCode =
550
+ await ApplicationConfig.getComponentConfigValue('system-code');
551
+
552
+ const isPrivileged = await loginUser.checkPrivileges(
553
+ systemCode,
554
+ 'Rental PeriodEndProcess',
555
+ );
556
+
557
+ if (!isPrivileged) {
558
+ throw new ClassError(
559
+ 'Rental',
560
+ 'RentalErrMsg04',
561
+ "You do not have 'Rental - PeriodEndProcess' privilege.",
562
+ );
563
+ }
564
+
565
+ // Validate Existing Rental
566
+ if (this.AgreementNo === undefined || this.AgreementNo === null) {
567
+ throw new ClassError(
568
+ 'Rental',
569
+ 'RentalErrMsg05',
570
+ 'Rental must be existing rental.',
571
+ );
572
+ }
573
+
574
+ // Validate Rental End Period
575
+ if (this.EndDateTime === new Date(new Date().setHours(0, 0, 0, 0))) {
576
+ throw new ClassError(
577
+ 'Rental',
578
+ 'RentalErrMsg06',
579
+ 'Rental period is not ending today.',
580
+ );
581
+ }
582
+
583
+ // Mark Rental Item as Available
584
+ await stockInventory.setAvailable(loginUser, dbTransaction);
585
+
586
+ // Capture Record Info Before Changes
587
+ const entityValueBefore = {
588
+ RentalId: this.RentalId,
589
+ CustomerId: this.CustomerId,
590
+ CustomerType: this.CustomerType,
591
+ ItemId: this.ItemId,
592
+ ItemType: this.ItemType,
593
+ PriceId: this.PriceId,
594
+ StartDateTime: this.StartDateTime,
595
+ EndDateTime: this.EndDateTime,
596
+ CancelRemarks: this.CancelRemarks,
597
+ TerminateRemarks: this.TerminateRemarks,
598
+ AgreementNo: this.AgreementNo,
599
+ AccountType: this.AccountType,
600
+ Status: this.Status,
601
+ EscheatmentYN: this.EscheatmentYN,
602
+ CreatedById: this.CreatedById,
603
+ CreatedAt: this.CreatedAt,
604
+ UpdatedById: this.UpdatedById,
605
+ UpdatedAt: this.UpdatedAt,
606
+ };
607
+
608
+ // Mark Rental as Terminated and Capture Updater Info
609
+ this.setTerminated();
610
+ this._UpdatedById = loginUser.ObjectId;
611
+ this._UpdatedAt = new Date();
612
+
613
+ // Capture Record Info after Changes
614
+ const entityValueAfter = {
615
+ RentalId: this.RentalId,
616
+ CustomerId: this.CustomerId,
617
+ CustomerType: this.CustomerType,
618
+ ItemId: this.ItemId,
619
+ ItemType: this.ItemType,
620
+ PriceId: this.PriceId,
621
+ StartDateTime: this.StartDateTime,
622
+ EndDateTime: this.EndDateTime,
623
+ CancelRemarks: this.CancelRemarks,
624
+ TerminateRemarks: this.TerminateRemarks,
625
+ AgreementNo: this.AgreementNo,
626
+ AccountType: this.AccountType,
627
+ Status: this.Status,
628
+ EscheatmentYN: this.EscheatmentYN,
629
+ CreatedById: this.CreatedById,
630
+ CreatedAt: this.CreatedAt,
631
+ UpdatedById: this.UpdatedById,
632
+ UpdatedAt: this.UpdatedAt,
633
+ };
634
+
635
+ // Record the Update Activity
636
+ const activity = new Activity();
637
+ activity.ActivityId = activity.createId();
638
+ activity.Action = ActionEnum.UPDATE;
639
+ activity.Description = 'Set Rental as Terminated';
640
+ activity.EntityType = 'Rental';
641
+ activity.EntityId = this.RentalId;
642
+ activity.EntityValueBefore = JSON.stringify(entityValueBefore);
643
+ activity.EntityValueAfter = JSON.stringify(entityValueAfter);
644
+ await activity.create(loginUser.ObjectId, dbTransaction);
645
+
646
+ return this;
647
+ } catch (err) {
648
+ throw err;
649
+ }
650
+ }
651
+
652
+ async getCustomerActiveRentals(
653
+ loginUser: LoginUser,
654
+ dbTransaction: any,
655
+ CustomerId: string,
656
+ ): Promise<IRentalAttr[]> {
657
+ try {
658
+ // Part 1: Privilege Checking
659
+ // Call loginUser.checkPrivileges() by passing:
660
+ // SystemCode: <get_from_app_config>
661
+ // PrivilegeCode: "RENTAL_VIEW"
662
+ const systemCode =
663
+ ApplicationConfig.getComponentConfigValue('system-code');
664
+ const isPrivileged = loginUser.checkPrivileges(systemCode, 'RENTAL_VIEW');
665
+
666
+ if (!isPrivileged) {
667
+ throw new ClassError(
668
+ 'Rental',
669
+ 'RentalErrMsg01',
670
+ "You do not have 'Rental - View' privilege.",
671
+ );
672
+ }
673
+
674
+ // Part 2: Retrieve Rentals and Returns
675
+ // Call Rental._Repo findAll method by passing:
676
+ // where:
677
+ // Status: "Active"
678
+ // [Op.OR]:
679
+ // CustomerId: Params.CustomerId
680
+ // '$JointHirers.CustomerId$': Params.CustomerId
681
+ // include:
682
+ // model: JointHirerModel
683
+ // attributes: []
684
+ const query = `
685
+ SELECT
686
+ r.*
687
+ FROM
688
+ rental_Rental r
689
+ LEFT JOIN
690
+ rental_JointHirer jh ON r.RentalId = jh.RentalId
691
+ WHERE
692
+ r.Status = 'Active'
693
+ AND (
694
+ r.CustomerId = '${CustomerId}'
695
+ OR jh.CustomerId = '${CustomerId}'
696
+ )
697
+ GROUP BY
698
+ r.RentalId
699
+ `;
700
+ const db = rentalDb.getConnection();
701
+ const result = await db.query(query, {
702
+ type: QueryTypes.SELECT,
703
+ transaction: dbTransaction,
704
+ model: RentalModel,
705
+ mapToModel: true,
706
+ });
707
+
708
+ // Format the returned records
709
+ const records: IRentalAttr[] = result.map((record: RentalModel) => {
710
+ return {
711
+ RentalId: record.RentalId,
712
+ CustomerId: record.CustomerId,
713
+ CustomerType: record.CustomerType,
714
+ ItemId: record.ItemId,
715
+ ItemType: record.ItemType,
716
+ PriceId: record.PriceId,
717
+ StartDateTime: record.StartDateTime,
718
+ EndDateTime: record.EndDateTime,
719
+ CancelRemarks: record.CancelRemarks,
720
+ TerminateRemarks: record.TerminateRemarks,
721
+ AgreementNo: record.AgreementNo,
722
+ AccountType: record.AccountType,
723
+ Status: record.Status,
724
+ EscheatmentYN: record.EscheatmentYN,
725
+ CreatedById: record.CreatedById,
726
+ CreatedAt: record.CreatedAt,
727
+ UpdatedById: record.UpdatedById,
728
+ UpdatedAt: record.UpdatedAt,
729
+ };
730
+ });
731
+ // Return the returned records.
732
+ return records;
733
+ } catch (error) {
734
+ throw error;
735
+ }
736
+ }
737
+
738
+ async getJointHirers(dbTransaction: any) {
739
+ try {
740
+ if (!this.RentalId) {
741
+ throw new ClassError('Rental', 'RentalErrMsg01', 'RentalId is missing');
742
+ }
743
+ if (this.AccountType !== RentalAccountTypeEnum.JOINT) {
744
+ throw new ClassError(
745
+ 'Rental',
746
+ 'RentalErrMsg07',
747
+ 'This rental does not have joint hirers.',
748
+ );
749
+ }
750
+
751
+ const jointHirers = await Rental._JointHirerRepo.findAll({
752
+ where: {
753
+ RentalId: this.RentalId,
754
+ },
755
+ transaction: dbTransaction,
756
+ });
757
+ // Map the jointHirers to JointHirer instances
758
+ const jointHirerInstances = Promise.all(
759
+ jointHirers.map(async (hirer: JointHirerModel) => {
760
+ return await JointHirer.init(hirer.HirerId, dbTransaction);
761
+ }),
762
+ );
763
+ return jointHirerInstances;
764
+ } catch (error) {
765
+ console.error('Error in getJointHirers:', error);
766
+ throw error;
767
+ }
768
+ }
769
+
770
+ async getCustomerIds(loginUser: LoginUser, dbTransaction: any) {
771
+ try {
772
+ // Part 1: Privilege Checking
773
+ // Call loginUser.checkPrivileges() by passing:
774
+ // SystemCode: <get_from_app_config>
775
+ // PrivilegeCode: "RENTAL_VIEW"
776
+ const systemCode =
777
+ ApplicationConfig.getComponentConfigValue('system-code');
778
+ const isPrivileged = loginUser.checkPrivileges(systemCode, 'RENTAL_VIEW');
779
+
780
+ if (!isPrivileged) {
781
+ throw new ClassError(
782
+ 'Rental',
783
+ 'RentalErrMsg01',
784
+ "You do not have 'Rental - View' privilege.",
785
+ );
786
+ }
787
+
788
+ // Part 2: Validation
789
+ // Make sure this.RentalId exists, if not throw new ClassError by passing
790
+ if (!this.RentalId) {
791
+ throw new ClassError('Rental', 'RentalErrMsg01', 'RentalId is missing');
792
+ }
793
+
794
+ //Part 3: Retrieve Listing and Returns
795
+ // 3.1 Call Rental._JointHirerRepo findAll method by passing:
796
+ // where:
797
+ // RentalId: this.RentalId
798
+ // dbTransaction
799
+ const options: any = {
800
+ where: {
801
+ RentalId: this.RentalId,
802
+ },
803
+ transaction: dbTransaction,
804
+ };
805
+
806
+ const joinHirers = await Rental._JointHirerRepo.findAll(options);
807
+
808
+ // 3.2 Create a new array variable and set its value to joint hirer and Rental.CustomerId
809
+ // array translated to only CustomerId. Then, append this.CustomerId to the array.
810
+ const customerIds: string[] = [this.CustomerId];
811
+ for (let i = 0; i < joinHirers.length; i++) {
812
+ const jointHirer = joinHirers[i];
813
+ customerIds.push(jointHirer.CustomerId);
814
+ }
815
+
816
+ // 3.3 Return the array.
817
+ return customerIds;
818
+ } catch (error) {
819
+ throw error;
820
+ }
821
+ }
822
+
823
+ async signAgreement(
824
+ loginUser: LoginUser,
825
+ party: string,
826
+ PartyId: string,
827
+ PartyType: string,
828
+ dbTransaction: any,
829
+ statusAfterSign?: RentalStatusEnum | string,
830
+ method?: AgreementSignatureVerificationMethodEnum,
831
+ justification?: string,
832
+ ) {
833
+ try {
834
+ // Part 1: Privilege Checking
835
+ // Call loginUser.checkPrivileges() by passing:
836
+ // SystemCode: <get_from_app_config>
837
+ // PrivilegeCode: "RENTAL_SIGN"
838
+ const systemCode =
839
+ ApplicationConfig.getComponentConfigValue('system-code');
840
+ const isPrivileged = loginUser.checkPrivileges(systemCode, 'RENTAL_SIGN');
841
+
842
+ if (!isPrivileged) {
843
+ throw new ClassError(
844
+ 'Rental',
845
+ 'RentalErrMsg01',
846
+ "You do not have 'RENTAL_SIGN' privilege.",
847
+ );
848
+ }
849
+
850
+ // Part 2: Validation
851
+ // Make sure this.Status is "Pending Signing" and agreementStatus is "Generated", if not throw new ClassError
852
+ const agreement = await Agreement.init(this.AgreementNo, dbTransaction);
853
+ if (
854
+ this.Status !== RentalStatusEnum.PENDING_SIGNING &&
855
+ agreement.Status !== AggrementStatusEnum.GENERATED
856
+ ) {
857
+ throw new ClassError(
858
+ 'Rental',
859
+ 'RentalErrMsg01',
860
+ 'Rental is not ready to be signed yet.',
861
+ );
862
+ }
863
+
864
+ //Make sure CustomerId inside the listing and SignatureStatus is "Pending"
865
+ const signatureList = await Agreement.getSignatureList(
866
+ loginUser,
867
+ this.AgreementNo,
868
+ dbTransaction,
869
+ );
870
+ const customerSignature = signatureList.find(
871
+ (sig) =>
872
+ sig.PartyId === PartyId &&
873
+ sig.PartyType === PartyType &&
874
+ sig.Party === party &&
875
+ sig.SignatureStatus === AgreementSignatureStatusEnum.PENDING,
876
+ );
877
+
878
+ if (!customerSignature) {
879
+ throw new ClassError(
880
+ 'Rental',
881
+ 'RentalErrMsg01',
882
+ 'Signature is not pending.',
883
+ );
884
+ }
885
+
886
+ //Update rental_AgreementSignature
887
+ const signaturePayload = {
888
+ SignatureStatus: AgreementSignatureStatusEnum.SIGNED,
889
+ SignedAt: new Date(),
890
+ UpdatedById: loginUser.ObjectId,
891
+ UpdatedAt: new Date(),
892
+ VerificationMethod: method,
893
+ VerificationJustification: justification,
894
+ VerifiedById: loginUser.ObjectId,
895
+ };
896
+
897
+ await Rental._AgreementSignatureRepo.update(signaturePayload, {
898
+ where: {
899
+ AgreementNo: this.AgreementNo,
900
+ Party: party,
901
+ PartyId: PartyId,
902
+ PartyType: PartyType,
903
+ },
904
+ transaction: dbTransaction,
905
+ });
906
+
907
+ const signatureActivity = new Activity();
908
+ signatureActivity.ActivityId = signatureActivity.createId();
909
+ signatureActivity.Action = ActionEnum.UPDATE;
910
+ signatureActivity.Description = 'Update hirer signature';
911
+ signatureActivity.EntityType = 'AgreementSignature';
912
+ signatureActivity.EntityId = this.AgreementNo;
913
+ signatureActivity.EntityValueBefore = JSON.stringify(customerSignature);
914
+ signatureActivity.EntityValueAfter = JSON.stringify(signaturePayload);
915
+ await signatureActivity.create(loginUser.ObjectId, dbTransaction);
916
+
917
+ const updatedSignatureList = await Agreement.getSignatureList(
918
+ loginUser,
919
+ this.AgreementNo,
920
+ dbTransaction,
921
+ );
922
+
923
+ const pendingSignatures = updatedSignatureList.filter(
924
+ (sig) => sig.SignatureStatus === 'Pending',
925
+ );
926
+ if (pendingSignatures.length > 0) {
927
+ return;
928
+ }
929
+
930
+ //Part 3: Update Agreement Status
931
+ // 3.1 Set EntityValueBefore to current agreement instance.
932
+ const entityValueAgreementBefore = {
933
+ AgreementNo: agreement.AgreementNo,
934
+ Status: agreement.Status,
935
+ DateSigned: agreement.DateSigned,
936
+ };
937
+
938
+ // 3.2 Set below agreement attributes:
939
+ // DateSigned: current date & time
940
+ // Status: "Signed"
941
+ const payload = {
942
+ DateSigned: new Date(),
943
+ Status: AggrementStatusEnum.SIGNED,
944
+ };
945
+
946
+ // 3.3 Call Rental._AgreementRepo update()
947
+ await Rental._AgreementRepo.update(payload, {
948
+ where: {
949
+ AgreementNo: this.AgreementNo,
950
+ },
951
+ transaction: dbTransaction,
952
+ });
953
+
954
+ const entityValueAgreementAfter = {
955
+ entityValueAgreementBefore,
956
+ ...payload,
957
+ };
958
+
959
+ // Part 4: Record Update Agreement Activity
960
+ const activity = new Activity();
961
+ activity.ActivityId = activity.createId();
962
+ activity.Action = ActionEnum.UPDATE;
963
+ activity.Description = 'Update agreement';
964
+ activity.EntityType = 'RentalAgreement';
965
+ activity.EntityId = this.AgreementNo;
966
+ activity.EntityValueBefore = JSON.stringify(entityValueAgreementBefore);
967
+ activity.EntityValueAfter = JSON.stringify(entityValueAgreementAfter);
968
+ await activity.create(loginUser.ObjectId, dbTransaction);
969
+
970
+ // Part 5: Update Rental Status
971
+ // 5.1 Set EntityValueBefore to current rental instance.
972
+ const entityValueRentalBefore = {
973
+ RentalId: this.RentalId,
974
+ CustomerId: this.CustomerId,
975
+ CustomerType: this.CustomerType,
976
+ ItemId: this.ItemId,
977
+ ItemType: this.ItemType,
978
+ PriceId: this.PriceId,
979
+ StartDateTime: this.StartDateTime,
980
+ EndDateTime: this.EndDateTime,
981
+ CancelRemarks: this.CancelRemarks,
982
+ TerminateRemarks: this.TerminateRemarks,
983
+ AgreementNo: this.AgreementNo,
984
+ AccountType: this.AccountType,
985
+ Status: this.Status,
986
+ EscheatmentYN: this.EscheatmentYN,
987
+ CreatedById: this.CreatedById,
988
+ CreatedAt: this.CreatedAt,
989
+ UpdatedById: this.UpdatedById,
990
+ UpdatedAt: this.UpdatedAt,
991
+ };
992
+ // 5.2: Set below rental attributes:
993
+ // Status: "Pending Key Collection"
994
+ // UpdatedById: loginUser.ObjectId
995
+ // UpdatedAt: current date & time
996
+
997
+ this._Status = statusAfterSign
998
+ ? statusAfterSign
999
+ : RentalStatusEnum.ACTIVE;
1000
+
1001
+ const payloadRental = {
1002
+ Status: this._Status,
1003
+ UpdatedById: loginUser.ObjectId,
1004
+ UpdatedAt: new Date(),
1005
+ };
1006
+
1007
+ // 5.3: Call Rental._Repo update() method by passing:
1008
+ // populate rental instance attributes
1009
+ // dbTransaction
1010
+ await Rental._Repo.update(payloadRental, {
1011
+ where: {
1012
+ RentalId: this.RentalId,
1013
+ },
1014
+ transaction: dbTransaction,
1015
+ });
1016
+
1017
+ const entityValueRentalAfter = {
1018
+ entityValueRentalBefore,
1019
+ ...payloadRental,
1020
+ };
1021
+
1022
+ // Part 6: Record Update Agreement Activity
1023
+ const rentalActivity = new Activity();
1024
+ rentalActivity.ActivityId = activity.createId();
1025
+ rentalActivity.Action = ActionEnum.UPDATE;
1026
+ rentalActivity.Description = 'Sign rental agreement';
1027
+ rentalActivity.EntityType = 'Rental';
1028
+ rentalActivity.EntityId = this.RentalId;
1029
+ rentalActivity.EntityValueBefore = JSON.stringify(
1030
+ entityValueRentalBefore,
1031
+ );
1032
+ rentalActivity.EntityValueAfter = JSON.stringify(entityValueRentalAfter);
1033
+ await rentalActivity.create(loginUser.ObjectId, dbTransaction);
1034
+ } catch (error) {
1035
+ throw error;
1036
+ }
1037
+ }
1038
+
1039
+ async generateAgreement(
1040
+ loginUser: LoginUser,
1041
+ dbTransaction: any,
1042
+ MediaId: string,
1043
+ ) {
1044
+ //This method will generate a new rental agreement.
1045
+ try {
1046
+ // Part 1: Privilege Checking
1047
+ // Call loginUser.checkPrivileges() by passing:
1048
+ // SystemCode: "<get_from_app_config>"
1049
+ // PrivilegeCode: "RENTAL_AGREEMENT_CREATE"
1050
+
1051
+ const systemCode =
1052
+ ApplicationConfig.getComponentConfigValue('system-code');
1053
+ const isPrivileged = loginUser.checkPrivileges(
1054
+ systemCode,
1055
+ 'RENTAL_AGREEMENT_CREATE',
1056
+ );
1057
+
1058
+ if (!isPrivileged) {
1059
+ throw new ClassError(
1060
+ 'Rental',
1061
+ 'RentalErrMsg01',
1062
+ "You do not have 'RENTAL_AGREEMENT_CREATE' privilege.",
1063
+ );
1064
+ }
1065
+
1066
+ // Part 2: Validation
1067
+ // Instantiate existing RentalAgreement by passing:
1068
+ // dbTransaction
1069
+ // AgreementNo: this.AgreementNo
1070
+ // Make sure Params.MediaId exists, if not throw new ClassError by passing:
1071
+ // Classname: "Rental"
1072
+ // MessageCode: "RentalErrMsg0X"
1073
+ // Message: "MediaId is required."
1074
+ const agreement = await Agreement.init(this.AgreementNo, dbTransaction);
1075
+ if (!MediaId) {
1076
+ throw new ClassError(
1077
+ 'Rental',
1078
+ 'RentalErrMsg0X',
1079
+ 'MediaId is required.',
1080
+ );
1081
+ }
1082
+
1083
+ // Part 3: Update Agreement Record
1084
+ // Set EntityValueBefore to the agreement instance.
1085
+ // Set below agreement attributes:
1086
+ // Status: "Generated"
1087
+ // MediaId: Params.MediaId
1088
+
1089
+ const EntityValueBefore = agreement;
1090
+ agreement.Status = AggrementStatusEnum.GENERATED;
1091
+ agreement.MediaId = MediaId;
1092
+
1093
+ // Call Rental._AgreementRepo update method by passing:
1094
+ // Status: agreement.Status
1095
+ // MediaId: agreement.MediaId
1096
+ // dbTransaction
1097
+
1098
+ await Rental._AgreementRepo.update(
1099
+ {
1100
+ Status: agreement.Status,
1101
+ MediaId: agreement.MediaId,
1102
+ },
1103
+ {
1104
+ where: {
1105
+ AgreementNo: this.AgreementNo,
1106
+ },
1107
+ transaction: dbTransaction,
1108
+ },
1109
+ );
1110
+
1111
+ // Part 4: Record Update Agreement Activity
1112
+ // Initialise EntityValueAfter variable and set to agreement instance
1113
+ const EntityValueAfter = agreement;
1114
+ // Instantiate new activity from Activity class, call createId() method, then set:
1115
+ const activity = new Activity();
1116
+ // Action: ActionEnum.UPDATE
1117
+ // Description: "Generate agreement."
1118
+ // EntityType: "RentalAgreement"
1119
+ // EntityId: this.AgreementNo
1120
+ // EntityValueBefore: EntityValueBefore
1121
+ // EntityValueAfter: EntityValueAfter
1122
+ activity.ActivityId = activity.createId();
1123
+ activity.Action = ActionEnum.UPDATE;
1124
+ activity.Description = 'Generate agreement.';
1125
+ activity.EntityType = 'RentalAgreement';
1126
+ activity.EntityId = this.AgreementNo;
1127
+ activity.EntityValueBefore = JSON.stringify(EntityValueBefore);
1128
+ activity.EntityValueAfter = JSON.stringify(EntityValueAfter);
1129
+
1130
+ // Call new activity create method by passing:
1131
+ // dbTransaction
1132
+ // userId: loginUser.ObjectId
1133
+ await activity.create(loginUser.ObjectId, dbTransaction);
1134
+
1135
+ // Part 5: Add Record To Agreement History Table
1136
+ // Make sure there is a private static readonly _AgreementHistoryRepo variable.
1137
+ // Set newRecord to an object with below key-value:
1138
+ // AgreementNo: this.AgreementNo
1139
+ // MediaId: params.MediaId
1140
+ // ActivityCompleted: "Agreement Generated"
1141
+ // CreatedAt: Current Timestamp
1142
+ // Use _AgreementHistoryRepo.create() method and pass newRecord and dbTransaction.
1143
+ const agreementHistory = await Rental._AgreementHistoryRepo.create(
1144
+ {
1145
+ AgreementNo: this.AgreementNo,
1146
+ MediaId,
1147
+ ActivityCompleted: 'Agreement Generated',
1148
+ CreatedAt: new Date(),
1149
+ },
1150
+ { transaction: dbTransaction },
1151
+ );
1152
+
1153
+ // Part 6: Record Agreement History Activity
1154
+ // Initialise EntityValueAfter variable and set to newRecord from previous part.
1155
+ // Instantiate new activity from Activity class, call createId() method, then set:
1156
+ // Action: ActionEnum.CREATE
1157
+ // Description: "Generate agreement."
1158
+ // EntityType: "RentalAgreementHistory"
1159
+ // EntityId: HistoryId from previous part.
1160
+ // EntityValueBefore: empty object.
1161
+ // EntityValueAfter: EntityValueAfter
1162
+ // Call new activity create method by passing:
1163
+ // dbTransaction
1164
+ // userId: loginUser.ObjectId
1165
+ const entityValueAfter = agreementHistory.get({ plain: true });
1166
+ const activityHistory = new Activity();
1167
+ activityHistory.ActivityId = activityHistory.createId();
1168
+ activityHistory.Action = ActionEnum.CREATE;
1169
+ activityHistory.Description = 'Generate agreement.';
1170
+ activityHistory.EntityType = 'RentalAgreementHistory';
1171
+ activityHistory.EntityId = agreementHistory.HistoryId.toString();
1172
+ activityHistory.EntityValueBefore = JSON.stringify({});
1173
+ activityHistory.EntityValueAfter = JSON.stringify(entityValueAfter);
1174
+ await activityHistory.create(loginUser.ObjectId, dbTransaction);
1175
+ } catch (error) {
1176
+ throw error;
1177
+ }
1178
+ }
1179
+
1180
+ public toJSON(): IRentalAttr {
1181
+ return {
1182
+ RentalId: this.RentalId,
1183
+ CustomerId: this.CustomerId,
1184
+ CustomerType: this.CustomerType,
1185
+ ItemId: this.ItemId,
1186
+ ItemType: this.ItemType,
1187
+ PriceId: this.PriceId,
1188
+ StartDateTime: this.StartDateTime,
1189
+ EndDateTime: this.EndDateTime,
1190
+ Status: this.Status,
1191
+ CancelRemarks: this.CancelRemarks,
1192
+ TerminateRemarks: this.TerminateRemarks,
1193
+ EscheatmentYN: this.EscheatmentYN,
1194
+ AgreementNo: this.AgreementNo,
1195
+ AccountType: this.AccountType,
1196
+ CreatedById: this.CreatedById,
1197
+ CreatedAt: this.CreatedAt,
1198
+ UpdatedById: this.UpdatedById,
1199
+ UpdatedAt: this.UpdatedAt,
1200
+ };
1201
+ }
1202
+
1203
+ public async getInvoices(
1204
+ loginUser: LoginUser,
1205
+ dbTransaction: any,
1206
+ accountingSystem?: IAccountSystem,
1207
+ ) {
1208
+ try {
1209
+ // Part 1: Privilege Checking
1210
+ // Call loginUser.checkPrivileges() by passing:
1211
+ // SystemCode: <get_from_app_config>
1212
+ // PrivilegeCode: "RENTAL_VIEW_INVOICE"
1213
+ const systemCode =
1214
+ ApplicationConfig.getComponentConfigValue('system-code');
1215
+ const isPrivileged = loginUser.checkPrivileges(
1216
+ systemCode,
1217
+ 'RENTAL_VIEW_INVOICE',
1218
+ );
1219
+
1220
+ if (!isPrivileged) {
1221
+ throw new ClassError(
1222
+ 'Rental',
1223
+ 'RentalErrMsg01',
1224
+ "You do not have 'RENTAL_VIEW_INVOICE' privilege.",
1225
+ );
1226
+ }
1227
+
1228
+ // Part 2: Validation
1229
+ // Make sure this._ObjectId exists, if not throw new ClassError by passing
1230
+ if (!this.ObjectId) {
1231
+ throw new ClassError(
1232
+ 'Rental',
1233
+ 'RentalErrMsg01',
1234
+ 'ObjectId is missing.',
1235
+ );
1236
+ }
1237
+
1238
+ // Part 3: Check Existing Invoices
1239
+ if (this.Invoices.length > 0) {
1240
+ return this.Invoices;
1241
+ }
1242
+
1243
+ // Part 4: Retrieve Invoices and Returns
1244
+ const search = {
1245
+ DocType: DocType.INVOICE,
1246
+ RelatedObjectId: this.ObjectId,
1247
+ RelatedObjectType: this.ObjectType,
1248
+ };
1249
+
1250
+ const documents = await Document.findAll(
1251
+ loginUser,
1252
+ dbTransaction,
1253
+ undefined,
1254
+ undefined,
1255
+ search,
1256
+ undefined,
1257
+ accountingSystem,
1258
+ );
1259
+
1260
+ this.Invoices = documents.rows.map((doc) => {
1261
+ const document = new Document(dbTransaction, doc);
1262
+ return document;
1263
+ });
1264
+
1265
+ return this.Invoices;
1266
+ } catch (error) {
1267
+ throw error;
1268
+ }
1269
+ }
1270
+
1271
+ public async getItem(dbTransaction: any): Promise<any> {
1272
+ if (this.Item) {
1273
+ return this.Item;
1274
+ } else {
1275
+ const ItemClass = ItemClassMap[this.ItemType];
1276
+
1277
+ if (!ItemClass || typeof ItemClass.init !== 'function') {
1278
+ throw new Error(`Invalid or unregistered ItemType: ${this.ItemType}`);
1279
+ }
1280
+
1281
+ ItemClass._Repo = ItemClass._Repo || ItemClass.getRepo();
1282
+
1283
+ if (!ItemClass._Repo) {
1284
+ throw new Error(
1285
+ `ItemType ${this.ItemType} does not have a repository.`,
1286
+ );
1287
+ }
1288
+
1289
+ const itemInstance = await ItemClass.init(this.ItemId, dbTransaction);
1290
+
1291
+ if (!itemInstance) {
1292
+ throw new Error(`${this.ItemType} not found with ID ${this.ItemId}`);
1293
+ }
1294
+ this.Item = itemInstance;
1295
+
1296
+ // Make sure item has setAvailable method
1297
+ if (typeof this.Item.setAvailable !== 'function') {
1298
+ throw new Error(`${this.ItemType} does not implement setAvailable()`);
1299
+ }
1300
+ return this.Item;
1301
+ }
1302
+ }
1303
+
1304
+ public async cancel(
1305
+ loginUser: LoginUser,
1306
+ dbTransaction: any,
1307
+ remarks: string,
1308
+ ): Promise<Rental> {
1309
+ try {
1310
+ // Part 1: Privilege Checking
1311
+ const systemCode =
1312
+ ApplicationConfig.getComponentConfigValue('system-code');
1313
+ const isPrivileged = await loginUser.checkPrivileges(
1314
+ systemCode,
1315
+ 'RENTAL_CANCEL',
1316
+ );
1317
+
1318
+ if (!isPrivileged) {
1319
+ throw new ClassError(
1320
+ 'Rental',
1321
+ 'RentalErrMsg01',
1322
+ "You do not have 'RENTAL_CANCEL' privilege.",
1323
+ );
1324
+ }
1325
+
1326
+ // Part 2: Validation
1327
+ if (!this.ObjectId) {
1328
+ throw new ClassError(
1329
+ 'Rental',
1330
+ 'RentalErrMsg01',
1331
+ 'Rental not found. Rental Id is empty.',
1332
+ );
1333
+ }
1334
+
1335
+ if (
1336
+ this.Status === RentalStatusEnum.ACTIVE ||
1337
+ this.Status === RentalStatusEnum.SUSPENDED
1338
+ ) {
1339
+ throw new ClassError(
1340
+ 'Rental',
1341
+ 'RentalErrMsg01',
1342
+ `Rental already ${this.Status}, please do termination process.`,
1343
+ );
1344
+ }
1345
+
1346
+ if (!remarks) {
1347
+ throw new ClassError(
1348
+ 'Rental',
1349
+ 'RentalErrMsg01',
1350
+ 'Cancellation remarks is required.',
1351
+ );
1352
+ }
1353
+
1354
+ // Part 3: Capture Record Info Before Changes
1355
+ const entityValueBefore = this.toJSON();
1356
+
1357
+ // Part 4: Update Rental Status and Remarks
1358
+ this._Status = RentalStatusEnum.CANCELLED;
1359
+ this.CancelRemarks = remarks;
1360
+ this._UpdatedById = loginUser.ObjectId;
1361
+ this._UpdatedAt = new Date();
1362
+
1363
+ // Part 5: Update Rental Record
1364
+ await Rental._Repo.update(
1365
+ {
1366
+ Status: this.Status,
1367
+ CancelRemarks: this.CancelRemarks,
1368
+ UpdatedById: this.UpdatedById,
1369
+ UpdatedAt: this.UpdatedAt,
1370
+ },
1371
+ {
1372
+ where: {
1373
+ RentalId: this.RentalId,
1374
+ },
1375
+ transaction: dbTransaction,
1376
+ },
1377
+ );
1378
+
1379
+ // Part 6: Mark Item as Available
1380
+ const item = await this.getItem(dbTransaction);
1381
+
1382
+ await item.setAvailable(loginUser, dbTransaction);
1383
+
1384
+ // Part 7: Capture Record Info After Changes
1385
+ const entityValueAfter = this.toJSON();
1386
+ // Part 8: Record Activity
1387
+ const activity = new Activity();
1388
+ activity.ActivityId = activity.createId();
1389
+ activity.Action = ActionEnum.UPDATE;
1390
+ activity.Description = 'Rental Cancellation';
1391
+ activity.EntityType = this.ObjectType;
1392
+ activity.EntityId = this.ObjectId;
1393
+ activity.EntityValueBefore = JSON.stringify(entityValueBefore);
1394
+ activity.EntityValueAfter = JSON.stringify(entityValueAfter);
1395
+ await activity.create(loginUser.ObjectId, dbTransaction);
1396
+ return this;
1397
+ } catch (error) {
1398
+ throw error;
1399
+ }
1400
+ }
1401
+ }