added DD-AM role in roles also aligned with role mapping for onboarding flow
This commit is contained in:
parent
837be9bce1
commit
c6b7b79021
@ -23,7 +23,8 @@ const rolesToSeed = [
|
|||||||
{ roleCode: ROLES.CEO, roleName: 'CEO', category: 'LEADERSHIP', description: 'Chief Executive Officer' },
|
{ roleCode: ROLES.CEO, roleName: 'CEO', category: 'LEADERSHIP', description: 'Chief Executive Officer' },
|
||||||
{ roleCode: ROLES.SPARES_MANAGER, roleName: 'Spares Manager', category: 'DEPARTMENT', description: 'Spares Department Clearance' },
|
{ roleCode: ROLES.SPARES_MANAGER, roleName: 'Spares Manager', category: 'DEPARTMENT', description: 'Spares Department Clearance' },
|
||||||
{ roleCode: ROLES.SERVICE_MANAGER, roleName: 'Service Manager', category: 'DEPARTMENT', description: 'Service Department Clearance' },
|
{ roleCode: ROLES.SERVICE_MANAGER, roleName: 'Service Manager', category: 'DEPARTMENT', description: 'Service Department Clearance' },
|
||||||
{ roleCode: ROLES.ACCOUNTS_MANAGER, roleName: 'Accounts Manager', category: 'DEPARTMENT', description: 'Accounts Department Clearance' }
|
{ roleCode: ROLES.ACCOUNTS_MANAGER, roleName: 'Accounts Manager', category: 'DEPARTMENT', description: 'Accounts Department Clearance' },
|
||||||
|
{ roleCode: ROLES.DD_AM, roleName: 'DD-AM', category: 'SALES', description: 'Dealer Development Area Manager' }
|
||||||
];
|
];
|
||||||
|
|
||||||
async function seedRoles() {
|
async function seedRoles() {
|
||||||
|
|||||||
@ -31,7 +31,8 @@ async function seed() {
|
|||||||
{ roleCode: 'FDD', roleName: 'FDD Team', category: 'EXTERNAL' },
|
{ roleCode: 'FDD', roleName: 'FDD Team', category: 'EXTERNAL' },
|
||||||
{ roleCode: 'Legal Admin', roleName: 'Legal Admin', category: 'DEPARTMENT' },
|
{ roleCode: 'Legal Admin', roleName: 'Legal Admin', category: 'DEPARTMENT' },
|
||||||
{ roleCode: 'CEO', roleName: 'CEO', category: 'NATIONAL' },
|
{ roleCode: 'CEO', roleName: 'CEO', category: 'NATIONAL' },
|
||||||
{ roleCode: 'CCO', roleName: 'CCO', category: 'NATIONAL' }
|
{ roleCode: 'CCO', roleName: 'CCO', category: 'NATIONAL' },
|
||||||
|
{ roleCode: 'DD-AM', roleName: 'Dealer Development Area Manager', category: 'AREA' }
|
||||||
];
|
];
|
||||||
|
|
||||||
for (const r of roles) {
|
for (const r of roles) {
|
||||||
@ -139,7 +140,8 @@ async function seed() {
|
|||||||
{ email: 'manav@royalenfield.com', name: 'manav', role: 'ZBH', zone: 'North Zone' },
|
{ email: 'manav@royalenfield.com', name: 'manav', role: 'ZBH', zone: 'North Zone' },
|
||||||
{ email: 'piyush@royalenfield.com', name: 'piyush', role: 'DD-ZM', zone: 'North Zone' },
|
{ email: 'piyush@royalenfield.com', name: 'piyush', role: 'DD-ZM', zone: 'North Zone' },
|
||||||
{ email: 'manish@royalenfield.com', name: 'manish', role: 'RBM', zone: 'North Zone' },
|
{ email: 'manish@royalenfield.com', name: 'manish', role: 'RBM', zone: 'North Zone' },
|
||||||
{ email: 'abhishek@royalenfield.com', name: 'abhishek', role: 'ASM', district: 'South Delhi' }
|
{ email: 'abhishek@royalenfield.com', name: 'abhishek', role: 'ASM', district: 'South Delhi' },
|
||||||
|
{ email: 'bharghav@gmail.com', name: 'Bharghav', role: 'DD-AM', district: 'South Delhi' }
|
||||||
];
|
];
|
||||||
for (const m of frontendMocks) {
|
for (const m of frontendMocks) {
|
||||||
const assignment: any = {};
|
const assignment: any = {};
|
||||||
|
|||||||
@ -384,12 +384,12 @@ export const createUser = async (req: AuthRequest, res: Response) => {
|
|||||||
|
|
||||||
if (Array.isArray(assignments) && assignments.length > 0) {
|
if (Array.isArray(assignments) && assignments.length > 0) {
|
||||||
await upsertUserAssignments(user.id, assignments, req.user?.id);
|
await upsertUserAssignments(user.id, assignments, req.user?.id);
|
||||||
} else if (districts && Array.isArray(districts) && roleCode === 'ASM') {
|
} else if (districts && Array.isArray(districts) && ['ASM', 'DD-AM'].includes(roleCode)) {
|
||||||
const targetRole = await Role.findOne({ where: { roleCode: 'ASM' } });
|
const targetRole = await Role.findOne({ where: { roleCode } });
|
||||||
if (targetRole) {
|
if (targetRole) {
|
||||||
for (const distId of districts) {
|
for (const distId of districts) {
|
||||||
const sampleDistrict = await db.District.findByPk(distId);
|
const sampleDistrict = await db.District.findByPk(distId);
|
||||||
const managerCode = await resolveManagerCode(targetRole.id, 'ASM', null);
|
const managerCode = await resolveManagerCode(targetRole.id, roleCode, null);
|
||||||
await db.UserRole.create({
|
await db.UserRole.create({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
roleId: targetRole.id,
|
roleId: targetRole.id,
|
||||||
@ -551,16 +551,20 @@ export const updateUser = async (req: AuthRequest, res: Response) => {
|
|||||||
|
|
||||||
if (Array.isArray(assignments)) {
|
if (Array.isArray(assignments)) {
|
||||||
await upsertUserAssignments(id as string, assignments, req.user?.id);
|
await upsertUserAssignments(id as string, assignments, req.user?.id);
|
||||||
} else if (districts && Array.isArray(districts) && roleCode === 'ASM') {
|
} else if (districts && Array.isArray(districts) && ['ASM', 'DD-AM'].includes(roleCode)) {
|
||||||
const targetRole = await Role.findOne({ where: { roleCode: 'ASM' } });
|
const targetRole = await Role.findOne({ where: { roleCode } });
|
||||||
if (!targetRole) throw new Error(`ASM role not found`);
|
if (!targetRole) throw new Error(`${roleCode} role not found`);
|
||||||
|
|
||||||
await db.UserRole.destroy({ where: { userId: id, roleId: targetRole.id } });
|
await db.UserRole.destroy({ where: { userId: id, roleId: targetRole.id } });
|
||||||
await db.District.update({ asmId: null, asmCode: null }, { where: { asmId: id } });
|
if (roleCode === 'ASM') {
|
||||||
|
await db.District.update({ asmId: null, asmCode: null }, { where: { asmId: id } });
|
||||||
|
} else {
|
||||||
|
await db.District.update({ ddAmId: null, ddAmCode: null }, { where: { ddAmId: id } });
|
||||||
|
}
|
||||||
|
|
||||||
for (const distId of districts) {
|
for (const distId of districts) {
|
||||||
const sampleDistrict = await db.District.findByPk(distId);
|
const sampleDistrict = await db.District.findByPk(distId);
|
||||||
const managerCode = await resolveManagerCode(targetRole.id, 'ASM', null);
|
const managerCode = await resolveManagerCode(targetRole.id, roleCode, null);
|
||||||
await db.UserRole.create({
|
await db.UserRole.create({
|
||||||
userId: id,
|
userId: id,
|
||||||
roleId: targetRole.id,
|
roleId: targetRole.id,
|
||||||
|
|||||||
@ -887,7 +887,7 @@ export const getASMs = async (req: Request, res: Response) => {
|
|||||||
try {
|
try {
|
||||||
const asms = await db.User.findAll({
|
const asms = await db.User.findAll({
|
||||||
where: {
|
where: {
|
||||||
roleCode: { [db.Sequelize.Op.in]: ['ASM', 'AREA SALES MANAGER'] },
|
roleCode: { [db.Sequelize.Op.in]: ['ASM', 'AREA SALES MANAGER', 'DD-AM', ROLES.DD_AM] },
|
||||||
isActive: true
|
isActive: true
|
||||||
},
|
},
|
||||||
include: [
|
include: [
|
||||||
@ -896,7 +896,7 @@ export const getASMs = async (req: Request, res: Response) => {
|
|||||||
as: 'userRoles',
|
as: 'userRoles',
|
||||||
where: { isActive: true },
|
where: { isActive: true },
|
||||||
required: false,
|
required: false,
|
||||||
include: [{ model: db.Role, as: 'role', where: { roleCode: 'ASM' } }]
|
include: [{ model: db.Role, as: 'role', where: { roleCode: { [db.Sequelize.Op.in]: ['ASM', 'DD-AM', ROLES.DD_AM] } } }]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
model: db.District,
|
model: db.District,
|
||||||
@ -906,15 +906,29 @@ export const getASMs = async (req: Request, res: Response) => {
|
|||||||
{ model: db.Region, as: 'region', attributes: ['id', 'name'] },
|
{ model: db.Region, as: 'region', attributes: ['id', 'name'] },
|
||||||
{ model: db.Zone, as: 'zone', attributes: ['id', 'name'] }
|
{ model: db.Zone, as: 'zone', attributes: ['id', 'name'] }
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
model: db.District,
|
||||||
|
as: 'managedDdAmDistricts',
|
||||||
|
include: [
|
||||||
|
{ model: db.State, as: 'state', attributes: ['id', 'name'] },
|
||||||
|
{ model: db.Region, as: 'region', attributes: ['id', 'name'] },
|
||||||
|
{ model: db.Zone, as: 'zone', attributes: ['id', 'name'] }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
order: [['fullName', 'ASC']]
|
order: [['fullName', 'ASC']]
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = (asms || []).map((u: any) => {
|
const result = (asms || []).map((u: any) => {
|
||||||
const districts = u.managedAsmDistricts || [];
|
const asmDistricts = u.managedAsmDistricts || [];
|
||||||
const asmRoleAssignment = (u.userRoles || []).find((r: any) => r.role?.roleCode === 'ASM');
|
const ddAmDistricts = u.managedDdAmDistricts || [];
|
||||||
const asmCode = asmRoleAssignment?.managerCode || u.employeeId;
|
const districts = [...asmDistricts, ...ddAmDistricts];
|
||||||
|
|
||||||
|
const roleAssignment = (u.userRoles || []).find((r: any) =>
|
||||||
|
['ASM', 'DD-AM'].includes(r.role?.roleCode)
|
||||||
|
);
|
||||||
|
const managerCode = roleAssignment?.managerCode || u.employeeId;
|
||||||
|
|
||||||
const zoneSet = new Set();
|
const zoneSet = new Set();
|
||||||
const regionSet = new Set();
|
const regionSet = new Set();
|
||||||
@ -943,7 +957,8 @@ export const getASMs = async (req: Request, res: Response) => {
|
|||||||
email: u.email,
|
email: u.email,
|
||||||
phone: u.mobileNumber,
|
phone: u.mobileNumber,
|
||||||
employeeId: u.employeeId,
|
employeeId: u.employeeId,
|
||||||
asmCode: asmCode || 'N/A',
|
asmCode: managerCode || 'N/A',
|
||||||
|
roleCode: u.roleCode,
|
||||||
status: u.status,
|
status: u.status,
|
||||||
zoneId: zones[0]?.id || '',
|
zoneId: zones[0]?.id || '',
|
||||||
zoneName: zones[0]?.name || 'Unassigned',
|
zoneName: zones[0]?.name || 'Unassigned',
|
||||||
|
|||||||
@ -683,8 +683,13 @@ const assignStageEvaluators = async (appIdOrId: string) => {
|
|||||||
// --- INTERVIEWS ---
|
// --- INTERVIEWS ---
|
||||||
|
|
||||||
// --- GROUND STAKEHOLDERS (Area / District Level) ---
|
// --- GROUND STAKEHOLDERS (Area / District Level) ---
|
||||||
// SRS §9.3.4: ASM is responsible for ground opportunity identification and field validation.
|
// SRS §9.3.4: DD-AM is responsible for ground opportunity identification and field validation in onboarding.
|
||||||
if (district.asmId) evaluatorMappings['DD'] = [{ id: district.asmId, role: 'ASM' }];
|
// Falls back to ASM if DD-AM is not assigned for this district.
|
||||||
|
if (district.ddAmId) {
|
||||||
|
evaluatorMappings['DD'] = [{ id: district.ddAmId, role: 'DD-AM' }];
|
||||||
|
} else if (district.asmId) {
|
||||||
|
evaluatorMappings['DD'] = [{ id: district.asmId, role: 'ASM' }];
|
||||||
|
}
|
||||||
|
|
||||||
// Level 1: DD-ZM (District manager) + RBM (Region manager)
|
// Level 1: DD-ZM (District manager) + RBM (Region manager)
|
||||||
if (district.zmId) evaluatorMappings[1].push({ id: district.zmId, role: 'DD-ZM' });
|
if (district.zmId) evaluatorMappings[1].push({ id: district.zmId, role: 'DD-ZM' });
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user