Step 2: เงื่อนไขการวางบิล
Step นี้ใช้กำหนด “สูตรการคิดเงิน” ของสัญญา

เงื่อนไขสัญญามีกี่แบบ
จากโค้ดที่ตรวจสอบพบว่าเงื่อนไขสัญญาหลักมี 9 แบบ คือ A1, A2, A3, B1, B2, C, D, E, และ F
นอกจากนี้ B1 และ B2 ยังมี groupOptionalLogic เพิ่มอีก 2 แบบ คือ
VEHICLE_TYPE- กำหนดตามประเภทรถPACAKGE_PRICE- กำหนดตามราคาเหมา
ใช้ทำอะไร
- เลือกกลุ่มเงื่อนไขจริงของสัญญา
- แสดงฟอร์มเฉพาะตามกลุ่มที่เลือก
- กำหนดราคาและเงื่อนไขการวางบิลของแต่ละ group
- ตั้งค่าราคาน้ำมัน, ตารางช่วงราคา, ราคาต่อเที่ยว, ราคาต่อกิโลเมตร, ค่ารถร่วม, ค่า standby, และค่าใช้จ่ายอื่นๆ ตามที่ group นั้นต้องใช้
สรุปแต่ละกลุ่ม
ตัวอย่างตัวเลขด้านล่างเป็นตัวอย่างเพื่ออธิบายวิธีคิดจากโค้ด ไม่ใช่ค่าจริงของระบบ
กลุ่ม A: ค่าเที่ยว
A1: ค่าเที่ยวพื้นฐาน ราคาแน่นอน
- ใช้ทำอะไร: คิดค่าเที่ยวหลักแบบราคาตายตัว
- คำนวณยังไง: backend นับ
tripRecordVehicleที่อยู่ในช่วงบิลและตรงกับcontractRoute/vehicleTypeแล้วคูณpricePerRound - เที่ยวตีเปล่า: ถ้ามี
passPriceระบบจะสร้างรายการเพิ่ม โดยนับจากลำดับเที่ยวIN/OUT - ตัวอย่าง: ถ้านับได้ 120 เที่ยว และ
pricePerRound = 250บาท จะได้120 x 250 = 30,000บาท - ตัวอย่างเที่ยวตีเปล่า: ถ้านับได้ 20 เที่ยว และ
passPrice = 80บาท จะได้20 x 80 = 1,600บาท
A2: ค่าเที่ยวที่ผูกกับราคาน้ำมัน
- ใช้ทำอะไร: คิดค่าเที่ยวเหมือน A1 แต่ราคาถูกเลือกจากช่วงราคาน้ำมัน
- คำนวณยังไง: backend เอา
fuelPriceของช่วงบิลไปเทียบกับpricePerFuelRangeแล้วใช้ราคาที่ตรงช่วงนั้นมาคูณจำนวนเที่ยว - เที่ยวตีเปล่า: ใช้หลักเดียวกัน แต่เลือกเรตราคาตามน้ำมันแทนราคาแน่นอน
- ตัวอย่าง: ถ้า
fuelPriceตรงช่วงที่กำหนดราคาไว้ 270 บาท/เที่ยว และนับได้ 120 เที่ยว จะได้120 x 270 = 32,400บาท
A3: ค่าเที่ยวที่ต้องระบุเวลาและชนิดเที่ยวเพิ่ม
- ใช้ทำอะไร: คิดค่าเที่ยวที่ต้องแยกตามเวลาเดินรถและชนิดเที่ยว
IN/OUT - คำนวณยังไง: หน้าฟอร์มเก็บ
tripTime,tripType, และtripRoundPerRoute; backend จะนับเที่ยวที่ตรงcontractRoute,vehicleType, ช่วงบิล และrouteRoundTripTimeแล้วคูณpricePerRound - ตัวอย่าง: ถ้าเที่ยวที่ตรงเงื่อนไขมี 40 เที่ยว และ
pricePerRound = 300บาท จะได้40 x 300 = 12,000บาท
กลุ่ม B: เหมาจ่ายรายเดือน
B1: เหมาจ่ายรายเดือน ไม่แปรผันตามน้ำมัน
- ใช้ทำอะไร: คิดแบบเหมารายเดือน โดยเลือกได้ 2 แบบผ่าน
groupOptionalLogic - คำนวณยังไง:
- ถ้าเป็น
VEHICLE_TYPEจะคิดแยกตามประเภทรถ ใช้vehicleAmount x pricePerRound - ถ้าเป็น
PACAKGE_PRICEจะรวมเป็น 1 รายการ แล้วใช้ราคาจากแถวแรก
- ถ้าเป็น
- ตัวอย่างแบบแยกประเภทรถ: ถ้ามีรถ 3 คัน และราคา 50,000 บาท/คัน จะได้
3 x 50,000 = 150,000บาท - ตัวอย่างแบบแพ็กเกจ: ถ้าระบบรวมเป็น 1 รายการ และตั้งราคา 180,000 บาท จะได้
180,000บาท
B2: เหมาจ่ายรายเดือนที่ผูกกับราคาน้ำมัน
- ใช้ทำอะไร: โครงสร้างเหมือน B1 แต่ราคาเปลี่ยนตามช่วงน้ำมัน
- คำนวณยังไง: ใช้
fuelPriceไปหาเรตราคาจากpricePerFuelRangeแล้วค่อยคำนวณตามVEHICLE_TYPEหรือPACAKGE_PRICE - ตัวอย่าง: ถ้าช่วงน้ำมันปัจจุบันให้ราคา 62,000 บาท/เดือน และมี 1 แพ็กเกจ จะได้
62,000บาท
กลุ่ม C: ค่าตัวรถ + ระยะทาง
- ใช้ทำอะไร: แยกการคิดเป็น
ค่าตัวรถ,ค่ากิโลเมตร, และรายการที่อ้างอิงน้ำมัน - คำนวณยังไงจาก backend:
- รายการจาก
contractBillingDetailsใช้vehicleAmount x pricePerVehicle - รายการจาก
vehicleCalculateDetailsใช้vehicleAmount x pricePerVehicle - รายการจาก
contractRouteCalculationsใช้trip count x pricePerKilometerและใส่oilRateเพื่ออ้างอิงราคาน้ำมันของรอบนั้น
- รายการจาก
- ตัวอย่าง: ถ้ารายการสายรถมี 2,000 กม. และตั้ง
pricePerKilometer = 8บาท จะได้2,000 x 8 = 16,000บาท
กลุ่ม D: Standby
- ใช้ทำอะไร: คิดบิลจากงาน standby จริงในฐานข้อมูล
- คำนวณยังไง: backend เปิด/ปิดตาม switch เช่น
kmEnabled,vehiclePriceEnabled,otWorkDayEnabled,weekendEnabled,driverSalaryEnabled - รายการที่พบในโค้ด:
ค่ากิโลเมตร STBค่ากิโลเมตรเกินราคาตัวรถOT วันธรรมดาOT วันหยุดค่าพนักงานขับรถรายวัน
- ตัวอย่าง: ถ้า standby รวมได้ 120 กม. และ
stbPrice = 25บาท/กม. จะได้120 x 25 = 3,000บาท
กลุ่ม E: Full-time
- ใช้ทำอะไร: คิดงานประจำแบบ full-time ที่มีหลายองค์ประกอบ
- คำนวณยังไง: backend ใช้ข้อมูลจาก
fullTimePricePerKmDetail,fullTimeVehicleInWeekendDetails,fullTimeTripRoundDetails,fullTimeVehicleCalculateDetailsและยังคำนวณส่วน standby ต่อท้ายเหมือนกลุ่ม D - รายการที่พบในโค้ด:
ค่ากิโลเมตรค่ารถในวันหยุดค่าต่อเที่ยวค่าตัวรถStandbyต่อท้าย
- ตัวอย่าง: ถ้ารายการ full-time คิดได้ 120 เที่ยว และตั้งราคา 100 บาท/เที่ยว จะได้
120 x 100 = 12,000บาท
กลุ่ม F: เงื่อนไขพิเศษ
- ใช้ทำอะไร: คิดส่วน
partner invoiceแยกจากบิลหลัก - คำนวณยังไง: backend ใช้
contractPartnerInvoiceDetailsแล้วคำนวณตามoperationCalculationTypeFIXED_PRICEใช้ราคาตายตัวจากรายละเอียดที่กรอกPERCENTAGEใช้ราคาจากบิลแล้วหักตามเปอร์เซ็นต์ของpartnerCompany.operationPercentage
- ตัวอย่างแบบราคาแน่นอน: ถ้าค่าดำเนินการ 1,000 บาท/เที่ยว และมี 10 เที่ยว จะได้
10,000บาท - ตัวอย่างแบบเปอร์เซ็นต์: ถ้าราคาตั้งต้น 1,000 บาท/เที่ยว, 10 เที่ยว รวม 10,000 บาท และหัก 10% จะเหลือ
9,000บาท
ภาพรวมที่ควรจำ
A1,A2,A3เป็นกลุ่มค่าเที่ยวB1,B2เป็นกลุ่มเหมาจ่ายรายเดือนCเป็นกลุ่มที่ผูกกับค่าตัวรถและกิโลเมตรDและEใช้ข้อมูล standby / full-time ที่ละเอียดกว่าFเป็นกรณีพิเศษที่ต้องดูcontractPartnerInvoiceDetailsและoperationCalculationType
ฟอร์มที่ระบบแสดงตามกลุ่ม
A1- ฟอร์มสัญญาแบบเที่ยวคงที่A2- ฟอร์มสัญญาแบบเที่ยวผูกกับราคาน้ำมันA3- ฟอร์มสัญญาแบบเที่ยวที่มี logic เพิ่มเติมB1- ฟอร์มเหมาจ่ายรายเดือนB2- ฟอร์มเหมาจ่ายรายเดือนที่ผูกกับราคาน้ำมันC- ฟอร์มคิดตามระยะทางD- ฟอร์มงาน StandbyE- ฟอร์มรถประจำ/Full-timeF- ฟอร์มเงื่อนไขพิเศษ
สิ่งที่ควรรู้
- Step นี้คือจุดที่กำหนดว่ากลุ่มสัญญาจะคิดเงินแบบไหน
- บาง group ต้องกรอกข้อมูลเพิ่ม เช่น ตารางราคาน้ำมัน, ราคาต่อ km, หรือรายละเอียดรถร่วม
- หน้าจอจะเปลี่ยนฟิลด์อัตโนมัติตาม group ที่เลือกจาก Step 1
ระบบตรวจจริงก่อนข้ามไป Step 3
จากโค้ดล่าสุด หน้า Create/Edit Contract จะยิง POST /contracts/validate ตอนขยับจาก Step 2 ไป Step 3
โดยไม่ได้ตรวจแค่ field ว่าง แต่ตรวจ configuration จริงเทียบกับกติกาใน backend แล้วส่ง error กลับมาเป็นกลุ่ม section
สิ่งที่ระบบตรวจเพิ่มจาก backend เช่น:
routeที่ถูกอ้างในcontractBillingDetails,contractPartnerInvoiceDetails,passDetail, และชุดข้อมูล Full-time ต้องอ้างถึงสายรถที่มีจริงใน Step 1- กลุ่ม
A2,B2, และFต้องมีcontractBillingDetails - กลุ่ม
A3ต้องมีpassDetail - ถ้าเปิด pricing บางประเภทใน
DหรือEระบบจะบังคับว่าต้องมี detail ของหมวดนั้นจริง - ถ้าเปิด section ของ Full-time เช่น
fullTimeKm,fullTimeTripRound,fullTimeWeekend, หรือfullTimeVehiclePriceระบบจะตรวจว่ามีข้อมูลรองรับครบ - fuel price configuration ต้องครอบช่วงราคาที่ระบบใช้คำนวณจริง มิฉะนั้นจะถูก block ก่อนบันทึก
ถ้าพบปัญหา ระบบจะแสดง dialog รวม error โดยแยกหัวข้อ เช่น ข้อมูลสายรถ, ข้อมูลการวางบิล, ข้อมูลการคำนวณราคาน้ำมัน, หรือ ข้อมูลเที่ยวตีเปล่า
ทำให้ผู้ดูแลระบบย้อนกลับไปแก้เฉพาะ section ที่ผิดได้เร็วกว่าเดิม
อ้างอิงโค้ดล่าสุด
/Users/chanchaitasujai/Project-ATP30/atp30-tos-frontend/src/views/pages/contracts/forms/ContractMasterForm.tsx/Users/chanchaitasujai/Project-ATP30/atp30-tos-frontend/src/api/contracts.ts/Users/chanchaitasujai/Project-ATP30/atp30-core-api/src/contracts/contracts.controller.ts/Users/chanchaitasujai/Project-ATP30/atp30-core-api/src/contracts/contracts.service.ts
สรุปสั้นๆ
ถ้า Step 1 คือ “โครงสัญญา”
Step 2 ก็คือ “สูตรคำนวณเงิน” ที่ผูกกับสัญญานั้นโดยตรง
สิ่งที่ควรจำ
- Step นี้เป็นตัวกำหนดวิธีคิดเงินหลัก
- ถ้าเลือกกลุ่มผิด ฟอร์มที่แสดงและผลคำนวณจะผิดตามไปด้วย