#accounting#vat#wht#tax#postgres
ทะเบียนภาษีซื้อ/ภาษีขาย และภาษีหัก ณ ที่จ่าย
ภาษีซื้อเก็บใน gl_journal_vat_buy ภาษีขายเก็บใน gl_journal_vat_sale ส่วนภาษีหัก ณ ที่จ่ายเก็บใน gl_wht_list + gl_wht_list_detail แถว VAT ของเอกสารปกติเป็นค่า derived ที่สร้างจากหัวเอกสารทุกครั้งที่บันทึก ส่วน WHT และ VAT ที่ผู้ใช้คีย์เองเป็น raw ที่ไม่ถูกคำนวณทับ
ทำงานอย่างไร
flag ที่มีแท็บ VAT (transVatTabs trans_tax.go:37)
- ภาษีซื้อ: 12, 14, 16, 87, 89, 91, 260, 262, 264, 315, 316, 317, 461, มัดจำ 11, 25
- ภาษีขาย: 44, 46, 48, 99, 101, 103, 144, 250, 252, 254, 1802, มัดจำ 110, 112
- เอกสารลดหนี้ (16, 91, 262, 317, 48, 103, 252, 25, 112) เก็บยอดเป็นบวก แต่
vat_calc= -1 - ap_ar_trans 19 (จ่ายชำระหนี้) และ 239 (รับชำระหนี้) มีแท็บ VAT + WHT ที่ผู้ใช้คีย์ทั้งหมด (
apArTaxTabs:53,apArTaxStmts:169) ใช้กับภาษีบริการที่ถึงกำหนดเมื่อชำระ (comment ในโค้ดอ้าง ประมวลรัษฎากร ม.78/1(1) และ ม.86; ยังไม่ได้ตรวจกับแหล่งทางการ)
แถว VAT อัตโนมัติ (defaultTransVat trans_tax.go:74)
- vat_type 3 (ไม่กระทบภาษี) ไม่สร้างแถว
- ฐานภาษี =
total_before_vat, ภาษี =total_vat_value, ยอดรวม = round2(ฐาน) + round2(ภาษี), ยกเว้น =total_except_vat(scale 2 ทั้งหมด) - เลขที่/วันที่ใบกำกับว่าง ใช้เลขที่/วันที่เอกสาร
- อัตราเป็น 0 แต่มีฐานและภาษี: คำนวณอัตรากลับ = ภาษี x 100 / ฐาน (ปัด 2)
- ถ้าผู้ใช้ติ๊ก VAT เอง (
ManualVat) หรือส่งมามากกว่า 1 แถว จะบันทึกตามที่ส่ง และตั้งic_trans.is_manual_vat= 1 (transTaxStmts:109)
WHT (transWhtParty trans_tax.go:48)
- "ap" ภาษีหัก ณ ที่จ่าย (เราหักผู้ขาย): 12, 16, 260, 262, 264, 315, 11, 25
- "ar" ภาษีถูกหัก ณ ที่จ่าย (ลูกค้าหักเรา): 44, 48, 144, 250, 252, 1802, 110, 112
- ยอดหัว WHT = ผลรวมบรรทัด (journaltax.go:294); แถวที่ไม่มีประเภทเงินได้จะถูกตัดทิ้ง
- มัดจำที่ไม่ได้จ่ายเงินสด (แท็บจ่ายปิด) ลบ WHT อย่างเดียว ไม่เขียนใหม่
gl_wht_list.tax_doc_noต้องไม่ซ้ำข้ามเอกสาร
JV ทั่วไป (journaltax.go)
flagJournalVat= 1999 (บัญชี_ข้อมูลรายวัน),flagWhtIn= 1502 (เราหักผู้ขาย),flagWhtOut= 1501 (ลูกค้าหักเรา)- เฉพาะ JV ที่คีย์มือ (
isVoucherFlag= flag < 1 หรือ 1999) เท่านั้นที่เป็นเจ้าของแท็บภาษี; journal อัตโนมัติไม่มี - ชื่อ ที่อยู่ เลขผู้เสียภาษีของ WHT ดึงจาก master คู่ค้า; VAT ที่ชื่อ/เลขภาษี/สาขาว่างจะดึงจาก master ไม่เช่นนั้นตั้ง
manual_add= 1 (vatInsertSQL:153)
ห้ามเลขใบกำกับภาษีซ้ำ (checkTaxDocNo trans_tax_doc_no.go:18)
- ภาษีขาย:
vat_numberห้ามซ้ำกับเอกสารใดๆ - ภาษีซื้อ:
vat_doc_noห้ามซ้ำภายในผู้ขายเดียวกันและ flag เดียวกัน - ตรวจภายใต้ advisory lock ใน transaction บันทึก; เอกสารที่บันทึกซ้ำด้วยเลขเดิมของตัวเองผ่านได้
คำนวณทะเบียนภาษีใหม่ (RebuildTransTax trans_tax.go:252)
- สร้างแถว VAT derived ใหม่ของทุกเอกสาร
ic_transและas_transจากหัวเอกสาร - ข้ามเอกสารที่ VAT คีย์มือ หรือมีมากกว่า 1 แถว (เพื่อไม่ทับข้อมูลจากโปรแกรม C#)
- ลบแถว VAT/WHT ที่เอกสารต้นทางหายไปแล้ว; ใช้ lock เดียวทั้งระบบ; รันซ้ำได้ผลเดิม
ที่มาในโค้ด
backend/internal/application/process/trans_tax.go:16หลัก raw vs derivedbackend/internal/application/process/trans_tax.go:37transVatTabsbackend/internal/application/process/trans_tax.go:48transWhtPartybackend/internal/application/process/trans_tax.go:74defaultTransVatbackend/internal/application/process/trans_tax.go:109transTaxStmtsbackend/internal/application/process/trans_tax.go:169apArTaxStmtsbackend/internal/application/process/trans_tax.go:252RebuildTransTaxbackend/internal/application/process/trans_tax_doc_no.go:18checkTaxDocNobackend/internal/application/process/journaltax.go:15แท็บภาษีของ JVbackend/internal/application/process/journaltax.go:153vatInsertSQL