ปัจจุบันงานทั้งหมดคุมด้วย Excel 1 ไฟล์ต่อเดือน 33 ชีต (ชีตสรุป “ใบคุมเที่ยว” + ชีตเช็คชื่อ + ชีตรายคน 31 ชีต) จากการตรวจไฟล์จริง พบว่าปัญหาไม่ใช่แค่ “สูตรเยอะ” แต่เป็นปัญหาเชิงโครงสร้างที่ทำให้ตัวเลขเชื่อถือไม่ได้และขยายงานต่อไม่ได้
| # | อาการที่พบจริง (ยืนยันจากไฟล์) | ต้นตอที่แท้จริง |
|---|---|---|
| 1 | สูตร error ~25 จุด (#VALUE!, #REF!) ลามถึงชีตสรุป จน % มาร์จิ้นรวมทั้งบริษัทคำนวณไม่ได้ | เคาะ space ในเซลล์ตัวเลข + ลบคอลัมน์ + ฝังสูตรคำนวณในเซลล์ข้อมูล |
| 2 | ต้อง map คอลัมน์ด้วยมือทีละแถว เพราะยอดรวมอยู่คนละตำแหน่ง (4W, 2W, รายวัน วางไม่เหมือนกัน) | Layout coupling — ค่าตรรกะเดียวกันอยู่คนละเซลล์ต่อคน |
| 3 | จ่ายเงินผิดจริง โดยไม่มี error เตือน — คอลัมน์ “จ่ายรถ” ของคนรถบางคนชี้ไปช่อง “ค่าฐานเงินเดือน” แทนยอดจ่ายจริง | map พิกัดด้วยมือ + ไม่มีการตรวจสอบ (validation) |
| 4 | วันที่ในชีตเช็คชื่อเพี้ยนเป็น “ปี 1969” | กรอกปี พ.ศ. 2 หลัก ไม่มีชนิดข้อมูลวันที่ |
| 5 | ชื่อคน/ชื่อชีตพิมพ์ไม่ตรงกัน (เช่น สกนซ์/สกนธ์, รัฐเซีย/รัฐเชีย) | เชื่อมข้อมูลด้วย “ชื่อ” ที่เป็นทั้งคีย์และสูตร |
| 6 | เพิ่มคน/Hub ต้องคัดลอกชีต + แก้สูตรด้วยมือ (มี 4 ชีต “ว่าง” ค้างไว้) | ไม่มีฐานข้อมูลกลาง — “คน” ถูกทำเป็นเลย์เอาต์ ไม่ใช่ข้อมูล |
| 7 | ไม่เคยกระทบยอดกับเงินจริงที่แพลตฟอร์มโอนมา — กำไรที่เห็นเป็น “กำไรบนกระดาษ” | คิดจากเรทที่บริษัทคีย์เอง ไม่มีการเทียบ settlement |
ในชีตสรุป คอลัมน์ “จ่ายรถ (SPDO 1–30)” ของคนรถ 2 คน ถูกตั้งสูตรชี้ไปที่ช่อง “ค่าฐานเงินเดือน” แทนที่จะเป็นยอดจ่ายจริง ทำให้ยอดหัวบิล ไม่ตรงกับผลรวมรอบ 1–15 บวกรอบ 16–30 ของคนคนนั้นเอง — เป็นความผิดพลาดที่ตาเปล่ามองไม่เห็น เพราะไม่ขึ้นเป็น error สีแดง นี่คือเหตุผลที่ระบบต้อง “คำนวณด้วยตรรกะเดียว + ตรวจสอบอัตโนมัติ”
หัวใจของการออกแบบคือ แยกระบบเป็น 3 ชั้น เพื่อตัดต้นตอปัญหา — ชั้นข้อมูลเก็บเฉพาะข้อมูลดิบ, ชั้นคำนวณคิดเงินตอนอ่าน (ไม่ฝังในเซลล์), ชั้นแสดงผลดึงไปแสดง
| โมดูล | หน้าที่ | แทนอะไรในไฟล์เดิม |
|---|---|---|
| M1 Master Data | ทะเบียนคนรถ / Hub / รถ — ตำแหน่งว่าง = สถานะ vacant | หัวชีตรายคน 31 ชีต |
| M2 Rate Card | ตารางเรทกลาง แบบมีเวอร์ชัน แยกฝั่ง SPX/SPDO ต่อประเภทรถ | เรทที่ฝังในหัวคอลัมน์ |
| M3 Daily Entry | บันทึก 1 แถว/คน/วัน เก็บข้อมูลดิบ + validation ที่ต้นทาง | ตารางวันที่ 1–31 ในชีตรายคน |
| M4 Inbound + Dispatch ใหม่ | รับล็อตงานจาก SPX/LEX เป็นยอดควบคุม + จ่ายงานให้คนรถ | — (ไม่เคยมี) |
| M5 Attendance | เช็คชื่อ มา/ลา/หยุด เป็นเวลาจริง → ผูกฐานประกันรายเดือน | ชีตเช็คชื่อ (ที่วันที่เพี้ยน) |
| M6 Pay Engine MVP | คิด SPX / SPDO / margin / incentive 10% ตามรอบบิล | สูตรคิดเงินที่ฝังเซลล์ |
| M7 Auto Summary MVP | ใบคุมเที่ยวรุ่นใหม่ดึงจากฐานข้อมูล (QUERY/SUMIFS) | ชีตสรุปที่อ้างข้ามชีตทีละเซลล์ |
| M8 Reconciliation ใหม่ | เทียบยอดที่ระบบคิด vs เงินจริงที่โอน → หาส่วนต่าง/งานถูกหัก | — (หัวใจของคุณค่าใหม่) |
| M9 Payslip | สร้างใบจ่าย PDF ต่อคนต่อรอบ ส่งเข้า LINE | สลิปทำมือ |
| M10 RBAC + Audit Log | สิทธิ์ตามบทบาท + บันทึกทุกการแก้ค่าเงิน (ใคร/เมื่อไร/เก่า→ใหม่) | — (ไม่เคยมี) |
โมดูลที่ให้คุณค่าสูงสุด (M4 จ่ายงาน, M8 กระทบยอด) ไม่อยู่ใน MVP — แต่ออกแบบโครงสร้างข้อมูลให้รองรับตั้งแต่แรก แล้วทยอยเปิดในเฟสถัดไป เพื่อให้เริ่มใช้ได้เร็วและไม่ต้องรื้อภายหลัง
| คุณสมบัติของโครงสร้างใหม่ | ผลที่ได้ |
|---|---|
| driver_id เป็นคีย์ — ทุกธุรกรรมอ้างรหัส ไม่ใช่ชื่อ | ดับปัญหาชื่อพิมพ์ไม่ตรง (สกนซ์/สกนธ์) — เชื่อมข้อมูลไม่พลาด |
| daily_entries เป็นตารางเดียว (long-format) ทุกประเภทรถใช้คอลัมน์เดียวกัน | ความต่าง 4W/2W/รายวัน ย้ายไปอยู่ที่ค่าในคอลัมน์ ไม่ใช่ตำแหน่งคอลัมน์ → ไม่มีคอลัมน์รายวันให้ลบ = ไม่มี #REF! อีก |
| work_date เป็นชนิดวันที่จริง + รอบบิลคำนวณจากวันที่ | ดับบั๊ก “ปี 1969” ที่ราก แสดงเป็น พ.ศ. ที่หน้าจอ |
| เพิ่มคน/Hub = เพิ่ม 1 แถว | ตำแหน่งว่าง = สถานะ vacant ไม่ใช่ชีตเปล่า ไม่แตะสูตร |
| payouts เป็นค่าที่คำนวณ (derived) คิดตอนอ่าน | แก้เรทแล้วคำนวณใหม่ทั้งระบบพร้อมกัน ไม่ต้องไล่แก้ 31 ชีต |
| rate_cards มีเวอร์ชัน (effective_from/to) | ขึ้นเรทใหม่ = เพิ่มเวอร์ชัน — บิลย้อนหลังยังคิดด้วยเรทที่ถูกตามวันงาน |
“ใช้คอลัมน์เดียวกันทุกคน” + “เก็บข้อมูลดิบ ไม่เก็บผลลัพธ์ที่คำนวณแล้ว” — เมื่อข้อมูลถูกแยกออกจากการคำนวณ error ทั้งคลาส (#REF!, #VALUE!, map ผิด) ก็หายไปพร้อมกัน
| ประเภท | ขั้นต่ำ (ชิ้น) | ฐาน SPX / SPDO ต่อวัน | เรท S (SPX/SPDO) | เรท L (SPX/SPDO) |
|---|---|---|---|---|
| 4W รายเดือน | 70 | 615.39 / 533.33 | 8 / 6 | L2 12/10 · L3 13/11 |
| 2W รายเดือน | 90 | 615.39 / 466.66 | 6 / 5 | L2 6/5 · L3 7/6 |
| รายวัน (เหมา/วัน) | 65 | 1,150 / 1,000 | 11 / 9 | ตามตกลง |
มิติเรท: platform × vehicle × employment × size_tier × side(SPX/SPDO) + ช่วงเวลาที่มีผล — เปลี่ยนเรท = เพิ่มเวอร์ชันใหม่ ไม่ทับของเก่า
Same / POOH หักทั้ง 2 ฝั่ง แต่ RST / Card / LOST หักเฉพาะฝั่ง SPDO · ชิ้น < ขั้นต่ำ → ได้แค่ค่ากล่อง ไม่ได้ค่าแรง · รายวันวันหยุด/ลา → ไม่ได้ค่าเหมา · ต้องนิยาม “base คิดอย่างไรต่อรอบบิล” ให้ชัด (พบความไม่สอดคล้องระหว่างรอบ 1 กับรอบ 2 ในไฟล์เดิม)
| ชั้น | ตรรกะ | จับอะไร |
|---|---|---|
| ① ภายในวัน | รับเข้า = จ่ายออก + RST + LOST · แจ้งเตือน margin ติดลบ, จ่ายออก > รับเข้า | error ที่ต้นทาง (Excel ทำไม่ได้) |
| ② รอบบิล | รวม SPX/SPDO ต่อคนต่อรอบ + incentive 10% | สรุปแทนใบคุมเที่ยว |
| ③ Settlement | variance = ยอดที่ระบบคิด − ยอดที่แพลตฟอร์มโอนจริง (แยก unpaid / underpaid / size mismatch) | งานจ่ายขาด, ถูกหัก RST/LOST, ปรับไซส์ |
ต่อให้ Excel ไม่มี error เลย ตัวเลขกำไรก็ยังเชื่อไม่ได้จนกว่าจะเทียบกับเงินที่โอนจริง — “กำไรจริง = settlement ที่ได้รับ − SPDO ที่จ่ายคนรถ” คือสิ่งที่ระบบให้ได้ แต่ Excel ปัจจุบันทำไม่ได้เลย
สำหรับธุรกิจขนาด ~26 คน งบจำกัด ไม่ควรเริ่มด้วยเว็บแอปเต็มรูปแบบ เพราะความเร็วในการได้ใช้งานจริง (time-to-value) และการยอมรับของผู้ใช้สำคัญกว่า
| เฟส | เทคโนโลยี | เหตุผล |
|---|---|---|
| Phase 0–1 (Bridge + MVP) | Google Sheets โครงใหม่ (flat table + RateCard + QUERY/SUMIFS) + Apps Script | แอดมิน/บัญชีคุ้นเคยอยู่แล้ว · ไม่มีค่า hosting · ประวัติเวอร์ชัน = audit ฟรี · ได้ใช้จริงใน 1–2 สัปดาห์ |
| Phase 2+ (System of record) | Supabase (Postgres + Auth + RLS) + Next.js มือถือ-first + n8n + LINE | ความถูกต้องระดับธุรกรรมสำหรับงานเงิน · RBAC ที่ระดับฐานข้อมูล · ขยายได้หลายร้อยคนโดยไม่แตะ schema |
ทางเลือกที่พิจารณาแล้วแต่ไม่เลือกเป็นหลัก: AppSheet/Glide (no-code คุมตรรกะ 2 ฝั่งระยะยาวยาก) · Airtable (ค่า seat แพงเมื่อเพิ่มคน) · เว็บแอป custom ตั้งแต่ต้น (ช้า/แพงเกินสำหรับ MVP)
| ช่องทาง | ใคร | การป้องกัน error ที่ต้นทาง |
|---|---|---|
| ฟอร์มมือถือ / LINE | คนรถ (เฟสหลัง) | ทุกช่องเป็นตัวเลข + ตัด space อัตโนมัติ → ดับ #VALUE! · บังคับ รับเข้า=จ่ายออก+RST+LOST ก่อนส่ง · แนบรูป POD |
| หน้าจ่ายงาน / Sheet | แอดมิน Hub | เลือกคนรถจาก dropdown → กันพิมพ์ชื่อผิด · เลือกวันที่จากปฏิทิน → กันบั๊ก 1969 |
| นำเข้า CSV / paste | จาก SPX/LEX | ตั้งยอดควบคุมของแต่ละวัน |
กลยุทธ์การยอมรับ: เฟสแรกไม่บังคับคนรถกรอกเอง (กัน adoption พัง) — แอดมินกรอกเหมือนเดิมแต่บนโครงสร้างที่ถูกต้อง แล้วค่อยดันให้คนรถกรอกเองในเฟสหลัง
Phase 0–2 อยู่บน Google Sheets ทั้งหมด (ลงทุนต่ำ พิสูจน์ตรรกะการคิดเงินได้จริง) ก่อนตัดสินใจลงทุนเว็บแอป — ลูกค้าได้เห็นของใช้งานได้และผลตอบแทนก่อนจ่ายเงินก้อนใหญ่
| # | ประเด็น |
|---|---|
| 1 | กฎคิดเงินที่ “ถูกต้อง” คืออะไรกันแน่ — base คิดอย่างไรต่อรอบบิล, ชิ้น<ขั้นต่ำได้เท่าไร, รายวันวันหยุดได้/ไม่ได้, RST/LOST/Same/POOH หักฝั่งไหนบ้าง (ขอเป็นลายลักษณ์อักษร) |
| 2 | Settlement มาในรูปแบบไหน — ลงรายชิ้น/มี order ref หรือเป็นยอดรวม? ขอไฟล์ตัวอย่างจริง 1–2 รอบ (กำหนดว่ากระทบยอดได้ละเอียดแค่ไหน) |
| 3 | เรทต่างกันต่อ Hub หรือเปลี่ยนกลางเดือนไหม และมีแผนขึ้นเรทเมื่อใด |
| 4 | เฟสแรกให้คนรถกรอกเอง หรือแอดมินกรอกแทน (กระทบขอบเขตงาน LINE อย่างมาก) |
| 5 | ใครต้องเห็นอะไรบ้าง / ใครปิดรอบได้ — เจ้าของ / แอดมิน Hub / บัญชี (กำหนด RBAC) |
| 6 | ต้อง export เข้าระบบบัญชีอะไร (FlowAccount/PEAK/Excel) และ Lazada (LEX) อยู่ในเฟสไหน |
| ประเด็น | การบรรเทา |
|---|---|
| สูตรเดิมบางจุดผิดอยู่แล้ว → migration จะไม่ตรง | ตกลงกับลูกค้าก่อนว่า “ค่าที่ถูก” คืออะไร ไม่ลอกของเดิมที่ผิด |
| กฎคิดเงินมี edge case ซ้อนกัน | ยืนยันเป็นลายลักษณ์อักษรทุกข้อก่อนเขียน engine — ไม่เดา |
| ความละเอียดของ settlement | ขอไฟล์ตัวอย่างจริงก่อนสัญญาฟีเจอร์กระทบยอด |
| การยอมรับของผู้ใช้ | validation เข้ม + ล็อกคอลัมน์สูตร + ฟอร์มสั้นภาษาไทย + รันคู่ขนาน 1 รอบ |
นัดประชุม 1 รอบเพื่อ (ก) ยืนยันกฎคิดเงินทุกข้อ (คำถามข้อ 1) และ (ข) รับไฟล์ Excel ปัจจุบัน + ไฟล์ settlement ตัวอย่าง → เริ่ม Phase 0 ทันที โดยใช้ไฟล์จริงพิสูจน์ว่าระบบให้ตัวเลขตรง (และชี้จุดที่ไฟล์เดิมจ่ายเงินผิด) ก่อนลงทุนเฟสถัดไป