add: CRUD user schedule

This commit is contained in:
Muhammad Afif
2025-10-21 10:59:25 +07:00
parent 0de69aa219
commit a9ad9cccc7
6 changed files with 316 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
const UserScheduleService = require('../services/user_schedule.service');
const { setResponse, setResponsePaging, checkValidate } = require('../helpers/utils');
const { insertUserScheduleSchema, updateUserScheduleSchema } = require('../validate/user_schedule.schema');
class UserScheduleController {
// Get all User Schedule
static async getAll(req, res) {
const queryParams = req.query;
const results = await UserScheduleService.getAllUserScheduleDb(queryParams);
const response = await setResponsePaging(queryParams, results, 'User Schedule found')
res.status(response.statusCode).json(response);
}
// Get User Schedule by ID
static async getById(req, res) {
const { id } = req.params;
const results = await UserScheduleService.getUserScheduleByID(id);
const response = await setResponse(results, 'User Schedule found')
res.status(response.statusCode).json(response);
}
// Create User Schedule
static async create(req, res) {
const { error, value } = await checkValidate(insertUserScheduleSchema, req)
if (error) {
return res.status(400).json(setResponse(error, 'Validation failed', 400));
}
value.userId = req.user.user_id
const results = await UserScheduleService.createUserSchedules(value);
const response = await setResponse(results, 'User Schedule created successfully')
return res.status(response.statusCode).json(response);
}
// Update User Schedule
static async update(req, res) {
const { id } = req.params;
const { error, value } = checkValidate(updateUserScheduleSchema, req)
if (error) {
return res.status(400).json(setResponse(error, 'Validation failed', 400));
}
value.userId = req.user.user_id
const results = await UserScheduleService.updateUserSchedules(id, value);
const response = await setResponse(results, 'User Schedule updated successfully')
res.status(response.statusCode).json(response);
}
// Soft delete User Schedule
static async delete(req, res) {
const { id } = req.params;
const results = await UserScheduleService.deleteUserSchedules(id, req.user.user_id);
const response = await setResponse(results, 'User Schedule deleted successfully')
res.status(response.statusCode).json(response);
}
}
module.exports = UserScheduleController;

116
db/user_schedule.db.js Normal file
View File

@@ -0,0 +1,116 @@
const pool = require("../config");
const getAllUserScheduleDb = async (searchParams = {}) => {
let queryParams = [];
// Handle pagination
if (searchParams.limit) {
const page = Number(searchParams.page ?? 1) - 1;
queryParams = [Number(searchParams.limit ?? 10), page];
}
const { whereOrConditions, whereParamOr } = pool.buildStringOrIlike(
["a.user_id", "a.user_schedule_id", "a.schedule_id", "a.user_schedule_id"],
searchParams.criteria,
queryParams
);
if (whereParamOr) queryParams = whereParamOr;
const { whereConditions, whereParamAnd } = pool.buildFilterQuery(
[
{ column: "a.user_id", param: searchParams.user_id, type: "int" },
{ column: "a.user_schedule_id", param: searchParams.user_schedule_id, type: "int" },
{ column: "a.schedule_id", param: searchParams.schedule_id, type: "int" },
{ column: "a.user_schedule_id", param: searchParams.user_schedule_id, type: "int" },
],
queryParams
);
if (whereParamAnd) queryParams = whereParamAnd;
const queryText = `
SELECT
COUNT(*) OVER() AS total_data,
a.*,
b.schedule_date,
c.shift_name,
c.start_time,
c.end_time,
d.user_fullname
FROM user_schedule a
LEFT JOIN schedule b ON a.user_schedule_id = b.schedule_id
LEFT JOIN m_shift c ON a.user_schedule_id = c.shift_id
LEFT JOIN m_users d ON a.user_schedule_id = d.user_id
WHERE a.deleted_at IS NULL
${whereConditions.length > 0 ? ` AND ${whereConditions.join(" AND ")}` : ""}
${whereOrConditions ? ` ${whereOrConditions}` : ""}
ORDER BY a.user_schedule_id ASC
${searchParams.limit ? `OFFSET $2 ROWS FETCH NEXT $1 ROWS ONLY` : ""}
`;
const result = await pool.query(queryText, queryParams);
const total =
result?.recordset?.length > 0
? parseInt(result.recordset[0].total_data, 10)
: 0;
return { data: result.recordset, total };
};
const getUserScheduleByIdDb = async (id) => {
const queryText = `
SELECT
a.*,
b.schedule_date,
c.shift_name,
c.start_time,
c.end_time,
d.user_fullname
FROM user_schedule a
LEFT JOIN schedule b ON a.user_schedule_id = b.schedule_id
LEFT JOIN m_shift c ON a.user_schedule_id = c.shift_id
LEFT JOIN m_users d ON a.user_schedule_id = d.user_id
WHERE a.user_schedule_id = $1 AND a.deleted_at IS NULL
`;
const result = await pool.query(queryText, [id]);
return result.recordset?.[0] || null;
};
const insertUserScheduleDb = async (store) => {
const { query: queryText, values } = pool.buildDynamicInsert("user_schedule", store);
const result = await pool.query(queryText, values);
const insertedId = result.recordset?.[0]?.inserted_id;
return insertedId ? await getUserScheduleByIdDb(insertedId) : null;
};
const updateUserScheduleDb = async (id, data) => {
const store = { ...data };
const whereData = { user_schedule_id: id };
const { query: queryText, values } = pool.buildDynamicUpdate(
"user_schedule",
store,
whereData
);
await pool.query(`${queryText} AND deleted_at IS NULL`, values);
return getUserScheduleByIdDb(id);
};
const deleteUserScheduleDb = async (id, deletedBy) => {
const queryText = `
UPDATE user_schedule
SET deleted_at = CURRENT_TIMESTAMP, deleted_by = $1
WHERE user_schedule_id = $2 AND deleted_at IS NULL
`;
await pool.query(queryText, [deletedBy, id]);
return true;
};
module.exports = {
getAllUserScheduleDb,
getUserScheduleByIdDb,
insertUserScheduleDb,
updateUserScheduleDb,
deleteUserScheduleDb,
};

