ตัวเลข เงิน ภาษี และปี พ.ศ. ฝั่ง frontend (numeric.ts)
ทุกการคำนวณ/แสดงผล/ส่ง SQL ที่เป็นตัวเลขเงิน ผ่านไฟล์เดียว src/lib/numeric.ts ซึ่งใช้ string + bigint ไม่ใช้ float/parseFloat/Number() (ระบุไว้ในหัวไฟล์ บรรทัด 1-5)
ทศนิยมและรูปแบบปีอ่านจากตั้งค่าระบบ (erp_option) แล้ว cache ไว้ใน module
ทำงานอย่างไร
ตัวเลขเป็น string + bigint
parseScaled(val): bigint(162) แปลงข้อความเป็นเลขจำนวนเต็มคูณSCALE_FACTOR = 10^12(บรรทัด 155) แล้วformatScaled(188) แปลงกลับเป็นข้อความตามจำนวนทศนิยม.- ฟังก์ชันเลขคณิต:
addDec/subDec/mulDec/divDec/cmpDec/sumDec(281-327) รับunknownคืน string. roundSml(val, digits=2, cascade=true)(231) ลอกMyLib._global._roundของ SMLERP เดิม:cascade=trueปัดทีละหลักจากท้ายขึ้นมา (เช่น1.2345 -> 1.235 -> 1.24),cascade=falseปัด half-up ที่หลักเป้าหมาย;digitsถูกจำกัด 0-8.isZeroDecimal(553),normalizeNumericOnBlur/formatNumericInput/formatLiveComma(564-660) ใช้กับช่องกรอก.
ส่งเข้า SQL: decimalSql(val, scaleOrFallback=6) (110) ตรวจรูปแบบ (ไม่เกิน 15 หลักจำนวนเต็ม, ทศนิยมไม่เกิน scale), ตัดจุลภาค, แปลง .5/5. ให้ถูก; ค่าว่าง -> "0"; ผิดรูป -> throw Error("ข้อมูลตัวเลขไม่ถูกต้อง") (ถ้าไม่มี fallback). ใช้ร่วมกับ sqlDecimal ใน ตัวเรียก API และตัวประกอบ SQL ฝั่งเบราว์เซอร์ (api-client, query-client, sml-query-builder).
ทศนิยมตามตั้งค่าระบบ
- ชนิด
SmlDecimalKind = "qty"|"price"|"amount"|"fx"|"gl"|"int"(335); ค่าเริ่ม 2 หลักทุกชนิด (ตัวแปรDEFAULT_DECIMAL_SETTINGS, ~บรรทัด 345). refreshSmlDecimalSettings()(451) ยิงPOST /api/query/listอ่านitem_qty_decimal, item_price_decimal, item_amount_decimal, currency_exchange_decimal, gl_no_decimal, year_typeจากตารางerp_option(บรรทัด 473) พร้อมหัวX-SML-DBจากlocalStorage["sml_selected_db"]; ข้ามหน้า/login,/select-database,/admin.getSmlDecimals(kind)(522) ให้จำนวนหลักตามชนิด;invalidateSmlSettings()(516) ถูกเรียกเมื่อสลับฐาน/ผู้ใช้ (ตัวเรียก API และตัวประกอบ SQL ฝั่งเบราว์เซอร์ (api-client, query-client, sml-query-builder));subscribeSmlSettings(386) ให้ React อัปเดตเมื่อตั้งค่าเปลี่ยน.- ผู้บันทึกหน้า "กำหนดข้อเลือกพิเศษ" เรียก
setSmlYearTypeและrefreshSmlDecimalSettingsหลังบันทึก (เครื่องฟอร์มแบบ schema (SchemaForm, FieldDef, useRecordForm) และจอตั้งค่าระบบ).
ปี พ.ศ./ค.ศ.: year_type 0 = ค.ศ. (23/10/2026), 1 = พ.ศ. (23/10/2569); getSmlYearType/setSmlYearType (394/399, เก็บ localStorage["sml_year_type"]) และ formatSmlDate(val, yearType) (422) แปลงรูปแบบแสดงผล; todayLocal() (137) คืนวันที่ตามเครื่องรูป YYYY-MM-DD.
สูตรเอกสาร (ต้องตรงกับ backend grid_calc.go)
calcAfterDiscount(discountWord, baseAmount, amountDecimal=2, qty="1", alwaysRound=true)(664): แยกคำส่วนลดด้วย,เท่านั้น;x%= ลดเป็น % จากยอดคงเหลือ,+x%= บวกเพิ่ม,@x= ลด x คูณจำนวน,x= ลดเป็นจำนวนเงิน.vatCalc({valueVat, valueNoVat, discountWord, vatRate, vatType, advance, amountDecimal})(739) คืนtotal_value, total_discount, total_before_vat, total_vat_value, total_after_vat, total_except_vat, total_amount.vatType0 = แยกนอก, 1 = รวมใน, 2 = ยกเว้นภาษี, 3 = ไม่กระทบภาษี (transLayouts.ts:10-15).evalArithmeticSafe(842) คำนวณนิพจน์เลขคณิตในช่องกรอก (ยังไม่ได้อ่านเนื้อใน).
ช่องกรอกตัวเลข: shared/ui/NumberBox.tsx - NumberBox (102) และ CommaNumberInput (242) ใช้ useFocusDraft (27) เก็บค่าที่พิมพ์เป็น string ระหว่างโฟกัส; ส่วน handleNumericKeyDown (numeric.ts:42) ใช้บล็อกอักขระที่ไม่ใช่ตัวเลข.
ข้อควรระวัง
- ห้ามคำนวณเงินด้วย
Number()/parseFloatในจอ - ใช้addDec/mulDec/...; ค่าจาก DB เป็น string. - จอเอกสารใช้ทั้ง
vatCalc(ฝั่งเว็บ) และtransTotals(เรียก backend/api/process/transgrid/totals) - หัวฟังก์ชันcalcAfterDiscountระบุว่าสูตรต้องตรงกับgrid_calc.goของ backend (numeric.ts:655-662); ห้ามแก้สูตรฝั่งเดียว (จอเอกสารธุรกรรมแบบเดียวกันทุกจอ (UniversalTransScreen)). - ถ้าเพิ่มชนิดทศนิยมใหม่ต้องแก้ทั้ง
SmlDecimalSettings, ค่าเริ่มต้น และ SQL ในrefreshSmlDecimalSettings.
ที่มาในโค้ด
frontend/src/lib/numeric.ts:1-5,110-136,155-231,281-327- หลักการ, decimalSql, bigint, round, เลขคณิตfrontend/src/lib/numeric.ts:335-400,451-530- ทศนิยม/ปีจากerp_optionfrontend/src/lib/numeric.ts:664-841- ส่วนลดและ VATfrontend/shared/ui/NumberBox.tsx:27,102,242- ช่องกรอกตัวเลข
ดูเพิ่ม
ภาพรวม Frontend ของ SML Ai Account (Frontend overview) · จอเอกสารธุรกรรมแบบเดียวกันทุกจอ (UniversalTransScreen) · ตัวเรียก API และตัวประกอบ SQL ฝั่งเบราว์เซอร์ (api-client, query-client, sml-query-builder) · ภาพรวมระบบบัญชี SML AI Account (Accounting Overview) · สารบัญมาตรฐานและกฎเหล็กของ SML Ai Account (Standards Overview)