Dealer_Onboarding_Backend/scripts/seed_normalized_data.ts

300 lines
13 KiB
TypeScript

import 'dotenv/config';
import db from '../src/database/models/index.js';
import bcrypt from 'bcryptjs';
import { syncLocationManagers, syncRegionManager, syncZoneManager } from '../src/modules/master/syncHierarchy.service.js';
import { APPLICATION_STAGES, APPLICATION_STATUS, BUSINESS_TYPES } from '../src/common/config/constants.js';
const { Role, Zone, Region, State, District, User, UserRole } = db;
async function seed() {
console.log('--- Seeding Comprehensive Golden Path Data ---');
await db.sequelize.authenticate();
await db.sequelize.sync({ alter: false });
const hashedPassword = await bcrypt.hash('Admin@123', 10);
// 1. Ensure Roles exist
const roles = [
{ roleCode: 'NBH', roleName: 'National Business Head', category: 'NATIONAL' },
{ roleCode: 'DD Head', roleName: 'DD Head', category: 'NATIONAL' },
{ roleCode: 'ZBH', roleName: 'Zonal Business Head', category: 'ZONAL' },
{ roleCode: 'DD Lead', roleName: 'DD Lead', category: 'ZONAL' },
{ roleCode: 'RBM', roleName: 'Regional Business Manager', category: 'REGIONAL' },
{ roleCode: 'DD-ZM', roleName: 'DD Zonal Manager', category: 'ZONAL' },
{ roleCode: 'ASM', roleName: 'Area Sales Manager', category: 'AREA' },
{ roleCode: 'Super Admin', roleName: 'Super Admin', category: 'NATIONAL' },
{ roleCode: 'Finance', roleName: 'Finance', category: 'DEPARTMENT' },
{ roleCode: 'Dealer', roleName: 'Dealer', category: 'EXTERNAL' },
{ roleCode: 'DD Admin', roleName: 'DD Admin', category: 'ADMIN' },
{ roleCode: 'ARCHITECTURE', roleName: 'Architecture Team', category: 'DEPARTMENT' },
{ roleCode: 'FDD', roleName: 'FDD Team', category: 'EXTERNAL' },
{ roleCode: 'Legal Admin', roleName: 'Legal Admin', category: 'DEPARTMENT' },
{ roleCode: 'CEO', roleName: 'CEO', category: 'NATIONAL' },
{ roleCode: 'CCO', roleName: 'CCO', category: 'NATIONAL' }
];
for (const r of roles) {
await Role.findOrCreate({ where: { roleCode: r.roleCode }, defaults: r });
}
const mapUserRole = async (userRec: any, roleCode: string, assignment: any = {}) => {
const role = await Role.findOne({ where: { roleCode } });
if (role) {
await UserRole.findOrCreate({
where: { userId: userRec.id, roleId: role.id, ...assignment },
defaults: { userId: userRec.id, roleId: role.id, ...assignment, isActive: true, isPrimary: true }
});
}
};
// 2. Create Hierarchical Structure
// Zones
const zones = [
{ name: 'North Zone', code: 'ZONE-N' },
{ name: 'South Zone', code: 'ZONE-S' }
];
const zoneMap: Record<string, any> = {};
for (const z of zones) {
const [zone] = await Zone.findOrCreate({ where: { name: z.name }, defaults: z });
zoneMap[z.name] = zone;
}
// Regions
const regions = [
{ name: 'NCR Region', zoneName: 'North Zone' },
{ name: 'Punjab Region', zoneName: 'North Zone' },
{ name: 'Karnataka Region', zoneName: 'South Zone' },
{ name: 'Tamil Nadu Region', zoneName: 'South Zone' }
];
const regionMap: Record<string, any> = {};
for (const r of regions) {
const zone = zoneMap[r.zoneName];
const [region] = await Region.findOrCreate({
where: { name: r.name },
defaults: { name: r.name, zoneId: zone.id }
});
regionMap[r.name] = region;
}
// 3. States & Districts (Mapping South Delhi to NCR)
const ncrRegion = regionMap['NCR Region'];
const [delhiState] = await State.findOrCreate({
where: { name: 'DELHI' },
defaults: { name: 'DELHI', zoneId: ncrRegion.zoneId }
});
const [southDelhi] = await District.findOrCreate({
where: { name: 'South Delhi' },
defaults: {
name: 'South Delhi',
stateId: delhiState.id,
regionId: ncrRegion.id,
zoneId: ncrRegion.zoneId,
isActive: true
}
});
// Ensure it's explicitly under NCR
await southDelhi.update({ regionId: ncrRegion.id });
console.log('✅ Mapping: South Delhi -> NCR Region');
// 3. Create Key Management Users
// National / Administrative
const nationalUsers = [
{ email: 'nbh@royalenfield.com', name: 'Alwyn John', role: 'NBH' },
{ email: 'ddhead@royalenfield.com', name: 'Vikram Singh', role: 'DD Head' },
{ email: 'finance@royalenfield.com', name: 'Rahul Verma', role: 'Finance' },
{ email: 'admin@royalenfield.com', name: 'Laxman H', role: 'Super Admin' },
{ email: 'lince@gmail.com', name: 'Lince', role: 'DD Admin' },
{ email: 'fdd@royalenfield.com', name: 'FDD Partner', role: 'FDD' },
{ email: 'architecture@royalenfield.com', name: 'RE Architect', role: 'ARCHITECTURE' },
{ email: 'legal@royalenfield.com', name: 'Legal Admin', role: 'Legal Admin' },
{ email: 'ceo@royalenfield.com', name: 'CEO User', role: 'CEO' },
{ email: 'cco@royalenfield.com', name: 'CCO User', role: 'CCO' }
];
for (const u of nationalUsers) {
const [user] = await User.findOrCreate({
where: { email: u.email },
defaults: { fullName: u.name, roleCode: u.role, password: hashedPassword, status: 'active' }
});
await mapUserRole(user, u.role);
}
// Frontend Mock Users for Quick Login (Ensuring exact matches)
const frontendMocks = [
{ email: 'ddlead@royalenfield.com', name: 'Meera Iyer', role: 'DD Lead', zone: 'North Zone' },
{ email: 'yashwin@gmail.com', name: 'Yashwin', role: 'ZBH', zone: 'North Zone' },
{ email: 'kenil@gmail.com', name: 'Kenil', role: 'DD Lead', zone: 'North Zone' },
{ email: 'dealer@royalenfield.com', name: 'Amit Sharma', role: 'Dealer', district: 'South Delhi' }
];
for (const m of frontendMocks) {
const assignment: any = {};
if (m.zone) assignment.zoneId = zoneMap[m.zone].id;
if (m.district) {
const d = await District.findOne({ where: { name: m.district } });
if (d) {
assignment.districtId = d.id;
assignment.zoneId = d.zoneId;
assignment.regionId = d.regionId;
}
}
const [user] = await User.findOrCreate({
where: { email: m.email },
defaults: { fullName: m.name, roleCode: m.role, password: hashedPassword, status: 'active' }
});
await mapUserRole(user, m.role, assignment);
}
// Zonal Business Heads (Additional)
const zbhUsers = [
{ email: 'zbh.south@royalenfield.com', name: 'Srinivasan K', zone: 'South Zone' }
];
for (const u of zbhUsers) {
const zone = zoneMap[u.zone];
const [user] = await User.findOrCreate({
where: { email: u.email },
defaults: { fullName: u.name, roleCode: 'ZBH', password: hashedPassword, status: 'active' }
});
await mapUserRole(user, 'ZBH', { zoneId: zone.id });
}
// Regional Managers (RBMs)
const rbmUsers = [
{ email: 'rbm.ncr@royalenfield.com', name: 'Sanjay Dutt', region: 'NCR Region' },
{ email: 'rbm.punjab@royalenfield.com', name: 'Harpreet Singh', region: 'Punjab Region' },
{ email: 'rbm.kar@royalenfield.com', name: 'Manish Kumar', region: 'Karnataka Region' }
];
for (const u of rbmUsers) {
const region = regionMap[u.region];
const [user] = await User.findOrCreate({
where: { email: u.email },
defaults: { fullName: u.name, roleCode: 'RBM', password: hashedPassword, status: 'active' }
});
await mapUserRole(user, 'RBM', { regionId: region.id, zoneId: region.zoneId });
}
// Zonal Managers (DD-ZM) - Assigned to Regions
const zmUsers = [
{ email: 'zm.ncr@royalenfield.com', name: 'Rajesh Khanna', region: 'NCR Region' },
{ email: 'zm.south@royalenfield.com', name: 'Kartik Subbaraj', region: 'Karnataka Region' }
];
for (const u of zmUsers) {
const region = regionMap[u.region];
const [user] = await User.findOrCreate({
where: { email: u.email },
defaults: { fullName: u.name, roleCode: 'DD-ZM', password: hashedPassword, status: 'active' }
});
await mapUserRole(user, 'DD-ZM', { regionId: region.id, zoneId: region.zoneId });
}
// ASMs (Assigned to Districts)
const asmUsers = [
{ email: 'asm.sdelhi@royalenfield.com', name: 'Arun Jaitley', district: 'South Delhi' },
{ email: 'asm.noida@royalenfield.com', name: 'Kishan Reddy', district: 'NOIDA' },
{ email: 'asm.bangalore@royalenfield.com', name: 'Vishnu Dev', district: 'Bangalore Urban' }
];
for (const u of asmUsers) {
const district = await District.findOne({ where: { name: u.district } });
if (district) {
const [user] = await User.findOrCreate({
where: { email: u.email },
defaults: { fullName: u.name, roleCode: 'ASM', password: hashedPassword, status: 'active' }
});
await mapUserRole(user, 'ASM', { districtId: district.id, zoneId: district.zoneId, regionId: district.regionId });
}
}
// 10. Create Test Dealer for Offboarding Workflows
console.log('🌱 Creating Test Dealer for Offboarding...');
const dealerUser = await User.findOne({ where: { email: 'dealer@royalenfield.com' } });
const asmUser = await User.findOne({ where: { email: 'asm.sdelhi@royalenfield.com' } });
if (dealerUser && southDelhi) {
// 1. Create Placeholder Application (The "Golden Path" root)
const [application] = await db.Application.findOrCreate({
where: { applicationId: 'APP-TEST-001' },
defaults: {
applicationId: 'APP-TEST-001',
applicantName: 'Amit Sharma',
email: 'dealer@royalenfield.com',
phone: '9876543210',
businessType: BUSINESS_TYPES.DEALERSHIP,
submittedBy: dealerUser.id, // Corrected: Prospect/Applicant initiates the request
constitutionType: 'Private Limited',
currentStage: APPLICATION_STAGES.APPROVED,
overallStatus: APPLICATION_STATUS.ONBOARDED,
progressPercentage: 100,
isShortlisted: true,
districtId: southDelhi.id,
documents: []
}
});
// 2. Create SAP/Dealer Codes (Dependency for Dealer Profile)
const [dealerCodeRecord] = await db.DealerCode.findOrCreate({
where: { dealerCode: 'D1001' },
defaults: {
dealerCode: 'D1001',
applicationId: application.id,
salesCode: 'S1001',
serviceCode: 'V1001',
gmaCode: 'G1001',
gearCode: 'GE1001',
sapMasterId: 'SAP-999',
status: 'active'
}
});
// 3. Create Dealer Profile (Linked to App and Code)
const [dealerProfile] = await db.Dealer.findOrCreate({
where: { applicationId: application.id },
defaults: {
applicationId: application.id,
dealerCodeId: dealerCodeRecord.id,
legalName: 'Amit Sharma Dealership Pvt Ltd',
businessName: 'Royal Enfield South Delhi',
constitutionType: 'Private Limited',
status: 'active',
onboardedAt: new Date()
}
});
// 4. Update Dealer User to link to the Dealer Profile
await dealerUser.update({ dealerId: dealerProfile.id });
// 5. Create Main Outlet
// Note: As per Outlet model, dealerId refers to the User ID (Owner)
await db.Outlet.findOrCreate({
where: { code: 'O001' },
defaults: {
dealerId: dealerUser.id, // Linked to the User ID as owner
name: 'Main Outlet - South Delhi',
code: 'O001',
type: 'Dealership',
address: '123, MG Road, South Delhi',
city: 'Delhi',
state: 'Delhi',
pincode: '110001',
establishedDate: new Date('2020-01-01'),
districtId: southDelhi.id,
status: 'Active'
}
});
console.log('✅ Successfully seeded Golden Path: Application -> DealerCode -> Dealer Profile -> User -> Outlet');
}
console.log('--- Triggering Hierarchy Synchronization ---');
// ... (rest same)
console.log('--- Golden Path Seeding Complete ---');
}
seed().catch(err => {
console.error(err);
process.exit(1);
}).then(() => process.exit(0));