-**Global** date.js

-แก้ไข  Expense สมบูรแบบ
This commit is contained in:
x2Skyz
2025-11-25 15:47:20 +07:00
parent d29744bcfb
commit 5e22a0af02
4 changed files with 90 additions and 26 deletions

View File

@@ -1,6 +1,7 @@
import { GeneralService } from '../share/generalservice.js';
import { connection } from '../config/db.js'; // ต้อง import connection เพื่อทำ Transaction
import { connection } from '../config/db.js';
import { sendError } from '../utils/response.js';
import { getDTM } from '../utils/date.js';
export class BudgetExpenseService {
@@ -28,31 +29,65 @@ export class BudgetExpenseService {
try {
await client.query('BEGIN'); // เริ่ม Transaction
const currentDate = getDTM();
// =========================================================
// STEP 1: คืนเงินงบประมาณเดิมก่อน (กรณีแก้ไข/ลบรายการ)
// =========================================================
// ดึงรายการเดิมที่เคยบันทึกไว้ของ Project นี้ เพื่อเอามาคืนเงิน
const oldExpenses = await client.query(
`SELECT trnbdgcod, trnexpbdg FROM ${database}.trnmst WHERE trnprjseq = $1`,
[projectSeq]
);
// วนลูปคืนเงินกลับเข้าตาราง bdgmst (bdgttl + ยอดเดิม)
for (const oldItem of oldExpenses.rows) {
await client.query(`
UPDATE ${database}.bdgmst
SET bdgttl = bdgttl + $1, bdgedtdtm = $2
WHERE bdgcod = $3
`, [oldItem.trnexpbdg, currentDate, oldItem.trnbdgcod]);
}
// =========================================================
// STEP 2: ลบรายการเดิมทิ้งทั้งหมด (Clear Old Transactions)
// =========================================================
// การลบทั้งหมดแล้วลงใหม่ จะครอบคลุมทั้งกรณี แก้ไขยอด, เพิ่มรายการใหม่, และลบรายการออก
await client.query(`DELETE FROM ${database}.trnmst WHERE trnprjseq = $1`, [projectSeq]);
// =========================================================
// STEP 3: บันทึกรายการใหม่ และตัดเงินใหม่
// =========================================================
let totalApprovedAmount = 0;
// Format วันที่: YYYYMMDD
const currentDate = new Date().toISOString().slice(0, 10).replace(/-/g, '');
// 1.2 หาชื่อโครงการ (ดึงครั้งเดียวนอกลูปเพื่อประสิทธิภาพ)
const prjRes = await client.query(`SELECT prjnam FROM ${database}.prjmst WHERE prjseq = $1`, [projectSeq]);
if (prjRes.rows.length === 0) throw new Error(`Project ${projectSeq} not found`);
const projectName = prjRes.rows[0].prjnam;
// 1. วนลูปตัดงบและบันทึก Transaction
for (const expense of expenseList) {
// expense: { bdgcod: '33', amount: 5000 }
// [Validation] ห้ามยอดเงินเป็น 0 หรือติดลบ
if (!expense.amount || Number(expense.amount) <= 0) {
throw new sendError(`ยอดเงินต้องมากกว่า 0 (รายการรหัสงบ: ${expense.bdgcod})`);
}
// [Check 2] เช็คก่อนว่ามีรหัสงบประมาณนี้จริงหรือไม่
const checkBdgSql = `SELECT bdgseq FROM ${database}.bdgmst WHERE bdgcod = $1`;
const checkBdgRes = await client.query(checkBdgSql, [expense.bdgcod]);
if (checkBdgRes.rows.length === 0) {
return sendError(`ไม่พบรหัสงบประมาณ: ${expense.bdgcod} ในระบบ`, `Cannot Find Budget Code ${expense.bdgcod} in System`);
// ⚠️ ต้อง throw error เพื่อให้ไปตกที่ catch แล้ว ROLLBACK
throw new sendError(`ไม่พบรหัสงบประมาณ: ${expense.bdgcod} ในระบบ`);
}
// 1.1 หา trnseq ล่าสุด
const seqRes = await client.query(`SELECT COALESCE(MAX(trnseq), 0) + 1 as nextseq FROM ${database}.trnmst`);
const nextTrnSeq = seqRes.rows[0].nextseq;
// 1.2 หาชื่อโครงการ
const prjRes = await client.query(`SELECT prjnam FROM ${database}.prjmst WHERE prjseq = $1`, [projectSeq]);
if (prjRes.rows.length === 0) throw new Error(`Project ${projectSeq} not found`);
const projectName = prjRes.rows[0].prjnam;
// แปลงยอดเงินเป็นทศนิยม 2 ตำแหน่งให้ชัวร์ก่อนบันทึก
const expenseAmount = Number(expense.amount).toFixed(2);
@@ -99,7 +134,7 @@ export class BudgetExpenseService {
await client.query(sqlUpdatePrj, [formattedTotal, currentDate, projectSeq]);
await client.query('COMMIT'); // ยืนยัน (ทุกอย่างจะถูกบันทึกพร้อมกันเมื่อถึงบรรทัดนี้)
return { status: true, total: totalApprovedAmount };
return { status: true, msg: 'Budget updated successfully', total: formattedTotal };
} catch (error) {
await client.query('ROLLBACK'); // ยกเลิกทั้งหมด (ถ้ามี error ข้อมูลจะกลับไปเหมือนเดิมทุกประการ)