933 lines
30 KiB
TypeScript
933 lines
30 KiB
TypeScript
import { genSalt, hash } from "bcrypt";
|
||
import { db } from "../config/database.ts";
|
||
import { config } from "../config/env.ts";
|
||
|
||
// Helper function to hash password with proper salt generation
|
||
async function hashPassword(password: string): Promise<string> {
|
||
const salt = await genSalt(config.BCRYPT_ROUNDS);
|
||
return await hash(password, salt);
|
||
}
|
||
|
||
async function seedDatabase() {
|
||
try {
|
||
console.log("🔌 Connecting to database...");
|
||
await db.connect();
|
||
console.log("✅ Connected to database\n");
|
||
|
||
// 1. Seed Departments
|
||
console.log("📁 Seeding departments...");
|
||
const existingDepts = await db.query<{ count: number }[]>(
|
||
"SELECT COUNT(*) as count FROM departments",
|
||
);
|
||
|
||
if (existingDepts[0].count === 0) {
|
||
await db.execute(`
|
||
INSERT INTO departments (name) VALUES
|
||
('Tudki'),
|
||
('Dana'),
|
||
('Groundnut')
|
||
`);
|
||
console.log(" ✅ Departments created");
|
||
} else {
|
||
console.log(" ℹ️ Departments already exist");
|
||
}
|
||
|
||
// 2. Seed Sub-departments and Activities for all departments
|
||
console.log("📂 Seeding sub-departments and activities...");
|
||
|
||
// Get department IDs
|
||
const tudkiDeptResult = await db.query<{ id: number }[]>(
|
||
"SELECT id FROM departments WHERE name = ?",
|
||
["Tudki"],
|
||
);
|
||
const danaDeptResult = await db.query<{ id: number }[]>(
|
||
"SELECT id FROM departments WHERE name = ?",
|
||
["Dana"],
|
||
);
|
||
const groundnutDeptResult = await db.query<{ id: number }[]>(
|
||
"SELECT id FROM departments WHERE name = ?",
|
||
["Groundnut"],
|
||
);
|
||
|
||
const tudkiId = tudkiDeptResult[0]?.id;
|
||
const danaId = danaDeptResult[0]?.id;
|
||
const groundnutId = groundnutDeptResult[0]?.id;
|
||
|
||
// Define sub-departments and activities per department based on activities.md
|
||
const departmentData: {
|
||
[key: number]: {
|
||
subDept: string;
|
||
activities: { name: string; unit: string }[];
|
||
}[];
|
||
} = {};
|
||
|
||
if (groundnutId) {
|
||
departmentData[groundnutId] = [
|
||
{
|
||
subDept: "Loading/Unloading",
|
||
activities: [
|
||
{
|
||
name: "Mufali Aavak Katai (Groundnut Arrival Cutting)",
|
||
unit: "Per Bag",
|
||
},
|
||
{
|
||
name: "Mufali Aavak Dhaang (Groundnut Arrival Stacking)",
|
||
unit: "Per Bag",
|
||
},
|
||
{ name: "Dhaang Se Katai (Cutting from Stack)", unit: "Per Bag" },
|
||
{
|
||
name: "Guthli Bori Silai Dhaang (Kernel Bag Stitching Stack)",
|
||
unit: "Per Bag",
|
||
},
|
||
{
|
||
name: "Guthali dhada Pala Tulai Silai Dhaang / Loading",
|
||
unit: "Per Bag",
|
||
},
|
||
{ name: "Mufali Patthar Bori silai Dhaang", unit: "Per Bag" },
|
||
{
|
||
name: "Mufali Patthar Bori Utrai (Groundnut Stone Bag Unloading)",
|
||
unit: "Per Bag",
|
||
},
|
||
{
|
||
name: "Bardana Bandal Loading (Gunny Bundle Loading)",
|
||
unit: "Per Bag",
|
||
},
|
||
{ name: "Bardana Gatthi Loading/Unloading", unit: "Per Bag" },
|
||
{ name: "Black Dana Loading/Unloading", unit: "Per Bag" },
|
||
{ name: "Dala - Chomu & Jaipur (Branch)", unit: "Per Bag" },
|
||
],
|
||
},
|
||
{
|
||
subDept: "Pre Cleaning",
|
||
activities: [{ name: "Pre Cleaner", unit: "Fixed Rate-Per Person" }],
|
||
},
|
||
{
|
||
subDept: "Destoner",
|
||
activities: [{ name: "Destoner", unit: "Fixed Rate-Per Person" }],
|
||
},
|
||
{
|
||
subDept: "Water",
|
||
activities: [{ name: "Water", unit: "Fixed Rate-Per Person" }],
|
||
},
|
||
{
|
||
subDept: "Decordicater & Cleaning and Round Chalna",
|
||
activities: [
|
||
{ name: "Decordicater", unit: "Fixed Rate-Per Person" },
|
||
{
|
||
name: "Round Chalna (Round Sieving)",
|
||
unit: "Fixed Rate-Per Person",
|
||
},
|
||
{ name: "Cleaning", unit: "Fixed Rate-Per Person" },
|
||
],
|
||
},
|
||
{
|
||
subDept: "Round Chalna No.1",
|
||
activities: [{
|
||
name: "Round Chalna No.1 (Round Sieving No.1)",
|
||
unit: "Fixed Rate-Per Person",
|
||
}],
|
||
},
|
||
];
|
||
}
|
||
|
||
if (danaId) {
|
||
departmentData[danaId] = [
|
||
{
|
||
subDept: "Loading/Unloading",
|
||
activities: [
|
||
{
|
||
name: "Tulai Silai Loading (Weighing Stitching Loading)",
|
||
unit: "Per Bag",
|
||
},
|
||
{ name: "Dhaang se Loading (Loading from Stack)", unit: "Per Bag" },
|
||
{ name: "Silai Dhaang (Stitching Stack)", unit: "Per Bag" },
|
||
{
|
||
name: "Tulai Silai Dhaang Ikai No. 2 Machine ke Pass",
|
||
unit: "Per Bag",
|
||
},
|
||
{
|
||
name: "Dana Unloading/Dhaang (Grain Unloading/Stack)",
|
||
unit: "Per Bag",
|
||
},
|
||
{
|
||
name: "Dana Aavak Keep Katai (Grain Arrival Hopper Cutting)",
|
||
unit: "Per Bag",
|
||
},
|
||
{
|
||
name: "Kachri Dhada Pala Bharai Tulai Silai Load/Dhaang 70kg",
|
||
unit: "Per Bag",
|
||
},
|
||
{
|
||
name: "Kachri Dhaang se loading (Waste Loading from Stack)",
|
||
unit: "Per Bag",
|
||
},
|
||
{
|
||
name: "Keep Katai Khulla Katta (Hopper Cutting Open Bag)",
|
||
unit: "Per Bag",
|
||
},
|
||
{
|
||
name:
|
||
"Keep Katai Silai Kholkar (Hopper Cutting Opening Stitched)",
|
||
unit: "Per Bag",
|
||
},
|
||
{ name: "Bardana Paltai (Gunny Turning)", unit: "Per Bag" },
|
||
{ name: "Ekai No. 2 me Keep Katai Khula Bag", unit: "Per Bag" },
|
||
{ name: "Ekai No. 2 me Keep Katai Silai Kholkar", unit: "Per Bag" },
|
||
{ name: "Silai Loading Company Gadi Dala Sahit", unit: "Per Bag" },
|
||
{ name: "Kachri Bharai Silai Dhaang Chatt Par", unit: "Per Bag" },
|
||
{ name: "Bardana Unloading (Gunny Unloading)", unit: "Per Bag" },
|
||
{ name: "Grading", unit: "Per Bag" },
|
||
],
|
||
},
|
||
{
|
||
subDept: "Destoner",
|
||
activities: [{ name: "Destoner", unit: "Fixed Rate-Per Person" }],
|
||
},
|
||
{
|
||
subDept: "Gravity",
|
||
activities: [{ name: "Gravity", unit: "Fixed Rate-Per Person" }],
|
||
},
|
||
{
|
||
subDept: "Tank",
|
||
activities: [{ name: "Tank", unit: "Fixed Rate-Per Person" }],
|
||
},
|
||
{
|
||
subDept: "Sortex",
|
||
activities: [{ name: "Sortex", unit: "Fixed Rate-Per Person" }],
|
||
},
|
||
{
|
||
subDept: "X-Ray",
|
||
activities: [{ name: "X-Ray", unit: "Fixed Rate-Per Person" }],
|
||
},
|
||
{
|
||
subDept: "Kachri",
|
||
activities: [{
|
||
name: "Kachri (Waste)",
|
||
unit: "Fixed Rate-Per Person",
|
||
}],
|
||
},
|
||
{
|
||
subDept: "Other Works",
|
||
activities: [{ name: "Other Works", unit: "Fixed Rate-Per Person" }],
|
||
},
|
||
];
|
||
}
|
||
|
||
if (tudkiId) {
|
||
departmentData[tudkiId] = [
|
||
{
|
||
subDept: "Loading/Unloading",
|
||
activities: [
|
||
{
|
||
name: "Dana Loading/Unloading (Grain Loading/Unloading)",
|
||
unit: "Per Bag",
|
||
},
|
||
{ name: "Loading/Unloading 40 Kg", unit: "Per Bag" },
|
||
{
|
||
name: "Grading Chalne se Maal Bharai Tulai Silai Dhaang",
|
||
unit: "Per Bag",
|
||
},
|
||
{
|
||
name: "Grading Chalne se Maal Bharai Tulai Silai Loading",
|
||
unit: "Per Bag",
|
||
},
|
||
{
|
||
name: "Chilka Bharai silai Dhaang (Husk Filling Stitching Stack)",
|
||
unit: "Per Bag",
|
||
},
|
||
{
|
||
name: "Keep katai Bahar Se (Hopper Cutting from Outside)",
|
||
unit: "Per Bag",
|
||
},
|
||
{
|
||
name: "Keep katai Andar Se (Hopper Cutting from Inside)",
|
||
unit: "Per Bag",
|
||
},
|
||
{
|
||
name: "Cartoon Banai Vacume Bharai Tulai Packing and Dhaang",
|
||
unit: "Per Bag",
|
||
},
|
||
{
|
||
name: "Cartoon Banai Vacume Bharai Tulai Packing and Loading",
|
||
unit: "Per Bag",
|
||
},
|
||
{ name: "Katta Paltai (Bag Turning)", unit: "Per Bag" },
|
||
{ name: "Dhada Pala Bharai Tulai Silai Dhaang", unit: "Per Bag" },
|
||
{ name: "Dhada Pala Bharai Tulai Silai Loading", unit: "Per Bag" },
|
||
{ name: "Sike Maal Ki Silai Dhaang Andar", unit: "Per Bag" },
|
||
{ name: "Sike Maal Ki Silai Dhaang Bahar", unit: "Per Bag" },
|
||
{
|
||
name:
|
||
"Nakku Silai Dhaang Bahar (Rejection Stitching Stack Outside)",
|
||
unit: "Per Bag",
|
||
},
|
||
],
|
||
},
|
||
{
|
||
subDept: "Tank",
|
||
activities: [{ name: "Tank", unit: "Fixed Rate-Per Person" }],
|
||
},
|
||
{
|
||
subDept: "Grader (Machine)",
|
||
activities: [{
|
||
name: "Grader (Machine)",
|
||
unit: "Fixed Rate-Per Person",
|
||
}],
|
||
},
|
||
{
|
||
subDept: "Sortex",
|
||
activities: [{ name: "Sortex", unit: "Fixed Rate-Per Person" }],
|
||
},
|
||
{
|
||
subDept: "X-Ray",
|
||
activities: [{ name: "X-Ray", unit: "Fixed Rate-Per Person" }],
|
||
},
|
||
{
|
||
subDept: "Rejection",
|
||
activities: [{ name: "Rejection", unit: "Fixed Rate-Per Person" }],
|
||
},
|
||
{
|
||
subDept: "Store",
|
||
activities: [{ name: "Store", unit: "Fixed Rate-Per Person" }],
|
||
},
|
||
{
|
||
subDept: "Roster",
|
||
activities: [{ name: "Roster", unit: "Fixed Rate-Per Person" }],
|
||
},
|
||
{
|
||
subDept: "Blancher",
|
||
activities: [{ name: "Blancher", unit: "Fixed Rate-Per Person" }],
|
||
},
|
||
{
|
||
subDept: "Other Works",
|
||
activities: [{ name: "Other Works", unit: "Fixed Rate-Per Person" }],
|
||
},
|
||
];
|
||
}
|
||
|
||
// Check if activities table exists, if not create it
|
||
try {
|
||
await db.execute(`
|
||
CREATE TABLE IF NOT EXISTS activities (
|
||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||
sub_department_id INT NOT NULL,
|
||
name VARCHAR(255) NOT NULL,
|
||
unit_of_measurement ENUM('Per Bag', 'Fixed Rate-Per Person') NOT NULL DEFAULT 'Per Bag',
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
FOREIGN KEY (sub_department_id) REFERENCES sub_departments(id) ON DELETE CASCADE,
|
||
UNIQUE KEY unique_activity (sub_department_id, name)
|
||
)
|
||
`);
|
||
} catch (_e) {
|
||
// Table might already exist
|
||
}
|
||
|
||
// Seed sub-departments and activities for each department
|
||
for (const [deptId, subDepts] of Object.entries(departmentData)) {
|
||
const existingSubDepts = await db.query<{ count: number }[]>(
|
||
"SELECT COUNT(*) as count FROM sub_departments WHERE department_id = ?",
|
||
[deptId],
|
||
);
|
||
|
||
if (existingSubDepts[0].count === 0) {
|
||
for (const { subDept, activities } of subDepts) {
|
||
// Insert sub-department
|
||
await db.execute(
|
||
"INSERT INTO sub_departments (department_id, name) VALUES (?, ?)",
|
||
[deptId, subDept],
|
||
);
|
||
|
||
// Get the sub-department ID
|
||
const subDeptResult = await db.query<{ id: number }[]>(
|
||
"SELECT id FROM sub_departments WHERE department_id = ? AND name = ?",
|
||
[deptId, subDept],
|
||
);
|
||
|
||
if (subDeptResult.length > 0) {
|
||
const subDeptId = subDeptResult[0].id;
|
||
// Insert activities for this sub-department
|
||
for (const activity of activities) {
|
||
try {
|
||
await db.execute(
|
||
"INSERT INTO activities (sub_department_id, name, unit_of_measurement) VALUES (?, ?, ?)",
|
||
[subDeptId, activity.name, activity.unit],
|
||
);
|
||
} catch (_e) {
|
||
// Activity might already exist
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
console.log(" ✅ Sub-departments and activities created");
|
||
|
||
// 3. Seed SuperAdmin
|
||
console.log("👤 Seeding SuperAdmin user...");
|
||
const existingAdmin = await db.query<{ id: number }[]>(
|
||
"SELECT id FROM users WHERE username = ?",
|
||
["admin"],
|
||
);
|
||
|
||
const adminPassword = await hashPassword("admin123");
|
||
|
||
if (existingAdmin.length > 0) {
|
||
await db.execute(
|
||
"UPDATE users SET password = ?, is_active = TRUE WHERE username = ?",
|
||
[adminPassword, "admin"],
|
||
);
|
||
console.log(" ✅ SuperAdmin password updated");
|
||
} else {
|
||
await db.execute(
|
||
"INSERT INTO users (username, name, email, password, role, is_active) VALUES (?, ?, ?, ?, ?, ?)",
|
||
[
|
||
"admin",
|
||
"Super Admin",
|
||
"admin@workallocate.com",
|
||
adminPassword,
|
||
"SuperAdmin",
|
||
true,
|
||
],
|
||
);
|
||
console.log(" ✅ SuperAdmin created");
|
||
}
|
||
|
||
// 4. Seed Supervisors for all departments
|
||
console.log("👥 Seeding supervisors...");
|
||
const supervisorPassword = await hashPassword("supervisor123");
|
||
|
||
const supervisors = [
|
||
{
|
||
username: "rajesh.sharma.tudki",
|
||
name: "Rajesh Sharma",
|
||
email: "rajesh.sharma@workallocate.com",
|
||
deptId: tudkiId,
|
||
phone: "9414567890",
|
||
},
|
||
{
|
||
username: "sunil.verma.dana",
|
||
name: "Sunil Verma",
|
||
email: "sunil.verma@workallocate.com",
|
||
deptId: danaId,
|
||
phone: "9414567891",
|
||
},
|
||
{
|
||
username: "mahesh.agarwal.groundnut",
|
||
name: "Mahesh Agarwal",
|
||
email: "mahesh.agarwal@workallocate.com",
|
||
deptId: groundnutId,
|
||
phone: "9414567892",
|
||
},
|
||
];
|
||
|
||
for (const sup of supervisors) {
|
||
if (sup.deptId) {
|
||
const existing = await db.query<{ id: number }[]>(
|
||
"SELECT id FROM users WHERE username = ?",
|
||
[sup.username],
|
||
);
|
||
if (existing.length === 0) {
|
||
await db.execute(
|
||
"INSERT INTO users (username, name, email, password, role, department_id, is_active, phone_number) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
|
||
[
|
||
sup.username,
|
||
sup.name,
|
||
sup.email,
|
||
supervisorPassword,
|
||
"Supervisor",
|
||
sup.deptId,
|
||
true,
|
||
sup.phone,
|
||
],
|
||
);
|
||
console.log(` ✅ ${sup.name} created`);
|
||
} else {
|
||
console.log(` ℹ️ ${sup.name} already exists`);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 5. Seed Contractors for all departments
|
||
console.log("🏗️ Seeding contractors...");
|
||
const contractorPassword = await hashPassword("contractor123");
|
||
|
||
const contractors = [
|
||
// Groundnut Department Contractors
|
||
{
|
||
username: "ramesh.patel.gn",
|
||
name: "Ramesh Patel",
|
||
email: "ramesh.patel@workallocate.com",
|
||
deptId: groundnutId,
|
||
phone: "9829012345",
|
||
aadhar: "234567891234",
|
||
bankAccount: "50100123456789",
|
||
bankName: "HDFC Bank",
|
||
bankIfsc: "HDFC0001234",
|
||
agreementNo: "AGR-GN-2024-001",
|
||
pfNo: "RJ/JPR/12345/001",
|
||
esicNo: "12-34-567890-001-0001",
|
||
},
|
||
{
|
||
username: "kishan.meena.gn",
|
||
name: "Kishan Meena",
|
||
email: "kishan.meena@workallocate.com",
|
||
deptId: groundnutId,
|
||
phone: "9829012346",
|
||
aadhar: "345678912345",
|
||
bankAccount: "50100123456790",
|
||
bankName: "State Bank of India",
|
||
bankIfsc: "SBIN0005678",
|
||
agreementNo: "AGR-GN-2024-002",
|
||
pfNo: "RJ/JPR/12345/002",
|
||
esicNo: "12-34-567890-001-0002",
|
||
},
|
||
// Dana Department Contractors
|
||
{
|
||
username: "gopal.sharma.dana",
|
||
name: "Gopal Sharma",
|
||
email: "gopal.sharma@workallocate.com",
|
||
deptId: danaId,
|
||
phone: "9829012347",
|
||
aadhar: "456789123456",
|
||
bankAccount: "50100123456791",
|
||
bankName: "Punjab National Bank",
|
||
bankIfsc: "PUNB0009876",
|
||
agreementNo: "AGR-DN-2024-001",
|
||
pfNo: "RJ/JPR/12345/003",
|
||
esicNo: "12-34-567890-002-0001",
|
||
},
|
||
{
|
||
username: "mohan.yadav.dana",
|
||
name: "Mohan Yadav",
|
||
email: "mohan.yadav@workallocate.com",
|
||
deptId: danaId,
|
||
phone: "9829012348",
|
||
aadhar: "567891234567",
|
||
bankAccount: "50100123456792",
|
||
bankName: "Bank of Baroda",
|
||
bankIfsc: "BARB0004567",
|
||
agreementNo: "AGR-DN-2024-002",
|
||
pfNo: "RJ/JPR/12345/004",
|
||
esicNo: "12-34-567890-002-0002",
|
||
},
|
||
// Tudki Department Contractors
|
||
{
|
||
username: "suresh.kumar.tudki",
|
||
name: "Suresh Kumar",
|
||
email: "suresh.kumar@workallocate.com",
|
||
deptId: tudkiId,
|
||
phone: "9829012349",
|
||
aadhar: "678912345678",
|
||
bankAccount: "50100123456793",
|
||
bankName: "ICICI Bank",
|
||
bankIfsc: "ICIC0003456",
|
||
agreementNo: "AGR-TK-2024-001",
|
||
pfNo: "RJ/JPR/12345/005",
|
||
esicNo: "12-34-567890-003-0001",
|
||
},
|
||
{
|
||
username: "dinesh.gupta.tudki",
|
||
name: "Dinesh Gupta",
|
||
email: "dinesh.gupta@workallocate.com",
|
||
deptId: tudkiId,
|
||
phone: "9829012350",
|
||
aadhar: "789123456789",
|
||
bankAccount: "50100123456794",
|
||
bankName: "Axis Bank",
|
||
bankIfsc: "UTIB0002345",
|
||
agreementNo: "AGR-TK-2024-002",
|
||
pfNo: "RJ/JPR/12345/006",
|
||
esicNo: "12-34-567890-003-0002",
|
||
},
|
||
];
|
||
|
||
for (const con of contractors) {
|
||
const existing = await db.query<{ id: number }[]>(
|
||
"SELECT id FROM users WHERE username = ?",
|
||
[con.username],
|
||
);
|
||
if (existing.length === 0) {
|
||
await db.execute(
|
||
`INSERT INTO users (username, name, email, password, role, department_id, is_active,
|
||
phone_number, aadhar_number, bank_account_number, bank_name, bank_ifsc,
|
||
contractor_agreement_number, pf_number, esic_number)
|
||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||
[
|
||
con.username,
|
||
con.name,
|
||
con.email,
|
||
contractorPassword,
|
||
"Contractor",
|
||
con.deptId,
|
||
true,
|
||
con.phone,
|
||
con.aadhar,
|
||
con.bankAccount,
|
||
con.bankName,
|
||
con.bankIfsc,
|
||
con.agreementNo,
|
||
con.pfNo,
|
||
con.esicNo,
|
||
],
|
||
);
|
||
console.log(` ✅ ${con.name} created`);
|
||
} else {
|
||
console.log(` ℹ️ ${con.name} already exists`);
|
||
}
|
||
}
|
||
|
||
// 6. Seed Employees for all departments
|
||
console.log("👷 Seeding employees...");
|
||
const employeePassword = await hashPassword("employee123");
|
||
|
||
// Get contractor IDs for employee assignment
|
||
const contractorIds: { [key: string]: number } = {};
|
||
for (const con of contractors) {
|
||
const result = await db.query<{ id: number }[]>(
|
||
"SELECT id FROM users WHERE username = ?",
|
||
[con.username],
|
||
);
|
||
if (result.length > 0) {
|
||
contractorIds[con.username] = result[0].id;
|
||
}
|
||
}
|
||
|
||
const employees = [
|
||
// Groundnut Department Employees - Under Ramesh Patel
|
||
{
|
||
username: "ravi.singh.gn1",
|
||
name: "Ravi Singh",
|
||
email: "ravi.singh@workallocate.com",
|
||
deptId: groundnutId,
|
||
contractorUsername: "ramesh.patel.gn",
|
||
phone: "9876501001",
|
||
aadhar: "111122223333",
|
||
bankAccount: "30100111122233",
|
||
bankName: "State Bank of India",
|
||
bankIfsc: "SBIN0001111",
|
||
},
|
||
{
|
||
username: "amit.kumar.gn2",
|
||
name: "Amit Kumar",
|
||
email: "amit.kumar@workallocate.com",
|
||
deptId: groundnutId,
|
||
contractorUsername: "ramesh.patel.gn",
|
||
phone: "9876501002",
|
||
aadhar: "222233334444",
|
||
bankAccount: "30100222233344",
|
||
bankName: "Punjab National Bank",
|
||
bankIfsc: "PUNB0002222",
|
||
},
|
||
{
|
||
username: "vijay.meena.gn3",
|
||
name: "Vijay Meena",
|
||
email: "vijay.meena@workallocate.com",
|
||
deptId: groundnutId,
|
||
contractorUsername: "ramesh.patel.gn",
|
||
phone: "9876501003",
|
||
aadhar: "333344445555",
|
||
bankAccount: "30100333344455",
|
||
bankName: "HDFC Bank",
|
||
bankIfsc: "HDFC0003333",
|
||
},
|
||
// Groundnut Department Employees - Under Kishan Meena
|
||
{
|
||
username: "sanjay.yadav.gn4",
|
||
name: "Sanjay Yadav",
|
||
email: "sanjay.yadav@workallocate.com",
|
||
deptId: groundnutId,
|
||
contractorUsername: "kishan.meena.gn",
|
||
phone: "9876501004",
|
||
aadhar: "444455556666",
|
||
bankAccount: "30100444455566",
|
||
bankName: "Bank of Baroda",
|
||
bankIfsc: "BARB0004444",
|
||
},
|
||
{
|
||
username: "prakash.sharma.gn5",
|
||
name: "Prakash Sharma",
|
||
email: "prakash.sharma@workallocate.com",
|
||
deptId: groundnutId,
|
||
contractorUsername: "kishan.meena.gn",
|
||
phone: "9876501005",
|
||
aadhar: "555566667777",
|
||
bankAccount: "30100555566677",
|
||
bankName: "ICICI Bank",
|
||
bankIfsc: "ICIC0005555",
|
||
},
|
||
// Dana Department Employees - Under Gopal Sharma
|
||
{
|
||
username: "rampal.verma.dn1",
|
||
name: "Rampal Verma",
|
||
email: "rampal.verma@workallocate.com",
|
||
deptId: danaId,
|
||
contractorUsername: "gopal.sharma.dana",
|
||
phone: "9876502001",
|
||
aadhar: "666677778888",
|
||
bankAccount: "30100666677788",
|
||
bankName: "State Bank of India",
|
||
bankIfsc: "SBIN0006666",
|
||
},
|
||
{
|
||
username: "lakhan.singh.dn2",
|
||
name: "Lakhan Singh",
|
||
email: "lakhan.singh@workallocate.com",
|
||
deptId: danaId,
|
||
contractorUsername: "gopal.sharma.dana",
|
||
phone: "9876502002",
|
||
aadhar: "777788889999",
|
||
bankAccount: "30100777788899",
|
||
bankName: "Punjab National Bank",
|
||
bankIfsc: "PUNB0007777",
|
||
},
|
||
{
|
||
username: "bharat.meena.dn3",
|
||
name: "Bharat Meena",
|
||
email: "bharat.meena@workallocate.com",
|
||
deptId: danaId,
|
||
contractorUsername: "gopal.sharma.dana",
|
||
phone: "9876502003",
|
||
aadhar: "888899990000",
|
||
bankAccount: "30100888899900",
|
||
bankName: "HDFC Bank",
|
||
bankIfsc: "HDFC0008888",
|
||
},
|
||
// Dana Department Employees - Under Mohan Yadav
|
||
{
|
||
username: "kailash.patel.dn4",
|
||
name: "Kailash Patel",
|
||
email: "kailash.patel@workallocate.com",
|
||
deptId: danaId,
|
||
contractorUsername: "mohan.yadav.dana",
|
||
phone: "9876502004",
|
||
aadhar: "999900001111",
|
||
bankAccount: "30100999900011",
|
||
bankName: "Bank of Baroda",
|
||
bankIfsc: "BARB0009999",
|
||
},
|
||
{
|
||
username: "shyam.gupta.dn5",
|
||
name: "Shyam Gupta",
|
||
email: "shyam.gupta@workallocate.com",
|
||
deptId: danaId,
|
||
contractorUsername: "mohan.yadav.dana",
|
||
phone: "9876502005",
|
||
aadhar: "000011112222",
|
||
bankAccount: "30100000011122",
|
||
bankName: "ICICI Bank",
|
||
bankIfsc: "ICIC0000000",
|
||
},
|
||
// Tudki Department Employees - Under Suresh Kumar
|
||
{
|
||
username: "ganesh.kumar.tk1",
|
||
name: "Ganesh Kumar",
|
||
email: "ganesh.kumar@workallocate.com",
|
||
deptId: tudkiId,
|
||
contractorUsername: "suresh.kumar.tudki",
|
||
phone: "9876503001",
|
||
aadhar: "112233445566",
|
||
bankAccount: "30100112233445",
|
||
bankName: "State Bank of India",
|
||
bankIfsc: "SBIN0001122",
|
||
},
|
||
{
|
||
username: "naresh.yadav.tk2",
|
||
name: "Naresh Yadav",
|
||
email: "naresh.yadav@workallocate.com",
|
||
deptId: tudkiId,
|
||
contractorUsername: "suresh.kumar.tudki",
|
||
phone: "9876503002",
|
||
aadhar: "223344556677",
|
||
bankAccount: "30100223344556",
|
||
bankName: "Punjab National Bank",
|
||
bankIfsc: "PUNB0002233",
|
||
},
|
||
{
|
||
username: "mukesh.sharma.tk3",
|
||
name: "Mukesh Sharma",
|
||
email: "mukesh.sharma@workallocate.com",
|
||
deptId: tudkiId,
|
||
contractorUsername: "suresh.kumar.tudki",
|
||
phone: "9876503003",
|
||
aadhar: "334455667788",
|
||
bankAccount: "30100334455667",
|
||
bankName: "HDFC Bank",
|
||
bankIfsc: "HDFC0003344",
|
||
},
|
||
// Tudki Department Employees - Under Dinesh Gupta
|
||
{
|
||
username: "pappu.singh.tk4",
|
||
name: "Pappu Singh",
|
||
email: "pappu.singh@workallocate.com",
|
||
deptId: tudkiId,
|
||
contractorUsername: "dinesh.gupta.tudki",
|
||
phone: "9876503004",
|
||
aadhar: "445566778899",
|
||
bankAccount: "30100445566778",
|
||
bankName: "Bank of Baroda",
|
||
bankIfsc: "BARB0004455",
|
||
},
|
||
{
|
||
username: "deepak.verma.tk5",
|
||
name: "Deepak Verma",
|
||
email: "deepak.verma@workallocate.com",
|
||
deptId: tudkiId,
|
||
contractorUsername: "dinesh.gupta.tudki",
|
||
phone: "9876503005",
|
||
aadhar: "556677889900",
|
||
bankAccount: "30100556677889",
|
||
bankName: "ICICI Bank",
|
||
bankIfsc: "ICIC0005566",
|
||
},
|
||
{
|
||
username: "rahul.meena.tk6",
|
||
name: "Rahul Meena",
|
||
email: "rahul.meena@workallocate.com",
|
||
deptId: tudkiId,
|
||
contractorUsername: "dinesh.gupta.tudki",
|
||
phone: "9876503006",
|
||
aadhar: "667788990011",
|
||
bankAccount: "30100667788990",
|
||
bankName: "Axis Bank",
|
||
bankIfsc: "UTIB0006677",
|
||
},
|
||
];
|
||
|
||
for (const emp of employees) {
|
||
const existing = await db.query<{ id: number }[]>(
|
||
"SELECT id FROM users WHERE username = ?",
|
||
[emp.username],
|
||
);
|
||
if (existing.length === 0) {
|
||
const contractorId = contractorIds[emp.contractorUsername];
|
||
if (contractorId) {
|
||
await db.execute(
|
||
`INSERT INTO users (username, name, email, password, role, department_id, contractor_id, is_active,
|
||
phone_number, aadhar_number, bank_account_number, bank_name, bank_ifsc)
|
||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||
[
|
||
emp.username,
|
||
emp.name,
|
||
emp.email,
|
||
employeePassword,
|
||
"Employee",
|
||
emp.deptId,
|
||
contractorId,
|
||
true,
|
||
emp.phone,
|
||
emp.aadhar,
|
||
emp.bankAccount,
|
||
emp.bankName,
|
||
emp.bankIfsc,
|
||
],
|
||
);
|
||
console.log(` ✅ ${emp.name} created`);
|
||
}
|
||
} else {
|
||
console.log(` ℹ️ ${emp.name} already exists`);
|
||
}
|
||
}
|
||
|
||
// 7. Seed Contractor Rates for all contractors
|
||
console.log("💰 Seeding contractor rates...");
|
||
const today = new Date().toISOString().split("T")[0];
|
||
|
||
// Get all sub-departments for rate assignment
|
||
const allSubDepts = await db.query<
|
||
{ id: number; name: string; department_id: number }[]
|
||
>(
|
||
"SELECT id, name, department_id FROM sub_departments",
|
||
);
|
||
|
||
// Create rates for each contractor based on their department
|
||
for (const [username, contractorId] of Object.entries(contractorIds)) {
|
||
const existingRate = await db.query<{ id: number }[]>(
|
||
"SELECT id FROM contractor_rates WHERE contractor_id = ?",
|
||
[contractorId],
|
||
);
|
||
|
||
if (existingRate.length === 0) {
|
||
// Find the contractor's department
|
||
const contractor = contractors.find((c) => c.username === username);
|
||
if (contractor) {
|
||
// Get sub-departments for this contractor's department
|
||
const deptSubDepts = allSubDepts.filter((sd) =>
|
||
sd.department_id === contractor.deptId
|
||
);
|
||
|
||
// Create rates for Loading/Unloading sub-department (Per Bag rates)
|
||
const loadingSubDept = deptSubDepts.find((sd) =>
|
||
sd.name === "Loading/Unloading"
|
||
);
|
||
if (loadingSubDept) {
|
||
// Get activities for this sub-department
|
||
const activities = await db.query<{ id: number; name: string }[]>(
|
||
"SELECT id, name FROM activities WHERE sub_department_id = ? LIMIT 3",
|
||
[loadingSubDept.id],
|
||
);
|
||
|
||
for (const activity of activities) {
|
||
const rate = 5 + Math.random() * 3; // Random rate between 5-8 per bag
|
||
await db.execute(
|
||
"INSERT INTO contractor_rates (contractor_id, sub_department_id, activity, rate, effective_date) VALUES (?, ?, ?, ?, ?)",
|
||
[
|
||
contractorId,
|
||
loadingSubDept.id,
|
||
activity.name,
|
||
rate.toFixed(2),
|
||
today,
|
||
],
|
||
);
|
||
}
|
||
}
|
||
|
||
// Create fixed rates for other sub-departments
|
||
const fixedSubDepts = deptSubDepts.filter((sd) =>
|
||
sd.name !== "Loading/Unloading"
|
||
);
|
||
for (const subDept of fixedSubDepts.slice(0, 2)) { // Limit to 2 fixed rate sub-depts per contractor
|
||
const rate = 300 + Math.random() * 200; // Random rate between 300-500 per person
|
||
await db.execute(
|
||
"INSERT INTO contractor_rates (contractor_id, sub_department_id, rate, effective_date) VALUES (?, ?, ?, ?)",
|
||
[contractorId, subDept.id, rate.toFixed(2), today],
|
||
);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
console.log(" ✅ Contractor rates created");
|
||
|
||
console.log(`
|
||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||
✅ Database seeding completed successfully!
|
||
|
||
🔑 Default Login Credentials:
|
||
|
||
SuperAdmin:
|
||
Username: admin
|
||
Password: admin123
|
||
|
||
Supervisors (password: supervisor123):
|
||
- Tudki: rajesh.sharma.tudki
|
||
- Dana: sunil.verma.dana
|
||
- Groundnut: mahesh.agarwal.groundnut
|
||
|
||
Contractors (password: contractor123):
|
||
- Groundnut: ramesh.patel.gn, kishan.meena.gn
|
||
- Dana: gopal.sharma.dana, mohan.yadav.dana
|
||
- Tudki: suresh.kumar.tudki, dinesh.gupta.tudki
|
||
|
||
Employees (password: employee123):
|
||
- Use any employee username like ravi.singh.gn1, rampal.verma.dn1, ganesh.kumar.tk1
|
||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||
`);
|
||
} catch (error) {
|
||
console.error("❌ Error seeding database:", (error as Error).message);
|
||
Deno.exit(1);
|
||
} finally {
|
||
await db.close();
|
||
}
|
||
}
|
||
|
||
await seedDatabase();
|