const { ErrorHandler } = require("../helpers/error"); const { getErrorCodesByBrandIdDb, getErrorCodeByIdDb, getErrorCodeByBrandAndCodeDb, createErrorCodeDb, updateErrorCodeDb, deleteErrorCodeDb, getAllErrorCodesDb, } = require("../db/brand_code.db"); const { getSolutionsByErrorCodeIdDb, createSolutionDb, updateSolutionDb, deleteSolutionDb, } = require("../db/brand_code_solution.db"); const { getSparepartsByErrorCodeIdDb, insertMultipleErrorCodeSparepartsDb, updateErrorCodeSparepartsDb, } = require("../db/brand_sparepart.db"); const { getFileUploadByPathDb } = require("../db/file_uploads.db"); class ErrorCodeService { static async getAllErrorCodes(param) { try { const results = await getAllErrorCodesDb(param); return results; } catch (error) { throw new ErrorHandler(error.statusCode, error.message); } } // Get error code by ID with complete data static async getErrorCodeById(id) { try { const errorCode = await getErrorCodeByIdDb(id); if (!errorCode) throw new ErrorHandler(404, "Error code not found"); const solutions = await getSolutionsByErrorCodeIdDb(errorCode.error_code_id); const spareparts = await getSparepartsByErrorCodeIdDb(errorCode.error_code_id); const solutionsWithFiles = await Promise.all( solutions.map(async (solution) => { let fileData = null; if (solution.path_solution && solution.type_solution !== "text") { fileData = await getFileUploadByPathDb(solution.path_solution); } return { ...solution, file_upload_name: fileData?.file_upload_name || null, path_document: fileData?.path_document || null, }; }) ); return { ...errorCode, solution: solutionsWithFiles, spareparts: spareparts, }; } catch (error) { throw new ErrorHandler(error.statusCode, error.message); } } // Get error codes by brand ID static async getErrorCodesByBrandId(brandId, queryParams = {}) { try { const results = await getErrorCodesByBrandIdDb(brandId, queryParams); if (results.data && results.total !== undefined) { return results; } const errorCodesWithDetails = await Promise.all( results.map(async (errorCode) => { const solutions = await getSolutionsByErrorCodeIdDb(errorCode.error_code_id); const spareparts = await getSparepartsByErrorCodeIdDb(errorCode.error_code_id); const solutionsWithFiles = await Promise.all( solutions.map(async (solution) => { let fileData = null; if (solution.path_solution && solution.type_solution !== "text") { fileData = await getFileUploadByPathDb(solution.path_solution); } return { ...solution, file_upload_name: fileData?.file_upload_name || null, path_document: fileData?.path_document || null, }; }) ); return { ...errorCode, solution: solutionsWithFiles, spareparts: spareparts, }; }) ); return errorCodesWithDetails; } catch (error) { throw new ErrorHandler(error.statusCode, error.message); } } // Create error code with solutions and spareparts static async createErrorCodeWithFullData(brandId, data) { try { if (!data || typeof data !== "object") data = {}; const errorId = await createErrorCodeDb(brandId, { error_code: data.error_code, error_code_name: data.error_code_name, error_code_description: data.error_code_description, error_code_color: data.error_code_color, path_icon: data.path_icon, is_active: data.is_active, created_by: data.created_by, }); if (!errorId) { throw new Error("Failed to create error code"); } if (data.spareparts && Array.isArray(data.spareparts)) { await insertMultipleErrorCodeSparepartsDb(errorId, data.spareparts, data.created_by); } if (data.solution && Array.isArray(data.solution)) { for (const solutionData of data.solution) { await createSolutionDb(errorId, { solution_name: solutionData.solution_name, type_solution: solutionData.type_solution, text_solution: solutionData.text_solution || null, path_solution: solutionData.path_solution || null, is_active: solutionData.is_active, created_by: data.created_by, }); } } const createdErrorCode = await this.getErrorCodeById(errorId); return createdErrorCode; } catch (error) { throw new ErrorHandler(500, `Create error code failed: ${error.message}`); } } // Update error code with solutions and spareparts static async updateErrorCodeWithFullData(brandId, errorCodeId, data) { try { const existingErrorCode = await getErrorCodeByIdDb(errorCodeId); if (!existingErrorCode) throw new ErrorHandler(404, "Error code not found"); // Verify the error code belongs to the specified brand if (existingErrorCode.brand_id !== parseInt(brandId)) { throw new ErrorHandler(403, "Error code does not belong to specified brand"); } // Check if there are any error code fields to update const hasMainFieldUpdate = data.error_code !== undefined || data.error_code_name !== undefined || data.error_code_description !== undefined || data.error_code_color !== undefined || data.path_icon !== undefined || data.is_active !== undefined; if (hasMainFieldUpdate) { await updateErrorCodeDb(brandId, existingErrorCode.error_code, { error_code: data.error_code, error_code_name: data.error_code_name, error_code_description: data.error_code_description, error_code_color: data.error_code_color, path_icon: data.path_icon, is_active: data.is_active, updated_by: data.updated_by, }); } if (data.spareparts && Array.isArray(data.spareparts)) { await updateErrorCodeSparepartsDb(existingErrorCode.error_code_id, data.spareparts, data.updated_by); } if (data.solution && Array.isArray(data.solution)) { const existingSolutions = await getSolutionsByErrorCodeIdDb(existingErrorCode.error_code_id); const incomingSolutionNames = data.solution.map((s) => s.solution_name); for (const solutionData of data.solution) { const existingSolution = existingSolutions.find( (s) => s.solution_name === solutionData.solution_name ); if (existingSolution) { await updateSolutionDb( existingSolution.brand_code_solution_id, { solution_name: solutionData.solution_name, type_solution: solutionData.type_solution, text_solution: solutionData.text_solution || null, path_solution: solutionData.path_solution || null, is_active: solutionData.is_active, updated_by: data.updated_by, } ); } else { await createSolutionDb(existingErrorCode.error_code_id, { solution_name: solutionData.solution_name, type_solution: solutionData.type_solution, text_solution: solutionData.text_solution || null, path_solution: solutionData.path_solution || null, is_active: solutionData.is_active, created_by: data.updated_by, }); } } for (const existingSolution of existingSolutions) { if (!incomingSolutionNames.includes(existingSolution.solution_name)) { await deleteSolutionDb(existingSolution.brand_code_solution_id, data.updated_by); } } } const updatedErrorCode = await this.getErrorCodeById(existingErrorCode.error_code_id); return updatedErrorCode; } catch (error) { throw new ErrorHandler(500, `Update error code failed: ${error.message}`); } } // Soft delete error code static async deleteErrorCode(brandId, errorCodeId, deletedBy) { try { const errorCodeExist = await getErrorCodeByIdDb(errorCodeId); if (!errorCodeExist) { throw new ErrorHandler(404, "Error code not found"); } // Verify the error code belongs to the specified brand if (errorCodeExist.brand_id !== parseInt(brandId)) { throw new ErrorHandler(403, "Error code does not belong to specified brand"); } const result = await deleteErrorCodeDb(brandId, errorCodeExist.error_code, deletedBy); return result; } catch (error) { throw new ErrorHandler(error.statusCode, error.message); } } } module.exports = ErrorCodeService;