rez_core 2.1.23 → 2.1.25

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 (32) hide show
  1. package/dist/module/enterprise/controller/organization.controller.d.ts +3 -1
  2. package/dist/module/enterprise/controller/organization.controller.js +6 -3
  3. package/dist/module/enterprise/controller/organization.controller.js.map +1 -1
  4. package/dist/module/enterprise/repository/school.repository.d.ts +1 -1
  5. package/dist/module/enterprise/repository/school.repository.js +122 -68
  6. package/dist/module/enterprise/repository/school.repository.js.map +1 -1
  7. package/dist/module/enterprise/service/organization.service.d.ts +1 -1
  8. package/dist/module/enterprise/service/organization.service.js +2 -2
  9. package/dist/module/enterprise/service/organization.service.js.map +1 -1
  10. package/dist/module/module/service/module-access.service.js +9 -1
  11. package/dist/module/module/service/module-access.service.js.map +1 -1
  12. package/dist/module/user/entity/user.entity.d.ts +2 -0
  13. package/dist/module/user/entity/user.entity.js +8 -0
  14. package/dist/module/user/entity/user.entity.js.map +1 -1
  15. package/dist/module/user/service/login.service.d.ts +2 -2
  16. package/dist/module/user/service/login.service.js +22 -10
  17. package/dist/module/user/service/login.service.js.map +1 -1
  18. package/dist/module/user/service/user-session.service.js +1 -1
  19. package/dist/module/user/service/user-session.service.js.map +1 -1
  20. package/dist/module/user/service/user.service.d.ts +1 -0
  21. package/dist/module/user/service/user.service.js +9 -0
  22. package/dist/module/user/service/user.service.js.map +1 -1
  23. package/dist/tsconfig.build.tsbuildinfo +1 -1
  24. package/package.json +1 -1
  25. package/src/module/enterprise/controller/organization.controller.ts +5 -2
  26. package/src/module/enterprise/repository/school.repository.ts +148 -75
  27. package/src/module/enterprise/service/organization.service.ts +2 -2
  28. package/src/module/module/service/module-access.service.ts +28 -1
  29. package/src/module/user/entity/user.entity.ts +6 -0
  30. package/src/module/user/service/login.service.ts +33 -17
  31. package/src/module/user/service/user-session.service.ts +2 -2
  32. package/src/module/user/service/user.service.ts +17 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rez_core",
3
- "version": "2.1.23",
3
+ "version": "2.1.25",
4
4
  "description": "",
5
5
  "author": "",
6
6
  "private": false,
@@ -23,7 +23,10 @@ export class OrganizationController {
23
23
 
24
24
  @UseGuards(JwtAuthGuard)
25
25
  @Get('hierarchy')
26
- async getOrganizationHierarchy(): Promise<any[]> {
27
- return await this.orgService.getOrganizationHierarchy();
26
+ async getOrganizationHierarchy(@Req() req: Request & { user: any }) {
27
+ const userId = req.user.userData?.id;
28
+ const appcode = req.user.userData?.appcode;
29
+
30
+ return await this.orgService.getOrganizationHierarchy(userId, appcode);
28
31
  }
29
32
  }
@@ -24,93 +24,166 @@ export class SchoolRepository {
24
24
  });
25
25
  }
26
26
 
