EDMS/server/utils/departmentUtils.js
2025-05-31 16:58:30 +08:00

301 lines
6.8 KiB
JavaScript

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<Object>} 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<Object>} 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<Object|null>} 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<Object>} 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<Object>} 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<Array>} 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;