View File

@@ -9,6 +9,7 @@ const shift = require("./shift.route");
const schedule = require("./schedule.route");
const status = require("./status.route");
const unit = require("./unit.route")
const UserSchedule = require("./user_schedule.route")
router.use("/auth", auth);
router.use("/user", users);
@@ -20,6 +21,7 @@ router.use("/shift", shift);
router.use("/schedule", schedule);
router.use("/status", status);
router.use("/unit", unit);
router.use("/user-schedule", UserSchedule)
module.exports = router;

View File

@@ -0,0 +1,17 @@
const express = require('express');
const UserSchedulesController = require('../controllers/user_schedule.controller');
const verifyToken = require("../middleware/verifyToken")
const verifyAccess = require("../middleware/verifyAccess")
const router = express.Router();
router.route("/")
.get(verifyToken.verifyAccessToken, UserSchedulesController.getAll)
.post(verifyToken.verifyAccessToken, verifyAccess(), UserSchedulesController.create);
router.route("/:id")
.get(verifyToken.verifyAccessToken, UserSchedulesController.getById)
.put(verifyToken.verifyAccessToken, verifyAccess(), UserSchedulesController.update)
.delete(verifyToken.verifyAccessToken, verifyAccess(), UserSchedulesController.delete);
module.exports = router;

View File

@@ -0,0 +1,89 @@
const {
getAllUserScheduleDb,
getUserScheduleByIdDb,
insertUserScheduleDb,
updateUserScheduleDb,
deleteUserScheduleDb
} = require('../db/user_schedule.db');
const { ErrorHandler } = require('../helpers/error');
class UserScheduleService {
// Get all devices
static async getAllUserScheduleDb(param) {
try {
const results = await getAllUserScheduleDb(param);
results.data.map(element => {
});
return results
} catch (error) {
throw new ErrorHandler(error.statusCode, error.message);
}
}
// Get device by ID
static async getUserScheduleByID(id) {
try {
const result = await getUserScheduleByIdDb(id);
if (result.length < 1) throw new ErrorHandler(404, 'User Schedule not found');
return result;
} catch (error) {
throw new ErrorHandler(error.statusCode, error.message);
}
}
// Create device
static async createUserSchedules(data) {
try {
if (!data || typeof data !== 'object') data = {};
const result = await insertUserScheduleDb(data);
return result;
} catch (error) {
throw new ErrorHandler(error.statusCode, error.message);
}
}
// Update device
static async updateUserSchedules(id, data) {
try {
if (!data || typeof data !== 'object') data = {};
const dataExist = await getUserScheduleByIdDb(id);
if (dataExist.length < 1) {
throw new ErrorHandler(404, 'UserSchedules not found');
}
const result = await updateUserScheduleDb(id, data);
return result;
} catch (error) {
throw new ErrorHandler(error.statusCode, error.message);
}
}
// Soft delete device
static async deleteUserSchedules(id, userId) {
try {
const dataExist = await getUserScheduleByIdDb(id);
if (dataExist.length < 1) {
throw new ErrorHandler(404, 'UserSchedules not found');
}
const result = await deleteUserScheduleDb(id, userId);
return result;
} catch (error) {
throw new ErrorHandler(error.statusCode, error.message);
}
}
}
module.exports = UserScheduleService;

View File

@@ -0,0 +1,21 @@
const Joi = require("joi");
// ========================
// User Schedule Validation
// ========================
const insertUserScheduleSchema = Joi.object({
user_id: Joi.number().integer().required(),
schedule_id: Joi.number().integer().required(),
shift_id: Joi.number().required(),
});
const updateUserScheduleSchema = Joi.object({
user_id: Joi.number().integer().optional(),
schedule_id: Joi.number().integer().optional(),
shift_id: Joi.number().optional()
}).min(1);
module.exports = {
insertUserScheduleSchema,
updateUserScheduleSchema
};