27
- async getUserContextDropdown(): Promise<any[]> {
28
- const data = await this.dataSource
29
- .createQueryBuilder()
30
- .select([
31
- 'org.id AS org_id',
32
- 'org.name AS org_name',
33
- 'org.address AS org_address',
34
- 'org.type AS org_type',
35
-
36
- // Full brand columns
37
- 'br.id AS brand_id',
38
- 'br.entity_type AS brand_entity_type',
39
- 'br.name AS brand_name',
40
- 'br.status AS brand_status',
41
- 'br.parent_type AS brand_parent_type',
42
- 'br.parent_id AS brand_parent_id',
43
- 'br.code AS brand_code',
44
- 'br.enterprise_id AS brand_enterprise_id',
45
- 'br.organization_id AS brand_organization_id',
46
- 'br.appcode AS brand_appcode',
47
- 'br.level_id AS brand_level_id',
48
- 'br.level_type AS brand_level_type',
49
- 'br.type AS brand_type',
50
-
51
- // Full school columns
52
- 'sch.id AS school_id',
53
- 'sch.entity_type AS school_entity_type',
54
- 'sch.name AS school_name',
55
- 'sch.status AS school_status',
56
- 'sch.parent_type AS school_parent_type',
57
- 'sch.parent_id AS school_parent_id',
58
- 'sch.code AS school_code',
59
- 'sch.enterprise_id AS school_enterprise_id',
60
- 'sch.organization_id AS school_organization_id',
61
- 'sch.appcode AS school_appcode',
62
- 'sch.level_id AS school_level_id',
63
- 'sch.level_type AS school_level_type',
64
- 'sch.type AS school_type',
65
- ])
66
- .from('cr_school', 'sch')
67
- .innerJoin('cr_brand', 'br', 'sch.brand_id = br.id')
68
- .innerJoin('cr_organization', 'org', 'br.organization_id = org.id')
69
- .orderBy('org.id, br.id, sch.id')
70
- .getRawMany();
71
-
72
- const result = {};
27
+ async getUserContextDropdown(userId: number, appCode: string) {
28
+ const userRoleRepo = this.dataSource.getRepository(UserRoleMapping);
73
29
 
74
- for (const row of data) {
75
- const { org_id, org_name, org_address, org_type: type, brand_id } = row;
30
+ const hasOrgAccess = await userRoleRepo
31
+ .createQueryBuilder('urm')
32
+ .where('urm.user_id = :userId', { userId })
33
+ .andWhere('urm.appcode = :appCode', { appCode })
34
+ .andWhere('urm.level_type = :levelType', { levelType: 'ORG' })
35
+ .getRawMany();
76
36
 
77
- // const {
78
- // school_id,ol_
79
- // } = row;
37
+ if (hasOrgAccess.length > 0) {
38
+ const schools = await this.dataSource
39
+ .createQueryBuilder()
40
+ .select([
41
+ 'org.id AS org_id',
42
+ 'org.name AS org_name',
43
+ 'org.address AS org_address',
44
+ 'org.status AS org_status',
45
+ 'br.id AS brand_id',
46
+ 'br.name AS brand_name',
47
+ 'br.status AS brand_status',
48
+ 'sch.id AS school_id',
49
+ 'sch.name AS school_name',
50
+ 'sch.location AS school_location',
51
+ 'sch.status AS school_status',
52
+ ])
53
+ .from('cr_school', 'sch')
54
+ .innerJoin('cr_brand', 'br', 'sch.brand_id = br.id')
55
+ .innerJoin('cr_organization', 'org', 'br.organization_id = org.id')
56
+ .where('org.id = :orgId', { orgId: hasOrgAccess[0].urm_level_id })
57
+ .getRawMany();
80
58
 
81
- if (!result[org_id]) {
82
- result[org_id] = {
59
+ const result = {};
60
+ for (const row of schools) {
61
+ const {
83
62
  org_id,
84
63
  org_name,
85
64
  org_address,
86
- type,
87
- brands: {},
88
- };
89
- }
65
+ org_status,
66
+ brand_id,
67
+ brand_name,
68
+ brand_status,
69
+ school_id,
70
+ school_name,
71
+ school_location,
72
+ school_status,
73
+ } = row;
90
74
 
91
- if (!result[org_id].brands[brand_id]) {
92
- const brandInfo: any = {};
93
- for (const key in row) {
94
- if (key.startsWith('brand_')) {
95
- brandInfo[key.replace('brand_', '')] = row[key];
96
- }
75
+ if (!result[org_id]) {
76
+ result[org_id] = {
77
+ org_id,
78
+ org_name,
79
+ org_address,
80
+ status: org_status,
81
+ type: 'Organization',
82
+ brands: {},
83
+ };
97
84
  }
98
- brandInfo.schools = [];
99
- result[org_id].brands[brand_id] = brandInfo;
85
+
86
+ if (!result[org_id].brands[brand_id]) {
87
+ result[org_id].brands[brand_id] = {
88
+ brand_id,
89
+ brand_name,
90
+ status: brand_status,
91
+ type: 'Brand',
92
+ schools: [],
93
+ };
94
+ }
95
+
96
+ result[org_id].brands[brand_id].schools.push({
97
+ school_id,
98
+ school_name,
99
+ school_location,
100
+ status: school_status,
101
+ type: 'School',
102
+ });
100
103
  }
101
104
 
102
- const schoolInfo: any = {};
103
- for (const key in row) {
104
- if (key.startsWith('school_')) {
105
- schoolInfo[key.replace('school_', '')] = row[key];
105
+ return Object.values(result).map((org: any) => ({
106
+ ...org,
107
+ brands: Object.values(org.brands),
108
+ }));
109
+ } else {
110
+ const brnMappings = await this.dataSource
111
+ .createQueryBuilder()
112
+ .select([
113
+ 'brand.id AS brand_id',
114
+ 'brand.name AS brand_name',
115
+ 'brand.status AS brand_status',
116
+ 'school.id AS school_id',
117
+ 'school.name AS school_name',
118
+ 'school.location AS school_location',
119
+ 'school.status AS school_status',
120
+ ])
121
+ .from('cr_user_role_mapping', 'urm')
122
+ .innerJoin('cr_brand', 'brand', 'brand.id = urm.level_id')
123
+ .innerJoin('cr_school', 'school', 'school.brand_id = brand.id')
124
+ .where('urm.user_id = :userId', { userId })
125
+ .andWhere('urm.appcode = :appCode', { appCode })
126
+ .andWhere('urm.level_type = :levelType', { levelType: 'BRN' })
127
+ .getRawMany();
128
+
129
+ const schMappings = await this.dataSource
130
+ .createQueryBuilder()
131
+ .select([
132
+ 'brand.id AS brand_id',
133
+ 'brand.name AS brand_name',
134
+ 'brand.status AS brand_status',
135
+ 'school.id AS school_id',
136
+ 'school.name AS school_name',
137
+ 'school.location AS school_location',
138
+ 'school.status AS school_status',
139
+ ])
140
+ .from('cr_user_role_mapping', 'urm')
141
+ .innerJoin('cr_school', 'school', 'school.id = urm.level_id')
142
+ .innerJoin('cr_brand', 'brand', 'brand.id = school.brand_id')
143
+ .where('urm.user_id = :userId', { userId })
144
+ .andWhere('urm.appcode = :appCode', { appCode })
145
+ .andWhere('urm.level_type = :levelType', { levelType: 'SCH' })
146
+ .getRawMany();
147
+
148
+ const allMappings = [...brnMappings, ...schMappings];
149
+
150
+ const result = {};
151
+ for (const row of allMappings) {
152
+ const {
153
+ brand_id,
154
+ brand_name,
155
+ brand_status,
156
+ school_id,
157
+ school_name,
158
+ school_location,
159
+ school_status,
160
+ } = row;
161
+
162
+ if (!result[brand_id]) {
163
+ result[brand_id] = {
164
+ brand_id,
165
+ brand_name,
166
+ status: brand_status,
167
+ type: 'Brand',
168
+ schools: [],
169
+ };
170
+ }
171
+
172
+ if (
173
+ school_id &&
174
+ !result[brand_id].schools.some((s) => s.school_id === school_id)
175
+ ) {
176
+ result[brand_id].schools.push({
177
+ school_id,
178
+ school_name,
179
+ school_location,
180
+ status: school_status,
181
+ type: 'School',
182
+ });
106
183
  }
107
184
  }
108
- result[org_id].brands[brand_id].schools.push(schoolInfo);
109
- }
110
185
 
111
- return Object.values(result).map((org: any) => ({
112
- ...org,
113
- brands: Object.values(org.brands),
114
- }));
186
+ return Object.values(result);
187
+ }
115
188
  }
116
189
  }
@@ -78,7 +78,7 @@ export class OrganizationService {
78
78
  await repo.delete(id);
79
79
  }
80
80
 
81
- async getOrganizationHierarchy(): Promise<any[]> {
82
- return await this.schoolRepository.getUserContextDropdown();
81
+ async getOrganizationHierarchy(userId: number, appCode: string) {
82
+ return await this.schoolRepository.getUserContextDropdown(userId, appCode);
83
83
  }
84
84
  }
@@ -129,6 +129,7 @@ export class ModuleAccessService {
129
129
  level_type: string;
130
130
  level_id: number;
131
131
  }) {
132
+ // Step 1: Resolve roles
132
133
  const roleCodes = await this.menuRepository.resolveUserRoles(
133
134
  userId,
134
135
  appcode,
@@ -141,8 +142,34 @@ export class ModuleAccessService {
141
142
  }
142
143
 
143
144
  const roleIds = roleCodes.map(Number);
144
- return this.moduleAccessRepository.getModuleAccessByRoles(roleIds, appcode);
145
+
146
+ // Step 2: Get full permissions
147
+ const allPermissions = await this.moduleAccessRepository.getModuleAccessByRoles(
148
+ roleIds,
149
+ appcode,
150
+ );
151
+
152
+ // Step 3: If level_type is SCH, check school status using raw query
153
+ if (level_type === 'SCH') {
154
+ const result = await this.dataSource.query(
155
+ `SELECT * FROM cr_school WHERE id = ${level_id}`,
156
+ [level_id],
157
+ );
158
+
159
+ const school = result?.[0];
160
+
161
+ if (!school || school.status === "INACTIVE") {
162
+ // Return only VIEW permissions
163
+ return allPermissions.filter(
164
+ (perm) => perm.action === 'VIEW'
165
+ );
166
+ }
167
+ }
168
+
169
+ // Step 4: Return all permissions normally
170
+ return allPermissions;
145
171
  }
146
172
 
147
173
 
174
+
148
175
  }
@@ -44,4 +44,10 @@ export class UserData extends BaseEntity {
44
44
 
45
45
  @Column({ type: 'varchar', nullable: true })
46
46
  last_app_access: string;
47
+
48
+ @Column({ type: 'varchar', nullable: true })
49
+ last_level_type: string;
50
+
51
+ @Column({ type: 'varchar', nullable: true })
52
+ last_level_id: string;
47
53
  }
@@ -59,25 +59,41 @@ export class LoginService {
59
59
  };
60
60
  }
61
61
 
62
- // ✅ Get user-role mappings for this app
63
- const roleMappings = await this.userRoleMappingRepository.find({
64
- where: {
65
- user_id: user.id,
66
- appcode: user.last_app_access,
67
- },
68
- });
62
+ let defaultAccess;
69
63
 
70
- if (!roleMappings.length) {
71
- throw new BadRequestException(
72
- 'User does not have any access mapped for this app.',
73
- );
74
- }
64
+ if (!user.last_level_type && !user.last_level_id) {
65
+ const roleMappings = await this.userRoleMappingRepository.find({
66
+ where: {
67
+ user_id: user.id,
68
+ appcode: user.last_app_access,
69
+ },
70
+ });
71
+
72
+ if (!roleMappings.length) {
73
+ throw new BadRequestException(
74
+ 'User does not have any access mapped for this app.',
75
+ );
76
+ }
75
77
 
76
- // ✅ Pick default access based on priority
77
- const priority = { org: 1, sch: 2, brn: 3 };
78
- const defaultAccess = roleMappings.sort(
79
- (a, b) => priority[a.level_type] - priority[b.level_type],
80
- )[0];
78
+ // ✅ Pick default access based on priority
79
+ const priority = { org: 1, sch: 2, brn: 3 };
80
+ defaultAccess = roleMappings.sort(
81
+ (a, b) => priority[a.level_type] - priority[b.level_type],
82
+ )[0];
83
+
84
+ if ((defaultAccess.level_type, defaultAccess.level_id)) {
85
+ await this.userService.setLastLevelTypeAndId(
86
+ user.id,
87
+ defaultAccess.level_type,
88
+ defaultAccess.level_id,
89
+ );
90
+ }
91
+ } else {
92
+ defaultAccess = {
93
+ level_type: user.last_level_type,
94
+ level_id: user.last_level_id,
95
+ };
96
+ }
81
97
 
82
98
  //appcode
83
99
 
@@ -85,8 +85,8 @@ export class UserSessionService {
85
85
  };
86
86
 
87
87
  await this.dataSource.query(
88
- `UPDATE cr_user SET last_app_access = ? WHERE id = ?`,
89
- [data.appcode, currentUser.id],
88
+ `UPDATE cr_user SET last_app_access = ? , last_level_type = ?, last_level_id = ? WHERE id = ?`,
89
+ [data.appcode, data.level_type, data.level_id, currentUser.id],
90
90
  );
91
91
 
92
92
  return {
@@ -249,4 +249,21 @@ export class UserService extends EntityServiceImpl {
249
249
 
250
250
  await this.userRepository.saveUser(user); // This persists the updated field
251
251
  }
252
+
253
+ async setLastLevelTypeAndId(
254
+ userId: number,
255
+ levelType: string,
256
+ levelId: string,
257
+ ): Promise<void> {
258
+ const user = await this.userRepository.findById(userId);
259
+
260
+ if (!user) {
261
+ throw new BadRequestException('User not found');
262
+ }
263
+
264
+ user.last_level_type = levelType;
265
+ user.last_level_id = levelId;
266
+
267
+ await this.userRepository.saveUser(user); // This persists the updated field
268
+ }
252
269
  }