diff --git a/exthernal-ttc-api/src/controllers/accountingSumController.js b/exthernal-ttc-api/src/controllers/accountingSumController.js deleted file mode 100644 index 532d0fb..0000000 --- a/exthernal-ttc-api/src/controllers/accountingSumController.js +++ /dev/null @@ -1,142 +0,0 @@ -import { AccountingSumService } from '../services/accountingSumService.js' -import { sendError } from '../utils/response.js' -import { GeneralService } from '../share/generalservice.js'; -import { trim_all_array } from '../utils/trim.js' -import { verifyToken, generateToken } from '../utils/token.js' - -export class accountingSum { - - constructor() { - this.generalService = new GeneralService(); - this.accountingSumService = new AccountingSumService(); - } - - async onNavigate(req, res) { - this.generalService.devhint(1, 'AccountingSum.js', 'onNavigate() start'); - let organization = req.body.organization; - const prommis = await this.onAccountingSum(req, res, organization); - return prommis; - } - - async onAccountingSum(req, res, database) { - let idx = -1 - let result = [] - var aryResult - try { - let token = req.body.request.token; - const decoded = verifyToken(token); - - let id = decoded.id - let username = decoded.name - database = decoded.organization - - result = await this.accountingSumService.getAccountingSum(database, id); // เช็คกับ db กลาง ส่ง jwttoken ออกมา - // if(result){ - // if(result.acttyp == 'e'){ - // // (ยังไม่มีการใช้งาน) - // } - // } - - } catch (error) { - idx = 1; - } finally { - if (idx === 1) return sendError('เกิดข้อผิดพลาดไม่คาดคิดเกิดขึ้น', 'Unexpected error'); - if (!result) return sendError('ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง', 'Invalid credentials'); - - try { - // ✅ 1) เตรียม data สำหรับใช้คำนวณ - // ถ้า service คืนมาเป็น { code, message, data: [...] } - const data = Array.isArray(result) - ? result - : Array.isArray(result.data) - ? result.data - : []; - - // ถ้าไม่มีข้อมูลก็ไม่ต้องคำนวณ - if (!data.length) { - return result; - } - - // ✅ 2) แยก income / expense - const incomeList = data.filter(i => i.acttyp === 'i'); - const expenseList = data.filter(e => e.acttyp === 'e'); - - const totalIncome = incomeList.reduce((sum, i) => sum + parseFloat(i.actqty || 0), 0); - const totalExpense = expenseList.reduce((sum, e) => sum + parseFloat(e.actqty || 0), 0); - - const netProfit = totalIncome - totalExpense; - const profitRate = totalIncome > 0 ? (netProfit / totalIncome) * 100 : 0; - const adjustedProfitRate = profitRate + 1.9; - - // ✅ 3) แนบ summary (เหมือนที่เราทำไปก่อนหน้า) - var summary = { - totalIncome: totalIncome.toFixed(2), - totalExpense: totalExpense.toFixed(2), - netProfit: netProfit.toFixed(2), - profitRate: profitRate.toFixed(2) + ' %', - adjustedProfitRate: adjustedProfitRate.toFixed(2) + ' %', - period: '30 วัน' - }; - - // ✅ 4) ดึงสีจาก dtlmst (แนะนำให้เรียกจาก service เพิ่ม) - // ตัวอย่างสมมติ: คุณไป query มาจาก service ก่อนหน้าแล้วได้เป็น object แบบนี้ - // key = ชื่อหมวด (actcatnam หรือ code), value = color - const categoryColorMap = await this.accountingSumService.getCategoryColorMap(database); - // ตัวอย่างที่คาดหวังจาก service: - // { 'ค่าอาหาร': '#FF6384', 'ค่าเดินทาง': '#36A2EB', 'ขายสินค้า': '#4BC0C0', ... } - - // ✅ 5) สรุปยอดตามหมวด แล้วคำนวณ % สำหรับ expense - const expenseAgg = {}; - expenseList.forEach(row => { - const key = row.actcatnam; // หรือใช้รหัส category ถ้ามี เช่น row.actcatcod - const amount = parseFloat(row.actqty || 0); - expenseAgg[key] = (expenseAgg[key] || 0) + amount; - }); - - const incomeAgg = {}; - incomeList.forEach(row => { - const key = row.actcatnam; - const amount = parseFloat(row.actqty || 0); - incomeAgg[key] = (incomeAgg[key] || 0) + amount; - }); - - const expensePie = Object.entries(expenseAgg).map(([cat, value]) => { - const percent = totalExpense > 0 ? (value / totalExpense) * 100 : 0; - const color = categoryColorMap[cat] || '#CCCCCC'; // fallback สี default - return { - label: cat, - value: value.toFixed(2), - percent: percent.toFixed(2), - color - }; - }); - - const incomePie = Object.entries(incomeAgg).map(([cat, value]) => { - const percent = totalIncome > 0 ? (value / totalIncome) * 100 : 0; - const color = categoryColorMap[cat] || '#CCCCCC'; - return { - label: cat, - value: value.toFixed(2), - percent: percent.toFixed(2), - color - }; - }); - - // ✅ 6) แนบข้อมูล pie chart เข้า result - var pie = { - expense: expensePie, - income: incomePie - }; - - } catch (err) { - console.error('calculate summary/pie error:', err); - } - let arydiy = { - summary, - pie - } - - return arydiy; - } - } -} diff --git a/exthernal-ttc-api/src/controllers/accountingSearchController.js b/exthernal-ttc-api/src/controllers/budgetSearchController.js similarity index 64% rename from exthernal-ttc-api/src/controllers/accountingSearchController.js rename to exthernal-ttc-api/src/controllers/budgetSearchController.js index 6890fc8..fc96121 100644 --- a/exthernal-ttc-api/src/controllers/accountingSearchController.js +++ b/exthernal-ttc-api/src/controllers/budgetSearchController.js @@ -1,25 +1,25 @@ -import { AccountingSearchService } from '../services/accountingSearchService.js' +import { BudgetSearchService } from '../services/budgetSearchService.js' import { sendError } from '../utils/response.js' // import { OftenError } from '../utils/oftenError.js' import { GeneralService } from '../share/generalservice.js'; import { trim_all_array } from '../utils/trim.js' import { verifyToken, generateToken } from '../utils/token.js' -export class accountingSearch { +export class budgetSearch { constructor() { this.generalService = new GeneralService(); - this.accountingSearchService = new AccountingSearchService(); + this.budgetSearchService = new BudgetSearchService(); } async onNavigate(req, res) { - this.generalService.devhint(1, 'accountingSearch.js', 'onNavigate() start'); + this.generalService.devhint(1, 'budgetSearch.js', 'onNavigate() start'); let organization = req.body.organization; - const prommis = await this.onAccountingSearch(req, res, organization); + const prommis = await this.onBudgetSearch(req, res, organization); return prommis; } - async onAccountingSearch(req, res, database) { + async onBudgetSearch(req, res, database) { let idx = -1 let aryResult = [] try { @@ -32,8 +32,8 @@ export class accountingSearch { let username = decoded.name database = decoded.organization - aryResult = await this.accountingSearchService.getAccountingSearch(database, id, username); // เช็คกับ db กลาง ส่ง jwttoken ออกมา - // this.generalService.devhint(1, 'accountingSearch.js', 'Login success'); + aryResult = await this.budgetSearchService.getBudgetSearch(database, id); // เช็คกับ db กลาง ส่ง jwttoken ออกมา + // this.generalService.devhint(1, 'budgetSearch.js', 'Login success'); } catch (error) { idx = 1; } finally { diff --git a/exthernal-ttc-api/src/controllers/accountingSetupController.js b/exthernal-ttc-api/src/controllers/budgetSetupController.js similarity index 63% rename from exthernal-ttc-api/src/controllers/accountingSetupController.js rename to exthernal-ttc-api/src/controllers/budgetSetupController.js index 2651508..92334f8 100644 --- a/exthernal-ttc-api/src/controllers/accountingSetupController.js +++ b/exthernal-ttc-api/src/controllers/budgetSetupController.js @@ -1,25 +1,25 @@ -import { AccountingSetupService } from '../services/accountingSetupService.js' +import { BudgetSetupService } from '../services/budgetSetupService.js' import { sendError } from '../utils/response.js' // import { OftenError } from '../utils/oftenError.js' import { GeneralService } from '../share/generalservice.js'; import { trim_all_array } from '../utils/trim.js' import { verifyToken, generateToken } from '../utils/token.js' -export class accountingSetup { +export class budgetSetup { constructor() { this.generalService = new GeneralService(); - this.AccountingSetupService = new AccountingSetupService(); + this.BudgetSetupService = new BudgetSetupService(); } async onNavigate(req, res) { - this.generalService.devhint(1, 'accountingSetup.js', 'onNavigate() start'); + this.generalService.devhint(1, 'budgetSetup.js', 'onNavigate() start'); let organization = req.body.organization; - const prommis = await this.onAccountingSetup(req, res, organization); + const prommis = await this.onBudgetSetup(req, res, organization); return prommis; } - async onAccountingSetup(req, res, database) { + async onBudgetSetup(req, res, database) { let idx = -1 let result = [] try { @@ -31,13 +31,13 @@ export class accountingSetup { database = decoded.organization - result = await this.AccountingSetupService.getAccountingSetup(database); // เช็คกับ db กลาง ส่ง jwttoken ออกมา - // this.generalService.devhint(1, 'accountingSetup.js', 'Login success'); + result = await this.BudgetSetupService.getBudgetSetup(database); // เช็คกับ db กลาง ส่ง jwttoken ออกมา + // this.generalService.devhint(1, 'budgetSetup.js', 'Login success'); } catch (error) { idx = 1; } finally { if (idx === 1) return sendError('เกิดข้อผิดพลาดไม่คาดคิดเกิดขึ้น', 'Unexpected error'); - if (!result) return sendError('ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง', 'Invalid credentials'); + if (!result) return sendError('ไม่พบข้อมูล', 'Data not found'); // แยกกลุ่ม income / expense let income = result.filter(item => item.dtltblcod === 'ACTCAT_INC').map(({ dtltblcod, ...rest }) => rest); diff --git a/exthernal-ttc-api/src/routes/route.js b/exthernal-ttc-api/src/routes/route.js index 698eec4..5ea01e4 100644 --- a/exthernal-ttc-api/src/routes/route.js +++ b/exthernal-ttc-api/src/routes/route.js @@ -1,59 +1,36 @@ import express from 'express' -import { accountingSetup } from '../controllers/accountingSetupController.js' -import { accountingSearch } from '../controllers/accountingSearchController.js' -import { accountingSum } from '../controllers/accountingSumController.js' +import { budgetSearch } from '../controllers/budgetSearchController.js' // import { authMiddleware } from '../middlewares/auth.js' // import { sendResponse } from '../utils/response.js' const router = express.Router() -const controller_accountingSetup_post = new accountingSetup() -const controller_accountingSearch_post = new accountingSearch() -const controller_accountingSum_post = new accountingSum() +const controller_budgetSearch_get = new budgetSearch() - -router.post('/accountingSetup', async (req, res) => { - const result = await controller_accountingSetup_post.onNavigate(req, res) +router.post('/budgetSetup', async (req, res) => { + const result = await controller_budgetSetup_post.onNavigate(req, res) if (result) return res.json(result) }) +// router.put('/budgetadd', async (req, res) => { +// const result = await controller_budgetSetup_post.onNavigate(req, res) +// if (result) return res.json(result) +// }) -router.post('/accountingSearch', async (req, res) => { - const result = await controller_accountingSearch_post.onNavigate(req, res) +router.get('/budgetsearch', async (req, res) => { + const result = await controller_budgetSearch_get.onNavigate(req, res) if (result) return res.json(result) }) -router.post('/accountingSum', async (req, res) => { - const result = await controller_accountingSum_post.onNavigate(req, res) - if (result) return res.json(result) -}) - - -// // =================================================== -// // 🔹 BIOMETRIC LOGIN -// // =================================================== -// router.post('/biometric/login', async (req, res) => { -// const data = await controller_login_post.onBiometricLogin(req, res) -// if (data) -// return sendResponse(res, 200, 'เข้าสู่ระบบผ่าน Biometric สำเร็จ', 'Biometric login succeed', data) +// router.get('/projectsearch', async (req, res) => { +// const result = await controller_budgetSetup_post.onNavigate(req, res) +// if (result) return res.json(result) // }) -// // =================================================== -// // 🔹 BIOMETRIC REGISTER (ต้อง login ก่อน) -// // =================================================== -// router.post('/biometric/register', authMiddleware, async (req, res) => { -// const data = await controller_login_post.onBiometricRegister(req, res) -// if (data) -// return sendResponse(res, 200, 'ผูก Biometric สำเร็จ', 'Biometric registered', data) +// router.put('/budgetexpense', async (req, res) => { +// const result = await controller_budgetSetup_post.onNavigate(req, res) +// if (result) return res.json(result) // }) -// // =================================================== -// // 🔹 TOKEN RENEW (ต่ออายุ Token) -// // =================================================== -// router.post('/token/renew', authMiddleware, async (req, res) => { -// const data = await controller_login_post.onRenewToken(req, res) -// if (data) -// return sendResponse(res, 200, 'ออก Token ใหม่สำเร็จ', 'Token renewed', data) -// }) export default router diff --git a/exthernal-ttc-api/src/services/accountingSearchService.js b/exthernal-ttc-api/src/services/accountingSearchService.js deleted file mode 100644 index bb0150a..0000000 --- a/exthernal-ttc-api/src/services/accountingSearchService.js +++ /dev/null @@ -1,27 +0,0 @@ -import { GeneralService } from '../share/generalservice.js' - -export class AccountingSearchService { - - constructor() { - this.generalService = new GeneralService() - } - - async getAccountingSearch(database, id, username) { - const sql = ` - SELECT - actseq, - actnum, - acttyp, - ${database}.translatedtl('ACTTYP', acttyp) as acttypnam, - ${database}.translatedtl_multi(ARRAY['ACTCAT_INC', 'ACTCAT_EXP'], actcat) as actcatnam, - actqty, - actcmt, - actacpdtm - FROM ${database}.actmst - WHERE actnum = $1 - ` - const params = [id] - const result = await this.generalService.executeQueryParam(database, sql, params); - return result - } -} \ No newline at end of file diff --git a/exthernal-ttc-api/src/services/accountingSumService.js b/exthernal-ttc-api/src/services/accountingSumService.js deleted file mode 100644 index caedd62..0000000 --- a/exthernal-ttc-api/src/services/accountingSumService.js +++ /dev/null @@ -1,44 +0,0 @@ -import { GeneralService } from '../share/generalservice.js' - -export class AccountingSumService { - constructor() { - this.generalService = new GeneralService() - } - async getAccountingSum(database, id) { - const sql = ` - SELECT - actseq, - actnum, - acttyp, - ${database}.translatedtl('ACTTYP', acttyp) as acttypnam, - ${database}.translatedtl_multi(ARRAY['ACTCAT_INC', 'ACTCAT_EXP'], actcat) as actcatnam, - actqty, - actcmt, - actacpdtm - FROM ${database}.actmst - WHERE actnum = $1 - ` - const params = [id] - const result = await this.generalService.executeQueryParam(database, sql, params); - return result - } - - - async getCategoryColorMap(database) { - const sql = ` - SELECT dtlcod, dtlnam, dtlmsc as dtlclr - FROM ${database}.dtlmst - WHERE dtltblcod IN ('ACTCAT_INC', 'ACTCAT_EXP') - `; - const params = [] - const rows = await this.generalService.executeQueryParam(database, sql, params); - - const map = {}; - rows.forEach(r => { - map[r.dtlnam] = r.dtlclr; // ใช้ชื่อหมวดเป็น key - }); - - return map; - } - -} \ No newline at end of file diff --git a/exthernal-ttc-api/src/services/budgetSearchService.js b/exthernal-ttc-api/src/services/budgetSearchService.js new file mode 100644 index 0000000..2e222fe --- /dev/null +++ b/exthernal-ttc-api/src/services/budgetSearchService.js @@ -0,0 +1,23 @@ +import { GeneralService } from '../share/generalservice.js' + +export class BudgetSearchService { + + constructor() { + this.generalService = new GeneralService() + } + + async getBudgetSearch(database, id) { + const sql = ` + SELECT + bdgseq, + bdgnam, + bdgcod, + bdgttl, + bdgedtdtm + FROM ${database}.bdgmst + ` + const params = [] + const result = await this.generalService.executeQueryParam(database, sql, params); + return result + } +} \ No newline at end of file diff --git a/exthernal-ttc-api/src/services/accountingSetupService.js b/exthernal-ttc-api/src/services/budgetSetupService.js similarity index 76% rename from exthernal-ttc-api/src/services/accountingSetupService.js rename to exthernal-ttc-api/src/services/budgetSetupService.js index a3aba89..c41c93c 100644 --- a/exthernal-ttc-api/src/services/accountingSetupService.js +++ b/exthernal-ttc-api/src/services/budgetSetupService.js @@ -1,16 +1,17 @@ import { GeneralService } from '../share/generalservice.js' -export class AccountingSetupService { +export class BudgetSetupService { constructor() { this.generalService = new GeneralService() } - async getAccountingSetup(database) { + async getBudgetSetup(database) { const sql = ` SELECT - dtlnam, - dtlcod, - dtltblcod - FROM ${database}.dtlmst + bgdnam, + bgdcod, + bgdttl, + bgdedtdtm + FROM ${database}.bdgmst WHERE dtltblcod IN ('ACTTYP', 'ACTCAT_INC', 'ACTCAT_EXP'); ` const params = []