/* eslint-disable @typescript-eslint/no-explicit-any */ 'use server'; /* IMPORT */ import { and, asc, desc, ilike, or, } from 'drizzle-orm'; import { countRegEvalCriteria, deleteRegEvalCriteria, deleteRegEvalCriteriaDetails, insertRegEvalCriteria, insertRegEvalCriteriaDetails, selectRegEvalCriteria, selectRegEvalCriteriaWithDetails, updateRegEvalCriteria, updateRegEvalCriteriaDetails, } from './repository'; import db from '@/db/db'; import { filterColumns } from '@/lib/filter-columns'; import { REG_EVAL_CRITERIA_CATEGORY2_ENUM, REG_EVAL_CRITERIA_CATEGORY_ENUM, REG_EVAL_CRITERIA_ITEM_ENUM, regEvalCriteriaView, type NewRegEvalCriteria, type NewRegEvalCriteriaDetails, type RegEvalCriteria, type RegEvalCriteriaDetails, type RegEvalCriteriaView, } from '@/db/schema'; import { type GetRegEvalCriteriaSchema } from './validations'; // ---------------------------------------------------------------------------------------------------- /* TYPES */ // ---------------------------------------------------------------------------------------------------- /* FUNCTION FOR GETTING CRITERIA */ async function getRegEvalCriteria(input: GetRegEvalCriteriaSchema) { try { const offset = (input.page - 1) * input.perPage; const advancedWhere = filterColumns({ table: regEvalCriteriaView, filters: input.filters, joinOperator: input.joinOperator, }); // Filtering let globalWhere; if (input.search) { const s = `%${input.search}%`; globalWhere = or( ilike(regEvalCriteriaView.category, s), ilike(regEvalCriteriaView.item, s), ilike(regEvalCriteriaView.classification, s), ); } const finalWhere = and(advancedWhere, globalWhere); // Sorting const orderBy = input.sort.length > 0 ? input.sort.map((item) => { return item.desc ? desc(regEvalCriteriaView[item.id]) : asc(regEvalCriteriaView[item.id]); }) : [asc(regEvalCriteriaView.id)]; // Getting Data const { data, total } = await db.transaction(async (tx) => { const data = await selectRegEvalCriteria(tx, { where: finalWhere, orderBy, offset, limit: input.perPage, }); const total = await countRegEvalCriteria(tx, finalWhere); return { data, total }; }); const pageCount = Math.ceil(total / input.perPage); return { data, pageCount }; } catch (err) { console.error('Error in Getting Regular Evaluation Criteria: ', err); return { data: [], pageCount: 0 }; } } /* FUNCTION FOR GETTING CRITERIA WITH DETAILS */ async function getRegEvalCriteriaWithDetails(id: number) { try { return await db.transaction(async (tx) => { return await selectRegEvalCriteriaWithDetails(tx, id); }); } catch (err) { console.error('Error in Getting Regular Evaluation Criteria with Details: ', err); return null; } } // ---------------------------------------------------------------------------------------------------- /* FUNCTION FOR CREATING CRITERIA WITH DETAILS */ async function createRegEvalCriteriaWithDetails( criteriaData: NewRegEvalCriteria, detailList: Omit[], ) { try { return await db.transaction(async (tx) => { const criteria = await insertRegEvalCriteria(tx, criteriaData); const criteriaId = criteria.id; const newDetailList = detailList.map((detailItem, index) => ({ ...detailItem, criteriaId, orderIndex: detailItem.orderIndex || index, })); const criteriaDetails: NewRegEvalCriteriaDetails[] = []; for (let idx = 0; idx < newDetailList.length; idx += 1) { criteriaDetails.push(await insertRegEvalCriteriaDetails(tx, newDetailList[idx])); } return { ...criteria, criteriaDetails }; }); } catch (error) { console.error('Error in Creating New Regular Evaluation Criteria with Details: ', error); throw new Error('Failed to Create New Regular Evaluation Criteria with Details'); } } // ---------------------------------------------------------------------------------------------------- /* FUNCTION FOR MODIFYING CRITERIA WITH DETAILS */ async function modifyRegEvalCriteriaWithDetails( id: number, criteriaData: Partial, detailList: Partial[], ) { try { return await db.transaction(async (tx) => { const modifiedCriteria = await updateRegEvalCriteria(tx, id, criteriaData); const originCriteria = await getRegEvalCriteriaWithDetails(id); const originCriteriaDetails = originCriteria?.criteriaDetails || []; const detailIdList = detailList .filter(item => item.id !== undefined) .map(item => item.id); const toDeleteIdList = originCriteriaDetails.filter( (item) => !detailIdList.includes(item.id), ); for (const item of toDeleteIdList) { await deleteRegEvalCriteriaDetails(tx, item.id); } const criteriaDetails = []; for (let idx = 0; idx < detailList.length; idx += 1) { const detailItem = detailList[idx]; const isUpdate = detailItem.id; const isInsert = !detailItem.id && detailItem.detail; if (isUpdate) { const updatedDetail = await updateRegEvalCriteriaDetails(tx, detailItem.id!, detailItem); criteriaDetails.push(updatedDetail); } else if (isInsert) { const newDetailItem = { ...detailItem, criteriaId: id, detail: detailItem.detail!, orderIndex: detailItem.orderIndex || idx, }; const insertedDetail = await insertRegEvalCriteriaDetails(tx, newDetailItem); criteriaDetails.push(insertedDetail); } } return { ...modifiedCriteria, criteriaDetails }; }); } catch (error) { console.error('Error in Modifying Regular Evaluation Criteria with Details: ', error); throw new Error('Failed to Modify Regular Evaluation Criteria with Details'); } } // ---------------------------------------------------------------------------------------------------- /* FUNCTION FOR REMOVING CRITERIA WITH DETAILS */ async function removeRegEvalCriteria(id: number) { try { return await db.transaction(async (tx) => { return await deleteRegEvalCriteria(tx, id); }); } catch (err) { console.error('Error in Removing Regular Evaluation Criteria with Details: ', err); throw new Error('Failed to Remove Regular Evaluation Criteria with Details'); } } /* FUNCTION FOR REMOVING CRITERIA DETAILS */ async function removeRegEvalCriteriaDetails(id: number) { try { return await db.transaction(async (tx) => { return await deleteRegEvalCriteriaDetails(tx, id); }); } catch (err) { console.error('Error in Removing Regular Evaluation Criteria Details: ', err); throw new Error('Failed to Remove Regular Evaluation Criteria Details'); } } // ---------------------------------------------------------------------------------------------------- /* EXPORT */ export { createRegEvalCriteriaWithDetails, modifyRegEvalCriteriaWithDetails, getRegEvalCriteria, getRegEvalCriteriaWithDetails, removeRegEvalCriteria, removeRegEvalCriteriaDetails, };