ภาพรวม
มติเจ้าของ (24 ต.ค. 2026): DB เก็บปี ค.ศ. ทั้งหมด หน้าจอ/รายงาน/PDF แปลงตาม erp_option.year_type (0=ค.ศ., 1=พ.ศ.) แต่โค้ดที่พอร์ตจาก C# ติด +543 ตายตัวหลายจุด เลยเจอ 4 กลุ่ม: ปีที่ "เก็บ" ลง DB เป็น พ.ศ., รายงาน/ป้ายคอลัมน์ฝัง +543, หน้าจอที่ไม่ตาม year_type, และ "วันนี้" ที่ได้เมื่อวานเพราะ UTC
อาการ
- A)
account_yearของ stock_beginning และvat_effective_yearของ journaltax เก็บ พ.ศ. ขณะที่erp_account_period.period_yearเป็น ค.ศ. (ตามข้อความ commit68f5a4d4) - B) ตั้ง year_type=0 แล้วรายงานยังขึ้นปี พ.ศ. ในหัวเงื่อนไข ป้ายคอลัมน์ค่าเสื่อมรายปี/เดือน และเดือนภาษีใน VAT summary
- C) หน้าจอ GL/บิล/เช็ค/ประวัติ/ยกเลิก ใช้
<input type="date">หรือแสดงปีเอง ไม่ตาม year_type; FormDesigner แสดงวันที่เป็น ISO - D) ค่าเริ่มต้น "วันนี้" ก่อน 07:00 ได้วันที่เมื่อวาน (M8) และ
formatThaiDateของYYYY-MM-DDถอยหนึ่งวันบนเครื่องที่ timezone ช้ากว่า UTC (N6)
สาเหตุ (root cause)
- A) default
d.Year() + 543ตามโค้ด C#_year_add(diff68f5a4d4ตรวจแล้ว) - B)
formatThaiDateShortฝัง+543,glfaBucketKeyใช้t.Year()+543, SQL VAT summary มี/100+543(diffceda88d1ตรวจแล้ว) - C) แต่ละหน้าจอแปลงปีเอง ไม่มี store กลาง (
5fa7e098เพิ่มsetSmlYearType/getSmlYearType+subscribeSmlSettings;678fc5fc/7dc1b3a6ตามไปแก้หน้าจอ ตามข้อความ commit ไม่ได้ตรวจ diff ทุกหน้า) - D)
new Date().toISOString().slice(0,10)คือ UTC;new Date("YYYY-MM-DD")คือเที่ยงคืน UTC (ตรวจแล้วจาก diff7dc1b3a6และคอมเมนต์ในutils.ts)
วิธีแก้
- A)
68f5a4d4: default เป็นd.Year()/t.Year();JournalTaxTabsแสดง/รับปีตาม year_type แต่เก็บ ค.ศ. และแปลงค่าเก่าที่ >2400 กลับตอนโหลด; แก้ Go test ให้คาดปี ค.ศ. - B)
5fa7e098เพิ่มreadErpYearType, ฟิลด์yearTypeในผลรายงาน และapplyReportYearTypeเป็นตาข่ายสุดท้ายที่แปลงวันที่ในConditionTextและเซลล์สตริง; วันที่พิมพ์ใน PDF ตามres.YearType.ceda88d1ส่งyearTypeเข้าglfaBucketKey/glfaBuckets/sopoMonthSpec, ทำหัวเงื่อนไขเป็น "ปี ค.ศ./พ.ศ.", และให้ SQL VAT อ่านerp_option.year_type - C)
678fc5fc/7dc1b3a6: แสดงด้วยformatSmlDate(.., yearType)และเปลี่ยน input date ธรรมดาเป็นDateBox;1ea23586แปลง ISO เป็น DD/MM/YYYY ใน FormDesigner (diff แสดงเฉพาะสลับลำดับ ยังเป็นปี ค.ศ. ไม่ได้แปลงตาม year_type) - D)
7dc1b3a6:todayLocal()แทนtoISOString()ทุกจอ;faa6e6d0:formatThaiDateแยก Y-M-D เอง
commit ที่เกี่ยวข้อง
5fa7e098 (23 ต.ค., year_type ไดนามิก), 678fc5fc + 7dc1b3a6 (24 ต.ค., หน้าจอ + todayLocal), 68f5a4d4 (DB เก็บ ค.ศ.), ceda88d1 (รายงานไม่ฝัง +543), 1ea23586 (FormDesigner), faa6e6d0 (N6)
โค้ดปัจจุบันที่ป้องกัน
backend/internal/application/process/report.go:185,559,574,650(readErpYearType,formatDateShortByYearType,formatDateByYearType,applyReportYearType; เรียกที่:357ทางRunReportครอบทุก menu report)backend/internal/application/process/report_menu_gl_fa.go:1317(glfaBucketKey),:1720(SQL VAT ตาม year_type); เทสต์report_menu_gl_fa_test.go:69,report_menu_so_po_test.go:282backend/internal/application/process/journaltax.go:208,stock_beginning.go:269(เก็บ ค.ศ.);frontend/account/transaction/JournalTaxTabs.tsx:124,527(แปลงค่า >2400)frontend/src/lib/numeric.ts:137,394,422(todayLocal,getSmlYearType,formatSmlDate);frontend/src/lib/utils.ts:20(formatThaiDate);AGENTS.md:41,57
บทเรียน / กฎที่ได้
- DB เก็บ ค.ศ. เท่านั้น แปลงเฉพาะตอนแสดง/รับ input ผ่าน
year_typeห้ามบวก/ลบ 543 ในโค้ดธุรกิจ - ฟังก์ชันจัดรูปวันที่ต้องรับ
yearTypeเป็นพารามิเตอร์ ห้ามมี default ที่ฝัง พ.ศ. (ตอนนี้formatThaiDateShortยังเรียกByYearType(iso, 1)และอาศัยapplyReportYearTypeแก้ปลายทาง, จุดเรียกreport.go:499report_menu_gl_fa.go:156,866,927,1365,1371) - ใช้
todayLocal()เสมอ ห้ามtoISOString().slice(0,10)ที่GlobalDocFormPrintModal.tsx:1625-1626ยังเหลือแบบ UTC (frontend/shared/components, ตรวจเจอตอนเขียนโน้ตนี้ ยังไม่ได้แก้) - heuristic
>2400 = พ.ศ.(ในformatDateByYearType,formatSmlDate) ใช้รับค่าเก่าได้ แต่ไม่ใช่ที่เก็บ — ปี DB ที่เป็น 2400+ จริงจะถูกลบ 543 - ตรวจสอบ 3 ชั้นพร้อมกัน: Go (default/รายงาน), SQL (
+543ในสตริง SQL), หน้าจอ (grep543)
ดูเพิ่ม
บทเรียน ช่องตัวเลข/วันที่และกฎ "ศูนย์แสดงเป็นว่าง" (Numeric input, DateBox and blank-zero) · บทเรียน เครื่องมือรายงานให้ตรง C# (Report engine parity) · บทเรียน ข้อความไทยใน PDF และงานพิมพ์ (Thai text, PDF and print) · ปีปฏิทิน พ.ศ./ค.ศ. และระบบ 2 ภาษา + Balloon Help (year_type, Bilingual) · ช่องกรอกมาตรฐานและกฎป้ายข้อความ (NumberBox, DateBox, CodeBox, LookupBox, ห้าม F1-F12) · history-overview
ที่มาในโค้ด
repo smlaiaccount (อ่านอย่างเดียว): backend/internal/application/process/{report.go,report_menu_gl_fa.go,journaltax.go,stock_beginning.go}, frontend/src/lib/{numeric.ts,utils.ts}, frontend/account/transaction/JournalTaxTabs.tsx, AGENTS.md:41,57, docs/kms/KMS_SECURITY_DATA_INTEGRITY_LESSONS.md (M8, มติเจ้าของ), diff ของ 68f5a4d4, ceda88d1, 1ea23586, 5fa7e098, 7dc1b3a6