Compare commits
No commits in common. "eb97317b1c74ce4bccf0ad0c20f0de4771ee847a" and "85c9b01bb2046d43862b8febd05fe0b731b770f6" have entirely different histories.
eb97317b1c
...
85c9b01bb2
@ -1,104 +0,0 @@
|
|||||||
import pool from "../../shared/db.ts";
|
|
||||||
|
|
||||||
export const getEmployees = async (ctx: any) => {
|
|
||||||
try {
|
|
||||||
const [rows] = await pool.query(
|
|
||||||
`SELECT
|
|
||||||
e.employee_code,
|
|
||||||
p.first_name,
|
|
||||||
p.last_name,
|
|
||||||
d.name AS department,
|
|
||||||
j.title AS designation,
|
|
||||||
c.work_email
|
|
||||||
FROM employees e
|
|
||||||
JOIN partners p ON e.partner_id = p.partner_id
|
|
||||||
JOIN contracts c ON e.employee_id = c.employee_id
|
|
||||||
JOIN departments d ON c.department_id = d.department_id
|
|
||||||
JOIN job_positions j ON c.job_id = j.job_id`
|
|
||||||
);
|
|
||||||
|
|
||||||
ctx.response.body = {
|
|
||||||
success: true,
|
|
||||||
count: (rows as any[]).length,
|
|
||||||
data: rows
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
ctx.response.status = 500;
|
|
||||||
ctx.response.body = {
|
|
||||||
success: false,
|
|
||||||
error: (error as Error).message
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const createEmployee = async (ctx: any) => {
|
|
||||||
// 1. Extract the JSON payload from the request
|
|
||||||
const body = ctx.request.body;
|
|
||||||
if (body.type() !== "json") {
|
|
||||||
ctx.response.status = 400;
|
|
||||||
ctx.response.body = { success: false, error: "Invalid JSON body" };
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = await body.json();
|
|
||||||
|
|
||||||
// 2. Acquire a dedicated connection from the pool for our transaction
|
|
||||||
const connection = await pool.getConnection();
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 3. Start the transaction
|
|
||||||
await connection.beginTransaction();
|
|
||||||
|
|
||||||
// STEP A: Insert into Partners
|
|
||||||
const [partnerResult] = await connection.execute(
|
|
||||||
`INSERT INTO partners (first_name, last_name, dob, gender, personal_email, personal_phone)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?)`,
|
|
||||||
[data.firstName, data.lastName, data.dob, data.gender, data.personalEmail, data.personalPhone]
|
|
||||||
);
|
|
||||||
const partnerId = (partnerResult as any).insertId;
|
|
||||||
|
|
||||||
// STEP B: Insert into Addresses
|
|
||||||
await connection.execute(
|
|
||||||
`INSERT INTO addresses (partner_id, address_type, door_number, landmark, address_line, pincode, district, state)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
||||||
[partnerId, data.address.type, data.address.doorNumber, data.address.landmark, data.address.line, data.address.pincode, data.address.district, data.address.state]
|
|
||||||
);
|
|
||||||
|
|
||||||
// STEP C: Insert into Employees
|
|
||||||
const [employeeResult] = await connection.execute(
|
|
||||||
`INSERT INTO employees (employee_code, partner_id, company_id, branch_id, is_active)
|
|
||||||
VALUES (?, ?, ?, ?, ?)`,
|
|
||||||
[data.employeeCode, partnerId, data.companyId, data.branchId, true]
|
|
||||||
);
|
|
||||||
const employeeId = (employeeResult as any).insertId;
|
|
||||||
|
|
||||||
// STEP D: Insert into Contracts
|
|
||||||
await connection.execute(
|
|
||||||
`INSERT INTO contracts (employee_id, department_id, job_id, work_email, date_joining, probation_days, status, salary_structure_id)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
||||||
[employeeId, data.departmentId, data.jobId, data.workEmail, data.dateJoining, data.probationDays, 'ACTIVE', data.salaryStructureId]
|
|
||||||
);
|
|
||||||
|
|
||||||
// 4. Commit the transaction if all steps succeed
|
|
||||||
await connection.commit();
|
|
||||||
|
|
||||||
ctx.response.status = 201;
|
|
||||||
ctx.response.body = {
|
|
||||||
success: true,
|
|
||||||
message: "Employee created successfully",
|
|
||||||
employee_id: employeeId
|
|
||||||
};
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
// 5. Rollback everything if any step fails
|
|
||||||
await connection.rollback();
|
|
||||||
ctx.response.status = 500;
|
|
||||||
ctx.response.body = {
|
|
||||||
success: false,
|
|
||||||
error: "Transaction failed: " + (error as Error).message
|
|
||||||
};
|
|
||||||
} finally {
|
|
||||||
// 6. Release the connection back to the pool
|
|
||||||
connection.release();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -1,12 +1,38 @@
|
|||||||
import { Router } from "@oak/oak";
|
import { Router } from "@oak/oak";
|
||||||
import { getEmployees, createEmployee } from "./controllers/employee.controller.ts";
|
import pool from "../shared/db.ts";
|
||||||
|
|
||||||
const router = new Router();
|
const router = new Router();
|
||||||
|
|
||||||
// Route definitions are now clean and easy to read
|
// GET all employees with their relational data
|
||||||
router.get("/api/v1/employees", getEmployees);
|
router.get("/api/employees", async (ctx) => {
|
||||||
|
try {
|
||||||
// Create a new employee
|
const [rows] = await pool.query(
|
||||||
router.post("/api/v1/employees", createEmployee);
|
`SELECT
|
||||||
|
e.employee_code,
|
||||||
|
p.first_name,
|
||||||
|
p.last_name,
|
||||||
|
d.name AS department,
|
||||||
|
j.title AS designation,
|
||||||
|
c.work_email
|
||||||
|
FROM employees e
|
||||||
|
JOIN partners p ON e.partner_id = p.partner_id
|
||||||
|
JOIN contracts c ON e.employee_id = c.employee_id
|
||||||
|
JOIN departments d ON c.department_id = d.department_id
|
||||||
|
JOIN job_positions j ON c.job_id = j.job_id`
|
||||||
|
);
|
||||||
|
|
||||||
|
ctx.response.body = {
|
||||||
|
success: true,
|
||||||
|
count: (rows as any[]).length,
|
||||||
|
data: rows
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
ctx.response.status = 500;
|
||||||
|
ctx.response.body = {
|
||||||
|
success: false,
|
||||||
|
error: (error as Error).message
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
Loading…
x
Reference in New Issue
Block a user