From cb5e864206c6c39d5500d975f09ef03601f607b8 Mon Sep 17 00:00:00 2001 From: Fachba Date: Sat, 25 Apr 2026 19:40:53 +0700 Subject: [PATCH 1/2] feat: add sparepart_number and sparepart_yearly fields to sparepart schema and database queries --- db/sparepart.db.js | 4 ++++ services/sparepart.service.js | 12 ++++++++++++ validate/sparepart.schema.js | 12 ++++++++++++ 3 files changed, 28 insertions(+) diff --git a/db/sparepart.db.js b/db/sparepart.db.js index c5296b5..994048d 100644 --- a/db/sparepart.db.js +++ b/db/sparepart.db.js @@ -14,6 +14,7 @@ const getAllSparepartDb = async (searchParams = {}) => { const { whereOrConditions, whereParamOr } = pool.buildStringOrIlike( [ "a.sparepart_name", + "a.sparepart_number", "a.sparepart_code", "a.sparepart_model", "a.updated_at", @@ -28,6 +29,7 @@ const getAllSparepartDb = async (searchParams = {}) => { const { whereConditions, whereParamAnd } = pool.buildFilterQuery( [ { column: "a.sparepart_name", param: searchParams.code, type: "string" }, + { column: "a.sparepart_number", param: searchParams.code, type: "string" }, { column: "a.sparepart_code", param: searchParams.location, @@ -156,6 +158,7 @@ const getSparepartsByIdsDb = async (sparepartIds) => { SELECT sparepart_id, sparepart_name, + sparepart_number, sparepart_code, sparepart_description, sparepart_model, @@ -165,6 +168,7 @@ const getSparepartsByIdsDb = async (sparepartIds) => { sparepart_unit, sparepart_merk, sparepart_stok, + sparepart_yearly, created_at, updated_at FROM m_sparepart diff --git a/services/sparepart.service.js b/services/sparepart.service.js index e380091..ff11de0 100644 --- a/services/sparepart.service.js +++ b/services/sparepart.service.js @@ -28,6 +28,8 @@ class SparepartService { throw new ErrorHandler(404, "Sparepart not found"); } + sparepart[0].sparepart_yearly = JSON.parse(sparepart[0].sparepart_yearly); + return sparepart[0]; } catch (error) { throw new ErrorHandler(error.statusCode || 500, error.message); @@ -42,6 +44,11 @@ class SparepartService { if (exists) throw new ErrorHandler(400, "Sparepart name already exists"); } + + if (data.sparepart_yearly) { + data.sparepart_yearly = JSON.stringify(data.sparepart_yearly); + } + const created = await createSparepartDb(data); if (!created) throw new ErrorHandler(500, "Failed to create Sparepart"); return created; @@ -65,6 +72,11 @@ class SparepartService { if (exists) throw new ErrorHandler(400, "Sparepart name already exists"); } + + if (data.sparepart_yearly) { + data.sparepart_yearly = JSON.stringify(data.sparepart_yearly); + } + const updated = await updateSparepartDb(id, data); if (!updated) throw new ErrorHandler(500, "Failed to update Sparepart"); return await this.getSparepartById(id); diff --git a/validate/sparepart.schema.js b/validate/sparepart.schema.js index 9f2815b..7133f98 100644 --- a/validate/sparepart.schema.js +++ b/validate/sparepart.schema.js @@ -4,6 +4,7 @@ const Joi = require("joi"); // ======================== const insertSparepartSchema = Joi.object({ sparepart_name: Joi.string().max(255).required(), + sparepart_number: Joi.string().max(255).optional(), sparepart_description: Joi.string().max(255).optional(), sparepart_model: Joi.string().max(255).optional(), sparepart_foto: Joi.string().max(255).optional().allow(""), @@ -12,11 +13,17 @@ const insertSparepartSchema = Joi.object({ sparepart_unit: Joi.string().max(255).optional(), sparepart_merk: Joi.string().max(255).optional(), sparepart_stok: Joi.string().max(255).optional(), + sparepart_yearly: Joi.array() + .items(Joi.number().integer()) + .min(0) + .allow(null) + .optional() }); // Update Validation const updateSparepartSchema = Joi.object({ sparepart_name: Joi.string().max(255).optional(), + sparepart_number: Joi.string().max(255).optional(), sparepart_description: Joi.string().max(255).optional(), sparepart_model: Joi.string().max(255).optional(), sparepart_foto: Joi.string().max(255).optional().allow(''), @@ -25,6 +32,11 @@ const updateSparepartSchema = Joi.object({ sparepart_unit: Joi.string().max(255).optional(), sparepart_merk: Joi.string().max(255).optional(), sparepart_stok: Joi.string().max(255).optional(), + sparepart_yearly: Joi.array() + .items(Joi.number().integer()) + .min(0) + .allow(null) + .optional() }); module.exports = { insertSparepartSchema, -- 2.49.1 From b7fa4b3d0781df137c2fd0381e4f3ffe0718ecdc Mon Sep 17 00:00:00 2001 From: Fachba Date: Sun, 26 Apr 2026 13:38:33 +0700 Subject: [PATCH 2/2] feat: add optional fields listen_channel_reminder and reminder_at to device schema --- validate/device.schema.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/validate/device.schema.js b/validate/device.schema.js index 4b3f945..e5e3369 100644 --- a/validate/device.schema.js +++ b/validate/device.schema.js @@ -16,7 +16,9 @@ const insertDeviceSchema = Joi.object({ .messages({ 'string.ip': 'IP address must be a valid IPv4 or IPv6 address' }), - listen_channel: Joi.string().max(100).required() + listen_channel: Joi.string().max(100).required(), + listen_channel_reminder: Joi.string().max(100).optional(), + reminder_at: Joi.date().iso().allow(null).optional() }); const updateDeviceSchema = Joi.object({ @@ -30,7 +32,10 @@ const updateDeviceSchema = Joi.object({ .messages({ 'string.ip': 'IP address must be a valid IPv4 or IPv6 address' }), - listen_channel: Joi.string().max(100) + listen_channel: Joi.string().max(100), + listen_channel_reminder: Joi.string().max(100).optional(), + reminder_at: Joi.date().iso().allow(null).optional() + }).min(1); -- 2.49.1