@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.
- package/.commitlintrc.json +22 -22
- package/.gitlab-ci.yml +16 -16
- package/.husky/commit-msg +15 -9
- package/.husky/pre-commit +7 -7
- package/.prettierrc +4 -4
- package/Jenkinsfile +57 -57
- package/README.md +23 -23
- package/__tests__/unit/components/group/group.spec.ts +79 -79
- package/__tests__/unit/components/group-object-privilege/group-object-privilege.spec.ts +88 -88
- package/__tests__/unit/components/group-privilege/group-privilege.spec.ts +68 -68
- package/__tests__/unit/components/group-reporting-user/group-reporting-user.spec.ts +66 -66
- package/__tests__/unit/components/group-system-access/group-system-access.spec.ts +83 -83
- package/__tests__/unit/components/login-user/l.spec.ts +746 -746
- package/__tests__/unit/components/login-user/login.spec.ts +1164 -1164
- package/__tests__/unit/components/password-hash/password-hash.service.spec.ts +31 -31
- package/__tests__/unit/components/system/system.spec.ts +254 -254
- package/__tests__/unit/components/system-privilege/system-privilege.spec.ts +83 -83
- package/__tests__/unit/components/user-group/user-group.spec.ts +86 -86
- package/__tests__/unit/components/user-object-privilege/user-object-privilege.spec.ts +78 -78
- package/__tests__/unit/components/user-privilege/user-privilege.spec.ts +72 -72
- package/__tests__/unit/components/user-system-access/user-system-access.spec.ts +89 -89
- package/__tests__/unit/redis-client/redis.service.spec.ts +23 -23
- package/__tests__/unit/session/session.service.spec.ts +47 -47
- package/__tests__/unit/system-privilege/system-privilage.spec.ts +91 -91
- package/coverage/clover.xml +1452 -1452
- package/coverage/coverage-final.json +47 -47
- package/coverage/lcov-report/base.css +224 -224
- package/coverage/lcov-report/block-navigation.js +87 -87
- package/coverage/lcov-report/components/group/group.repository.ts.html +117 -117
- package/coverage/lcov-report/components/group/group.ts.html +327 -327
- package/coverage/lcov-report/components/group/index.html +130 -130
- package/coverage/lcov-report/components/group-object-privilege/group-object-privilege.repository.ts.html +117 -117
- package/coverage/lcov-report/components/group-object-privilege/group-object-privilege.ts.html +321 -321
- package/coverage/lcov-report/components/group-object-privilege/index.html +130 -130
- package/coverage/lcov-report/components/group-privilege/group-privilege.repository.ts.html +117 -117
- package/coverage/lcov-report/components/group-privilege/group-privilege.ts.html +303 -303
- package/coverage/lcov-report/components/group-privilege/index.html +130 -130
- package/coverage/lcov-report/components/group-reporting-user/group-reporting-user.repository.ts.html +117 -117
- package/coverage/lcov-report/components/group-reporting-user/group-reporting-user.ts.html +327 -327
- package/coverage/lcov-report/components/group-reporting-user/index.html +130 -130
- package/coverage/lcov-report/components/group-system-access/group-system-access.repository.ts.html +117 -117
- package/coverage/lcov-report/components/group-system-access/group-system-access.ts.html +309 -309
- package/coverage/lcov-report/components/group-system-access/index.html +130 -130
- package/coverage/lcov-report/components/login-history/index.html +115 -115
- package/coverage/lcov-report/components/login-history/login-history.repository.ts.html +117 -117
- package/coverage/lcov-report/components/login-user/index.html +130 -130
- package/coverage/lcov-report/components/login-user/login-user.ts.html +5007 -5007
- package/coverage/lcov-report/components/login-user/user.repository.ts.html +117 -117
- package/coverage/lcov-report/components/password-hash/index.html +115 -115
- package/coverage/lcov-report/components/password-hash/password-hash.service.ts.html +126 -126
- package/coverage/lcov-report/components/system/index.html +130 -130
- package/coverage/lcov-report/components/system/system.repository.ts.html +117 -117
- package/coverage/lcov-report/components/system/system.ts.html +909 -909
- package/coverage/lcov-report/components/system-privilege/index.html +130 -130
- package/coverage/lcov-report/components/system-privilege/system-privilege.repository.ts.html +120 -120
- package/coverage/lcov-report/components/system-privilege/system-privilege.ts.html +390 -390
- package/coverage/lcov-report/components/user-group/index.html +130 -130
- package/coverage/lcov-report/components/user-group/user-group.repository.ts.html +117 -117
- package/coverage/lcov-report/components/user-group/user-group.ts.html +354 -354
- package/coverage/lcov-report/components/user-object-privilege/index.html +130 -130
- package/coverage/lcov-report/components/user-object-privilege/user-object-privilege.repository.ts.html +117 -117
- package/coverage/lcov-report/components/user-object-privilege/user-object-privilege.ts.html +312 -312
- package/coverage/lcov-report/components/user-privilege/index.html +130 -130
- package/coverage/lcov-report/components/user-privilege/user-privilege.repository.ts.html +117 -117
- package/coverage/lcov-report/components/user-privilege/user-privilege.ts.html +306 -306
- package/coverage/lcov-report/components/user-system-access/index.html +130 -130
- package/coverage/lcov-report/components/user-system-access/user-system-access.repository.ts.html +117 -117
- package/coverage/lcov-report/components/user-system-access/user-system-access.ts.html +312 -312
- package/coverage/lcov-report/enum/group-type.enum.ts.html +108 -108
- package/coverage/lcov-report/enum/index.html +160 -160
- package/coverage/lcov-report/enum/index.ts.html +93 -93
- package/coverage/lcov-report/enum/user-status.enum.ts.html +105 -105
- package/coverage/lcov-report/enum/yn.enum.ts.html +96 -96
- package/coverage/lcov-report/index.html +370 -370
- package/coverage/lcov-report/models/group-object-privilege.entity.ts.html +333 -333
- package/coverage/lcov-report/models/group-privilege.entity.ts.html +315 -315
- package/coverage/lcov-report/models/group-reporting-user.entity.ts.html +339 -339
- package/coverage/lcov-report/models/group-system-access.entity.ts.html +324 -324
- package/coverage/lcov-report/models/group.entity.ts.html +435 -435
- package/coverage/lcov-report/models/index.html +310 -310
- package/coverage/lcov-report/models/login-history.entity.ts.html +252 -252
- package/coverage/lcov-report/models/staff.entity.ts.html +411 -411
- package/coverage/lcov-report/models/system-privilege.entity.ts.html +354 -354
- package/coverage/lcov-report/models/system.entity.ts.html +423 -423
- package/coverage/lcov-report/models/user-group.entity.ts.html +354 -354
- package/coverage/lcov-report/models/user-object-privilege.entity.ts.html +330 -330
- package/coverage/lcov-report/models/user-privilege.entity.ts.html +315 -315
- package/coverage/lcov-report/models/user-system-access.entity.ts.html +315 -315
- package/coverage/lcov-report/models/user.entity.ts.html +522 -522
- package/coverage/lcov-report/prettify.css +1 -1
- package/coverage/lcov-report/prettify.js +2 -2
- package/coverage/lcov-report/redis-client/index.html +115 -115
- package/coverage/lcov-report/redis-client/redis.service.ts.html +240 -240
- package/coverage/lcov-report/session/index.html +115 -115
- package/coverage/lcov-report/session/session.service.ts.html +246 -246
- package/coverage/lcov-report/sorter.js +196 -196
- package/coverage/lcov.info +2490 -2490
- package/coverage/test-report.xml +128 -128
- package/create-sso-user.sql +39 -39
- package/dist/src/components/login-user/user.js +9 -1
- package/dist/src/components/login-user/user.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/eslint.config.mjs +58 -58
- package/jest.config.js +14 -14
- package/migrations/20240314080602-create-user-table.js +124 -124
- package/migrations/20240314080603-create-user-group-table.js +85 -85
- package/migrations/20240314080604-create-user-user-group-table.js +55 -55
- package/migrations/20240314080605-create-login-history-table.js +53 -53
- package/migrations/20240527064925-create-system-table.js +78 -78
- package/migrations/20240527064926-create-system-privilege-table.js +71 -71
- package/migrations/20240527065342-create-group-table.js +93 -93
- package/migrations/20240527065633-create-group-reporting-user-table.js +76 -76
- package/migrations/20240528011551-create-group-system-access-table.js +72 -72
- package/migrations/20240528023018-user-system-access-table.js +75 -75
- package/migrations/20240528032229-user-privilege-table.js +76 -76
- package/migrations/20240528063003-create-group-privilege-table.js +76 -76
- package/migrations/20240528063051-create-group-object-privilege-table.js +84 -84
- package/migrations/20240528063107-create-user-object-privilege-table.js +84 -84
- package/migrations/20240528063108-create-api-key-table.js +85 -85
- package/migrations/20241104104802-create-building-table.js +95 -95
- package/migrations/20250108091132-add-area-manager-user-id-to-building-table.js +14 -14
- package/migrations/20250108091133-add-passcode-to-user-table.js +36 -36
- package/migrations/20250210115636-create-user-reporting-hierarchy.js +76 -76
- package/migrations/20250326043818-crate-user-password-history.js +42 -42
- package/package.json +90 -90
- package/sampledotenv +7 -7
- package/sonar-project.properties +22 -22
- package/src/components/api-key/api-key.repository.ts +15 -15
- package/src/components/api-key/api-key.ts +448 -448
- package/src/components/api-key/index.ts +4 -4
- package/src/components/building/building.repository.ts +27 -27
- package/src/components/building/index.ts +2 -2
- package/src/components/group/group.repository.ts +26 -26
- package/src/components/group/group.ts +2284 -2284
- package/src/components/group/index.ts +3 -3
- package/src/components/group-object-privilege/group-object-privilege.repository.ts +25 -25
- package/src/components/group-object-privilege/group-object-privilege.ts +278 -278
- package/src/components/group-object-privilege/index.ts +2 -2
- package/src/components/group-privilege/group-privilege.repository.ts +29 -29
- package/src/components/group-privilege/group-privilege.ts +84 -84
- package/src/components/group-privilege/index.ts +2 -2
- package/src/components/group-reporting-user/group-reporting-user.repository.ts +23 -23
- package/src/components/group-reporting-user/group-reporting-user.ts +506 -506
- package/src/components/group-reporting-user/index.ts +3 -3
- package/src/components/group-system-access/group-system-access.repository.ts +43 -43
- package/src/components/group-system-access/group-system-access.ts +90 -90
- package/src/components/group-system-access/index.ts +2 -2
- package/src/components/index.ts +20 -20
- package/src/components/login-history/index.ts +1 -1
- package/src/components/login-history/login-history.repository.ts +11 -11
- package/src/components/login-user/index.ts +5 -5
- package/src/components/login-user/interfaces/check-user-info-duplicated.interface.ts +7 -7
- package/src/components/login-user/interfaces/index.ts +1 -1
- package/src/components/login-user/interfaces/system-access.interface.ts +13 -13
- package/src/components/login-user/interfaces/user-info.interface.ts +34 -34
- package/src/components/login-user/login-user.ts +362 -362
- package/src/components/login-user/user.repository.ts +11 -11
- package/src/components/login-user/user.ts +3142 -3134
- package/src/components/password-hash/index.ts +2 -2
- package/src/components/password-hash/interfaces/index.ts +1 -1
- package/src/components/password-hash/interfaces/password-hash-service.interface.ts +4 -4
- package/src/components/password-hash/password-hash.service.ts +14 -14
- package/src/components/staff/index.ts +2 -2
- package/src/components/staff/staff.repository.ts +27 -27
- package/src/components/system/index.ts +3 -3
- package/src/components/system/system.repository.ts +11 -11
- package/src/components/system/system.ts +456 -456
- package/src/components/system-privilege/index.ts +4 -4
- package/src/components/system-privilege/system-privilege.repository.ts +18 -18
- package/src/components/system-privilege/system-privilege.ts +541 -541
- package/src/components/user-group/index.ts +2 -2
- package/src/components/user-group/user-group.repository.ts +19 -19
- package/src/components/user-group/user-group.ts +764 -764
- package/src/components/user-object-privilege/index.ts +2 -2
- package/src/components/user-object-privilege/user-object-privilege.repository.ts +11 -11
- package/src/components/user-object-privilege/user-object-privilege.ts +79 -79
- package/src/components/user-password-history/index.ts +2 -2
- package/src/components/user-password-history/user-password-history.repository.ts +39 -39
- package/src/components/user-password-history/user-password-history.ts +187 -187
- package/src/components/user-privilege/index.ts +2 -2
- package/src/components/user-privilege/user-privilege.repository.ts +25 -25
- package/src/components/user-privilege/user-privilege.ts +662 -662
- package/src/components/user-reporting-hierarchy/index.ts +2 -2
- package/src/components/user-reporting-hierarchy/user-reporting-hierarchy.repository.ts +30 -30
- package/src/components/user-reporting-hierarchy/user-reporting-hierarchy.ts +505 -505
- package/src/components/user-system-access/index.ts +2 -2
- package/src/components/user-system-access/user-system-access.repository.ts +41 -41
- package/src/components/user-system-access/user-system-access.ts +717 -717
- package/src/database.ts +15 -15
- package/src/enum/api-key.enum.ts +5 -5
- package/src/enum/building-type.enum.ts +6 -6
- package/src/enum/group-type.enum.ts +8 -8
- package/src/enum/index.ts +6 -6
- package/src/enum/login-status.enum.ts +4 -4
- package/src/enum/object-status.enum.ts +4 -4
- package/src/enum/user-status.enum.ts +7 -7
- package/src/enum/yn.enum.ts +4 -4
- package/src/index.ts +8 -8
- package/src/interfaces/api-key-attr.interface.ts +16 -16
- package/src/interfaces/group-object-privilege.interface.ts +14 -14
- package/src/interfaces/group-privilege.interface.ts +10 -10
- package/src/interfaces/group-reporting-user.interface.ts +11 -11
- package/src/interfaces/group-search-attr.interface.ts +9 -9
- package/src/interfaces/group-system-access.interface.ts +10 -10
- package/src/interfaces/group.interface.ts +17 -17
- package/src/interfaces/index.ts +13 -13
- package/src/interfaces/system-login.interface.ts +6 -6
- package/src/interfaces/system-privilege-search.interface.ts +5 -5
- package/src/interfaces/system-privilege.interface.ts +11 -11
- package/src/interfaces/system-search-attr.interface.ts +5 -5
- package/src/interfaces/system.interface.ts +15 -15
- package/src/interfaces/user-group.interface.ts +12 -12
- package/src/interfaces/user-object-privilege.interface.ts +14 -14
- package/src/interfaces/user-password-history.interface.ts +6 -6
- package/src/interfaces/user-privilege.interface.ts +10 -10
- package/src/interfaces/user-reporting-hierarchy.interface.ts +11 -11
- package/src/interfaces/user-session.interface.ts +5 -5
- package/src/interfaces/user-system-access.interface.ts +10 -10
- package/src/models/api-key-entity.ts +101 -101
- package/src/models/building.entity.ts +103 -103
- package/src/models/group-object-privilege.entity.ts +91 -91
- package/src/models/group-privilege.entity.ts +78 -78
- package/src/models/group-reporting-user.entity.ts +95 -95
- package/src/models/group-system-access.entity.ts +81 -81
- package/src/models/group.entity.ts +127 -127
- package/src/models/login-history.entity.ts +63 -63
- package/src/models/staff.entity.ts +91 -91
- package/src/models/system-privilege.entity.ts +90 -90
- package/src/models/system.entity.ts +113 -113
- package/src/models/user-group.entity.ts +91 -91
- package/src/models/user-object-privilege.entity.ts +90 -90
- package/src/models/user-password-history.ts +51 -51
- package/src/models/user-privilege.entity.ts +78 -78
- package/src/models/user-reporting-hierarchy.entity.ts +102 -102
- package/src/models/user-system-access.entity.ts +87 -87
- package/src/models/user.entity.ts +193 -193
- package/src/redis-client/__mocks__/jest-initial-setup.ts +2 -2
- package/src/redis-client/__mocks__/redis-mock.ts +28 -28
- package/src/redis-client/index.ts +1 -1
- package/src/redis-client/redis.service.ts +75 -75
- package/src/session/index.ts +2 -2
- package/src/session/interfaces/index.ts +1 -1
- package/src/session/interfaces/session-service.interface.ts +26 -26
- package/src/session/session.service.ts +96 -96
- package/src/types/auth-context.ts +10 -10
- package/src/types/index.ts +1 -1
- package/tsconfig.build.json +5 -5
- 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
|
+
}
|