@tomei/sso 0.60.4-staging.1 → 0.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (248) hide show
  1. package/.commitlintrc.json +22 -22
  2. package/.gitlab-ci.yml +16 -16
  3. package/.husky/commit-msg +15 -9
  4. package/.husky/pre-commit +7 -7
  5. package/.prettierrc +4 -4
  6. package/Jenkinsfile +57 -57
  7. package/README.md +23 -23
  8. package/__tests__/unit/components/group/group.spec.ts +79 -79
  9. package/__tests__/unit/components/group-object-privilege/group-object-privilege.spec.ts +88 -88
  10. package/__tests__/unit/components/group-privilege/group-privilege.spec.ts +68 -68
  11. package/__tests__/unit/components/group-reporting-user/group-reporting-user.spec.ts +66 -66
  12. package/__tests__/unit/components/group-system-access/group-system-access.spec.ts +83 -83
  13. package/__tests__/unit/components/login-user/l.spec.ts +746 -746
  14. package/__tests__/unit/components/login-user/login.spec.ts +1164 -1164
  15. package/__tests__/unit/components/password-hash/password-hash.service.spec.ts +31 -31
  16. package/__tests__/unit/components/system/system.spec.ts +254 -254
  17. package/__tests__/unit/components/system-privilege/system-privilege.spec.ts +83 -83
  18. package/__tests__/unit/components/user-group/user-group.spec.ts +86 -86
  19. package/__tests__/unit/components/user-object-privilege/user-object-privilege.spec.ts +78 -78
  20. package/__tests__/unit/components/user-privilege/user-privilege.spec.ts +72 -72
  21. package/__tests__/unit/components/user-system-access/user-system-access.spec.ts +89 -89
  22. package/__tests__/unit/redis-client/redis.service.spec.ts +23 -23
  23. package/__tests__/unit/session/session.service.spec.ts +47 -47
  24. package/__tests__/unit/system-privilege/system-privilage.spec.ts +91 -91
  25. package/coverage/clover.xml +1452 -1452
  26. package/coverage/coverage-final.json +47 -47
  27. package/coverage/lcov-report/base.css +224 -224
  28. package/coverage/lcov-report/block-navigation.js +87 -87
  29. package/coverage/lcov-report/components/group/group.repository.ts.html +117 -117
  30. package/coverage/lcov-report/components/group/group.ts.html +327 -327
  31. package/coverage/lcov-report/components/group/index.html +130 -130
  32. package/coverage/lcov-report/components/group-object-privilege/group-object-privilege.repository.ts.html +117 -117
  33. package/coverage/lcov-report/components/group-object-privilege/group-object-privilege.ts.html +321 -321
  34. package/coverage/lcov-report/components/group-object-privilege/index.html +130 -130
  35. package/coverage/lcov-report/components/group-privilege/group-privilege.repository.ts.html +117 -117
  36. package/coverage/lcov-report/components/group-privilege/group-privilege.ts.html +303 -303
  37. package/coverage/lcov-report/components/group-privilege/index.html +130 -130
  38. package/coverage/lcov-report/components/group-reporting-user/group-reporting-user.repository.ts.html +117 -117
  39. package/coverage/lcov-report/components/group-reporting-user/group-reporting-user.ts.html +327 -327
  40. package/coverage/lcov-report/components/group-reporting-user/index.html +130 -130
  41. package/coverage/lcov-report/components/group-system-access/group-system-access.repository.ts.html +117 -117
  42. package/coverage/lcov-report/components/group-system-access/group-system-access.ts.html +309 -309
  43. package/coverage/lcov-report/components/group-system-access/index.html +130 -130
  44. package/coverage/lcov-report/components/login-history/index.html +115 -115
  45. package/coverage/lcov-report/components/login-history/login-history.repository.ts.html +117 -117
  46. package/coverage/lcov-report/components/login-user/index.html +130 -130
  47. package/coverage/lcov-report/components/login-user/login-user.ts.html +5007 -5007
  48. package/coverage/lcov-report/components/login-user/user.repository.ts.html +117 -117
  49. package/coverage/lcov-report/components/password-hash/index.html +115 -115
  50. package/coverage/lcov-report/components/password-hash/password-hash.service.ts.html +126 -126
  51. package/coverage/lcov-report/components/system/index.html +130 -130
  52. package/coverage/lcov-report/components/system/system.repository.ts.html +117 -117
  53. package/coverage/lcov-report/components/system/system.ts.html +909 -909
  54. package/coverage/lcov-report/components/system-privilege/index.html +130 -130
  55. package/coverage/lcov-report/components/system-privilege/system-privilege.repository.ts.html +120 -120
  56. package/coverage/lcov-report/components/system-privilege/system-privilege.ts.html +390 -390
  57. package/coverage/lcov-report/components/user-group/index.html +130 -130
  58. package/coverage/lcov-report/components/user-group/user-group.repository.ts.html +117 -117
  59. package/coverage/lcov-report/components/user-group/user-group.ts.html +354 -354
  60. package/coverage/lcov-report/components/user-object-privilege/index.html +130 -130
  61. package/coverage/lcov-report/components/user-object-privilege/user-object-privilege.repository.ts.html +117 -117
  62. package/coverage/lcov-report/components/user-object-privilege/user-object-privilege.ts.html +312 -312
  63. package/coverage/lcov-report/components/user-privilege/index.html +130 -130
  64. package/coverage/lcov-report/components/user-privilege/user-privilege.repository.ts.html +117 -117
  65. package/coverage/lcov-report/components/user-privilege/user-privilege.ts.html +306 -306
  66. package/coverage/lcov-report/components/user-system-access/index.html +130 -130
  67. package/coverage/lcov-report/components/user-system-access/user-system-access.repository.ts.html +117 -117
  68. package/coverage/lcov-report/components/user-system-access/user-system-access.ts.html +312 -312
  69. package/coverage/lcov-report/enum/group-type.enum.ts.html +108 -108
  70. package/coverage/lcov-report/enum/index.html +160 -160
  71. package/coverage/lcov-report/enum/index.ts.html +93 -93
  72. package/coverage/lcov-report/enum/user-status.enum.ts.html +105 -105
  73. package/coverage/lcov-report/enum/yn.enum.ts.html +96 -96
  74. package/coverage/lcov-report/index.html +370 -370
  75. package/coverage/lcov-report/models/group-object-privilege.entity.ts.html +333 -333
  76. package/coverage/lcov-report/models/group-privilege.entity.ts.html +315 -315
  77. package/coverage/lcov-report/models/group-reporting-user.entity.ts.html +339 -339
  78. package/coverage/lcov-report/models/group-system-access.entity.ts.html +324 -324
  79. package/coverage/lcov-report/models/group.entity.ts.html +435 -435
  80. package/coverage/lcov-report/models/index.html +310 -310
  81. package/coverage/lcov-report/models/login-history.entity.ts.html +252 -252
  82. package/coverage/lcov-report/models/staff.entity.ts.html +411 -411
  83. package/coverage/lcov-report/models/system-privilege.entity.ts.html +354 -354
  84. package/coverage/lcov-report/models/system.entity.ts.html +423 -423
  85. package/coverage/lcov-report/models/user-group.entity.ts.html +354 -354
  86. package/coverage/lcov-report/models/user-object-privilege.entity.ts.html +330 -330
  87. package/coverage/lcov-report/models/user-privilege.entity.ts.html +315 -315
  88. package/coverage/lcov-report/models/user-system-access.entity.ts.html +315 -315
  89. package/coverage/lcov-report/models/user.entity.ts.html +522 -522
  90. package/coverage/lcov-report/prettify.css +1 -1
  91. package/coverage/lcov-report/prettify.js +2 -2
  92. package/coverage/lcov-report/redis-client/index.html +115 -115
  93. package/coverage/lcov-report/redis-client/redis.service.ts.html +240 -240
  94. package/coverage/lcov-report/session/index.html +115 -115
  95. package/coverage/lcov-report/session/session.service.ts.html +246 -246
  96. package/coverage/lcov-report/sorter.js +196 -196
  97. package/coverage/lcov.info +2490 -2490
  98. package/coverage/test-report.xml +128 -128
  99. package/create-sso-user.sql +39 -39
  100. package/dist/src/components/login-user/user.js +9 -1
  101. package/dist/src/components/login-user/user.js.map +1 -1
  102. package/dist/tsconfig.tsbuildinfo +1 -1
  103. package/eslint.config.mjs +58 -58
  104. package/jest.config.js +14 -14
  105. package/migrations/20240314080602-create-user-table.js +124 -124
  106. package/migrations/20240314080603-create-user-group-table.js +85 -85
  107. package/migrations/20240314080604-create-user-user-group-table.js +55 -55
  108. package/migrations/20240314080605-create-login-history-table.js +53 -53
  109. package/migrations/20240527064925-create-system-table.js +78 -78
  110. package/migrations/20240527064926-create-system-privilege-table.js +71 -71
  111. package/migrations/20240527065342-create-group-table.js +93 -93
  112. package/migrations/20240527065633-create-group-reporting-user-table.js +76 -76
  113. package/migrations/20240528011551-create-group-system-access-table.js +72 -72
  114. package/migrations/20240528023018-user-system-access-table.js +75 -75
  115. package/migrations/20240528032229-user-privilege-table.js +76 -76
  116. package/migrations/20240528063003-create-group-privilege-table.js +76 -76
  117. package/migrations/20240528063051-create-group-object-privilege-table.js +84 -84
  118. package/migrations/20240528063107-create-user-object-privilege-table.js +84 -84
  119. package/migrations/20240528063108-create-api-key-table.js +85 -85
  120. package/migrations/20241104104802-create-building-table.js +95 -95
  121. package/migrations/20250108091132-add-area-manager-user-id-to-building-table.js +14 -14
  122. package/migrations/20250108091133-add-passcode-to-user-table.js +36 -36
  123. package/migrations/20250210115636-create-user-reporting-hierarchy.js +76 -76
  124. package/migrations/20250326043818-crate-user-password-history.js +42 -42
  125. package/package.json +90 -90
  126. package/sampledotenv +7 -7
  127. package/sonar-project.properties +22 -22
  128. package/src/components/api-key/api-key.repository.ts +15 -15
  129. package/src/components/api-key/api-key.ts +448 -448
  130. package/src/components/api-key/index.ts +4 -4
  131. package/src/components/building/building.repository.ts +27 -27
  132. package/src/components/building/index.ts +2 -2
  133. package/src/components/group/group.repository.ts +26 -26
  134. package/src/components/group/group.ts +2284 -2284
  135. package/src/components/group/index.ts +3 -3
  136. package/src/components/group-object-privilege/group-object-privilege.repository.ts +25 -25
  137. package/src/components/group-object-privilege/group-object-privilege.ts +278 -278
  138. package/src/components/group-object-privilege/index.ts +2 -2
  139. package/src/components/group-privilege/group-privilege.repository.ts +29 -29
  140. package/src/components/group-privilege/group-privilege.ts +84 -84
  141. package/src/components/group-privilege/index.ts +2 -2
  142. package/src/components/group-reporting-user/group-reporting-user.repository.ts +23 -23
  143. package/src/components/group-reporting-user/group-reporting-user.ts +506 -506
  144. package/src/components/group-reporting-user/index.ts +3 -3
  145. package/src/components/group-system-access/group-system-access.repository.ts +43 -43
  146. package/src/components/group-system-access/group-system-access.ts +90 -90
  147. package/src/components/group-system-access/index.ts +2 -2
  148. package/src/components/index.ts +20 -20
  149. package/src/components/login-history/index.ts +1 -1
  150. package/src/components/login-history/login-history.repository.ts +11 -11
  151. package/src/components/login-user/index.ts +5 -5
  152. package/src/components/login-user/interfaces/check-user-info-duplicated.interface.ts +7 -7
  153. package/src/components/login-user/interfaces/index.ts +1 -1
  154. package/src/components/login-user/interfaces/system-access.interface.ts +13 -13
  155. package/src/components/login-user/interfaces/user-info.interface.ts +34 -34
  156. package/src/components/login-user/login-user.ts +362 -362
  157. package/src/components/login-user/user.repository.ts +11 -11
  158. package/src/components/login-user/user.ts +3142 -3134
  159. package/src/components/password-hash/index.ts +2 -2
  160. package/src/components/password-hash/interfaces/index.ts +1 -1
  161. package/src/components/password-hash/interfaces/password-hash-service.interface.ts +4 -4
  162. package/src/components/password-hash/password-hash.service.ts +14 -14
  163. package/src/components/staff/index.ts +2 -2
  164. package/src/components/staff/staff.repository.ts +27 -27
  165. package/src/components/system/index.ts +3 -3
  166. package/src/components/system/system.repository.ts +11 -11
  167. package/src/components/system/system.ts +456 -456
  168. package/src/components/system-privilege/index.ts +4 -4
  169. package/src/components/system-privilege/system-privilege.repository.ts +18 -18
  170. package/src/components/system-privilege/system-privilege.ts +541 -541
  171. package/src/components/user-group/index.ts +2 -2
  172. package/src/components/user-group/user-group.repository.ts +19 -19
  173. package/src/components/user-group/user-group.ts +764 -764
  174. package/src/components/user-object-privilege/index.ts +2 -2
  175. package/src/components/user-object-privilege/user-object-privilege.repository.ts +11 -11
  176. package/src/components/user-object-privilege/user-object-privilege.ts +79 -79
  177. package/src/components/user-password-history/index.ts +2 -2
  178. package/src/components/user-password-history/user-password-history.repository.ts +39 -39
  179. package/src/components/user-password-history/user-password-history.ts +187 -187
  180. package/src/components/user-privilege/index.ts +2 -2
  181. package/src/components/user-privilege/user-privilege.repository.ts +25 -25
  182. package/src/components/user-privilege/user-privilege.ts +662 -662
  183. package/src/components/user-reporting-hierarchy/index.ts +2 -2
  184. package/src/components/user-reporting-hierarchy/user-reporting-hierarchy.repository.ts +30 -30
  185. package/src/components/user-reporting-hierarchy/user-reporting-hierarchy.ts +505 -505
  186. package/src/components/user-system-access/index.ts +2 -2
  187. package/src/components/user-system-access/user-system-access.repository.ts +41 -41
  188. package/src/components/user-system-access/user-system-access.ts +717 -717
  189. package/src/database.ts +15 -15
  190. package/src/enum/api-key.enum.ts +5 -5
  191. package/src/enum/building-type.enum.ts +6 -6
  192. package/src/enum/group-type.enum.ts +8 -8
  193. package/src/enum/index.ts +6 -6
  194. package/src/enum/login-status.enum.ts +4 -4
  195. package/src/enum/object-status.enum.ts +4 -4
  196. package/src/enum/user-status.enum.ts +7 -7
  197. package/src/enum/yn.enum.ts +4 -4
  198. package/src/index.ts +8 -8
  199. package/src/interfaces/api-key-attr.interface.ts +16 -16
  200. package/src/interfaces/group-object-privilege.interface.ts +14 -14
  201. package/src/interfaces/group-privilege.interface.ts +10 -10
  202. package/src/interfaces/group-reporting-user.interface.ts +11 -11
  203. package/src/interfaces/group-search-attr.interface.ts +9 -9
  204. package/src/interfaces/group-system-access.interface.ts +10 -10
  205. package/src/interfaces/group.interface.ts +17 -17
  206. package/src/interfaces/index.ts +13 -13
  207. package/src/interfaces/system-login.interface.ts +6 -6
  208. package/src/interfaces/system-privilege-search.interface.ts +5 -5
  209. package/src/interfaces/system-privilege.interface.ts +11 -11
  210. package/src/interfaces/system-search-attr.interface.ts +5 -5
  211. package/src/interfaces/system.interface.ts +15 -15
  212. package/src/interfaces/user-group.interface.ts +12 -12
  213. package/src/interfaces/user-object-privilege.interface.ts +14 -14
  214. package/src/interfaces/user-password-history.interface.ts +6 -6
  215. package/src/interfaces/user-privilege.interface.ts +10 -10
  216. package/src/interfaces/user-reporting-hierarchy.interface.ts +11 -11
  217. package/src/interfaces/user-session.interface.ts +5 -5
  218. package/src/interfaces/user-system-access.interface.ts +10 -10
  219. package/src/models/api-key-entity.ts +101 -101
  220. package/src/models/building.entity.ts +103 -103
  221. package/src/models/group-object-privilege.entity.ts +91 -91
  222. package/src/models/group-privilege.entity.ts +78 -78
  223. package/src/models/group-reporting-user.entity.ts +95 -95
  224. package/src/models/group-system-access.entity.ts +81 -81
  225. package/src/models/group.entity.ts +127 -127
  226. package/src/models/login-history.entity.ts +63 -63
  227. package/src/models/staff.entity.ts +91 -91
  228. package/src/models/system-privilege.entity.ts +90 -90
  229. package/src/models/system.entity.ts +113 -113
  230. package/src/models/user-group.entity.ts +91 -91
  231. package/src/models/user-object-privilege.entity.ts +90 -90
  232. package/src/models/user-password-history.ts +51 -51
  233. package/src/models/user-privilege.entity.ts +78 -78
  234. package/src/models/user-reporting-hierarchy.entity.ts +102 -102
  235. package/src/models/user-system-access.entity.ts +87 -87
  236. package/src/models/user.entity.ts +193 -193
  237. package/src/redis-client/__mocks__/jest-initial-setup.ts +2 -2
  238. package/src/redis-client/__mocks__/redis-mock.ts +28 -28
  239. package/src/redis-client/index.ts +1 -1
  240. package/src/redis-client/redis.service.ts +75 -75
  241. package/src/session/index.ts +2 -2
  242. package/src/session/interfaces/index.ts +1 -1
  243. package/src/session/interfaces/session-service.interface.ts +26 -26
  244. package/src/session/session.service.ts +96 -96
  245. package/src/types/auth-context.ts +10 -10
  246. package/src/types/index.ts +1 -1
  247. package/tsconfig.build.json +5 -5
  248. package/tsconfig.json +23 -23
