From 4253e2988903f8b520c917b19cc16ff594451914 Mon Sep 17 00:00:00 2001 From: mhmmdafif Date: Mon, 24 Nov 2025 14:56:33 +0700 Subject: [PATCH] repair: reset brand device without sparepart --- db/brand_code.db.js | 5 - services/brand.service.js | 440 +++++++++++++++++++++----------------- validate/brand.schema.js | 24 --- 3 files changed, 242 insertions(+), 227 deletions(-) diff --git a/db/brand_code.db.js b/db/brand_code.db.js index 7c4de4c..4d8925a 100644 --- a/db/brand_code.db.js +++ b/db/brand_code.db.js @@ -13,8 +13,6 @@ const getErrorCodesByBrandIdDb = async (brandId) => { return result.recordset; }; - -// Create error code for brand const createErrorCodeDb = async (brandId, data) => { const store = { brand_id: brandId, @@ -33,7 +31,6 @@ const createErrorCodeDb = async (brandId, data) => { return insertedId; }; -// Update error code by brand ID and error code const updateErrorCodeDb = async (brandId, errorCode, data) => { const store = { ...data }; const whereData = { @@ -46,7 +43,6 @@ const updateErrorCodeDb = async (brandId, errorCode, data) => { return true; }; -// Soft delete error code by brand ID and error code const deleteErrorCodeDb = async (brandId, errorCode, deletedBy) => { const queryText = ` UPDATE brand_code @@ -57,7 +53,6 @@ const deleteErrorCodeDb = async (brandId, errorCode, deletedBy) => { return true; }; -// Get error code by error_code_id const getErrorCodeByIdDb = async (error_code_id) => { const queryText = ` SELECT diff --git a/services/brand.service.js b/services/brand.service.js index 92cfedd..9bf28b2 100644 --- a/services/brand.service.js +++ b/services/brand.service.js @@ -1,4 +1,4 @@ -// BrandService.js +// Brand operations const { getAllBrandsDb, getBrandByIdDb, @@ -7,308 +7,352 @@ const { updateBrandDb, deleteBrandDb, checkBrandNameExistsDb, -} = require('../db/brand.db'); +} = require("../db/brand.db"); +// Error code operations const { getErrorCodesByBrandIdDb, createErrorCodeDb, updateErrorCodeDb, deleteErrorCodeDb, -} = require('../db/brand_code.db'); - -const { - getSparePartnsByErrorCodeIdDb, - createSparePartDb, - updateSparePartDb, - deleteSparePartDb, -} = require('../db/brand_sparepart.db'); +} = require("../db/brand_code.db"); +// Solution operations const { getSolutionsByErrorCodeIdDb, createSolutionDb, updateSolutionDb, deleteSolutionDb, -} = require('../db/brand_code_solution.db'); - -const { getFileUploadByPathDb } = require('../db/file_uploads.db'); -const { ErrorHandler } = require('../helpers/error'); +} = require("../db/brand_code_solution.db"); +const { getFileUploadByPathDb } = require("../db/file_uploads.db"); +const { ErrorHandler } = require("../helpers/error"); class BrandService { + // Get all brands static async getAllBrands(param) { try { const results = await getAllBrandsDb(param); + + results.data.map((element) => {}); + return results; } catch (error) { - throw new ErrorHandler(error.statusCode || 500, error.message || 'Failed to get brands'); + throw new ErrorHandler(error.statusCode, error.message); } } + // Get brand by ID with complete data static async getBrandById(id) { try { const brand = await getBrandByIdDb(id); - if (!brand) throw new ErrorHandler(404, 'Brand not found'); + if (!brand) throw new ErrorHandler(404, "Brand not found"); - const errorCodes = await getErrorCodesByBrandIdDb(brand.brand_id) || []; + const errorCodes = await getErrorCodesByBrandIdDb(brand.brand_id); - const errorCodesWithDetails = await Promise.all( + const errorCodesWithSolutions = await Promise.all( errorCodes.map(async (errorCode) => { - const solutions = (await getSolutionsByErrorCodeIdDb(errorCode.error_code_id)) || []; - const solutionsWithFile = await Promise.all( - solutions.map(async (s) => { + const solutions = await getSolutionsByErrorCodeIdDb( + errorCode.error_code_id + ); + + const solutionsWithFiles = await Promise.all( + solutions.map(async (solution) => { let fileData = null; - if (s.path_solution && s.type_solution && s.type_solution !== 'text') { - try { - fileData = await getFileUploadByPathDb(s.path_solution); - } catch (e) { - fileData = null; - } + // console.log('Processing solution:', { + // solution_id: solution.brand_code_solution_id, + // path_solution: solution.path_solution, + // type_solution: solution.type_solution + // }); + + if (solution.path_solution && solution.type_solution !== "text") { + fileData = await getFileUploadByPathDb(solution.path_solution); + console.log("File data found:", fileData); } - return { - ...s, + + const enhancedSolution = { + ...solution, file_upload_name: fileData?.file_upload_name || null, - path_document: fileData?.path_document || null + path_document: fileData?.path_document || null, }; + + // console.log('Enhanced solution:', { + // solution_id: enhancedSolution.brand_code_solution_id, + // original_path_solution: enhancedSolution.path_solution, + // path_document: enhancedSolution.path_document, + // file_upload_name: enhancedSolution.file_upload_name + // }); + + return enhancedSolution; }) ); - const spareparts = (await getSparePartnsByErrorCodeIdDb(errorCode.error_code_id)) || []; - return { ...errorCode, - solution: solutionsWithFile, - sparepart: spareparts + solution: solutionsWithFiles, }; }) ); return { ...brand, - error_code: errorCodesWithDetails + error_code: errorCodesWithSolutions, }; } catch (error) { - throw new ErrorHandler(error.statusCode || 500, error.message || 'Failed to get brand detail'); + throw new ErrorHandler(error.statusCode, error.message); } } + // Create brand static async createBrandWithFullData(data) { try { - if (!data || typeof data !== 'object') data = {}; + if (!data || typeof data !== "object") data = {}; - if (!data.brand_name) throw new ErrorHandler(400, 'brand_name is required'); - const exists = await checkBrandNameExistsDb(data.brand_name); - if (exists) throw new ErrorHandler(400, 'Brand name already exists'); - - if (!Array.isArray(data.error_code) || data.error_code.length === 0) { - throw new ErrorHandler(400, 'Brand must have at least 1 error code with solution'); + if (data.brand_name) { + const brandExists = await checkBrandNameExistsDb(data.brand_name); + if (brandExists) { + throw new ErrorHandler(400, "Brand name already exists"); + } } - for (const ec of data.error_code) { - if (!Array.isArray(ec.solution) || ec.solution.length === 0) { - throw new ErrorHandler(400, `Error code ${ec.error_code} must have at least 1 solution`); + if ( + !data.error_code || + !Array.isArray(data.error_code) || + data.error_code.length === 0 + ) { + throw new ErrorHandler( + 400, + "Brand must have at least 1 error code with solution" + ); + } + + for (const errorCode of data.error_code) { + if ( + !errorCode.solution || + !Array.isArray(errorCode.solution) || + errorCode.solution.length === 0 + ) { + throw new ErrorHandler( + 400, + `Error code ${errorCode.error_code} must have at least 1 solution` + ); } } const brandData = { brand_name: data.brand_name, - brand_type: data.brand_type || null, - brand_manufacture: data.brand_manufacture || null, - brand_model: data.brand_model || null, + brand_type: data.brand_type, + brand_manufacture: data.brand_manufacture, + brand_model: data.brand_model, is_active: data.is_active, - created_by: data.created_by || null + created_by: data.created_by, }; const createdBrand = await createBrandDb(brandData); - if (!createdBrand || !createdBrand.brand_id) { - throw new Error('Failed to create brand'); + if (!createdBrand) { + throw new Error("Failed to create brand"); } const brandId = createdBrand.brand_id; - for (const ec of data.error_code) { - const errorCodePayload = { - error_code: ec.error_code, - error_code_name: ec.error_code_name || null, - error_code_description: ec.error_code_description || null, - error_code_color: ec.error_code_color || null, - path_icon: ec.path_icon || null, - is_active: ec.is_active, - created_by: data.created_by || null - }; + for (const errorCodeData of data.error_code) { + const errorId = await createErrorCodeDb(brandId, { + error_code: errorCodeData.error_code, + error_code_name: errorCodeData.error_code_name, + error_code_description: errorCodeData.error_code_description, + error_code_color: errorCodeData.error_code_color, + path_icon: errorCodeData.path_icon, + is_active: errorCodeData.is_active, + created_by: data.created_by, + }); - const errorId = await createErrorCodeDb(brandId, errorCodePayload); if (!errorId) { - throw new Error('Failed to create error code'); + throw new Error("Failed to create error code"); } - // solutions - if (Array.isArray(ec.solution)) { - for (const s of ec.solution) { - const solPayload = { - solution_name: s.solution_name, - type_solution: s.type_solution, - text_solution: s.text_solution || null, - path_solution: s.path_solution || null, - is_active: s.is_active, - created_by: data.created_by || null - }; - await createSolutionDb(errorId, solPayload); - } - } - - // spareparts - if (Array.isArray(ec.sparepart)) { - for (const sp of ec.sparepart) { - const spPayload = { - sparepart_name: sp.sparepart_name, - brand_sparepart_description: sp.brand_sparepart_description || null, - path_foto: sp.path_foto || null, - is_active: sp.is_active, - created_by: data.created_by || null - }; - await createSparePartDb(errorId, spPayload); + // Create solutions for this error code + if (errorCodeData.solution && Array.isArray(errorCodeData.solution)) { + for (const solutionData of errorCodeData.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, + }); } } } return await this.getBrandById(brandId); } catch (error) { - if (error instanceof ErrorHandler) throw error; - throw new ErrorHandler(500, error.message || 'Create brand failed'); + throw new ErrorHandler(500, `Bulk insert failed: ${error.message}`); } } + // Soft delete brand by ID + static async deleteBrand(id, userId) { + try { + const brandExist = await getBrandByIdDb(id); + + if (!brandExist) { + throw new ErrorHandler(404, "Brand not found"); + } + + const result = await deleteBrandDb(id, userId); + + return result; + } catch (error) { + throw new ErrorHandler(error.statusCode, error.message); + } + } + + // Update brand static async updateBrandWithFullData(id, data) { try { const existingBrand = await getBrandByIdDb(id); - if (!existingBrand) throw new ErrorHandler(404, 'Brand not found'); + if (!existingBrand) throw new ErrorHandler(404, "Brand not found"); if (data.brand_name && data.brand_name !== existingBrand.brand_name) { const brandExists = await checkBrandNameExistsDb(data.brand_name, id); - if (brandExists) throw new ErrorHandler(400, 'Brand name already exists'); + if (brandExists) { + throw new ErrorHandler(400, "Brand name already exists"); + } } - const brandUpdatePayload = { - brand_name: data.brand_name ?? existingBrand.brand_name, - brand_type: data.brand_type ?? existingBrand.brand_type, - brand_manufacture: data.brand_manufacture ?? existingBrand.brand_manufacture, - brand_model: data.brand_model ?? existingBrand.brand_model, - is_active: typeof data.is_active === 'boolean' ? data.is_active : existingBrand.is_active, - updated_by: data.updated_by || null + const brandData = { + brand_name: data.brand_name, + brand_type: data.brand_type, + brand_manufacture: data.brand_manufacture, + brand_model: data.brand_model, + is_active: data.is_active, + updated_by: data.updated_by, }; - await updateBrandDb(existingBrand.brand_name, brandUpdatePayload); - if (!Array.isArray(data.error_code)) { - return await this.getBrandById(id); - } + await updateBrandDb(existingBrand.brand_name, brandData); - const existingErrorCodes = await getErrorCodesByBrandIdDb(id) || []; - const incomingErrorCodes = data.error_code.map(ec => ec.error_code); + if (data.error_code && Array.isArray(data.error_code)) { + const existingErrorCodes = await getErrorCodesByBrandIdDb(id); + const incomingErrorCodes = data.error_code.map((ec) => ec.error_code); - for (const ec of data.error_code) { - const existingEC = existingErrorCodes.find(e => e.error_code === ec.error_code); - let errorId = null; + // Create/update/delete error codes + for (const errorCodeData of data.error_code) { + // Check if error code already exists + const existingEC = existingErrorCodes.find( + (ec) => ec.error_code === errorCodeData.error_code + ); - if (existingEC) { - const updatePayload = { - error_code_name: ec.error_code_name ?? existingEC.error_code_name, - error_code_description: ec.error_code_description ?? existingEC.error_code_description, - error_code_color: ec.error_code_color ?? existingEC.error_code_color, - path_icon: ec.path_icon ?? existingEC.path_icon, - is_active: existingEC.is_active, - updated_by: data.updated_by || null - }; - await updateErrorCodeDb(existingEC.brand_id, existingEC.error_code, updatePayload); - errorId = existingEC.error_code_id; - } else { - const createPayload = { - error_code: ec.error_code, - error_code_name: ec.error_code_name || null, - error_code_description: ec.error_code_description || null, - error_code_color: ec.error_code_color || null, - path_icon: ec.path_icon || null, - is_active: ec.is_active, - created_by: data.updated_by || null - }; - errorId = await createErrorCodeDb(id, createPayload); - } + if (existingEC) { + // Update existing error code using separate db function + await updateErrorCodeDb( + existingEC.brand_id, + existingEC.error_code, + { + error_code_name: errorCodeData.error_code_name, + error_code_description: errorCodeData.error_code_description, + error_code_color: errorCodeData.error_code_color, + path_icon: errorCodeData.path_icon, + is_active: errorCodeData.is_active, + updated_by: data.updated_by, + } + ); - if (!errorId) throw new Error(`Failed to create/update error code ${ec.error_code}`); + if ( + errorCodeData.solution && + Array.isArray(errorCodeData.solution) + ) { + const existingSolutions = await getSolutionsByErrorCodeIdDb( + existingEC.error_code_id + ); + const incomingSolutionNames = errorCodeData.solution.map( + (s) => s.solution_name + ); - const existingSolutions = await getSolutionsByErrorCodeIdDb(errorId) || []; - const incomingSolutionNames = (ec.solution || []).map(s => s.solution_name); + // Update or create solutions + for (const solutionData of errorCodeData.solution) { + const existingSolution = existingSolutions.find( + (s) => s.solution_name === solutionData.solution_name + ); - for (const s of (ec.solution || [])) { - const existsSolution = existingSolutions.find(es => es.solution_name === s.solution_name); - const solPayload = { - solution_name: s.solution_name, - type_solution: s.type_solution, - text_solution: s.text_solution || null, - path_solution: s.path_solution || null, - is_active: s.is_active, - updated_by: data.updated_by || null, - created_by: data.updated_by || null - }; - if (existsSolution) { - await updateSolutionDb(existsSolution.brand_code_solution_id, solPayload); + if (existingSolution) { + // Update existing solution + 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 { + // Create new solution + await createSolutionDb(existingEC.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, + }); + } + } + + // Delete solutions that are not in the incoming request + for (const existingSolution of existingSolutions) { + if ( + !incomingSolutionNames.includes( + existingSolution.solution_name + ) + ) { + await deleteSolutionDb( + existingSolution.brand_code_solution_id, + data.updated_by + ); + } + } + } } else { - await createSolutionDb(errorId, solPayload); + const errorId = await createErrorCodeDb(id, { + error_code: errorCodeData.error_code, + error_code_name: errorCodeData.error_code_name, + error_code_description: errorCodeData.error_code_description, + error_code_color: errorCodeData.error_code_color, + path_icon: errorCodeData.path_icon, + is_active: errorCodeData.is_active, + created_by: data.updated_by, + }); + + if ( + errorCodeData.solution && + Array.isArray(errorCodeData.solution) + ) { + for (const solutionData of errorCodeData.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.updated_by, + }); + } + } } } - for (const es of existingSolutions) { - if (!incomingSolutionNames.includes(es.solution_name)) { - await deleteSolutionDb(es.brand_code_solution_id, data.updated_by); + for (const existingEC of existingErrorCodes) { + if (!incomingErrorCodes.includes(existingEC.error_code)) { + await deleteErrorCodeDb(id, existingEC.error_code, data.updated_by); } } - - const existingSpareparts = await getSparePartnsByErrorCodeIdDb(errorId) || []; - const incomingSparepartNames = (ec.sparepart || []).map(sp => sp.sparepart_name); - - for (const sp of (ec.sparepart || [])) { - const existsSP = existingSpareparts.find(e => e.sparepart_name === sp.sparepart_name); - const spPayload = { - sparepart_name: sp.sparepart_name, - brand_sparepart_description: sp.brand_sparepart_description || null, - path_foto: sp.path_foto || null, - is_active: sp.is_active, - updated_by: data.updated_by || null, - created_by: data.updated_by || null - }; - if (existsSP) { - await updateSparePartDb(existsSP.brand_sparepart_id, spPayload); - } else { - await createSparePartDb(errorId, spPayload); - } - } - - for (const es of existingSpareparts) { - if (!incomingSparepartNames.includes(es.sparepart_name)) { - await deleteSparePartDb(es.brand_sparepart_id, data.updated_by); - } - } - } - - for (const ec of existingErrorCodes) { - if (!incomingErrorCodes.includes(ec.error_code)) { - await deleteErrorCodeDb(id, ec.error_code, data.updated_by); - } } return await this.getBrandById(id); } catch (error) { - if (error instanceof ErrorHandler) throw error; - throw new ErrorHandler(500, `Update failed: ${error.message || 'unknown error'}`); - } - } - - static async deleteBrand(id, userId) { - try { - const brandExist = await getBrandByIdDb(id); - if (!brandExist) throw new ErrorHandler(404, 'Brand not found'); - const result = await deleteBrandDb(id, userId); - return result; - } catch (error) { - throw new ErrorHandler(error.statusCode || 500, error.message || 'Delete failed'); + throw new ErrorHandler(500, `Update failed: ${error.message}`); } } } diff --git a/validate/brand.schema.js b/validate/brand.schema.js index b9209ad..3f5d99a 100644 --- a/validate/brand.schema.js +++ b/validate/brand.schema.js @@ -42,18 +42,6 @@ const insertBrandSchema = Joi.object({ ) .min(1) .required(), - sparepart: Joi.array() - .items( - Joi.object({ - sparepart_name: Joi.string().max(100).optional(), - brand_sparepart_description: Joi.string() - .max(255) - .optional(), - path_foto: Joi.string().optional().allow(""), - is_active: Joi.boolean().required(), - }) - ) - .optional(), }) ) .min(1) @@ -100,18 +88,6 @@ const updateBrandSchema = Joi.object({ ) .min(1) .required(), - sparepart: Joi.array() - .items( - Joi.object({ - sparepart_name: Joi.string().max(100).optional(), - brand_sparepart_description: Joi.string() - .max(255) - .optional(), - path_foto: Joi.string().optional().allow(""), - is_active: Joi.boolean().required(), - }) - ) - .optional(), }) ) .optional(),