UNPKG

@tomei/sso

Version:
507 lines (469 loc) 20.1 kB
import { Op, Transaction } from 'sequelize'; import { ClassError, ObjectBase } from '@tomei/general'; import { GroupReportingUserRepository } from './group-reporting-user.repository'; import { IGroupReportingUserAttr } from '../../interfaces/group-reporting-user.interface'; import { User } from '../login-user/user'; import UserModel from '../../models/user.entity'; import { Group } from '../group/group'; import { ApplicationConfig } from '@tomei/config'; import { ActionEnum, Activity } from '@tomei/activity-history'; export class GroupReportingUser extends ObjectBase { ObjectId: string; ObjectName: string; TableName = 'sso_GroupReportingUser'; ObjectType = 'GroupReportingUser'; GroupReportingUserId: number; GroupCode: string; UserId: number; Rank: number; Status: string; private _CreatedById: number; private _CreatedAt: Date; private _UpdatedById: number; private _UpdatedAt: Date; private static _Repo = new GroupReportingUserRepository(); get CreatedById(): number { return this._CreatedById; } get CreatedAt(): Date { return this._CreatedAt; } get UpdatedById(): number { return this._UpdatedById; } get UpdatedAt(): Date { return this._UpdatedAt; } private constructor(groupReportingUserAttr?: IGroupReportingUserAttr) { super(); if (groupReportingUserAttr) { this.GroupReportingUserId = groupReportingUserAttr.GroupReportingUserId; this.GroupCode = groupReportingUserAttr.GroupCode; this.UserId = groupReportingUserAttr?.UserId; this.Rank = groupReportingUserAttr?.Rank; this.Status = groupReportingUserAttr?.Status; this._CreatedById = groupReportingUserAttr.CreatedById; this._CreatedAt = groupReportingUserAttr.CreatedAt; this._UpdatedById = groupReportingUserAttr.UpdatedById; this._UpdatedAt = groupReportingUserAttr.UpdatedAt; } } public static async init(dbTransaction: any, GroupReportingUserId?: string) { try { if (GroupReportingUserId) { const groupReportingUser = await GroupReportingUser._Repo.findByPk( GroupReportingUserId, { transaction: dbTransaction, }, ); if (groupReportingUser) { return new GroupReportingUser(groupReportingUser); } else { throw new ClassError( 'GroupReportingUser', 'GroupReportingUserErrMsg00', 'GroupReportingUser Not Found', 'init', 404, ); } } return new GroupReportingUser(); } catch (error) { throw error; } } async createGroupReportingUser( loginUser: User, //The user performing the operation(typically the logged -in user). dbTransaction: any, //Database transaction object to ensure the operation is atomic. groupCode: string, //The code of the group to which the user is being assigned. userId: number, //The ID of the user to be added to the group. rank: number, //The rank to be assigned to the user in the group. status: 'Active' | 'Inactive', //The initial status of the user in the group. ): Promise<GroupReportingUser> { // Returns a GroupReportingUser instance representing the newly created record. try { //Creates a new group reporting user entry in the sso_GroupReportingUser table. // Validate Input Parameters // Ensure groupCode exists in the sso_Group table by calling the Group.init() method. const group = await Group.init(dbTransaction, groupCode); // Ensure userId exists in the sso_User table by calling the User.init() method. const user = await User.init(dbTransaction, userId); // Privilege Checking // Call the loginUser.checkPrivileges() method by passing: // SystemCode: Retrieve from app config. // PrivilegeCode: "GROUP_REPORTING_USER_CREATE". const systemCode = ApplicationConfig.getComponentConfigValue('system-code'); const isPrivileged = await loginUser.checkPrivileges( systemCode, 'GROUP_REPORTING_USER_CREATE', ); if (!isPrivileged) { throw new ClassError( 'GroupReportingUser', 'GroupReportingUserErrMsg02', 'Insufficient privileges to add a user to the group', ); } // Check for Duplicate User in Group // Query the sso_GroupReportingUser table to see if the userId already exists in the specified groupCode. const groupReportingUser = await GroupReportingUser._Repo.findOne({ where: { GroupCode: groupCode, UserId: userId, }, transaction: dbTransaction, }); // If the user already exists in the group, throw an error indicating the user is already part of the group. if (groupReportingUser) { throw new ClassError( 'GroupReportingUser', 'GroupReportingUserErrMsg03', 'User already exists in the group', 'createGroupReportingUser', ); } //Query the sso_GroupReportingUser table to see if the rank already exists in the specified groupCode. //If the rank already exists in the group, throw an error indicating the rank is already in of the group. const groupReportingUserRank = await GroupReportingUser._Repo.findOne({ where: { GroupCode: groupCode, Rank: rank, }, transaction: dbTransaction, }); if (groupReportingUserRank) { throw new ClassError( 'GroupReportingUser', 'GroupReportingUserErrMsg04', 'Rank already exists in the group', 'createGroupReportingUser', ); } // Create GroupReportingUser Entry // If validation and privilege checks pass, insert a new record in the sso_GroupReportingUser table with the provided groupCode, userId, rank, status, and loginUser.UserId.Automatically capture the current timestamp for CreatedAt. this.GroupCode = groupCode; this.UserId = userId; this.Rank = rank; this.Status = status; this._CreatedById = loginUser.UserId; this._CreatedAt = new Date(); this._UpdatedAt = new Date(); this._UpdatedById = loginUser.UserId; const entityValueAfter: any = { GroupCode: groupCode, UserId: userId, Rank: rank, Status: status, CreatedById: loginUser.UserId, CreatedAt: this._CreatedAt, UpdatedById: loginUser.UserId, UpdatedAt: this._UpdatedAt, }; const newGroupReportingUser = await GroupReportingUser._Repo.create( entityValueAfter, { transaction: dbTransaction, }, ); entityValueAfter.GroupReportingUserId = newGroupReportingUser.GroupReportingUserId; // Record Create Activity // Instantiate a new activity from the Activity class, and set:\ // ActivityId: activity.createId() // Action: ActionEnum.Create // Description: Create Group Reporting User // EntityType: GroupReportingUser // EntityId: newGroupReportingUser.GroupReportingUserId // EntityValueBefore: Stringified empty object({}) // EntityValueAfter: EntityValueAfter(stringified representation of the newly created entity) const activity = new Activity(); activity.ActivityId = activity.createId(); activity.Action = ActionEnum.CREATE; activity.Description = 'Create Group Reporting User'; activity.EntityType = 'GroupReportingUser'; activity.EntityId = newGroupReportingUser.GroupReportingUserId.toString(); activity.EntityValueBefore = JSON.stringify({}); activity.EntityValueAfter = JSON.stringify(entityValueAfter); // Call the activity create() method by passing: // dbTransaction // userId: loginUser.UserId await activity.create(loginUser.ObjectId, dbTransaction); // Return the Created GroupReportingUser // Return the newly created GroupReportingUser instance, including all the relevant details like GroupReportingUserId, groupCode, userId, rank, status, and timestamps for CreatedAt. return this; } catch (error) { throw error; } } async updateGroupReportingUser( loginUser: User, //The user performing the operation(typically the logged -in user). dbTransaction: any, //Database transaction object to ensure the operation is atomic. groupCode: string, //The code of the group to which the user is being assigned. userId: number, //The ID of the user to be added to the group. rank: number, //The rank to be assigned to the user in the group. status: 'Active' | 'Inactive', //The initial status of the user in the group. ): Promise<GroupReportingUser> { // Returns a GroupReportingUser instance representing the updated record. try { //Update a group reporting user entry in the sso_GroupReportingUser table. // Validate Input Parameters // Ensure groupCode exists in the sso_Group table by calling the Group.init() method. await Group.init(dbTransaction, groupCode); // Ensure userId exists in the sso_User table by calling the User.init() method. await User.init(dbTransaction, userId); // Privilege Checking // Call the loginUser.checkPrivileges() method by passing: // SystemCode: Retrieve from app config. // PrivilegeCode: "GROUP_REPORTING_USER_UPDATE". const systemCode = ApplicationConfig.getComponentConfigValue('system-code'); const isPrivileged = await loginUser.checkPrivileges( systemCode, 'GROUP_REPORTING_USER_UPDATE', ); if (!isPrivileged) { throw new ClassError( 'GroupReportingUser', 'GroupReportingUserErrMsg02', 'Insufficient privileges to update a user to the group', ); } //Get the current groupReportingUser const currentGroupReportingUser = await GroupReportingUser._Repo.findOne({ where: { GroupCode: groupCode, GroupReportingUserId: this.GroupReportingUserId, }, transaction: dbTransaction, }); // Check for Duplicate User in Group // Query the sso_GroupReportingUser table to see if the userId already exists in the specified groupCode. const groupReportingUser = await GroupReportingUser._Repo.findOne({ where: { GroupCode: groupCode, UserId: userId, GroupReportingUserId: { [Op.ne]: this.GroupReportingUserId, }, }, transaction: dbTransaction, }); // If the user already exists in the group, throw an error indicating the user is already part of the group. if (groupReportingUser) { throw new ClassError( 'GroupReportingUser', 'GroupReportingUserErrMsg03', 'User already exists in the group', 'updateGroupReportingUser', ); } //Query the sso_GroupReportingUser table to see if the rank already exists in the specified groupCode. //If the rank already exists in the group, throw an error indicating the rank is already in of the group. const groupReportingUserRank = await GroupReportingUser._Repo.findOne({ where: { GroupCode: groupCode, Rank: rank, GroupReportingUserId: { [Op.ne]: this.GroupReportingUserId, }, }, transaction: dbTransaction, }); if (groupReportingUserRank) { throw new ClassError( 'GroupReportingUser', 'GroupReportingUserErrMsg04', 'Rank already exists in the group', 'updateGroupReportingUser', ); } // UPDATE GroupReportingUser Entry // If validation and privilege checks pass, insert a new record in the sso_GroupReportingUser table with the provided groupCode, userId, rank, status, and loginUser.UserId.Automatically capture the current timestamp for CreatedAt. this.GroupCode = groupCode; this.UserId = userId; this.Rank = rank; this.Status = status; this._CreatedById = currentGroupReportingUser.CreatedById; this._CreatedAt = currentGroupReportingUser.CreatedAt; this._UpdatedAt = new Date(); this._UpdatedById = loginUser.UserId; const entityValueAfter: any = { GroupCode: groupCode, UserId: userId, Rank: rank, Status: status, CreatedById: currentGroupReportingUser.CreatedById, CreatedAt: this._CreatedAt, UpdatedById: loginUser.UserId, UpdatedAt: this._UpdatedAt, }; await GroupReportingUser._Repo.update(entityValueAfter, { where: { GroupReportingUserId: this.GroupReportingUserId, }, transaction: dbTransaction, }); // Record Update Activity // Instantiate a new activity from the Activity class, and set:\ // ActivityId: activity.createId() // Action: ActionEnum.Update // Description: Update Group Reporting User // EntityType: GroupReportingUser // EntityId: newGroupReportingUser.GroupReportingUserId // EntityValueBefore: Stringified empty object({}) // EntityValueAfter: EntityValueAfter(stringified representation of the newly created entity) const activity = new Activity(); activity.ActivityId = activity.createId(); activity.Action = ActionEnum.UPDATE; activity.Description = 'Update Group Reporting User'; activity.EntityType = 'GroupReportingUser'; activity.EntityId = this.GroupReportingUserId.toString(); activity.EntityValueBefore = JSON.stringify({}); activity.EntityValueAfter = JSON.stringify(entityValueAfter); // Call the activity create() method by passing: // dbTransaction // userId: loginUser.UserId await activity.create(loginUser.ObjectId, dbTransaction); // Return the Updated GroupReportingUser // Return the updated GroupReportingUser instance, including all the relevant details like GroupReportingUserId, groupCode, userId, rank, status, and timestamps for CreatedAt. return this; } catch (error) { throw error; } } public static async findAllGroupReportingUsers( loginUser: User, //The authenticated user requesting the information. dbTransaction: any, //The database transaction to be used for this operation. groupCode?: string, //The code of the group whose reporting users should be retrieved. ) { //This public static method retrieves all GroupReportingUser records for a given group from the sso_GroupReportingUser table. try { // Part 1: Privilege Check // Call loginUser.checkPrivileges() method by passing: // - SystemCode: Retrieve from the app config. // - PrivilegeCode: GROUP_REPORTING_USER_VIEW. // If the user does not have the required privilege, throw a ForbiddenError. const systemCode = ApplicationConfig.getComponentConfigValue('system-code'); const isPrivileged = await loginUser.checkPrivileges( systemCode, 'GROUP_REPORTING_USER_VIEW', ); if (!isPrivileged) { throw new ClassError( 'Group', 'GroupReportingUserErrMsg05', 'You do not have the privilege to view group reporting user', ); } // Part 2: Group Existence Check // Call Group.init(dbTransaction, groupCode) to verify the group exists. // If the group does not exist, throw a NotFoundError. await Group.init(dbTransaction, groupCode); // Part 3: Retrieve Group Reporting Users // Call GroupReportingUser._Repo.findAll() to retrieve all users associated with the provided groupCode. // The users should be sorted by Rank in ascending order (Rank 1, Rank 2, and so on). // Ensure the query is performed within the dbTransaction. const result = await GroupReportingUser._Repo.findAll({ where: { GroupCode: groupCode, }, include: [ { model: UserModel, as: 'User', }, ], order: [ ['Rank', 'ASC'], // or 'DESC' for descending order ], transaction: dbTransaction, }); // Part 4: Return Results // Return the array of GroupReportingUser records found. return result; } catch (error) { // Part 5: Handle Errors // Catch and handle any errors during the execution. If an error occurs, ensure the transaction is rolled back. throw error; } } public static async removeGroupReportingUser( loginUser: User, //The user performing the operation, used for privilege checking and logging. dbTransaction: Transaction, // The database transaction object to ensure the operation's atomicity. groupReportingUserId: number, //The ID of the GroupReportingUser to be removed. ): Promise<void> { // This method removes a GroupReportingUser record from the database. try { // Part 1: Privilege Checking // Call loginUser.checkPrivileges() method by passing: // SystemCode: Retrieve from app config. // PrivilegeCode: "GROUP_REPORTING_USER_REMOVE". const systemCode = ApplicationConfig.getComponentConfigValue('system-code'); const isPrivileged = await loginUser.checkPrivileges( systemCode, 'GROUP_REPORTING_USER_REMOVE', ); if (!isPrivileged) { throw new ClassError( 'GroupReportingUser', 'GroupReportingUserErrMsg06', 'Insufficient privileges to remove a user from the group', 'removeGroupReportingUser', 403, ); } // Part 2: Find User // Call GroupReportingUser.init(dbTransaction, groupReportingUserId) to check if the user exists. const groupReportingUser = await GroupReportingUser.init( dbTransaction, groupReportingUserId.toString(), ); // Part 3: Remove User // Call GroupReportingUser._Repo.destroy({ where: { GroupReportingUserId: groupReportingUserId }, transaction: dbTransaction }) to remove the user from the database. await GroupReportingUser._Repo.destroy( groupReportingUserId, dbTransaction, ); // Part 4: Record Create Activity // Initialise EntityValueBefore variable and set it to the GroupReportingUser instance before destruction. const entityValueBefore = { GroupReportingUserId: groupReportingUser.GroupReportingUserId, GroupCode: groupReportingUser.GroupCode, UserId: groupReportingUser.UserId, Rank: groupReportingUser.Rank, Status: groupReportingUser.Status, CreatedById: groupReportingUser.CreatedById, CreatedAt: groupReportingUser.CreatedAt, UpdatedById: groupReportingUser.UpdatedById, UpdatedAt: groupReportingUser.UpdatedAt, }; // Instantiate a new activity from the Activity class, and set: const activity = new Activity(); // ActivityId: activity.createId() // Action: ActionEnum.Delete // Description: Remove Group Reporting User // EntityType: GroupReportingUser // EntityId: groupReportingUserId // EntityValueBefore: Stringified representation of the GroupReportingUser instance before destroy // EntityValueAfter: Stringified empty object ({}) activity.ActivityId = activity.createId(); activity.Action = ActionEnum.DELETE; activity.Description = 'Remove Group Reporting User'; activity.EntityType = 'GroupReportingUser'; activity.EntityId = groupReportingUserId.toString(); activity.EntityValueBefore = JSON.stringify(entityValueBefore); activity.EntityValueAfter = JSON.stringify({}); // Call the activity.create() method by passing: // dbTransaction // userId: loginUser.UserId await activity.create(loginUser.ObjectId, dbTransaction); } catch (error) { throw error; } } }