@@ -1,505 +1,505 @@
1
- import { ClassError, ObjectBase } from '@tomei/general';
2
- import { IUserReportingHierarchyAttr } from '../../interfaces/user-reporting-hierarchy.interface';
3
- import { UserReportingHierarchyRepository } from './user-reporting-hierarchy.repository';
4
- import { User } from '../login-user/user';
5
- import { ApplicationConfig } from '@tomei/config';
6
- import { ActionEnum, Activity } from '@tomei/activity-history';
7
- import { Op } from 'sequelize';
8
-
9
- export class UserReportingHierarchy
10
- extends ObjectBase
11
- implements IUserReportingHierarchyAttr
12
- {
13
- ObjectId: string;
14
- ObjectName: string;
15
- ObjectType = 'UserReportingHierarchy';
16
- TableName = 'sso_UserReportingHierarchy';
17
- ReportingUserId: number;
18
- UserId: number;
19
- Rank: number;
20
- Status: string;
21
- private _CreatedById: number;
22
- private _CreatedAt: Date;
23
- private _UpdatedById: number;
24
- private _UpdatedAt: Date;
25
-
26
- private static _Repo = new UserReportingHierarchyRepository();
27
-
28
- get UserReportingHierarchyId(): number {
29
- return parseInt(this.ObjectId);
30
- }
31
-
32
- set UserReportingHierarchyId(value: number) {
33
- this.ObjectId = value.toString();
34
- }
35
-
36
- get CreatedById(): number {
37
- return this._CreatedById;
38
- }
39
-
40
- get CreatedAt(): Date {
41
- return this._CreatedAt;
42
- }
43
-
44
- get UpdatedById(): number {
45
- return this._UpdatedById;
46
- }
47
-
48
- get UpdatedAt(): Date {
49
- return this._UpdatedAt;
50
- }
51
-
52
- private constructor(params?: IUserReportingHierarchyAttr) {
53
- super();
54
- if (params) {
55
- this.ObjectId = params.UserReportingHierarchyId.toString();
56
- this.ReportingUserId = params.ReportingUserId;
57
- this.UserId = params.UserId;
58
- this.Rank = params.Rank;
59
- this.Status = params.Status;
60
- this._CreatedById = params.CreatedById;
61
- this._CreatedAt = params.CreatedAt;
62
- this._UpdatedById = params.UpdatedById;
63
- this._UpdatedAt = params.UpdatedAt;
64
- }
65
- }
66
-
67
- public static async init(
68
- userReportingHierarchyId?: number,
69
- dbTransaction?: any,
70
- ): Promise<UserReportingHierarchy> {
71
- try {
72
- if (userReportingHierarchyId) {
73
- const data = await UserReportingHierarchy._Repo.findByPk(
74
- userReportingHierarchyId.toString(),
75
- dbTransaction,
76
- );
77
- if (!data) {
78
- throw new ClassError(
79
- 'UserReportingHierarchy',
80
- 'UserReportingHierarchyErrMsg01',
81
- 'UserReportingHierarchy not found',
82
- 'init',
83
- 400,
84
- );
85
- }
86
-
87
- return new UserReportingHierarchy(data.get({ plain: true }));
88
- }
89
- return new UserReportingHierarchy();
90
- } catch (error) {
91
- throw error;
92
- }
93
- }
94
-
95
- async createUserReportingHierarchy(
96
- loginUser: User, //The user performing the operation(typically the logged -in user).
97
- dbTransaction: any, //Database transaction object to ensure the operation is atomic.
98
- reportingUserId: number, //The ID of the user who will do the reporting.
99
- userId: number, //The Id of the user who need to be reported to.
100
- rank: number, //The rank to be assigned to the user.
101
- status: 'Active' | 'Inactive', //The initial status of relationship.
102
- ): Promise<UserReportingHierarchy> {
103
- // Returns a ReportingUserHierarchy instance representing the newly created record.
104
- try {
105
- //Creates a new User Reporting Hierarchy entry in the sso_UserReportingHierarchy table.
106
-
107
- // Privilege Checking
108
- // Call the loginUser.checkPrivileges() method by passing:
109
- // SystemCode: Retrieve from app config.
110
- // PrivilegeCode: "GROUP_REPORTING_USER_CREATE".
111
- const systemCode =
112
- ApplicationConfig.getComponentConfigValue('system-code');
113
- const isPrivileged = await loginUser.checkPrivileges(
114
- systemCode,
115
- 'USER_REPORTING_HIERARCHY_CREATE',
116
- );
117
- if (!isPrivileged) {
118
- throw new ClassError(
119
- 'UserReportingHierarchy',
120
- 'UserReportingHierarchyErrMsg02',
121
- 'User does not have the required privileges',
122
- 'createUserReportingHierarchy',
123
- 403,
124
- );
125
- }
126
-
127
- // Validate Input Parameters
128
- // Ensure userId exists in the sso_User table by calling the User.init() method.
129
- await User.init(dbTransaction, userId);
130
- await User.init(dbTransaction, reportingUserId);
131
-
132
- // Query the sso_UserReportingHierarchy table to see if the relationship is already defined for the user.
133
- let userReportingHierarchy = await UserReportingHierarchy._Repo.findOne({
134
- where: {
135
- ReportingUserId: reportingUserId,
136
- UserId: userId,
137
- },
138
- transaction: dbTransaction,
139
- });
140
- // If the record already exists, throw an error.
141
- if (userReportingHierarchy) {
142
- throw new ClassError(
143
- 'UserReportingHierarchy',
144
- 'UserReportingHierarchyErrMsg03',
145
- 'Relationship already exists',
146
- 'createUserReportingHierarchy',
147
- 400,
148
- );
149
- }
150
- //Query the sso_UserReportingHierarchy table to see if the rank already exists for the reporting user.
151
- //If the rank already exists, throw an error indicating the rank is already exist.
152
- userReportingHierarchy = await UserReportingHierarchy._Repo.findOne({
153
- where: {
154
- ReportingUserId: reportingUserId,
155
- Rank: rank,
156
- },
157
- transaction: dbTransaction,
158
- });
159
- if (userReportingHierarchy) {
160
- throw new ClassError(
161
- 'UserReportingHierarchy',
162
- 'UserReportingHierarchyErrMsg04',
163
- 'Rank already exists',
164
- 'createUserReportingHierarchy',
165
- 400,
166
- );
167
- }
168
-
169
- //Check if one rank before the new rank is not already assigned to the user, if not throw an error
170
- if (rank > 1) {
171
- const userReportingHierarchyBefore =
172
- await UserReportingHierarchy._Repo.findOne({
173
- where: {
174
- ReportingUserId: reportingUserId,
175
- Rank: rank - 1,
176
- },
177
- transaction: dbTransaction,
178
- });
179
-
180
- if (!userReportingHierarchyBefore) {
181
- throw new ClassError(
182
- 'UserReportingHierarchy',
183
- 'UserReportingHierarchyErrMsg05',
184
- 'Rank before the new rank is not yet assigned to the user',
185
- 'createUserReportingHierarchy',
186
- 400,
187
- );
188
- }
189
- }
190
-
191
- // Create ReportingUserHierarchy Entry
192
- // If validation and privilege checks pass, insert a new record in the sso_UserReportingHierarchy table
193
- this.ReportingUserId = reportingUserId;
194
- this.UserId = userId;
195
- this.Rank = rank;
196
- this.Status = status;
197
- this._CreatedById = loginUser.UserId;
198
- this._CreatedAt = new Date();
199
- this._UpdatedAt = new Date();
200
- this._UpdatedById = loginUser.UserId;
201
-
202
- const entityValueAfter: any = {
203
- ReportingUserId: reportingUserId,
204
- UserId: userId,
205
- Rank: rank,
206
- Status: status,
207
- CreatedById: loginUser.UserId,
208
- CreatedAt: this._CreatedAt,
209
- UpdatedById: loginUser.UserId,
210
- UpdatedAt: this._UpdatedAt,
211
- };
212
-
213
- userReportingHierarchy = await UserReportingHierarchy._Repo.create(
214
- entityValueAfter,
215
- {
216
- transaction: dbTransaction,
217
- },
218
- );
219
-
220
- entityValueAfter.UserReportingHierarchyId =
221
- userReportingHierarchy.UserReportingHierarchyId;
222
-
223
- // Record Create Activity
224
- // Instantiate a new activity from the Activity class, and set:\
225
- // ActivityId: activity.createId()
226
- // Action: ActionEnum.Create
227
- // Description: Create User Reporting Hierarchy
228
- // EntityType: ReportingUserHierarchy
229
- // EntityId: newReportingUserHierarchy.ReportingUserHierarchyId
230
- // EntityValueBefore: Stringified empty object({})
231
- // EntityValueAfter: EntityValueAfter(stringified representation of the newly created entity)
232
- const activity = new Activity();
233
- activity.ActivityId = activity.createId();
234
- activity.Action = ActionEnum.CREATE;
235
- activity.Description = 'Create User Reporting Hierarchy';
236
- activity.EntityType = 'UserReportingHierarchy';
237
- activity.EntityId =
238
- userReportingHierarchy.UserReportingHierarchyId.toString();
239
- activity.EntityValueBefore = JSON.stringify({});
240
- activity.EntityValueAfter = JSON.stringify(entityValueAfter);
241
- // Call the activity create() method by passing:
242
- // dbTransaction
243
- // userId: loginUser.UserId
244
- await activity.create(loginUser.ObjectId, dbTransaction);
245
- // Return the Created ReportingUserHierarchy
246
- // Return the newly created ReportingUserHierarchy instance
247
- return this;
248
- } catch (error) {
249
- throw error;
250
- }
251
- }
252
-
253
- async updateUserReportingHierarchy(
254
- loginUser: User, //The user performing the operation(typically the logged -in user).
255
- dbTransaction: any, //Database transaction object to ensure the operation is atomic.
256
- reportingUserId: number, //The ID of the user who will do the reporting.
257
- userId: number, //The ID of the user who need to be reported to.
258
- rank: number, //The rank to be assigned to the user.
259
- status: 'Active' | 'Inactive', //The initial status of the user.
260
- ): Promise<UserReportingHierarchy> {
261
- // Returns a ReportingUserHierarchy instance representing the updated record.
262
- try {
263
- //Update a User Reporting Hierarchy entry in the sso_UserReportingHierarchy table.
264
-
265
- // Validate Input Parameters
266
- // Ensure userId exists in the sso_User table by calling the User.init() method.
267
- await User.init(dbTransaction, userId);
268
- await User.init(dbTransaction, reportingUserId);
269
- // Privilege Checking
270
- // Call the loginUser.checkPrivileges() method by passing:
271
- // SystemCode: Retrieve from app config.
272
- // PrivilegeCode: "GROUP_REPORTING_USER_UPDATE".
273
- const systemCode =
274
- ApplicationConfig.getComponentConfigValue('system-code');
275
- const isPrivileged = await loginUser.checkPrivileges(
276
- systemCode,
277
- 'USER_REPORTING_HIERARCHY_UPDATE',
278
- );
279
- if (!isPrivileged) {
280
- throw new ClassError(
281
- 'UserReportingHierarchy',
282
- 'UserReportingHierarchyErrMsg02',
283
- 'User does not have the required privileges',
284
- 'updateUserReportingHierarchy',
285
- 403,
286
- );
287
- }
288
-
289
- // Query the sso_UserReportingHierarchy table to see if the userId already exists.
290
- const userReportingHierarchy = await UserReportingHierarchy._Repo.findOne(
291
- {
292
- where: {
293
- ReportingUserId: reportingUserId,
294
- UserId: userId,
295
- UserReportingHierarchyId: {
296
- [Op.ne]: this.UserReportingHierarchyId,
297
- },
298
- },
299
- transaction: dbTransaction,
300
- },
301
- );
302
- // If the user already exists, throw an error indicating the reporting user is already part of reporting hierarchy.
303
- if (userReportingHierarchy) {
304
- throw new ClassError(
305
- 'UserReportingHierarchy',
306
- 'UserReportingHierarchyErrMsg03',
307
- 'Relationship already exists',
308
- 'updateUserReportingHierarchy',
309
- );
310
- }
311
- //Query the sso_UserReportingHierarchy table to see if the rank already exists in the specified groupCode.
312
- //If the rank already exists, throw an error indicating the rank is already in part of reporting hierarchy.
313
- const userReportingRank = await UserReportingHierarchy._Repo.findOne({
314
- where: {
315
- ReportingUserId: reportingUserId,
316
- Rank: rank,
317
- UserReportingHierarchyId: {
318
- [Op.ne]: this.UserReportingHierarchyId,
319
- },
320
- },
321
- transaction: dbTransaction,
322
- });
323
- if (userReportingRank) {
324
- throw new ClassError(
325
- 'UserReportingHierarchy',
326
- 'UserReportingHierarchyErrMsg04',
327
- 'Rank already exists',
328
- 'updateUserReportingHierarchy',
329
- );
330
- }
331
-
332
- //Check if rank before the new rank is not already assigned to the user
333
- if (rank > 1) {
334
- const userReportingRankBefore =
335
- await UserReportingHierarchy._Repo.findOne({
336
- where: {
337
- ReportingUserId: reportingUserId,
338
- Rank: rank - 1,
339
- UserReportingHierarchyId: {
340
- [Op.ne]: this.UserReportingHierarchyId,
341
- },
342
- },
343
- transaction: dbTransaction,
344
- });
345
-
346
- if (!userReportingRankBefore) {
347
- throw new ClassError(
348
- 'UserReportingHierarchy',
349
- 'UserReportingHierarchyErrMsg05',
350
- 'Rank before the new rank is not yet assigned to the user',
351
- 'updateUserReportingHierarchy',
352
- );
353
- }
354
- }
355
-
356
- // UPDATE ReportingUserHierarchy Entry
357
- // If validation and privilege checks pass, insert a new record in the sso_UserReportingHierarchy table.
358
- const entityValueBefore: any = {
359
- UserReportingHierarchyId: this.UserReportingHierarchyId,
360
- ReportingUserId: this.ReportingUserId,
361
- UserId: this.UserId,
362
- Rank: this.Rank,
363
- Status: this.Status,
364
- CreatedById: this._CreatedById,
365
- CreatedAt: this._CreatedAt,
366
- UpdatedById: this._UpdatedById,
367
- UpdatedAt: this._UpdatedAt,
368
- };
369
-
370
- this.ReportingUserId = reportingUserId;
371
- this.UserId = userId;
372
- this.Rank = rank;
373
- this.Status = status;
374
- this._CreatedById = this.CreatedById;
375
- this._CreatedAt = this.CreatedAt;
376
- this._UpdatedAt = new Date();
377
- this._UpdatedById = loginUser.UserId;
378
-
379
- const entityValueAfter: any = {
380
- ReportingUserId: reportingUserId,
381
- UserId: userId,
382
- Rank: rank,
383
- Status: status,
384
- CreatedById: this.CreatedById,
385
- CreatedAt: this._CreatedAt,
386
- UpdatedById: loginUser.UserId,
387
- UpdatedAt: this._UpdatedAt,
388
- };
389
-
390
- await UserReportingHierarchy._Repo.update(entityValueAfter, {
391
- where: {
392
- UserReportingHierarchyId: this.UserReportingHierarchyId,
393
- },
394
- transaction: dbTransaction,
395
- });
396
-
397
- // Record Update Activity
398
- // Instantiate a new activity from the Activity class, and set:\
399
- // ActivityId: activity.createId()
400
- // Action: ActionEnum.Update
401
- // Description: Update User Reporting Hierarchy
402
- // EntityType: ReportingUserHierarchy
403
- // EntityId: newReportingUserHierarchy.ReportingUserHierarchyId
404
- // EntityValueBefore: Stringified empty object({})
405
- // EntityValueAfter: EntityValueAfter(stringified representation of the newly created entity)
406
- const activity = new Activity();
407
- activity.ActivityId = activity.createId();
408
- activity.Action = ActionEnum.UPDATE;
409
- activity.Description = 'Update User Reporting Hierarchy';
410
- activity.EntityType = 'UserReportingHierarchy';
411
- activity.EntityId = this.UserReportingHierarchyId.toString();
412
- activity.EntityValueBefore = JSON.stringify(entityValueBefore);
413
- activity.EntityValueAfter = JSON.stringify(entityValueAfter);
414
- // Call the activity create() method by passing:
415
- // dbTransaction
416
- // userId: loginUser.UserId
417
- await activity.create(loginUser.ObjectId, dbTransaction);
418
- // Return the Updated ReportingUserHierarchy
419
- // Return the updated ReportingUserHierarchy instance, including all the relevant details like ReportingUserHierarchyId, groupCode, userId, rank, status, and timestamps for CreatedAt.
420
- return this;
421
- } catch (error) {
422
- throw error;
423
- }
424
- }
425
-
426
- public static async removeUserReportingHierarchy(
427
- loginUser: User, //The user performing the operation, used for privilege checking and logging.
428
- dbTransaction: any, // The database transaction object to ensure the operation's atomicity.
429
- userReportingHierarchyId: number, //The ID of the UserReportingHierarchy to be removed.
430
- ): Promise<void> {
431
- // This method removes a UserReportingHierarchy record from the database.
432
- try {
433
- // Part 1: Privilege Checking
434
- // Call loginUser.checkPrivileges() method by passing:
435
- // SystemCode: Retrieve from app config.
436
- // PrivilegeCode: "USER_REPORTING_HIERARCHY_REMOVE".
437
- const systemCode =
438
- ApplicationConfig.getComponentConfigValue('system-code');
439
- const isPrivileged = await loginUser.checkPrivileges(
440
- systemCode,
441
- 'USER_REPORTING_HIERARCHY_REMOVE',
442
- );
443
- if (!isPrivileged) {
444
- throw new ClassError(
445
- 'UserReportingHierarchy',
446
- 'UserReportingHierarchyErrMsg06',
447
- 'Insufficient privileges to remove reporting hierarchy',
448
- 'removeUserReportingHierarchy',
449
- 403,
450
- );
451
- }
452
-
453
- // Part 2: Find User
454
- // Call UserReportingHierarchy.init(dbTransaction, UserReportingHierarchyId) to check if the user exists.
455
- const userReportingHierarchy = await UserReportingHierarchy.init(
456
- userReportingHierarchyId,
457
- dbTransaction,
458
- );
459
-
460
- // Part 3: Remove User
461
- // Call UserReportingHierarchy._Repo.destroy({ where: { UserReportingHierarchyId: UserReportingHierarchyId }, transaction: dbTransaction }) to remove the user from the database.
462
- await UserReportingHierarchy._Repo.destroy(
463
- userReportingHierarchyId,
464
- dbTransaction,
465
- );
466
-
467
- // Part 4: Record Create Activity
468
- // Initialise EntityValueBefore variable and set it to the UserReportingHierarchy instance before destruction.
469
- const entityValueBefore = {
470
- UserReportingHierarchyId:
471
- userReportingHierarchy.UserReportingHierarchyId,
472
- ReportingUserId: userReportingHierarchy.ReportingUserId,
473
- UserId: userReportingHierarchy.UserId,
474
- Rank: userReportingHierarchy.Rank,
475
- Status: userReportingHierarchy.Status,
476
- CreatedById: userReportingHierarchy.CreatedById,
477
- CreatedAt: userReportingHierarchy.CreatedAt,
478
- UpdatedById: userReportingHierarchy.UpdatedById,
479
- UpdatedAt: userReportingHierarchy.UpdatedAt,
480
- };
481
- // Instantiate a new activity from the Activity class, and set:
482
- const activity = new Activity();
483
- // ActivityId: activity.createId()
484
- // Action: ActionEnum.Delete
485
- // Description: Remove User Reporting Hierarchy
486
- // EntityType: UserReportingHierarchy
487
- // EntityId: userReportingHierarchyId
488
- // EntityValueBefore: Stringified representation of the UserReportingHierarchy instance before destroy
489
- // EntityValueAfter: Stringified empty object ({})
490
- activity.ActivityId = activity.createId();
491
- activity.Action = ActionEnum.DELETE;
492
- activity.Description = 'Remove User Reporting Hierarchy';
493
- activity.EntityType = 'UserReportingHierarchy';
494
- activity.EntityId = userReportingHierarchy.toString();
495
- activity.EntityValueBefore = JSON.stringify(entityValueBefore);
496
- activity.EntityValueAfter = JSON.stringify({});
497
- // Call the activity.create() method by passing:
498
- // dbTransaction
499
- // userId: loginUser.UserId
500
- await activity.create(loginUser.ObjectId, dbTransaction);
501
- } catch (error) {
502
- throw error;
503
- }
504
- }
505
- }
1
+ import { ClassError, ObjectBase } from '@tomei/general';
2
+ import { IUserReportingHierarchyAttr } from '../../interfaces/user-reporting-hierarchy.interface';
3
+ import { UserReportingHierarchyRepository } from './user-reporting-hierarchy.repository';
4
+ import { User } from '../login-user/user';
5
+ import { ApplicationConfig } from '@tomei/config';
6
+ import { ActionEnum, Activity } from '@tomei/activity-history';
7
+ import { Op } from 'sequelize';
8
+
9
+ export class UserReportingHierarchy
10
+ extends ObjectBase
11
+ implements IUserReportingHierarchyAttr
12
+ {
13
+ ObjectId: string;
14
+ ObjectName: string;
15
+ ObjectType = 'UserReportingHierarchy';
16
+ TableName = 'sso_UserReportingHierarchy';
17
+ ReportingUserId: number;
18
+ UserId: number;
19
+ Rank: number;
20
+ Status: string;
21
+ private _CreatedById: number;
22
+ private _CreatedAt: Date;
23
+ private _UpdatedById: number;
24
+ private _UpdatedAt: Date;
25
+
26
+ private static _Repo = new UserReportingHierarchyRepository();
27
+
28
+ get UserReportingHierarchyId(): number {
29
+ return parseInt(this.ObjectId);
30
+ }
31
+
32
+ set UserReportingHierarchyId(value: number) {
33
+ this.ObjectId = value.toString();
34
+ }
35
+
36
+ get CreatedById(): number {
37
+ return this._CreatedById;
38
+ }
39
+
40
+ get CreatedAt(): Date {
41
+ return this._CreatedAt;
42
+ }
43
+
44
+ get UpdatedById(): number {
45
+ return this._UpdatedById;
46
+ }
47
+
48
+ get UpdatedAt(): Date {
49
+ return this._UpdatedAt;
50
+ }
51
+
52
+ private constructor(params?: IUserReportingHierarchyAttr) {
53
+ super();
54
+ if (params) {
55
+ this.ObjectId = params.UserReportingHierarchyId.toString();
56
+ this.ReportingUserId = params.ReportingUserId;
57
+ this.UserId = params.UserId;
58
+ this.Rank = params.Rank;
59
+ this.Status = params.Status;
60
+ this._CreatedById = params.CreatedById;
61
+ this._CreatedAt = params.CreatedAt;
62
+ this._UpdatedById = params.UpdatedById;
63
+ this._UpdatedAt = params.UpdatedAt;
64
+ }
65
+ }
66
+
67
+ public static async init(
68
+ userReportingHierarchyId?: number,
69
+ dbTransaction?: any,
70
+ ): Promise<UserReportingHierarchy> {
71
+ try {
72
+ if (userReportingHierarchyId) {
73
+ const data = await UserReportingHierarchy._Repo.findByPk(
74
+ userReportingHierarchyId.toString(),
75
+ dbTransaction,
76
+ );
77
+ if (!data) {
78
+ throw new ClassError(
79
+ 'UserReportingHierarchy',
80
+ 'UserReportingHierarchyErrMsg01',
81
+ 'UserReportingHierarchy not found',
82
+ 'init',
83
+ 400,
84
+ );
85
+ }
86
+
87
+ return new UserReportingHierarchy(data.get({ plain: true }));
88
+ }
89
+ return new UserReportingHierarchy();
90
+ } catch (error) {
91
+ throw error;
92
+ }
93
+ }
94
+
95
+ async createUserReportingHierarchy(
96
+ loginUser: User, //The user performing the operation(typically the logged -in user).
97
+ dbTransaction: any, //Database transaction object to ensure the operation is atomic.
98
+ reportingUserId: number, //The ID of the user who will do the reporting.
99
+ userId: number, //The Id of the user who need to be reported to.
100
+ rank: number, //The rank to be assigned to the user.
101
+ status: 'Active' | 'Inactive', //The initial status of relationship.
102
+ ): Promise<UserReportingHierarchy> {
103
+ // Returns a ReportingUserHierarchy instance representing the newly created record.
104
+ try {
105
+ //Creates a new User Reporting Hierarchy entry in the sso_UserReportingHierarchy table.
106
+
107
+ // Privilege Checking
108
+ // Call the loginUser.checkPrivileges() method by passing:
109
+ // SystemCode: Retrieve from app config.
110
+ // PrivilegeCode: "GROUP_REPORTING_USER_CREATE".
111
+ const systemCode =
112
+ ApplicationConfig.getComponentConfigValue('system-code');
113
+ const isPrivileged = await loginUser.checkPrivileges(
114
+ systemCode,
115
+ 'USER_REPORTING_HIERARCHY_CREATE',
116
+ );
117
+ if (!isPrivileged) {
118
+ throw new ClassError(
119
+ 'UserReportingHierarchy',
120
+ 'UserReportingHierarchyErrMsg02',
121
+ 'User does not have the required privileges',
122
+ 'createUserReportingHierarchy',
123
+ 403,
124
+ );
125
+ }
126
+
127
+ // Validate Input Parameters
128
+ // Ensure userId exists in the sso_User table by calling the User.init() method.
129
+ await User.init(dbTransaction, userId);
130
+ await User.init(dbTransaction, reportingUserId);
131
+
132
+ // Query the sso_UserReportingHierarchy table to see if the relationship is already defined for the user.
133
+ let userReportingHierarchy = await UserReportingHierarchy._Repo.findOne({
134
+ where: {
135
+ ReportingUserId: reportingUserId,
136
+ UserId: userId,
137
+ },
138
+ transaction: dbTransaction,
139
+ });
140
+ // If the record already exists, throw an error.
141
+ if (userReportingHierarchy) {
142
+ throw new ClassError(
143
+ 'UserReportingHierarchy',
144
+ 'UserReportingHierarchyErrMsg03',
145
+ 'Relationship already exists',
146
+ 'createUserReportingHierarchy',
147
+ 400,
148
+ );
149
+ }
150
+ //Query the sso_UserReportingHierarchy table to see if the rank already exists for the reporting user.
151
+ //If the rank already exists, throw an error indicating the rank is already exist.
152
+ userReportingHierarchy = await UserReportingHierarchy._Repo.findOne({
153
+ where: {
154
+ ReportingUserId: reportingUserId,
155
+ Rank: rank,
156
+ },
157
+ transaction: dbTransaction,
158
+ });
159
+ if (userReportingHierarchy) {
160
+ throw new ClassError(
161
+ 'UserReportingHierarchy',
162
+ 'UserReportingHierarchyErrMsg04',
163
+ 'Rank already exists',
164
+ 'createUserReportingHierarchy',
165
+ 400,
166
+ );
167
+ }
168
+
169
+ //Check if one rank before the new rank is not already assigned to the user, if not throw an error
170
+ if (rank > 1) {
171
+ const userReportingHierarchyBefore =
172
+ await UserReportingHierarchy._Repo.findOne({
173
+ where: {
174
+ ReportingUserId: reportingUserId,
175
+ Rank: rank - 1,
176
+ },
177
+ transaction: dbTransaction,
178
+ });
179
+
180
+ if (!userReportingHierarchyBefore) {
181
+ throw new ClassError(
182
+ 'UserReportingHierarchy',
183
+ 'UserReportingHierarchyErrMsg05',
184
+ 'Rank before the new rank is not yet assigned to the user',
185
+ 'createUserReportingHierarchy',
186
+ 400,
187
+ );
188
+ }
189
+ }
190
+
191
+ // Create ReportingUserHierarchy Entry
192
+ // If validation and privilege checks pass, insert a new record in the sso_UserReportingHierarchy table
193
+ this.ReportingUserId = reportingUserId;
194
+ this.UserId = userId;
195
+ this.Rank = rank;
196
+ this.Status = status;
197
+ this._CreatedById = loginUser.UserId;
198
+ this._CreatedAt = new Date();
199
+ this._UpdatedAt = new Date();
200
+ this._UpdatedById = loginUser.UserId;
201
+
202
+ const entityValueAfter: any = {
203
+ ReportingUserId: reportingUserId,
204
+ UserId: userId,
205
+ Rank: rank,
206
+ Status: status,
207
+ CreatedById: loginUser.UserId,
208
+ CreatedAt: this._CreatedAt,
209
+ UpdatedById: loginUser.UserId,
210
+ UpdatedAt: this._UpdatedAt,
211
+ };
212
+
213
+ userReportingHierarchy = await UserReportingHierarchy._Repo.create(
214
+ entityValueAfter,
215
+ {
216
+ transaction: dbTransaction,
217
+ },
218
+ );
219
+
220
+ entityValueAfter.UserReportingHierarchyId =
221
+ userReportingHierarchy.UserReportingHierarchyId;
222
+
223
+ // Record Create Activity
224
+ // Instantiate a new activity from the Activity class, and set:\
225
+ // ActivityId: activity.createId()
226
+ // Action: ActionEnum.Create
227
+ // Description: Create User Reporting Hierarchy
228
+ // EntityType: ReportingUserHierarchy
229
+ // EntityId: newReportingUserHierarchy.ReportingUserHierarchyId
230
+ // EntityValueBefore: Stringified empty object({})
231
+ // EntityValueAfter: EntityValueAfter(stringified representation of the newly created entity)
232
+ const activity = new Activity();
233
+ activity.ActivityId = activity.createId();
234
+ activity.Action = ActionEnum.CREATE;
235
+ activity.Description = 'Create User Reporting Hierarchy';
236
+ activity.EntityType = 'UserReportingHierarchy';
237
+ activity.EntityId =
238
+ userReportingHierarchy.UserReportingHierarchyId.toString();
239
+ activity.EntityValueBefore = JSON.stringify({});
240
+ activity.EntityValueAfter = JSON.stringify(entityValueAfter);
241
+ // Call the activity create() method by passing:
242
+ // dbTransaction
243
+ // userId: loginUser.UserId
244
+ await activity.create(loginUser.ObjectId, dbTransaction);
245
+ // Return the Created ReportingUserHierarchy
246
+ // Return the newly created ReportingUserHierarchy instance
247
+ return this;
248
+ } catch (error) {
249
+ throw error;
250
+ }
251
+ }
252
+
253
+ async updateUserReportingHierarchy(
254
+ loginUser: User, //The user performing the operation(typically the logged -in user).
255
+ dbTransaction: any, //Database transaction object to ensure the operation is atomic.
256
+ reportingUserId: number, //The ID of the user who will do the reporting.
257
+ userId: number, //The ID of the user who need to be reported to.
258
+ rank: number, //The rank to be assigned to the user.
259
+ status: 'Active' | 'Inactive', //The initial status of the user.
260
+ ): Promise<UserReportingHierarchy> {
261
+ // Returns a ReportingUserHierarchy instance representing the updated record.
262
+ try {
263
+ //Update a User Reporting Hierarchy entry in the sso_UserReportingHierarchy table.
264
+
265
+ // Validate Input Parameters
266
+ // Ensure userId exists in the sso_User table by calling the User.init() method.
267
+ await User.init(dbTransaction, userId);
268
+ await User.init(dbTransaction, reportingUserId);
269
+ // Privilege Checking
270
+ // Call the loginUser.checkPrivileges() method by passing:
271
+ // SystemCode: Retrieve from app config.
272
+ // PrivilegeCode: "GROUP_REPORTING_USER_UPDATE".
273
+ const systemCode =
274
+ ApplicationConfig.getComponentConfigValue('system-code');
275
+ const isPrivileged = await loginUser.checkPrivileges(
276
+ systemCode,
277
+ 'USER_REPORTING_HIERARCHY_UPDATE',
278
+ );
279
+ if (!isPrivileged) {
280
+ throw new ClassError(
281
+ 'UserReportingHierarchy',
282
+ 'UserReportingHierarchyErrMsg02',
283
+ 'User does not have the required privileges',
284
+ 'updateUserReportingHierarchy',
285
+ 403,
286
+ );
287
+ }
288
+
289
+ // Query the sso_UserReportingHierarchy table to see if the userId already exists.
290
+ const userReportingHierarchy = await UserReportingHierarchy._Repo.findOne(
291
+ {
292
+ where: {
293
+ ReportingUserId: reportingUserId,
294
+ UserId: userId,
295
+ UserReportingHierarchyId: {
296
+ [Op.ne]: this.UserReportingHierarchyId,
297
+ },
298
+ },
299
+ transaction: dbTransaction,
300
+ },
301
+ );
302
+ // If the user already exists, throw an error indicating the reporting user is already part of reporting hierarchy.
303
+ if (userReportingHierarchy) {
304
+ throw new ClassError(
305
+ 'UserReportingHierarchy',
306
+ 'UserReportingHierarchyErrMsg03',
307
+ 'Relationship already exists',
308
+ 'updateUserReportingHierarchy',
309
+ );
310
+ }
311
+ //Query the sso_UserReportingHierarchy table to see if the rank already exists in the specified groupCode.
312
+ //If the rank already exists, throw an error indicating the rank is already in part of reporting hierarchy.
313
+ const userReportingRank = await UserReportingHierarchy._Repo.findOne({
314
+ where: {
315
+ ReportingUserId: reportingUserId,
316
+ Rank: rank,
317
+ UserReportingHierarchyId: {
318
+ [Op.ne]: this.UserReportingHierarchyId,
319
+ },
320
+ },
321
+ transaction: dbTransaction,
322
+ });
323
+ if (userReportingRank) {
324
+ throw new ClassError(
325
+ 'UserReportingHierarchy',
326
+ 'UserReportingHierarchyErrMsg04',
327
+ 'Rank already exists',
328
+ 'updateUserReportingHierarchy',
329
+ );
330
+ }
331
+
332
+ //Check if rank before the new rank is not already assigned to the user
333
+ if (rank > 1) {
334
+ const userReportingRankBefore =
335
+ await UserReportingHierarchy._Repo.findOne({
336
+ where: {
337
+ ReportingUserId: reportingUserId,
338
+ Rank: rank - 1,
339
+ UserReportingHierarchyId: {
340
+ [Op.ne]: this.UserReportingHierarchyId,
341
+ },
342
+ },
343
+ transaction: dbTransaction,
344
+ });
345
+
346
+ if (!userReportingRankBefore) {
347
+ throw new ClassError(
348
+ 'UserReportingHierarchy',
349
+ 'UserReportingHierarchyErrMsg05',
350
+ 'Rank before the new rank is not yet assigned to the user',
351
+ 'updateUserReportingHierarchy',
352
+ );
353
+ }
354
+ }
355
+
356
+ // UPDATE ReportingUserHierarchy Entry
357
+ // If validation and privilege checks pass, insert a new record in the sso_UserReportingHierarchy table.
358
+ const entityValueBefore: any = {
359
+ UserReportingHierarchyId: this.UserReportingHierarchyId,
360
+ ReportingUserId: this.ReportingUserId,
361
+ UserId: this.UserId,
362
+ Rank: this.Rank,
363
+ Status: this.Status,
364
+ CreatedById: this._CreatedById,
365
+ CreatedAt: this._CreatedAt,
366
+ UpdatedById: this._UpdatedById,
367
+ UpdatedAt: this._UpdatedAt,
368
+ };
369
+
370
+ this.ReportingUserId = reportingUserId;
371
+ this.UserId = userId;
372
+ this.Rank = rank;
373
+ this.Status = status;
374
+ this._CreatedById = this.CreatedById;
375
+ this._CreatedAt = this.CreatedAt;
376
+ this._UpdatedAt = new Date();
377
+ this._UpdatedById = loginUser.UserId;
378
+
379
+ const entityValueAfter: any = {
380
+ ReportingUserId: reportingUserId,
381
+ UserId: userId,
382
+ Rank: rank,
383
+ Status: status,
384
+ CreatedById: this.CreatedById,
385
+ CreatedAt: this._CreatedAt,
386
+ UpdatedById: loginUser.UserId,
387
+ UpdatedAt: this._UpdatedAt,
388
+ };
389
+
390
+ await UserReportingHierarchy._Repo.update(entityValueAfter, {
391
+ where: {
392
+ UserReportingHierarchyId: this.UserReportingHierarchyId,
393
+ },
394
+ transaction: dbTransaction,
395
+ });
396
+
397
+ // Record Update Activity
398
+ // Instantiate a new activity from the Activity class, and set:\
399
+ // ActivityId: activity.createId()
400
+ // Action: ActionEnum.Update
401
+ // Description: Update User Reporting Hierarchy
402
+ // EntityType: ReportingUserHierarchy
403
+ // EntityId: newReportingUserHierarchy.ReportingUserHierarchyId
404
+ // EntityValueBefore: Stringified empty object({})
405
+ // EntityValueAfter: EntityValueAfter(stringified representation of the newly created entity)
406
+ const activity = new Activity();
407
+ activity.ActivityId = activity.createId();
408
+ activity.Action = ActionEnum.UPDATE;
409
+ activity.Description = 'Update User Reporting Hierarchy';
410
+ activity.EntityType = 'UserReportingHierarchy';
411
+ activity.EntityId = this.UserReportingHierarchyId.toString();
412
+ activity.EntityValueBefore = JSON.stringify(entityValueBefore);
413
+ activity.EntityValueAfter = JSON.stringify(entityValueAfter);
414
+ // Call the activity create() method by passing:
415
+ // dbTransaction
416
+ // userId: loginUser.UserId
417
+ await activity.create(loginUser.ObjectId, dbTransaction);
418
+ // Return the Updated ReportingUserHierarchy
419
+ // Return the updated ReportingUserHierarchy instance, including all the relevant details like ReportingUserHierarchyId, groupCode, userId, rank, status, and timestamps for CreatedAt.
420
+ return this;
421
+ } catch (error) {
422
+ throw error;
423
+ }
424
+ }
425
+
426
+ public static async removeUserReportingHierarchy(
427
+ loginUser: User, //The user performing the operation, used for privilege checking and logging.
428
+ dbTransaction: any, // The database transaction object to ensure the operation's atomicity.
429
+ userReportingHierarchyId: number, //The ID of the UserReportingHierarchy to be removed.
430
+ ): Promise<void> {
431
+ // This method removes a UserReportingHierarchy record from the database.
432
+ try {
433
+ // Part 1: Privilege Checking
434
+ // Call loginUser.checkPrivileges() method by passing:
435
+ // SystemCode: Retrieve from app config.
436
+ // PrivilegeCode: "USER_REPORTING_HIERARCHY_REMOVE".
437
+ const systemCode =
438
+ ApplicationConfig.getComponentConfigValue('system-code');
439
+ const isPrivileged = await loginUser.checkPrivileges(
440
+ systemCode,
441
+ 'USER_REPORTING_HIERARCHY_REMOVE',
442
+ );
443
+ if (!isPrivileged) {
444
+ throw new ClassError(
445
+ 'UserReportingHierarchy',
446
+ 'UserReportingHierarchyErrMsg06',
447
+ 'Insufficient privileges to remove reporting hierarchy',
448
+ 'removeUserReportingHierarchy',
449
+ 403,
450
+ );
451
+ }
452
+
453
+ // Part 2: Find User
454
+ // Call UserReportingHierarchy.init(dbTransaction, UserReportingHierarchyId) to check if the user exists.
455
+ const userReportingHierarchy = await UserReportingHierarchy.init(
456
+ userReportingHierarchyId,
457
+ dbTransaction,
458
+ );
459
+
460
+ // Part 3: Remove User
461
+ // Call UserReportingHierarchy._Repo.destroy({ where: { UserReportingHierarchyId: UserReportingHierarchyId }, transaction: dbTransaction }) to remove the user from the database.
462
+ await UserReportingHierarchy._Repo.destroy(
463
+ userReportingHierarchyId,
464
+ dbTransaction,
465
+ );
466
+
467
+ // Part 4: Record Create Activity
468
+ // Initialise EntityValueBefore variable and set it to the UserReportingHierarchy instance before destruction.
469
+ const entityValueBefore = {
470
+ UserReportingHierarchyId:
471
+ userReportingHierarchy.UserReportingHierarchyId,
472
+ ReportingUserId: userReportingHierarchy.ReportingUserId,
473
+ UserId: userReportingHierarchy.UserId,
474
+ Rank: userReportingHierarchy.Rank,
475
+ Status: userReportingHierarchy.Status,
476
+ CreatedById: userReportingHierarchy.CreatedById,
477
+ CreatedAt: userReportingHierarchy.CreatedAt,
478
+ UpdatedById: userReportingHierarchy.UpdatedById,
479
+ UpdatedAt: userReportingHierarchy.UpdatedAt,
480
+ };
481
+ // Instantiate a new activity from the Activity class, and set:
482
+ const activity = new Activity();
483
+ // ActivityId: activity.createId()
484
+ // Action: ActionEnum.Delete
485
+ // Description: Remove User Reporting Hierarchy
486
+ // EntityType: UserReportingHierarchy
487
+ // EntityId: userReportingHierarchyId
488
+ // EntityValueBefore: Stringified representation of the UserReportingHierarchy instance before destroy
489
+ // EntityValueAfter: Stringified empty object ({})
490
+ activity.ActivityId = activity.createId();
491
+ activity.Action = ActionEnum.DELETE;
492
+ activity.Description = 'Remove User Reporting Hierarchy';
493
+ activity.EntityType = 'UserReportingHierarchy';
494
+ activity.EntityId = userReportingHierarchy.toString();
495
+ activity.EntityValueBefore = JSON.stringify(entityValueBefore);
496
+ activity.EntityValueAfter = JSON.stringify({});
497
+ // Call the activity.create() method by passing:
498
+ // dbTransaction
499
+ // userId: loginUser.UserId
500
+ await activity.create(loginUser.ObjectId, dbTransaction);
501
+ } catch (error) {
502
+ throw error;
503
+ }
504
+ }
505
+ }