import prisma from './prisma'; /** * Collection of utility functions for working with departments */ export const DepartmentUtils = { /** * Create a new department * * @param {Object} data Department data * @param {string} data.dp_name Department name * @param {number} data.org_id Organization ID * @returns {Promise} Created department */ async create(data) { if (!data.dp_name) { throw new Error('Department name is required'); } if (!data.org_id) { throw new Error('Organization ID is required'); } // Check if organization exists const organization = await prisma.organization.findUnique({ where: { org_id: parseInt(data.org_id) } }); if (!organization) { throw new Error(`Organization with ID ${data.org_id} not found`); } return prisma.department.create({ data: { dp_name: data.dp_name, org_id: parseInt(data.org_id) } }); }, /** * Get all departments with pagination and filtering * * @param {Object} options Query options * @param {number} options.page Page number * @param {number} options.limit Items per page * @param {string} options.search Search term * @param {number} options.orgId Filter by organization ID * @returns {Promise} Departments and pagination metadata */ async getAll({ page = 1, limit = 10, search = '', orgId = null }) { const skip = (page - 1) * limit; // Define filters const filters = { where: {} }; // Filter by organization if provided if (orgId) { filters.where.org_id = parseInt(orgId); } // Add search filter if provided if (search) { filters.where = { ...filters.where, dp_name: { contains: search } }; } // Get departments with pagination const [departments, total] = await Promise.all([ prisma.department.findMany({ ...filters, skip, take: limit, orderBy: { dp_name: 'asc' }, include: { organization: { select: { org_id: true, org_name: true } }, _count: { select: { cabinets: true, user: true } } } }), prisma.department.count(filters) ]); // Calculate pagination metadata const totalPages = Math.ceil(total / limit); return { departments, pagination: { page, limit, total, totalPages, hasNextPage: page < totalPages, hasPrevPage: page > 1 } }; }, /** * Get department by ID * * @param {number} id Department ID * @returns {Promise} Department or null if not found */ async getById(id) { if (isNaN(parseInt(id))) { throw new Error('Invalid department ID'); } return prisma.department.findUnique({ where: { dp_id: parseInt(id) }, include: { organization: { select: { org_id: true, org_name: true, org_country: true, org_state: true, org_active: true } }, cabinets: { select: { cb_id: true } }, user: { select: { userID: true, userUsername: true, userFullName: true, userEmail: true, userStatus: true } } } }); }, /** * Update a department * * @param {number} id Department ID * @param {Object} data Department data * @returns {Promise} Updated department */ async update(id, data) { if (isNaN(parseInt(id))) { throw new Error('Invalid department ID'); } // Check if department exists const existingDept = await prisma.department.findUnique({ where: { dp_id: parseInt(id) } }); if (!existingDept) { throw new Error('Department not found'); } // Validate required fields if (!data.dp_name) { throw new Error('Department name is required'); } // If org_id is provided, check if organization exists if (data.org_id !== undefined) { const orgId = parseInt(data.org_id); if (isNaN(orgId)) { throw new Error('Invalid organization ID format'); } const organization = await prisma.organization.findUnique({ where: { org_id: orgId } }); if (!organization) { throw new Error(`Organization with ID ${data.org_id} not found`); } } return prisma.department.update({ where: { dp_id: parseInt(id) }, data: { dp_name: data.dp_name, org_id: data.org_id !== undefined ? parseInt(data.org_id) : existingDept.org_id } }); }, /** * Delete a department * * @param {number} id Department ID * @returns {Promise} Deleted department */ async delete(id) { if (isNaN(parseInt(id))) { throw new Error('Invalid department ID'); } // Check if department exists and get related entities const existingDept = await prisma.department.findUnique({ where: { dp_id: parseInt(id) }, include: { cabinets: { select: { cb_id: true } }, user: { select: { userID: true } } } }); if (!existingDept) { throw new Error('Department not found'); } // Check if department has related cabinets if (existingDept.cabinets.length > 0) { throw new Error(`Cannot delete department with existing cabinets. Remove all cabinets first (${existingDept.cabinets.length} found).`); } // Check if department has related users if (existingDept.user.length > 0) { throw new Error(`Cannot delete department with existing users. Reassign or remove all users first (${existingDept.user.length} found).`); } return prisma.department.delete({ where: { dp_id: parseInt(id) } }); }, /** * Get departments by organization ID * * @param {number} orgId Organization ID * @returns {Promise} List of departments */ async getByOrganization(orgId) { if (isNaN(parseInt(orgId))) { throw new Error('Invalid organization ID'); } return prisma.department.findMany({ where: { org_id: parseInt(orgId) }, orderBy: { dp_name: 'asc' }, include: { _count: { select: { cabinets: true, user: true } } } }); } }; export default DepartmentUtils;