MobileHub
USER MANUAL
ระบบจัดการร้านมือถือ Multi-Tenant SaaS
เวอร์ชัน 2.0 | อัปเดตล่าสุด: 14 พฤษภาคม 2569 (รับเครื่อง 3-step guided flow: intake → checklist → receipt + auto-preview / print colors fix / intake & warranty 1-page / SMALL_RECEIPT logo / repair-intake required fields)
| หัวข้อ | รายละเอียด |
|---|---|
| 1. บทนำ | ภาพรวมระบบ, ความสามารถหลัก, บทบาท, ตารางสิทธิ์ |
| 2. เริ่มต้นใช้งาน | สมัครใช้งาน, ยืนยัน OTP, เข้าสู่ระบบ, แดชบอร์ด, แนะนำระบบ (Tour), โปรไฟล์ |
| 3. คลังสินค้า | สต็อกมือถือ, อุปกรณ์เสริม, รอบนับสต็อก, โอนระหว่างสาขา |
| 4. รับซื้อ-ตีราคา | รับซื้อมือถือ, ตีราคา, Checklist อุปกรณ์, เกรด A/B/C/D |
| 5. งานซ่อม | รับเครื่อง, งานช่าง, รายการทั้งหมด, คลังอะไหล่, Template ราคาซ่อม, ผู้จัดหา + สั่งอะไหล่, Checklist, เอกสาร, ติดตามออนไลน์ลูกค้า, ประกัน |
| 6. ขายสินค้า (POS) | ตะกร้าสินค้า, รับเทรดเครื่องเก่า, วิธีชำระเงิน, PromptPay, หน้าจอลูกค้า, พักบิล, ประวัติ + reprint + void + refund + Z report, ใบแจ้งหนี้ B2B |
| 7. ประกันสินค้า | เพิ่มประกัน, ติดตามหมดอายุ, ประวัติ |
| 8. ลูกค้า | เพิ่ม/แก้ไข/ค้นหาลูกค้า, ประวัติการซื้อ |
| 9. ลงเวลาทำงาน | บันทึกเวลาเข้า-ออก, QR Code Kiosk |
| 10. เงินเดือน | คำนวณเงินเดือน, อนุมัติ, บันทึกการจ่าย |
| 10A. ค่าใช้จ่ายดำเนินงาน | บันทึก rent / utility / fuel / marketing — feed PIT ACTUAL + ภ.พ.30 input VAT + WHT |
| 10B. กะการขาย (Cashier Shift) | เปิด-ปิดกะ + ลิ้นชักเงินสด — variance ระหว่าง expected vs actual + บังคับเปิดกะก่อนขาย (CASHIER/SALES default, ปรับได้) |
| 11. รายงาน | ยอดขาย, การซ่อม, การรับซื้อ, สินค้าคงเหลือ, การเงิน |
| 11A. ภาษี (เมนูใหม่) | ภาพรวม + ภ.ง.ด.94/90 (PIT) + ภ.ง.ด.50/51 (CIT) + ภ.พ.30 (VAT) + ภ.ง.ด.3/53 (WHT) + ตั้งค่าภาษี |
| 12. เอกสารพิมพ์ในระบบ | ใบเสร็จขาย/รับซื้อ/ซ่อม, สลิปเงินเดือน, ใบเครม, ใบสรุปการมาทำงาน, ใบเบิก/รับเข้าอะไหล่ |
| 13. Portal (Tenant Self-Service) | Support Tickets, ประกาศ, Billing, อัปเกรดแพ็กเกจ |
| 14. การจัดการระบบ (Admin) | สาขา, ผู้ใช้งาน, ข้อมูลหลัก, ตั้งค่า, Audit Log |
| 15. การแจ้งเตือน | Notification Center แบบ Real-time + Push Notifications แม้ปิดเว็บ + ติดตั้งเป็นแอป (PWA) |
| 16. Multi-Tenant และ Multi-Branch | Tenant Isolation, Branch Selector |
| 17. ภาคผนวก | API Endpoints, Tech Stack, Deployment, Backup & Restore, Security |
MobileHub v2 เป็นระบบจัดการร้านมือถือแบบ Multi-Tenant SaaS ที่ออกแบบมาสำหรับร้านมือถือทุกขนาด ตั้งแต่ร้านสาขาเดียวจนถึงเชนร้านค้าหลายสาขา ระบบครอบคลุมการทำงานตั้งแต่การรับซื้อมือถือมือสอง การซ่อมบำรุง การขายสินค้าแบบ POS ไปจนถึงการจัดการบุคลากรและรายงานทางการเงิน
ระบบพัฒนาด้วย Next.js 16 + React 19 + Mantine v8 ทางฝั่งหน้า และ Fastify + Prisma + PostgreSQL ทางฝั่งหลัง รองรับการใช้งานแบบ Real-time ผ่าน Socket.IO และออกแบบตามมาตรฐาน Mobile-First เพื่อให้ใช้งานสะดวกบนมือถือ
โดเมน: mobilehub.ajsoftwaredev.com
| 🔧 ความสามารถ | 📝 รายละเอียด |
|---|---|
| 📦 คลังสินค้า | จัดการสต็อกมือถือและอุปกรณ์เสริม พร้อมอัปโหลดรูปภาพ |
| 🛒 รับซื้อ-ตีราคา | บันทึกการรับซื้อมือถือมือสอง พร้อม Checklist อุปกรณ์ |
| 🔧 งานซ่อม | ระบบรับเครื่องซ่อม ติดตามสถานะ แจ้งลูกค้าแบบ Real-time |
| 💰 POS ขายสินค้า | ระบบขายสินค้าพร้อม PromptPay QR, Credit Card, โอน |
| 🛡️ ประกันสินค้า | บันทึกและติดตามประกันสินค้าและงานซ่อม |
| 👥 ลูกค้า | จัดการฐานข้อมูลลูกค้า ประวัติการซื้อ-ซ่อม |
| ⏰ ลงเวลาทำงาน | QR Code Kiosk สำหรับพนักงานลงเวลาเข้า-ออก |
| 💵 เงินเดือน | คำนวณ อนุมัติ และบันทึกการจ่ายเงินเดือน |
| 📊 รายงาน | รายงานยอดขาย, ซ่อม, การเงิน, VAT ออก Excel ได้ |
| 🔔 การแจ้งเตือน Real-time | Bell notification ทุก role พร้อม Socket.IO |
| 🏢 Multi-Branch | รองรับหลายสาขา กรองข้อมูลตามสาขา |
| 🔒 Multi-Tenant | แต่ละ Tenant มีข้อมูลแยกกัน (Tenant Isolation) |
| 🎫 Support Tickets | ยื่น Ticket สนับสนุนกับทีมงาน |
| 📢 ประกาศ | รับข่าวสารประกาศจากทีมงาน |
| 💳 Billing | จัดการ Subscription และชำระค่าบริการ |
| 📝 Audit Log | บันทึกทุกการกระทำในระบบ (ใครทำอะไร เมื่อไหร่) |
| 🖥️ Customer Display | หน้าจอแสดงราคาสำหรับลูกค้า (POS) |
| 🏷️ ข้อมูลหลัก | จัดการ Master Data — ยี่ห้อ, รุ่น, สี, ความจุ ฯลฯ |
| บทบาท | ชื่อในระบบ | คำอธิบาย |
|---|---|---|
| 👑 เจ้าของ | OWNER | สิทธิ์สูงสุด เข้าถึงได้ทุกส่วน รวมถึง Billing |
| 🛠️ ผู้ดูแลระบบ | ADMIN | จัดการระบบ ผู้ใช้ สาขา ตั้งค่า |
| 📋 ผู้จัดการ | MANAGER | ดูรายงาน จัดการสต็อก ดูแลพนักงาน |
| 💰 แคชเชียร์ | CASHIER | รับชำระเงิน ขายสินค้า |
| 🏪 พนักงานขาย | SALES | ขายสินค้า ดูสต็อก |
| 🔧 ช่างซ่อม | TECHNICIAN | จัดการงานซ่อม คลังอะไหล่ |
| 🔧💰 ช่างขาย | SALESTECH | มีสิทธิ์ทั้ง SALES และ TECHNICIAN |
| โมดูล | OWNER | ADMIN | MANAGER | CASHIER | SALES | TECH | SALESTECH |
|---|---|---|---|---|---|---|---|
| แดชบอร์ด | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| สต็อกมือถือ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
| อุปกรณ์เสริม | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
| รับซื้อ-ตีราคา | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
| รับเครื่อง (ซ่อม) | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ |
| งานช่าง | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ |
| รายการซ่อมทั้งหมด | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ |
| คลังอะไหล่ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ |
| Repair Checklist | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ |
| ออกเอกสารซ่อม | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ |
| ประกันงานซ่อม | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ |
| ขายสินค้า (POS) | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
| ประกันสินค้า | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
| ลูกค้า | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
| ลงเวลา | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
| เงินเดือน | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| รายงาน | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
| Portal Tickets | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Portal ประกาศ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Portal Billing | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| สาขา | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| ผู้ใช้งาน | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| ข้อมูลหลัก | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
| ตั้งค่า | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Audit Log | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
ระบบมี 3 แพ็คเกจ ต่างกันที่ ขีดจำกัด (limits) + ฟีเจอร์ขั้นสูง (advanced features)
| แพ็คเกจ | ราคา/เดือน | ราคา/ปี | สาขา | ผู้ใช้ | สินค้า |
|---|---|---|---|---|---|
| เริ่มต้น (Starter) | ฿599 | ฿5,990 | 1 | 3 | 500 |
| มืออาชีพ (Professional) ⭐ | ฿1,499 | ฿14,990 | 3 | 10 | 2,000 |
| องค์กร (Enterprise) | ฿2,499 | ฿24,990 | ไม่จำกัด | ไม่จำกัด | ไม่จำกัด |
| ฟีเจอร์ | Starter | Pro | Enterprise |
|---|---|---|---|
| ระบบขายหน้าร้าน (POS) | ✅ | ✅ | ✅ |
| คลังสินค้า | ✅ | ✅ | ✅ |
| จัดการลูกค้า | ✅ | ✅ | ✅ |
| ระบบรับซ่อม | ✅ | ✅ | ✅ |
| ลงเวลา (พื้นฐาน) | ✅ | ✅ | ✅ |
| รายงานพื้นฐาน | ✅ | ✅ | ✅ |
| Export รายงาน Excel/PDF | ❌ | ✅ | ✅ |
| จอแสดงผลลูกค้า (Customer Display) | ❌ | ✅ | ✅ |
| โหมด Kiosk ลงเวลา QR | ❌ | ✅ | ✅ |
| Dashboard หลายสาขา ("ทุกสาขา") | ❌ | ✅ | ✅ |
| API access | ❌ | ✅ | ✅ |
| ระบบเงินเดือน (Payroll) | ❌ | ❌ | ✅ |
| ลบโลโก้ MobileHub (White-label) | ❌ | ❌ | ✅ |
| ซัพพอร์ต 24/7 (Priority) | ❌ | ❌ | ✅ |
💡 เมนูที่ไม่มีในแพ็คเกจของคุณจะถูกซ่อนอัตโนมัติ — ถ้าต้องการใช้งานต้องอัพเกรดแพ็คเกจที่หน้า Portal Billing
ถ้าสร้างสาขา / ผู้ใช้ / สินค้าเกินจำนวนที่แพ็คเกจกำหนด ระบบจะตอบกลับ:
ถึงขีดจำกัดจำนวนสาขา (แพ็คเกจ มืออาชีพ) 3/3 — กรุณาอัพเกรดแพ็คเกจเพื่อเพิ่ม
→ ต้องลบรายการเก่าออก หรือ อัพเกรดแพ็คเกจ
📍 หน้า: /register
👤 สิทธิ์: สาธารณะ (ไม่ต้องเข้าสู่ระบบ)
วัตถุประสงค์: สร้าง Tenant ใหม่ (ร้านค้า) ในระบบ MobileHub
ขั้นตอน:
https://mobilehub.ajsoftwaredev.com/register⚠️ หมายเหตุ: บัญชีที่สมัครใหม่จะได้รับสิทธิ์ OWNER โดยอัตโนมัติ และเป็น Tenant ใหม่แยกจากกัน
📍 หน้า: /verify-email
👤 สิทธิ์: ผู้ที่เพิ่งสมัครใหม่
วัตถุประสงค์: ยืนยันความเป็นเจ้าของอีเมลก่อนเข้าใช้งานระบบ
ขั้นตอน:
| ตัวเลือก | รายละเอียด |
|---|---|
| OTP หมดอายุ | OTP มีอายุ 10 นาที |
| ขอ OTP ใหม่ | กดปุ่ม "ส่งใหม่" ได้หลังจาก 60 วินาที |
| OTP ผิด | ระบบแจ้งเตือนและให้กรอกใหม่ |
💡 เคล็ดลับ: หาก OTP หมดอายุ กดปุ่ม "ส่งรหัสใหม่" เพื่อรับ OTP ชุดใหม่ได้ทันที
📍 หน้า: /login
👤 สิทธิ์: สาธารณะ
วัตถุประสงค์: เข้าสู่ระบบด้วยอีเมลและรหัสผ่าน
ขั้นตอน:
https://mobilehub.ajsoftwaredev.com/login⚠️ หมายเหตุ: Login ใช้เพียง 2 ฟิลด์ (อีเมล + รหัสผ่าน) ไม่ต้องกรอก Tenant Slug
💡 เคล็ดลับ: Token มีอายุ 24 ชั่วโมง หากหมดอายุจะถูก Redirect ไปหน้า Login โดยอัตโนมัติ
📍 หน้า: /dashboard
👤 สิทธิ์: ทุก Role
วัตถุประสงค์: ภาพรวมสถิติและข้อมูลสำคัญของร้าน แสดงข้อมูลตาม Role ของผู้ใช้
การแสดงผลตาม Role:
| Role | ข้อมูลที่เห็น |
|---|---|
| OWNER / ADMIN | สถิติทั้งหมด + กราฟรายได้ + Top Products + งานซ่อมรอ + สินค้าใกล้หมด |
| MANAGER | สถิติยอดขาย + รายงานสรุป + Top Products |
| TECHNICIAN | งานซ่อมของตัวเอง + สถิติการซ่อม |
| SALES / CASHIER | ยอดขายวันนี้ + สินค้าในสต็อก |
การ์ดสถิติหลัก (Admin/Owner):
💡 เคล็ดลับ: แดชบอร์ดกรองข้อมูลตาม สาขาที่เลือก ในส่วนบน เปลี่ยนสาขาได้จาก Branch Selector ด้านบน
📍 เปิดได้ที่: เด้งเองครั้งแรกหลังเข้าสู่ระบบ + ปุ่ม "แนะนำระบบ" ในเมนูซ้าย (มี Badge "ใหม่" สีฟ้า) 👤 สิทธิ์: ทุก Role (เนื้อหาแตกต่างกันตาม Role)
วัตถุประสงค์: ช่วยผู้ใช้ใหม่เริ่มต้นใช้งานเร็ว — ระบบจะแสดง Welcome Modal พร้อม Checklist สิ่งที่ควรทำก่อน + Guided Tour พาไล่ดูเมนูสำคัญทีละข้อ
Welcome Modal — เด้งครั้งเดียวต่อ User:
ครั้งแรกที่ Login จะเห็น Modal สีเทา-ฟ้า กลางจอ ประกอบด้วย:
Guided Tour — Spotlight แต่ละเมนู:
เมื่อเริ่ม Tour ระบบจะ:
Tour ตาม Role (สรุป):
| Role | จำนวน Steps | เมนูที่ Tour พาไล่ |
|---|---|---|
| OWNER / ADMIN | 7-8 ข้อ | Dashboard → POS → รับเครื่อง → รายงาน → สาขา → ผู้ใช้ → ตั้งค่า → 🔔 |
| MANAGER | 6-7 ข้อ | Dashboard → POS → รายการซ่อม → ลงเวลา → รายงาน → ข้อมูลหลัก → 🔔 |
| CASHIER | 4-5 ข้อ | Dashboard → POS → สต็อก → ลูกค้า → 🔔 |
| SALES | 5-6 ข้อ | Dashboard → POS → สต็อก → รับซื้อ → ลูกค้า → 🔔 |
| TECHNICIAN | 2-3 ข้อ | งานช่าง → คลังอะไหล่ → 🔔 |
เปิดดูซ้ำได้ตลอด:
ถ้าปิดไปแล้วต้องการดูใหม่ — คลิก "แนะนำระบบ" ในเมนูซ้าย (อยู่ด้านล่างใกล้กับ "คู่มือการใช้งาน") → Welcome Modal เปิดอีก
💡 เคล็ดลับ: ระบบบันทึกว่าคุณดูแล้วลง localStorage ของเบราว์เซอร์ — ถ้าเปลี่ยนเครื่อง / เคลียร์ cache จะเด้งใหม่อีกครั้ง
📍 หน้า: /profile
👤 สิทธิ์: ทุก Role
วัตถุประสงค์: ดูและแก้ไขข้อมูลส่วนตัว เปลี่ยนรหัสผ่าน อัปโหลดรูปโปรไฟล์
ฟิลด์ที่แก้ไขได้:
| ฟิลด์ | คำอธิบาย |
|---|---|
| ชื่อ-นามสกุล | ชื่อที่แสดงในระบบ |
| เบอร์โทร | เบอร์ติดต่อ |
| รูปโปรไฟล์ | อัปโหลดรูปภาพ (สูงสุด 5MB) |
| รหัสผ่านเก่า | ต้องกรอกเพื่อเปลี่ยนรหัสผ่าน |
| รหัสผ่านใหม่ | ขั้นต่ำ 8 ตัวอักษร |
📍 หน้า: /stock
👤 สิทธิ์: OWNER, ADMIN, MANAGER, CASHIER, SALES, SALESTECH
วัตถุประสงค์: จัดการสินค้ามือถือในคลัง — เพิ่ม แก้ไข ดูสต็อก
คุณสมบัติหน้านี้:
ขั้นตอนเพิ่มสินค้าใหม่:
| ฟิลด์ | คำอธิบาย | จำเป็น |
|---|---|---|
| ยี่ห้อ | เลือกจาก Master Brands (Apple, Samsung ฯลฯ) | ✅ |
| รุ่น | เลือกจาก Master Models | ✅ |
| ความจุ | 64GB, 128GB, 256GB ฯลฯ | ✅ |
| สี | เลือกจาก Master Colors | ✅ |
| IMEI/Serial | หมายเลขเครื่อง | ✅ |
| สภาพ | NEW (ใหม่) / LIKE_NEW (เหมือนใหม่) / GRADE_A (สภาพดีมาก) / GRADE_B (สภาพดี) / GRADE_C (มีตำหนิ) / GRADE_D (ตำหนิเยอะ — ราคาถูก) | ✅ |
| ราคาทุน | ราคาที่รับซื้อมา | ✅ |
| ราคาขาย | ราคาที่ตั้งขาย | ✅ |
| สถานะ | IN_STOCK, RESERVED, SOLD | ✅ |
| สาขา | เลือกสาขาที่เก็บสินค้า | ✅ |
| หมายเหตุ | รายละเอียดเพิ่มเติม | ❌ |
| รูปภาพ | อัปโหลดสูงสุดหลายรูป (5MB/ไฟล์) | ❌ |
การสแกน Barcode:
มุมมองมือถือ:
⚠️ หมายเหตุ: IMEI/Serial Number ต้องไม่ซ้ำกันในระบบ (Unique ต่อ Tenant)
📍 หน้า: /accessories
👤 สิทธิ์: OWNER, ADMIN, MANAGER, CASHIER, SALES, SALESTECH
วัตถุประสงค์: จัดการสินค้าประเภทอุปกรณ์เสริม เช่น เคส สายชาร์จ หูฟัง กระจก
คุณสมบัติ:
ฟิลด์สินค้าอุปกรณ์เสริม:
| ฟิลด์ | คำอธิบาย | จำเป็น |
|---|---|---|
| ชื่อสินค้า | ชื่อสินค้า | ✅ |
| ยี่ห้อ | เลือกจาก Master Brands | ❌ |
| หมวดหมู่ | เคส, สายชาร์จ, หูฟัง ฯลฯ | ✅ |
| จำนวน (Stock) | จำนวนชิ้นในคลัง | ✅ |
| ราคาทุน | ต้นทุนสินค้า | ✅ |
| ราคาขาย | ราคาที่ตั้งขาย | ✅ |
| สาขา | สาขาที่เก็บสินค้า | ✅ |
| สี | สีของอุปกรณ์ | ❌ |
| บาร์โค้ด | รหัสสินค้า | ❌ |
| หมายเหตุ | รายละเอียดเพิ่มเติม | ❌ |
ประเภทธุรกรรมอุปกรณ์เสริม:
IN — รับสินค้าเข้าคลังOUT — ตัดสต็อกออกSELL — ขายสินค้า (ผ่าน POS)💡 เคล็ดลับ: Category เริ่มต้นของระบบ ได้แก่ เคส, ฟิล์ม/กระจก, สายชาร์จ, หูฟัง, Power Bank, อื่นๆ
📍 หน้า: /stock-count (list) + /stock-count/[id] (counting)
👤 สิทธิ์: OWNER, ADMIN, MANAGER
วัตถุประสงค์: ตรวจสต็อกจริง vs ระบบ — ตรวจของหาย, ตรวจ data integrity, audit trail สำหรับผู้สอบบัญชี (มาตรฐาน auditor ขอ stock count log เป็นปกติ)
3 ประเภทการนับ:
| ประเภท | ใช้เมื่อไหร่ |
|---|---|
| FULL | นับสิ้นปี — ทุกรายการในร้าน |
| CYCLE | นับเฉพาะหมวด/ยี่ห้อ/location — ทำได้ทุกเดือน |
| SPOT_CHECK | ตรวจสุ่ม |
Workflow:
/stock-count → กด + เริ่มรอบนับใหม่ → เลือกประเภท/stock-count/[id] (mobile-first interface):
totals snapshot: expected/counted/missing/extraข้อดี:
⚠️ ห้ามมี 2 รอบนับเปิดพร้อมกันที่สาขาเดียวกัน — ระบบจะ block + redirect ไป รอบเก่า
📍 หน้า: /stock-transfer
👤 สิทธิ์: ขอโอน = ทุก role; อนุมัติ/ยกเลิก = MANAGER+
วัตถุประสงค์: Multi-branch ใช้ได้แล้ว แต่ก่อนหน้านี้ โอนของระหว่างสาขาไม่ได้ — ของอยู่สาขา A ลูกค้าอยากซื้อที่สาขา B → ต้องลบ-สร้างใหม่ (ไม่มี audit trail). ระบบ Stock Transfer แก้ปัญหานี้
Workflow 3 stages:
| สถานะ | คำอธิบาย | Action |
|---|---|---|
| PENDING | ขอโอน รอ manager ของสาขาต้นทางอนุมัติ | manager กด อนุมัติ + ส่ง → IN_TRANSIT |
| IN_TRANSIT | ส่งของแล้ว — สาขาต้นทางตัดสต็อก/RESERVED ไว้ | manager ปลายทางกด รับเข้า เมื่อของมา → RECEIVED |
| RECEIVED | ของมาถึงปลายทาง — สาขาปลายทางได้สต็อกเพิ่ม | (จบ — เลขที่ใบโอน TR-XXX-XXXX-XXXX จบ lifecycle) |
| CANCELLED | ยกเลิก (PENDING → cancel ได้ทันที / IN_TRANSIT → restore stock ที่ต้นทาง) | (จบ) |
สร้างคำขอโอน:
/stock-transfer → กด ขอโอนสินค้า (ต้องมี ≥ 2 สาขา)Auto stock movement:
branchId + status=AVAILABLEtransferNumber format: TR-{branchCode}-{BEyear}-{seq:04} — running serial ตาม docSerial system
Tabs: ทั้งหมด / ขาเข้า (รับ) / ขาออก (ส่ง) — filter ดูตามทิศทาง
📍 หน้า: /purchase
👤 สิทธิ์: OWNER, ADMIN, MANAGER, CASHIER, SALES, SALESTECH
วัตถุประสงค์: บันทึกการรับซื้อมือถือมือสองจากลูกค้า พร้อมตีราคา และออกใบรับซื้อ
ขั้นตอนรับซื้อมือถือ:
| ฟิลด์ | คำอธิบาย | จำเป็น |
|---|---|---|
| ลูกค้า | เลือกจากฐานข้อมูล หรือเพิ่มใหม่ | ✅ |
| ประเภทอุปกรณ์ | มือถือ, แท็บเล็ต ฯลฯ | ✅ |
| ยี่ห้อ | ยี่ห้อสินค้า | ✅ |
| รุ่น | รุ่นสินค้า | ✅ |
| ความจุ | หน่วยความจำ | ✅ |
| สี | สีสินค้า | ✅ |
| IMEI/Serial | หมายเลขเครื่อง (สแกน Barcode ได้) | ✅ |
| สภาพ | สภาพเครื่อง | ✅ |
| ราคารับซื้อ | ราคาที่จ่ายให้ลูกค้า | ✅ |
| ราคาตั้งขาย | ราคาที่จะขายต่อ | ✅ |
| Checklist อุปกรณ์ | ตรวจสอบอุปกรณ์แนบมา | ❌ |
| รูปภาพ | ถ่ายรูปสภาพเครื่อง | ❌ |
| หมายเหตุ | เงื่อนไขพิเศษ | ❌ |
คุณสมบัติเพิ่มเติม:
⚠️ ข้อควรระวัง — ตรวจเครื่องด้วยตนเองก่อนรับ
ระบบ MobileHub ไม่ได้ ตรวจ iCloud lock / Find My iPhone / blacklist global โดยอัตโนมัติ — checklist "ปลด Apple ID แล้ว" / "Factory Reset แล้ว" ในฟอร์มเป็นการ ยืนยันจากผู้ขาย เท่านั้น (self-declaration)
กรุณาตรวจด้วยตนเองก่อนจ่ายเงินรับเครื่อง:
หลักฐานทางกฎหมาย: ใบรับซื้อมือถือมือสองมีคำรับรองผู้ขาย 5 ข้อ (ไม่ใช่ของโจร / ไม่ติด iCloud / ไม่ติดผ่อน / IMEI ไม่ blacklist / ยินยอมรับผิดทางอาญา ม.357 ถ้าเป็นเท็จ) + ลายเซ็น 3 ฝ่าย + สำเนาบัตรประชาชน — ใช้ป้องกันร้านจากข้อหา "รับของโจร" ได้
💡 เคล็ดลับ: หลังรับซื้อสำเร็จ สินค้าจะปรากฏในหน้า สต็อกมือถือ โดยอัตโนมัติ พร้อมข้อมูลครบถ้วน
📍 เส้นทาง: /repair-intake → /repair-checklist → /repair-documents (preview)
👤 สิทธิ์: OWNER, ADMIN, MANAGER, SALESTECH (ช่างธรรมดา ไม่เห็น เมนูรับเครื่อง)
วัตถุประสงค์: รับเครื่องจากลูกค้า บันทึกข้อมูล + เช็คสภาพก่อนซ่อม + ออกใบรับซ่อมพร้อมพิมพ์ ภายในชุดเดียวกัน (ไม่ต้องสลับหน้าหลายครั้ง)
ที่ /repair-intake กด "+ รับเครื่อง" → modal เปิด
ฟิลด์ในฟอร์ม:
| ฟิลด์ | คำอธิบาย | จำเป็น |
|---|---|---|
| ลูกค้า | เลือกหรือเพิ่มใหม่ (ค้นหาด้วยชื่อ/เบอร์) | ✅ |
| 🚀 Quick-pick template | (ไม่บังคับ) เลือก template งานยอดฮิต → auto-fill ยี่ห้อ/รุ่น/ค่าแรง/อาการ | ❌ |
| ประเภทเครื่อง | มือถือ / แท็บเล็ต / สมาร์ทวอทช์ / หูฟัง / อื่นๆ | ✅ |
| ยี่ห้อ | จาก Master Brands ของสาขา | ✅ |
| รุ่น | จาก Master Models (กรองตามยี่ห้อ) | ✅ |
| IMEI / Serial | ตัวเลข 15 หลัก (มี 3-layer guard กันพิมพ์ตัวอักษร) | ❌ — สมาร์ทวอทช์/หูฟังไม่มี IMEI ก็เว้นได้ |
| รูปถ่ายเครื่อง | สูงสุด 10 รูป (ลาก-วาง ขนาด ≤ 5MB/รูป) | ❌ |
| อาการเสีย / ปัญหาที่พบ | ลูกค้าแจ้ง (Textarea) | ✅ |
| ราคาประเมิน (เบื้องต้น) | ช่างปรับภายหลังตามอาการจริง | ❌ |
| หมายเหตุ | เงื่อนไขพิเศษ | ❌ |
| ลายเซ็นลูกค้า | canvas เซ็น (mouse/touch) — เก็บใน Repair.intakeSignature | ❌ — แนะนำให้เซ็น |
Validation: ถ้าฟิลด์ที่บังคับขาด → toast แดง "ข้อมูลไม่ถูกต้อง" รวมทุกฟิลด์ที่ขาดเป็น bullet list + แต่ละ Select มี error message ใต้ label. แก้ไขฟิลด์ใดก็ตาม → error ของฟิลด์นั้นหายอัตโนมัติ
กด "บันทึก" → ระบบสร้างงานซ่อม → toast เขียว "รับเครื่องสำเร็จ — ต่อไปเช็คสภาพเครื่องก่อนซ่อม" → redirect อัตโนมัติไปขั้นที่ 2
ระบบพาไป /repair-checklist?repairId=...&autoOpen=PRE_REPAIR — modal เปิดเองทันที (ไม่ต้องคลิก)
สิ่งที่ทำ:
RepairChecklist.customerSignature)กด "บันทึก" → toast "บันทึกสำเร็จ — เช็คก่อนซ่อม + ออกใบรับซ่อมเรียบร้อย" → redirect ไปขั้นที่ 3
ระบบพาไป /repair-documents?repairId=...&autoPreview=intake — modal ตัวอย่างเอกสารเปิดเองพร้อมเนื้อหาครบ:
ทั้งหมด อยู่ใน 1 หน้า A4 (ใช้ .intake-receipt CSS scope compactions) → กดปุ่ม "พิมพ์" → printer dialog เปิด
ทำไมต้อง 3 ขั้น:
💡 Tip — Skip checklist: ถ้างานเร่งและไม่ต้องการ checklist (เช่น เปลี่ยนสาย charger 5 นาที) ขั้น 2 ปิด modal ทิ้งได้ — ระบบยังคงสร้างงานซ่อมไว้ที่ /repair แล้ว แค่ไม่มี checklist + ไม่ออกใบให้อัตโนมัติ. สามารถออกใบรับซ่อมเองภายหลังที่ /repair-documents (ใบจะไม่มี checklist section)
⚠️ หมายเหตุ: ช่างที่มี Role TECHNICIAN เท่านั้น ไม่เห็น เมนูรับเครื่อง — เห็นเฉพาะงานที่ถูกมอบหมายในเมนู งานช่าง
📍 หน้า: /technician-repairs
👤 สิทธิ์: OWNER, ADMIN, MANAGER, TECHNICIAN, SALESTECH
วัตถุประสงค์: ดูงานซ่อมที่ได้รับมอบหมาย อัปเดตสถานะ เบิกอะไหล่
สถานะงานซ่อม:
| สถานะ | สี | ความหมาย |
|---|---|---|
| PENDING (รับเครื่อง) | เทา | รับเครื่องแล้ว รอดำเนินการ |
| QUOTED (เสนอราคาแล้ว) | ม่วง | ประเมินราคา รอลูกค้าอนุมัติ |
| APPROVED (อนุมัติแล้ว) | ส้ม | ลูกค้าอนุมัติแล้ว พร้อมซ่อม |
| IN_PROGRESS (กำลังซ่อม) | ฟ้า | กำลังซ่อมอยู่ |
| WAITING_PARTS (รออะไหล่) | เหลือง | รออะไหล่ส่งมาก่อนซ่อมต่อ |
| COMPLETED (เสร็จแล้ว) | เขียว | ซ่อมเสร็จ รอลูกค้ามารับ |
| DELIVERED (ส่งมอบแล้ว) | ฟ้าทะเล | ส่งคืนลูกค้าแล้ว |
| CANCELLED (ยกเลิก) | แดง | ยกเลิก |
💡 ระบบแสดง badge สถานะเป็นภาษาไทยทั้งระบบ (/repair, /repair-intake, /technician-repairs, /repair-documents, /repair-warranty, /reports ฯลฯ) — ทำผ่านไฟล์กลาง lib/statusLabels.js
ขั้นตอนอัปเดตงานซ่อม:
การเบิกอะไหล่:
💡 เคล็ดลับ: ช่างเห็นเฉพาะงานซ่อมที่มอบหมายให้ตัวเอง ส่วน Manager และ Admin เห็นงานทั้งหมด
📍 หน้า: /repair
👤 สิทธิ์: OWNER, ADMIN, MANAGER, SALESTECH (ช่างธรรมดา ไม่เห็น)
วัตถุประสงค์: ดูรายการงานซ่อมทั้งหมด กรอง/ค้นหา สร้างงานซ่อมใหม่
ฟีเจอร์:
📍 หน้า: /spare-parts
👤 สิทธิ์: OWNER, ADMIN, MANAGER, TECHNICIAN, SALESTECH
วัตถุประสงค์: จัดการคลังอะไหล่สำหรับงานซ่อม — เพิ่ม, รับเข้า, เบิกออก
ฟิลด์อะไหล่:
| ฟิลด์ | คำอธิบาย | จำเป็น |
|---|---|---|
| ชื่ออะไหล่ | ชื่อ Part | ✅ |
| หมวดหมู่ | ประเภทอะไหล่ | ✅ |
| ยี่ห้อ | ยี่ห้อที่รองรับ | ❌ |
| รุ่น | รุ่นที่รองรับ | ❌ |
| จำนวนคงเหลือ | Stock ปัจจุบัน | ✅ |
| ราคาทุน (Unit Price) | ราคาต้นทุนต่อชิ้น | ✅ |
| ราคาขาย | ราคาที่คิดลูกค้า | ✅ |
| ตำแหน่งจัดเก็บ | Location ในคลัง | ❌ |
| หมายเหตุ | รายละเอียดเพิ่มเติม | ❌ |
การจัดการสต็อกอะไหล่:
/reorders (§5.4B) — track DRAFT → SENT → RECEIVED + auto bump stock📍 หน้า: /masters/repair-price-templates (CRUD) + quick-pick ใน /repair-intake
👤 สิทธิ์: OWNER, ADMIN
วัตถุประสงค์: ทุกร้านมีงานซ่อมยอดฮิต 20-30 รายการที่ทำซ้ำทุกวัน เช่น "iPhone 13 จอแตก = ฿2,500" — Template ทำให้ช่าง quick-pick แทนการพิมพ์ทุกครั้ง
สร้าง template:
/masters → กด Template ราคาซ่อมใช้งาน:
/repair-intake รับเครื่องpopularityScore += 1 (เรียงขึ้นบนใน list ครั้งถัดไป)ประโยชน์:
📍 หน้า: /suppliers (CRUD ผู้จัดหา) + /reorders (สั่งซื้อ + ติดตาม)
👤 สิทธิ์: OWNER, ADMIN (suppliers); + MANAGER (reorders)
วัตถุประสงค์: ก่อนหน้านี้สั่งอะไหล่ต้องจดเองใน LINE → จำเลขส่งของไม่ได้ → ส่งมาแล้วลืมเช็ค → stockout ตอนช่างต้องการ. ระบบ Reorder ช่วย:
/suppliers)จัดการ supplier ที่สั่งอะไหล่ประจำ:
ลบ supplier ไม่ได้ถ้ายังมีอะไหล่ผูกอยู่ — ต้องตั้ง active=false แทน
ใน /spare-parts form:
/reorders) — WorkflowTab "ใกล้หมด" — auto-detect:
quantity ≤ minStockWorkflow 3 stages:
| สถานะ | คำอธิบาย | Action |
|---|---|---|
| DRAFT | สร้างแล้ว ยังไม่ส่ง | กด ส่งคำสั่ง → SENT |
| SENT | ส่ง LINE/email ให้ supplier แล้ว | กด รับเข้า เมื่อของมาถึง → RECEIVED |
| RECEIVED | ของมาแล้ว — auto bump SparePart.quantity | (จบ) |
| CANCELLED | ยกเลิก (ก่อน RECEIVED) | (จบ) |
Create modal — มี search/picker แบบ:
Performance: modal ใช้ uncontrolled refs (qty/unitCost) — ไม่ lag แม้มีหลายรายการ
📍 หน้า: /repair-checklist
👤 สิทธิ์: OWNER, ADMIN, MANAGER, SALESTECH (ช่างธรรมดา ไม่เห็น)
วัตถุประสงค์: เก็บหลักฐานสภาพเครื่องก่อน/หลังซ่อม พร้อมลายเซ็นลูกค้า — ป้องกัน customer dispute ("ของผมก่อนเอามาซ่อมไม่เป็น พอซ่อมเสร็จกลับเป็น") + เป็นใบ QC ก่อนส่งมอบ
ระบบบังคับลำดับการเช็คตามมาตรฐานร้านมือถือสากล — ห้ามข้ามขั้นตอน:
1. รับเครื่อง (status = รับเครื่อง / PENDING)
↓
2. ✅ เช็คก่อนซ่อม (PRE_REPAIR) ← ทำตอนนี้! ก่อนเริ่มซ่อม + ขอลายเซ็นลูกค้า
↓
3. ประเมินราคา (status = เสนอราคา)
↓
4. ลูกค้าอนุมัติ (status = อนุมัติ)
↓
5. ช่างซ่อม (status = กำลังซ่อม / รออะไหล่)
↓
6. ซ่อมเสร็จ (status = เสร็จแล้ว) ← ปุ่ม pre จะ lock ตอนนี้แล้ว!
↓
7. ✅ เช็คหลังซ่อม (POST_REPAIR) ← ทำตอนนี้ + ขอลายเซ็นลูกค้ารับเครื่อง
↓
8. ส่งเครื่อง (status = ส่งคืนแล้ว)
↓
9. ✅ ปุ่ม "เปรียบเทียบ" pre vs post จะโผล่ที่ตาราง
กฎเหล็ก 3 ข้อ:
รับเครื่อง / เสนอราคา / อนุมัติ / กำลังซ่อม / รออะไหล่ เท่านั้น. พอซ่อมเสร็จ (เสร็จแล้ว / ส่งคืนแล้ว) ปุ่ม pre จะกลายเป็นเทา (disabled) ตลอดกาลเสร็จแล้ว หรือ ส่งคืนแล้ว ก่อน ปุ่ม post ถึงจะกดได้เหตุผลของกฎ (ทำไมเข้มขนาดนี้):
ผลถ้าลืมเช็ค PRE: ถ้าซ่อมเสร็จแล้วเพิ่งนึกได้ว่าลืมเช็ค PRE → ทำไม่ได้แล้ว ระบบ lock ตลอดกาล. แถวนี้จะไม่มีปุ่มเปรียบเทียบเลย เป็นบทเรียนให้ครั้งหน้าเช็คก่อน
💡 Guided flow จาก /repair-intake (ปรับปรุง 2026-05-14): เมื่อใช้ flow รับเครื่องที่หน้า /repair-intake ระบบจะ redirect มา /repair-checklist?autoOpen=PRE_REPAIR ทันที — modal PRE_REPAIR เปิดเองโดย user ไม่ต้องกดอะไร. เมื่อ save checklist เสร็จ ระบบจะ auto-issue ใบรับซ่อม + redirect ไป preview พิมพ์ — ไม่ต้องกลับมาที่ /repair-documents เอง. ดูรายละเอียดที่ §5.1
โครงสร้าง 2 แท็บ:
กลไก lock-edit: เมื่อเช็คครบทั้ง pre + post แล้ว ปุ่มแก้ไขจะหายไป — เหลือแค่ "✓ เช็คแล้ว" + ปุ่ม "เปรียบเทียบ" — กันแก้หลักฐานย้อนหลัง
ขั้นตอนการเช็ค (ใน modal):
Compare modal (เทียบก่อน/หลัง):
ผลกับเอกสารที่พิมพ์:
| เอกสาร | ใช้ Checklist อะไร |
|---|---|
| ใบรับซ่อม (intake) | PRE_REPAIR — แสดงสภาพเครื่องตอนรับ + ลายเซ็นลูกค้ายืนยัน |
| ใบเสร็จซ่อม / SMALL_RECEIPT | POST_REPAIR — แสดงผลตรวจ QC หลังซ่อม + ลายเซ็นลูกค้ารับเครื่อง |
| ใบส่งคืนหลังเครม (resolution) | POST_REPAIR — แทนรายการ Final QC แบบ generic ด้วยรายการจริงที่ช่างเช็ค + ลายเซ็นลูกค้ารับเครื่อง |
Mobile-friendly:
touchAction: none กัน scroll ตอนเซ็น)📍 หน้า: /repair-documents
👤 สิทธิ์: OWNER, ADMIN, MANAGER, SALESTECH (ช่างธรรมดา ไม่เห็น)
วัตถุประสงค์: ออกเอกสารเกี่ยวกับงานซ่อม 5 ประเภท — รับเครื่อง / เสนอราคา / เสร็จรับเงิน / ใบเล็ก / ประกัน
ประเภทเอกสาร 5 แบบ:
| เอกสาร | เลขที่ format | accent | เนื้อหา |
|---|---|---|---|
| ใบรับซ่อม (INTAKE_RECEIPT) | RCV-{branch}-{BEyear}-{seq:04} | slate #475569 | ข้อมูลลูกค้า + เครื่อง + อาการ + checklist PRE_REPAIR + รูปถ่ายเครื่องตอนรับ + QR tracking. ฟิตหน้า A4 เดียว |
| ใบเสนอราคา (QUOTATION) | QUO-{branch}-{BEyear}-{seq:04} | blue #2563eb | รายการอะไหล่ + ค่าแรง + ราคา (พร้อม/ไม่พร้อม VAT) — ขอลูกค้าอนุมัติก่อนเริ่มซ่อม |
| ใบเสร็จรับเงิน (RECEIPT) | RCP-{branch}-{BEyear}-{seq:04} | green #16a34a | เอกสารทางการเงิน — A4 พร้อม VAT/ไม่ VAT |
| ใบเสร็จเล็ก (SMALL_RECEIPT) | SLP-{branch}-{BEyear}-{seq:04} | teal #0d9488 | ขนาด 80mm thermal สำหรับ POS slip printer + มี logo ร้าน |
| ใบประกัน (WARRANTY_CARD) | WRT-{branch}-{BEyear}-{seq:04} | orange #ea580c | banner 30 วัน + ความคุ้มครอง/ข้อยกเว้น + วิธีเคลม. ฟิตหน้า A4 เดียว |
เปิดเอกสาร 2 วิธี:
/repair-documents → กดแถว repair ที่ต้องการ → modal "ออกเอกสาร" เปิด → เลือกชนิดเอกสาร → กรอกข้อมูลเฉพาะ (VAT / ค่าแรง / ระยะประกัน) → กด "สร้างเอกสาร" → preview เปิดให้พิมพ์Soft workflow ordering: ระบบมี order แนะนำ INTAKE → QUOTATION → RECEIPT → WARRANTY. ถ้าจะข้ามขั้น (เช่น ออก RECEIPT โดยยังไม่ได้ออก QUOTATION) → card จะเทาๆ + Badge "ข้ามลำดับ" + คลิกได้แต่ confirm modal ขึ้นก่อน. ใบรับซ่อมออกได้เสมอ (ไม่มี prereq)
สีพิมพ์: ทุก doc type ใช้ print-color-adjust: exact — สีพื้นหลัง title bar + table header + accent borders จะพิมพ์ออกสีครบแม้ผู้ใช้ไม่ติ๊ก "Background graphics" ใน print dialog ของ Chrome
ลายเซ็นลูกค้า (Priority chain — ใช้ตัวที่มีตามลำดับ):
repair.intakeSignature (สำหรับใบรับซ่อม) / repair.deliverySignature (สำหรับใบเสร็จ)💡 ลูกค้าเซ็นครั้งเดียวแล้วใช้ได้ทุกใบ — ระบบ resolve ลายเซ็นเองอัตโนมัติจาก priority chain ด้านบน. ในใช้งานจริง ลูกค้ามักเซ็น 2 ครั้ง: 1 ครั้งตอนรับเครื่อง (/repair-intake) + 1 ครั้งตอนเช็คสภาพ (/repair-checklist)
📍 หน้า (ลูกค้าใช้): /track และ /track/{slug}/{repairId}
👤 สิทธิ์: ลูกค้า — ไม่ต้องล็อกอิน (public, anyone with link)
วัตถุประสงค์: ให้ลูกค้าติดตามสถานะการซ่อมแบบเรียลไทม์เอง ไม่ต้องโทรถามร้าน — เหมือนติดตามพัสดุ Kerry/Flash
กลไก 3 ช่องทางที่ลูกค้ารู้ URL:
| ช่องทาง | วิธี | ครอบคลุม |
|---|---|---|
| 1. QR Code บนใบรับเครื่อง | สแกน QR ด้วยกล้องมือถือ | 95% case |
2. กรอกเลขใน /track | กรอก เลขเดียว (8 ตัวอักษร เช่น F340-38A4) — เหมือนเช็คพัสดุไปรษณีย์ ไม่ต้องระบุชื่อร้าน | กรณีทำใบหาย |
| 3. White Label custom domain (ENT) | repair.ชื่อร้าน.com | Phase 2 |
Single-field UX (เหมือน Kerry/Flash/ไปรษณีย์):
F340-38A4) ในกรอบ cyan/teal เด่นชัด/track → ระบบค้นข้าม tenant (UUID unique ทั้งระบบ) → redirect ไปหน้า detail อัตโนมัติF34038A4, F340-38A4, f34038a4 (case + dash insensitive)ข้อมูลที่ลูกค้าเห็น (ก่อนยืนยัน):
ข้อมูลเพิ่ม (หลังยืนยันด้วย 4 ตัวท้ายเบอร์โทร):
การออกแบบใบรับซ่อม:
INTAKE_RECEIPT) มี block QR + URL ที่ footer (cyan/teal gradient) แสดง:
https://โดเมน/track/{tenant.slug}/{repairId} (สแกนเปิดได้เลย)ความปลอดภัย:
💡 ข้อแนะนำ: ตอนรับเครื่อง ให้พนักงานบอกลูกค้าว่า "สแกน QR บนใบนี้เพื่อติดตามได้ตลอด 24 ชม." จะลดสายโทรเข้าได้มาก
📍 หน้า: /repair-warranty
👤 สิทธิ์: OWNER, ADMIN, MANAGER, SALESTECH (ช่างธรรมดา ไม่เห็น)
วัตถุประสงค์: บันทึกและติดตามประกันงานซ่อม รับเรื่องเคลมประกัน
ฟิลด์ประกันงานซ่อม:
| ฟิลด์ | คำอธิบาย |
|---|---|
| งานซ่อม | เชื่อมกับรายการซ่อมที่บันทึกไว้ |
| วันเริ่มประกัน | วันที่เริ่มต้นประกัน |
| วันหมดประกัน | วันที่สิ้นสุดประกัน |
| เงื่อนไขประกัน | รายละเอียดความครอบคลุม |
| สถานะ | ACTIVE, EXPIRED, CLAIMED |
การเคลมประกัน:
💡 เคล็ดลับ: ระบบแจ้งเตือนอัตโนมัติเมื่อประกันงานซ่อมใกล้หมดอายุ
📍 หน้า: /sales
👤 สิทธิ์: OWNER, ADMIN, MANAGER, CASHIER, SALES, SALESTECH
วัตถุประสงค์: ระบบขายสินค้าหน้าร้าน (Point of Sale) รองรับสินค้าทั้งมือถือและอุปกรณ์เสริม
⚠️ ก่อนเริ่มขาย — เปิดกะการขาย (ถ้าจำเป็น)
ตามมาตรฐาน POS สากล (Microsoft Dynamics, Shopify, Lightspeed) — บทบาท CASHIER + SALES (default) ต้อง เปิดกะการขาย (กรอกเงินสดตั้งต้นในลิ้นชัก) ก่อนรับเงินจากลูกค้า. หน้า /sales จะแสดง banner สีส้ม + ปุ่ม "ไปเปิดกะการขาย" ถ้ายังไม่เปิด — กดเข้าไปที่ /shift กรอก openingFloat + กดเปิดกะ แล้วกลับมาขายได้.
OWNER / ADMIN / MANAGER / TECHNICIAN ขายได้ตรง ไม่ต้องเปิดกะ (default config). เจ้าของร้านปรับนโยบายได้ที่ /settings → "นโยบายกะการขาย" — เลือกบทบาทที่ต้องบังคับ หรือเคลียร์ทั้งหมดเพื่อปิดการบังคับ.
ดูรายละเอียดการเปิด-ปิดกะ + variance check ที่ §10B.
Layout — Split Screen (Shopify POS pattern):
หน้าจอแบ่งเป็น 2 คอลัมน์ — ตะกร้าอยู่ขวาเสมอ ไม่ต้อง scroll หาข้อมูล
┌─ ซ้าย (lg=8) ─────────────┐ ┌─ ขวา (lg=4) ──────┐
│ [ทั้งหมด][โทรศัพท์][อุปกรณ์] │ │ ตะกร้าสินค้า (3) [⛌][🗑]│
│ 🔍 ค้นหา... [สแกน]│ │ ────────────────│
│ ┌──────────────────────┐ │ │ ► iPhone 13 │
│ │ 📱 iPhone 13 ┃ ฿17,900│ │ │ ► เคสกัน │
│ │ IMEI ... ┃ พร้อมขาย│ │ │ ────────────────│
│ │ 📱 iPhone 14 ┃ ฿24,900│ │ │ สรุปการชำระเงิน │
│ │ 🎧 เคสกัน ┃ ฿690 │ │ │ ลูกค้า: ... │
│ │ ┃ 5 ชิ้น│ │ │ ยอดรวม ฿xxx │
│ └──────────────────────┘ │ │ ส่วนลด: 0 │
│ (scroll ในกล่องผลค้นหา) │ │ ─────────────── │
└──────────────────────────┘ │ ยอดชำระ ฿xxx │
│ [เงินสด][PP][โอน]│
│ [ ยืนยันการขาย ] │
└─────────────────┘
ขั้นตอนการขาย:
+/− ในตะกร้าค้นหาสินค้า — 3 ทาง:
× ล้างคำค้นหาVisual Catalog Grid (โหลดสินค้าทั้งหมดไว้ตั้งแต่เริ่ม):
ระบบ pre-load สินค้าพร้อมขาย + อุปกรณ์เสริมทั้งหมดของสาขาไว้แล้ว แสดงเป็น การ์ดรูปภาพ ทันทีที่เปิดหน้า — cashier ไม่ต้องพิมพ์ก็เห็นทุกอย่าง — เลือกแตะได้เลย หรือพิมพ์เพื่อกรอง
Header แสดงจำนวน:
สินค้าทั้งหมด N รายการผลการค้นหา N รายการCard layout (compact 2-4 cols ตามขนาดจอ):
| ส่วน | สิ่งที่แสดง |
|---|---|
| รูปสินค้า (height 96px) | รูปจริง (cover) / fallback IconDeviceMobile หรือ IconHeadphones บน gradient เทา |
| Badge ขวาบน | จำนวนคงเหลือ (numeric เสมอ): 🟢 N ชิ้น (≥5) · 🟠 N ชิ้น (<5) · 🔴 หมด — คำนวณจาก stock − ที่อยู่ใน cart เห็นยอดที่ใส่ตะกร้าได้จริง |
| Badge ซ้ายล่าง | ประเภทสินค้า: cyan "มือถือ" · grape "อุปกรณ์" |
| ชื่อสินค้า | 2-line clamp, dark.8 fw 600 |
| IMEI/SKU | 9px monospace gray-6 |
| ราคา | sm fw 700 cyan-7 + tabular-nums |
Interaction:
ตะกร้าสินค้าขวา (Cart Card):
สรุปการชำระเงิน (Summary Card — ใต้ตะกร้า):
Empty + Loading states:
Auto-refresh + Cart-aware:
Performance optimizations (สำหรับร้านที่สต็อกเยอะ):
loading="lazy" — โหลดเฉพาะการ์ดที่อยู่ใน viewport (ลดภาระ network ลง 80% สำหรับร้านสต็อก 100+)| วิธี | ไอคอน | รายละเอียด |
|---|---|---|
| เงินสด (Cash) | 💵 | รับเงินสด — กรอกจำนวนรับ ระบบคำนวณเงินทอน |
| โอนเงิน (Transfer) | 🏦 | โอนผ่านธนาคาร — บันทึกเลขอ้างอิง |
| บัตรเครดิต (Credit Card) | 💳 | รูดบัตร — บันทึกเลขอนุมัติ |
| PromptPay | 📱 | สร้าง QR Code PromptPay อัตโนมัติ |
ขั้นตอน:
⚠️ หมายเหตุ: ตั้งค่าเบอร์ PromptPay ได้ที่ ตั้งค่า → ข้อมูลร้านค้า → PromptPay Phone
📍 หน้า: /customer-display
📦 แพ็คเกจ: Professional หรือ Enterprise (ฟีเจอร์นี้ถูกล็อคในแพ็คเกจ Starter)
การใช้งาน:
⚠️ ถ้าแพ็คเกจของคุณยังไม่รวม ปุ่ม "เปิดจอลูกค้า" จะถูกซ่อนอัตโนมัติ — ต้องอัพเกรดเป็น Professional ขึ้นไป
💡 เคล็ดลับ: ใช้ได้ทั้งจอ Monitor เพิ่มเติม หรือแท็บเล็ตที่ตั้งหันหาลูกค้า
📍 เปิดได้ที่: ปุ่ม "พักบิล" ในตะกร้า + ปุ่ม "บิลที่พักไว้ (N)" มุมขวาบน
วัตถุประสงค์: เก็บตะกร้าค้างไว้ก่อนชำระ — เช่น ลูกค้าเดินไปดูเคสเพิ่ม, หาเงินก่อน, ขอเปลี่ยนใจ → cashier กดพักบิลเพื่อรับลูกค้าคนถัดไปได้ทันที, ตอนกลับมาเปิด "บิลที่พักไว้" → restore cart → ชำระต่อ
ขั้นตอน:
สิ่งที่บันทึก:
สิ่งที่ ยังไม่ทำ ตอนพักบิล:
ข้อสังเกต:
💡 เคล็ดลับ: ทุกคืนปิดร้านควรเช็ค "บิลที่พักไว้" → ถ้ามีค้างให้ตัดสินใจว่าจะ checkout หรือลบ ไม่ปล่อยค้างหลายวัน
📍 หน้า: /sales-history
👤 สิทธิ์: OWNER, ADMIN, MANAGER, CASHIER, SALES, SALESTECH
วัตถุประสงค์: รวมงาน post-checkout ทั้งหมดในที่เดียว — ดูประวัติบิล / พิมพ์ใบเสร็จซ้ำ / ยกเลิกบิล / คืนเงิน / ปิดยอดสิ้นวัน
เลขที่ใบเสร็จ: ทุกบิลใหม่จะได้เลขรูปแบบ RC-{branchCode}-{BEyear}-{seq:04} (เช่น RC-HQ-2569-0001 = บิลใบแรกของสาขา HQ ปี พ.ศ. 2569) — เลขรันต่อเนื่อง ทั้งปีภาษี (reset 1 ม.ค.) แยกต่อสาขา ตามกฎสรรพากร (ประกาศอธิบดี ว.196/2553) ดูรายละเอียดที่ §12.0
ตัวกรอง:
ตาราง (desktop) / Card (mobile):
ใน SaleDetailModal → ปุ่ม "พิมพ์ใบเสร็จ" (สีฟ้า) → เปิด Receipt modal เดียวกับตอนขาย → เลือก thermal 80mm หรือ A4 → พิมพ์
💡 ใช้กรณี: ลูกค้ากลับมาบอกว่า "หาใบเสร็จไม่เจอขอใหม่" → ค้นหาบิลด้วยเบอร์โทร / IMEI → กดพิมพ์ซ้ำ
📍 ปุ่ม "ยกเลิกบิล" (สีแดง) ใน SaleDetailModal — แสดงเฉพาะบิลสถานะ ใช้งาน + role ADMIN/OWNER
ขั้นตอน:
บิลที่ยกเลิกแล้ว: ดูได้ตลอด แต่พิมพ์ใบเสร็จไม่ได้ + ไม่นับยอดในรายงาน + ไม่นับใน Z report
📍 ปุ่ม "คืนเงิน" (สีส้ม) ใน SaleDetailModal — role MANAGER/ADMIN/OWNER
Wizard 3 ขั้นตอน:
Step 1 — เลือกรายการที่คืน:
Step 2 — วิธี + เหตุผล:
Step 3 — ตรวจสอบ:
สถานะหลังคืนเงิน:
⚠️ คืนเงินไม่ได้ถ้าบิลสถานะ: ยกเลิกแล้ว / คืนเงินทั้งบิลแล้ว
📍 ปุ่ม "ปิดยอดวันนี้" มุมขวาบนของหน้า /sales-history
ใช้ทำอะไร: สรุปยอดทุกอย่างของวันนั้น สำหรับเช็คเงินสดในลิ้นชัก / นำส่งหัวหน้า / เก็บเป็นหลักฐาน — มาตรฐาน retail ทั่วโลก เรียกว่า "Z Report"
เนื้อหา:
| ส่วน | รายละเอียด |
|---|---|
| 3 KPI | บิลทั้งหมด + บิลยกเลิก + ครั้งที่คืนเงิน |
| สรุปยอด | ยอดขายรวม − VAT − คืนเงิน = รายได้สุทธิ |
| แยกตามวิธีชำระ (รับเข้า) | เงินสด / โอน / บัตร — แต่ละแบบ บิลกี่ใบ ยอดเท่าไหร่ |
| แยกตามวิธีคืนเงิน (จ่ายออก) | เงินสด / โอน / เครดิต — แต่ละแบบ ครั้งกี่ครั้ง ยอดเท่าไหร่ |
| ยอดเงินสดคงเหลือในลิ้นชัก (คาดหมาย) | = เงินสดเข้า − เงินสดคืน → ตัวเลขที่ควรนับเจอตอนปิดร้าน |
พิมพ์ Z Report: A4 — มี 2 ช่องลายเซ็น (Cashier ผู้ปิดยอด + ผู้ตรวจสอบ) เก็บไว้เป็นเอกสารตอนปิดร้าน
เลือกวันได้: Default เป็นวันนี้ — เปลี่ยนวันที่เพื่อดู Z Report ย้อนหลังได้
💡 เคล็ดลับ: ปิดร้านทุกคืนให้พิมพ์ Z Report → นับเงินสดในลิ้นชัก → เทียบกับ "ยอดเงินสดคงเหลือคาดหมาย" → ถ้าไม่ตรง ต้องหาสาเหตุก่อนเลิกงาน
📍 ตำแหน่ง: ปุ่มในหน้า /sales POS (ใต้ cart summary)
👤 สิทธิ์: ทุก role ที่ขายได้
วัตถุประสงค์: ลูกค้าที่ซื้อเครื่องใหม่มักอยากเอาเครื่องเก่ามาตีเครดิต. ก่อนหน้านี้ cashier ต้องทำ 2 transactions แยก (Purchase + Sale) → cashier งง + ตีเงินไปกลับไปกลับมา + ไม่มี link ระหว่างเครื่องเก่ากับ sale
Workflow ใหม่ — เซลเดียว:
total) แสดงเฉพาะ net amount due = สิ่งที่ลูกค้าต้องจ่ายเพิ่มPurchase (เครื่องเก่าเข้าระบบ)Product ใหม่จาก purchase (status=AVAILABLE in stock, source=TRADE_IN)Sale ของเครื่องใหม่ + เซ็ต tradeInPurchaseId, tradeInValue, netAmountDueข้อดี:
ลบเครื่องเทรด: กดไอคอนถังขยะที่บรรทัด violet → ลบออกก่อน checkout (ก่อน save = แก้ได้)
📍 หน้า: /refunds
👤 สิทธิ์: OWNER, ADMIN, MANAGER
วัตถุประสงค์: ระบบ Refund มีอยู่แล้วฝังใน /sales-history (refund per sale) แต่ไม่มีหน้า list รวม + analytics — ตอนนี้มี
Stat cards:
Filters:
List view:
ใช้สำหรับ:
📍 หน้า: /invoices
👤 สิทธิ์: OWNER, ADMIN
วัตถุประสงค์: ลูกค้าบุคคลจ่ายทันที — ลูกค้าบริษัท (ตัวแทน, ออฟฟิศซื้อยกล็อต) อยากได้ "ใบแจ้งหนี้" + เครดิต net-30/60 จ่ายภายหลัง. ระบบนี้รองรับ B2B workflow ครบ
Customer setup ก่อน:
ใน /customers form เพิ่ม fields ใหม่:
/invoices → ออก invoice)Workflow:
Customer.currentDebtใน detail modal กด บันทึกรับเงิน:
InvoicePayment recordInvoice.paidAmount += amountPARTIAL_PAID (ถ้า paidAmount < totalAmount) / PAID (ถ้าเต็ม)Customer.currentDebt| สถานะ | คำอธิบาย |
|---|---|
| DRAFT | ร่าง (ปัจจุบันไม่ได้ใช้ — ออก invoice = ISSUED ทันที) |
| ISSUED | ออกแล้ว รอจ่าย |
| PARTIAL_PAID | จ่ายแล้วบางส่วน |
| PAID | จ่ายเต็มแล้ว |
| OVERDUE | เลยกำหนด (ระบบ flag color แดง — manual update หรือ cron) |
| CANCELLED | ยกเลิก |
4 Stat cards บน list: จำนวน / รวมยอด / รับเงินแล้ว / คงค้าง (สีส้มถ้า > 0)
Tabs: ทั้งหมด / รอจ่าย / เกินกำหนด / จ่ายแล้ว
UI hints:
💡 Tip: ตั้ง creditLimit ให้ลูกค้า CORPORATE ทุกราย — ป้องกันออก invoice ใหม่ตอน debt เกินวงเงิน → หลีกเลี่ยง bad debt
📍 หน้า: /warranty
👤 สิทธิ์: OWNER, ADMIN, MANAGER, CASHIER, SALES, SALESTECH
วัตถุประสงค์: บันทึกและติดตามประกันสินค้าที่ขายออกไป (มือถือและอุปกรณ์เสริม)
ขั้นตอนเพิ่มประกัน:
มือถือ หรือ อุปกรณ์เสริมสถานะประกัน:
| สถานะ | สี | ความหมาย |
|---|---|---|
| ACTIVE | เขียว | ยังอยู่ในระยะประกัน |
| EXPIRED | แดง | หมดอายุแล้ว |
| CLAIMED | ส้ม | มีการเคลมแล้ว |
| VOID | เทา | ยกเลิกประกัน |
Expiring Warranties Widget:
📍 หน้า: /customers
👤 สิทธิ์: OWNER, ADMIN, MANAGER, CASHIER, SALES, SALESTECH
วัตถุประสงค์: จัดการฐานข้อมูลลูกค้า ค้นหา เพิ่ม แก้ไข และดูประวัติ
ขั้นตอนเพิ่มลูกค้าใหม่:
| ฟิลด์ | คำอธิบาย | จำเป็น |
|---|---|---|
| ชื่อ | ชื่อ-นามสกุล | ✅ |
| เบอร์โทร | หมายเลขโทรศัพท์ | ✅ |
| อีเมล | อีเมลลูกค้า | ❌ |
| ที่อยู่ | ที่อยู่สำหรับส่งของ | ❌ |
| LINE ID | สำหรับติดต่อ | ❌ |
| วันเกิด | สำหรับโปรโมชั่นวันเกิด | ❌ |
| หมายเหตุ | ข้อมูลเพิ่มเติม | ❌ |
ฟีเจอร์ค้นหาลูกค้า:
ประวัติลูกค้า:
📍 หน้า: /attendance
👤 สิทธิ์: OWNER, ADMIN, MANAGER
วัตถุประสงค์: ดูรายการการลงเวลาของพนักงาน กรอง ค้นหา และแก้ไข
ฟีเจอร์:
การลงเวลาผ่านระบบ (Admin):
ฟิลด์การลงเวลา:
| ฟิลด์ | คำอธิบาย |
|---|---|
| พนักงาน | ชื่อ-นามสกุล |
| เวลาเข้างาน | Check-in Time |
| เวลาออกงาน | Check-out Time |
| ชั่วโมงทำงาน | คำนวณอัตโนมัติ |
| สาย | isLate flag |
| ออกก่อนเวลา | isEarlyLeave flag พร้อม leaveReason |
| หมายเหตุ | Remark |
📍 หน้า: /kiosk/login → /kiosk
👤 สิทธิ์: ระบบแยกสำหรับพนักงาน (ไม่ต้อง Login หลัก)
📦 แพ็คเกจ: Professional หรือ Enterprise (ฟีเจอร์นี้ถูกล็อคในแพ็คเกจ Starter)
วัตถุประสงค์: หน้าจอ Kiosk สำหรับพนักงานสแกน QR Code เพื่อลงเวลาเข้า-ออก โดยไม่ต้องล็อกอินระบบหลัก — เหมาะกับ tablet/iPad วางหน้าร้าน
การเปิดใช้งาน Kiosk:
/attendance) ในฐานะ Admin/Managerhttps://shop.com/kiosk/login)⚠️ ถ้าแพ็คเกจของคุณยังไม่รวม Kiosk panel จะแสดง badge "PRO+" + ปุ่ม "อัพเกรด" → คลิกไปหน้า Billing
ขั้นตอนลงเวลาพนักงาน:
/kiosk บนแท็บเล็ตหรือคอมพิวเตอร์หน้าร้านQR Code พนักงาน:
💡 เคล็ดลับ: ตั้งแท็บเล็ตไว้ที่ทางเข้าออกร้าน ให้พนักงานสแกนเองทุกวัน ประหยัดเวลาและแม่นยำกว่าการลงเวลาแบบกระดาษ
📍 หน้า: /payroll
👤 สิทธิ์: OWNER, ADMIN, MANAGER
📦 แพ็คเกจ: ENTERPRISE (PAYROLL feature)
วัตถุประสงค์: คำนวณเงินเดือนพนักงาน เพิ่ม/หักรายการ อนุมัติ บันทึกการจ่าย และพิมพ์สลิป
ตั้งเงินเดือนพื้นฐานของพนักงาน ที่ /users → แก้ไข → ช่อง "เงินเดือนพื้นฐาน" → บันทึก. ระบบจะสร้าง EmployeeSalary record อัตโนมัติเมื่อ baseSalary > 0
(แนะนำ) ตั้งค่าประเภทรายการเงินเดือน ที่ /masters/deduction-types:
Payroll สำหรับพนักงานที่ยังไม่มีรอบนี้ตาราง 4 columns: เงินเดือนพื้นฐาน · รายได้เพิ่ม · รายการหัก · รวมสุทธิ — ค่าจริงดึงจาก totalAdditions / totalDeductions
/masters/deduction-types (auto-detect รายได้เพิ่ม/หัก จาก isDeduction ของประเภท)totalAdditions/totalDeductions/netSalary ทันที| สถานะ | สี | ความหมาย | ทำได้ | พิมพ์สลิป? |
|---|---|---|---|---|
| PENDING | เหลือง | รอดำเนินการ — ตัวเลขแก้ได้ | เพิ่ม/ลบ adjustment, อนุมัติ | ❌ disabled (กันสับสน) |
| APPROVED | น้ำเงิน | อนุมัติแล้ว รอจ่าย — locked | บันทึกการจ่าย, พิมพ์สลิป preview | ✅ |
| PAID | เขียว | จ่ายแล้ว — final | พิมพ์สลิป official (ใช้ขอ visa/loan) | ✅ |
ขั้นตอน:
⚠️ กฎทั่วไป: PENDING ปุ่มพิมพ์ disabled — เพราะตัวเลขยังเปลี่ยนได้ พิมพ์ตอนนี้พนักงานเซ็นรับ แล้วแก้ ทำให้สลิปไม่ตรงกับเงินที่จ่ายจริง
📍 เส้นทาง: เมนูซ้าย → "พนักงาน & การเงิน" → ค่าใช้จ่าย (/expenses)
👤 สิทธิ์: OWNER, ADMIN
วัตถุประสงค์: บันทึกค่าใช้จ่ายดำเนินงาน (ค่าเช่าร้าน, ค่าน้ำ-ไฟ, ค่าน้ำมัน, marketing, ฯลฯ) ที่ไม่ใช่ค่าซื้อสินค้าหรือเงินเดือน — เพื่อให้:
ระบบ auto-seed 9 หมวดเมื่อสร้าง tenant ใหม่:
| Code | ชื่อ | ตัวอย่าง |
|---|---|---|
| RENT | ค่าเช่าร้าน/สำนักงาน | ค่าเช่าตึก, ค่าเช่าโกดัง |
| UTILITY | ค่าน้ำ-ค่าไฟ-ค่าน้ำประปา | บิลค่าไฟทุกเดือน |
| INTERNET | ค่าอินเทอร์เน็ต/โทรศัพท์ | True/3BB, ค่ามือถือพนักงาน |
| FUEL | ค่าน้ำมันเชื้อเพลิง | ปั๊ม PTT, BCP, ส่งของ |
| MARKETING | ค่าโฆษณา/การตลาด | Facebook Ads, ป้ายไวนิล |
| SUPPLIES | ค่าวัสดุสิ้นเปลือง/ออฟฟิศ | กระดาษ, หมึก, ถุงพลาสติก |
| OUTSOURCE | ค่าจ้างซ่อม/Outsource | ส่งศูนย์ซ่อม mainboard |
| PROFESSIONAL | ค่าทำบัญชี/ที่ปรึกษา | สำนักงานบัญชี, ทนาย |
| OTHER | อื่นๆ | กรณีไม่เข้าหมวดใด |
จัดการเพิ่ม/แก้ไข/ลบหมวดได้ที่ /masters/expense-categories
| ฟิลด์ | คำอธิบาย | จำเป็น |
|---|---|---|
| วันที่ | วันที่จ่ายเงินจริง (หรือวันที่ในใบกำกับภาษี) | ✅ |
| หมวด | เลือกหมวด (RENT/UTILITY/...) | ✅ |
| ผู้ขาย | ชื่อร้าน/บริษัท เช่น "การไฟฟ้านครหลวง" | ❌ |
| จำนวนเงิน (ก่อน VAT) | ราคาก่อนภาษีมูลค่าเพิ่ม | ✅ |
| ภาษีซื้อ (VAT) | ใส่เฉพาะใบกำกับเต็มรูป — ใช้ใน ภ.พ.30 | ❌ |
| เลขที่ใบกำกับ | สำหรับใบกำกับเต็มรูป | ❌ |
| วิธีชำระ | เงินสด / โอน / PromptPay / บัตร | ❌ |
| รายละเอียด | บันทึกเพิ่มเติม | ❌ |
| ใบเสร็จ/สลิป | ถ่ายรูปแนบ (jpg/png) | ❌ |
| หัก ณ ที่จ่าย | toggle เปิด-ปิด | ❌ |
amount × rate ÷ 100)/expenses — จำนวนรายการ / รวมก่อน VAT / ภาษีซื้อ / WHT รวม💡 เคล็ดลับ: บันทึกทันทีหลังจ่ายเงินทุกครั้ง — ไม่ต้องรอสิ้นเดือน. แนบรูปใบเสร็จด้วยจะใช้เป็น audit trail ตอน RD มาตรวจ
⚠️ คำเตือน: ค่าใช้จ่ายที่หมวด isDeductible=false (ลดหย่อนไม่ได้) จะ ไม่ ถูกรวมใน ACTUAL deduction — ใช้สำหรับค่าใช้จ่ายส่วนตัว/นอกธุรกิจที่อยากบันทึกแต่ไม่อยากให้กระทบภาษี
📍 เส้นทาง: เมนูซ้าย → "ขาย & ลูกค้า" → กะการขาย (/shift)
👤 สิทธิ์: ทุก role ที่ขายได้ (CASHIER, SALES, MANAGER, ADMIN, OWNER) — เปิด-ปิดกะของตัวเอง; ADMIN/MANAGER ดูประวัติของพนักงานคนอื่นได้
วัตถุประสงค์: ทุกร้าน POS ต้องนับเงินสดในลิ้นชักตอนเปิด-ปิดงาน เทียบกับยอดที่ระบบบันทึก เพื่อ:
ตามมาตรฐาน POS สากล (Microsoft Dynamics 365 Commerce, Shopify POS, Lightspeed) — "POS requires that users have an active and open shift to perform any operations that produce a financial transaction"
กฎ default ใน MobileHub:
| Role | ต้องเปิดกะก่อนขาย? | เหตุผล |
|---|---|---|
| CASHIER | ✅ ใช่ | คนรับเงินหลัก — accountability + variance check |
| SALES | ✅ ใช่ | พนักงานขายที่รับเงินด้วย — accountability เดียวกัน |
| MANAGER | ❌ ไม่ | ผู้รับผิดชอบสาขา — bypass ได้ |
| ADMIN | ❌ ไม่ | ผู้ดูแลระบบ — bypass ได้ |
| OWNER | ❌ ไม่ | เจ้าของร้าน — bypass ได้ (มักทำเองคนเดียวในร้านเล็ก) |
| TECHNICIAN | ❌ ไม่ | ช่างซ่อมไม่ได้ขายเอง |
ปรับแก้นโยบายได้ที่ /settings → "นโยบายกะการขาย (POS Shift)" — MultiSelect ให้เลือกบทบาทใดบ้างที่ต้องบังคับ. เคลียร์ทั้งหมด = ปิดการบังคับ (ทุก role ขายได้ตรง).
สิ่งที่เกิดถ้าบังคับ + ยังไม่เปิดกะ:
/sales แสดง banner สีส้ม + ปุ่ม "ไปเปิดกะการขาย" → กดเข้า /shift/sales ตรง API → backend ตอบ 403 SHIFT_REQUIRED พร้อม message ภาษาไทย(1) เปิดกะ — ตอนเริ่มงาน
/shift → กดปุ่ม เปิดกะ(2) ระหว่างกะ — POS ทำงานปกติ
/sales ตามปกติ — ไม่ต้องคิดเรื่อง shift(3) ปิดกะ — ตอนเลิกงาน
/shift → กดปุ่ม ปิดกะ ที่ card "กะที่เปิดอยู่"เงินทอนเริ่มต้น ฿ 2,000.00
+ เงินสดที่ขาย (15 ออเดอร์) ฿ 18,500.00
− เงินสดที่ refund ฿ 500.00
─────────────────────
= ที่ควรจะมี ฿ 20,000.00
พร้อมยอดอื่น (โอน/PromptPay/บัตร) ที่ ไม่ต้องนับในลิ้นชัก| กะ (Shift) | Z Report (end-of-day) | |
|---|---|---|
| ระดับ | per cashier (ของพนักงาน 1 คน) | ทั้งร้าน (รวมทุกคน) |
| เปิดต่อวัน | หลายคนเปิดคนละเวลาได้ | 1 ครั้งสิ้นวัน |
| ที่อยู่ | /shift | /sales-history?type=z-report |
| ทำงานคู่กัน | ใช่ — Z Report รวมยอดของทุก shift ในวัน |
ระบบเตือนเมื่อ variance > ฿1 แต่ไม่ block — ยังปิดกะได้ถ้ากรอกเหตุผล. เหตุผลทั่วไป:
📍 หน้า: /reports
👤 สิทธิ์: OWNER, ADMIN, MANAGER
วัตถุประสงค์: ดูรายงานสรุปในรูปแบบต่างๆ เลือกช่วงวันที่ Export Excel ได้
ประเภทรายงาน:
| รายงาน | คำอธิบาย |
|---|---|
| 📊 รายงานยอดขาย | สรุปยอดขายสินค้า ยอดรวม จำนวนรายการ |
| 🔧 รายงานการซ่อม | สรุปงานซ่อม ค่าซ่อม สถิติตามช่าง |
| 🛒 รายงานการรับซื้อ | สรุปการรับซื้อสินค้า ต้นทุน |
| 📦 รายงานสินค้าคงเหลือ | Stock มือถือและอุปกรณ์เสริมปัจจุบัน |
| 💰 สรุปการเงิน | กำไร-ขาดทุน รายรับ-รายจ่ายรวม |
| 🧾 สรุปภาษี VAT (ภ.พ.30) | ยอด VAT ที่เก็บได้ สำหรับร้านที่จด VAT |
| 🧮 ภาษีเงินได้ (ภ.ง.ด.94/90) | คำนวณภาษีบุคคลธรรมดา + ตารางอัตราก้าวหน้า 8 ขั้น |
ขั้นตอนดูรายงาน:
📦 Export Excel/PDF เป็นฟีเจอร์ของแพ็คเกจ Professional ขึ้นไป — ในแพ็คเกจ Starter ปุ่มจะ disable แสดงข้อความ "PRO+ เท่านั้น"
💡 เคล็ดลับ: เลือกช่วงวันที่เป็น "เดือนปัจจุบัน" เพื่อดูยอดรวมประจำเดือน
📍 เลือก: /reports → ภาษีเงินได้บุคคลธรรมดา (ภ.ง.ด.94/90) 👤 สำหรับ: ร้านที่ไม่ได้จดเป็นนิติบุคคล (บุคคลธรรมดา) — ทั้งร้านที่จด VAT และไม่จด VAT
วัตถุประสงค์: คำนวณภาษีเงินได้สำหรับเจ้าของกิจการที่เป็น<strong>บุคคลธรรมดา</strong> ภายใต้มาตรา 40(8) (เงินได้จากการพาณิชย์) — ครอบคลุมทั้ง ภ.ง.ด.94 (กลางปี) และ ภ.ง.ด.90 (เต็มปี)
ก่อนใช้งาน — ตั้งค่าที่ /settings → ภาษีเงินได้ (ภ.ง.ด.):
ขั้นตอนดูรายงาน:
ผลลัพธ์ที่แสดง:
📜 กฎ ม.48(2): ผู้มีรายได้จาก ม.40(8) เกิน <strong>1,000,000 บาท/ปี</strong> ต้องเปรียบเทียบ 2 วิธี และเสียภาษีตามวิธีที่<strong>ได้ตัวเลขสูงกว่า</strong>: (a) อัตราก้าวหน้า 8 ขั้น vs (b) 0.5% × รายได้รวม ระบบเปรียบเทียบและเลือกวิธีที่ถูกต้องให้อัตโนมัติ
พิมพ์เอกสาร ภ.ง.ด. (ใหม่):
⚠️ ข้อสำคัญ: เอกสารฉบับนี้เป็น<strong>เอกสารอ้างอิง</strong>เท่านั้น — การยื่นภาษีจริงต้องผ่าน <strong>e-Filing</strong> ของกรมสรรพากรที่ <a href="https://efiling.rd.go.th/">efiling.rd.go.th</a> ตัวเลขในเอกสารคำนวณจากข้อมูลในระบบ MobileHub และต้องตรวจสอบโดยผู้เสียภาษีอีกครั้งก่อนยื่น
กำหนดการยื่นจริง:
ทำไมเหมาะกับร้านมือถือ?
📍 เมนูใหม่บน sidebar: "ภาษี" — section header + 4 sub-items 👤 สิทธิ์: ADMIN, OWNER
วัตถุประสงค์: รวบรวมเมนูที่เกี่ยวกับ<strong>ภาษี</strong>ทั้งหมดไว้ที่เดียว — ตั้งค่า, คำนวณ, พิมพ์เอกสาร เพื่อใช้งานในช่วงเตรียมยื่นภาษี
📊 ภาษี
├── 🏛 ภาพรวม /tax — Dashboard + กำหนดยื่น + Quick stats
├── 🧮 ภ.ง.ด.94/90 (PIT) /tax/pit — คำนวณภาษีเงินได้บุคคลธรรมดา (8-tier progressive + ม.48(2))
├── 🏢 ภ.ง.ด.50/51 (CIT) /tax/cit — คำนวณภาษีเงินได้นิติบุคคล (SME 0/15/20% หรือ Non-SME 20%)
├── ⚖️ ภ.พ.30 (VAT) /tax/vat — สรุปภาษีมูลค่าเพิ่มรายเดือน
├── 💰 ภ.ง.ด.3/53 (WHT) /tax/wht — สรุปหัก ณ ที่จ่ายตามผู้รับ + Export CSV
└── ⚙️ ตั้งค่าภาษี /tax/settings — entityType + วิธีหักค่าใช้จ่าย + ค่าลดหย่อน 4 กลุ่ม
หน้าศูนย์กลางสำหรับงานภาษี แสดง:
หน้าคำนวณภาษีเงินได้บุคคลธรรมดา (รายละเอียดเดียวกับ §11.1 ก่อนแยกเมนู) — กดปุ่มภายในหน้าเพื่อพิมพ์เอกสารอ้างอิง
📍 เส้นทาง: /tax/cit (sub-menu ของ /tax)
👤 เงื่อนไข: tenant.entityType = CORPORATION เท่านั้น (เปลี่ยนได้ที่ /tax/settings)
คำนวณภาษีจากกำไรสุทธิ (Net Profit = รายได้ − รายจ่าย) ตามอัตรา:
| ประเภท | เกณฑ์ | อัตรา |
|---|---|---|
| SME | รายได้ ≤ 30,000,000 บาท/ปี | 0–300k = 0% · 300k–3M = 15% · เกิน 3M = 20% |
| Non-SME | รายได้ > 30 ล้าน | flat 20% ทั้งหมด |
Workflow:
/tax/citDeadline:
⚠️ คำเตือน: ผลคำนวณนี้เป็นการประมาณการเบื้องต้น — รายการค่าใช้จ่ายบางตัวอาจเป็น "ค่าใช้จ่ายต้องห้าม" ตาม ม.65 ทวิ (เช่น ค่ารับรองเกิน 0.3% ของรายได้, ค่าเสื่อมราคารถยนต์ส่วนเกิน 1 ล้าน, ฯลฯ) ต้อง บวกกลับ ในการคำนวณภาษีจริง — ปรึกษาผู้สอบบัญชีก่อนยื่น
⚠️ ข้อจำกัด: ระบบยังไม่รองรับ:
หน้าสรุปภาษีมูลค่าเพิ่มรายเดือน สำหรับร้านที่จดทะเบียน VAT — เลือกช่วงเดือน + ปุ่มพิมพ์ ภ.พ.30 + Card รายเดือน
📍 เส้นทาง: /tax/wht 👤 สิทธิ์: ADMIN, OWNER
สรุปการหัก ณ ที่จ่ายรายเดือน สำหรับยื่น ภ.ง.ด.3 (จ่ายให้บุคคลธรรมดา) และ ภ.ง.ด.53 (จ่ายให้นิติบุคคล)
ใช้ข้อมูลจาก: /expenses ที่กรอก hasWht=true + whtRate + whtPayeeName + whtPayeeTaxId
การจำแนกแบบ:
| มี taxId 13 หลัก | ตัวเลขแรก | แบบ |
|---|---|---|
| ใช่ | "0" | ภ.ง.ด.53 (นิติบุคคล) |
| ใช่ | อื่นๆ | ภ.ง.ด.3 (บุคคลธรรมดา) |
| ไม่มี | — | ภ.ง.ด.3 (default) |
Workflow:
💡 เคล็ดลับ: กรอก whtPayeeTaxId ในรูปแบบ 13 หลัก ขีด/ไม่ขีดก็ได้ — ระบบ strip non-digit ก่อนเก็บ
หน้าฟอร์มตั้งค่าภาษี (entityType + deduction method + 4-group allowance) — เดิมอยู่ใน /settings ย้ายมาที่นี่เพื่อให้เป็นกลุ่มเดียวกัน
📝 ประวัติการ migration:
/reports?type=pit → /tax/pit)ระบบ MobileHub ออกเอกสารพิมพ์ A4/Thermal ได้ทั้งหมด 12 ประเภท ใช้รูปแบบ design system เดียวกัน (header 2-col + accent color cascade ผ่าน CSS variable + ลายเซ็นมาตรฐาน + ฟอนต์ Kanit). ทุกเอกสารพิมพ์ผ่านเบราว์เซอร์ — ไม่ต้องลง driver พิเศษ
ทุกเอกสารทางการเงินในระบบใช้เลขที่ running serial ต่อเนื่องตลอดปีภาษี ตามประกาศอธิบดีสรรพากร ว.196/2553 (ใบกำกับภาษีต้องมีเลขเรียงต่อเนื่อง)
Format มาตรฐาน: {PREFIX}-{branchCode}-{BEyear}-{seq:04}
| ช่อง | คำอธิบาย | ตัวอย่าง |
|---|---|---|
| PREFIX | รหัสประเภทเอกสาร | RC (ใบเสร็จขาย), RCV (รับซ่อม), QUO (เสนอราคา), INV (ใบแจ้งหนี้ซ่อม), RCP (ใบเสร็จซ่อม), SLP (สลิปย่อ), WRT (ใบประกัน), CLM (ใบเคลม) |
| branchCode | รหัสสาขา (จาก Branch.code) | HQ, CM01, BKK01 |
| BEyear | ปี พ.ศ. | 2569, 2570 |
| seq | ลำดับ 4 หลัก | 0001, 0023, 1547 |
ตัวอย่าง:
RC-HQ-2569-0001 — ใบเสร็จขายใบแรกของสาขา HQ ปี 2569RCV-CM01-2569-0042 — ใบรับซ่อมใบที่ 42 ของสาขาเชียงใหม่ ปี 2569WRT-HQ-2569-0015 — ใบประกันใบที่ 15 ของสาขา HQ ปี 2569กฎการ reset:
RC กับ RCV คนละ counterป้องกัน race condition:
INSERT ... ON CONFLICT DO UPDATE RETURNING (atomic upsert) → 2 POS เปิดพร้อมกันไม่ได้เลขซ้ำกันเลยDocumentSerial (tenantId + branchId + docType + year พ.ศ.) เก็บ counter ปัจจุบัน⚠️ ใบเก่าก่อน 12 พ.ค. 2569 ใช้ format เดิม RC-YYYYMMDD-NNNN (ค.ศ. + reset รายวัน) — ระบบยังเก็บไว้ใน DB เหมือนเดิม ไม่ rewrite. ใบใหม่ตั้งแต่ 12 พ.ค. 2569 ใช้ format ใหม่ทั้งหมด
| เอกสาร | ที่หน้า | รูปแบบ | สีธีม |
|---|---|---|---|
| ใบเสร็จขายสินค้า (POS) | /sales (auto-open หลัง checkout) | thermal 80mm + A4 toggle | เขียว |
| ใบรับซื้อโทรศัพท์มือสอง | /purchase (ปุ่มพิมพ์ในแต่ละ row) | A4 + คำรับรอง 5 ข้อ + ลายเซ็น 3 ฝ่าย + ช่องสำเนาบัตร ปชช. | ส้ม-แดง (เน้นกฎหมาย) |
/repair-documents)| เอกสาร | เมื่อใช้ | รูปแบบ |
|---|---|---|
| ใบรับซ่อม (INTAKE_RECEIPT) | ตอนรับเครื่องเข้าซ่อม | A4 — แสดงรูปถ่ายเครื่อง + อาการ + คำเตือน "ราคาแจ้งภายหลัง" |
| ใบเสนอราคา (QUOTATION) | หลังตรวจสอบ ก่อนซ่อม | A4 — รายการอะไหล่ + ค่าแรง + VAT |
| ใบเสร็จรับเงิน (RECEIPT) | หลังซ่อมเสร็จ ลูกค้ารับเครื่อง | A4 — items table + totals + payment + signatures |
| ใบเสร็จเล็ก (SMALL_RECEIPT) | สลิปย่อ (POS thermal) | thermal 80mm |
| ใบประกัน (WARRANTY_CARD) | ออกพร้อมส่งคืนเครื่อง | A4 — banner ระยะประกัน + ✓ ความคุ้มครอง / ✗ ข้อยกเว้น |
/repair-warranty)| โหมด | เมื่อใช้ | สีธีม |
|---|---|---|
| ใบรับเครื่องเข้าเครม (intake) | ตอนลูกค้านำเครื่องมาเครม — ออกได้ทุกสถานะของ claim | ส้ม |
| ใบส่งคืนหลังเครม (resolution) | ตอนเครมเสร็จส่งคืนลูกค้า — ออกได้เฉพาะ status COMPLETED | เขียว |
ทั้ง 2 ใบมี: warranty linkbox + days-remaining badge สี dynamic, ลายเซ็น 2-3 ฝ่าย, QC checklist 6 ข้อ (resolution mode)
📍 หน้า: /payroll (ปุ่ม 🖨️ "พิมพ์สลิปเงินเดือน" ในแถว + ในปุ่ม detail modal)
👤 สิทธิ์: OWNER, ADMIN, MANAGER
🎨 ธีม: cyan (ตรงกับสีแบรนด์ของแอป)
PayrollAdjustment (split อัตโนมัติด้วย isDeduction)📍 หน้า: /attendance (ปุ่ม "ใบสรุปรายเดือน" ใน header)
👤 สิทธิ์: ADMIN, MANAGER
/attendance/report API → พิมพ์ A4 1 หน้า📍 หน้า: /spare-parts → Modal "ประวัติการเคลื่อนไหว" (ปุ่มพิมพ์ในแต่ละ transaction row)
| โหมด | Trigger | สีธีม |
|---|---|---|
| ใบเบิกอะไหล่ (issue) | transaction type = OUT (เบิกใช้กับงานซ่อม) | teal |
| ใบรับสินค้าเข้าคลัง (receive) | transaction type = IN (ซื้อมาจาก supplier) | indigo |
📍 เปิดได้ที่: เปิดอัตโนมัติหลังกด "ยืนยันคืนเงิน" ใน RefundWizard (§6.6)
สีธีม: แดง (#dc2626) — แสดงการคืนเงิน/เงินไหลออก ฐานทางกฎหมาย: มาตรา 86/10 แห่งประมวลรัษฎากร (ส่วนที่ 10 ใบกำกับภาษี ใบเพิ่มหนี้ ใบลดหนี้)
ใบลดหนี้ออกได้เมื่อ:
โครงสร้างเอกสาร (compliance ตามมาตรา 86/10):
branch.taxId, format X-XXXX-XXXXX-XX-X)customer.idCard 13 หลัก)amount × rate / (100 + rate) สำหรับราคา VAT-inclusive)💡 สำคัญ: ผู้ซื้อ (ลูกค้าที่จด VAT) ต้องนำใบลดหนี้ไปใช้ ภายในเดือนที่ได้รับ เท่านั้น ไม่สามารถใช้ข้ามเดือนได้
⚠️ ถ้าสาขายังไม่จด VAT — ระบบแสดง Alert "ใบลดหนี้นี้ใช้เป็นเอกสารภายในร้านเท่านั้น" ไม่มีผลทางภาษี
📍 เปิดได้ที่: ปุ่ม "ปิดยอดวันนี้" มุมขวาบน /sales-history (§6.6)
สีธีม: ฟ้า (#0891b2) + กล่องเงินสดเขียว มาตรฐาน: Retail Z Report (ทั่วโลก) + Thai VAT compliance สำหรับ ภ.พ.30
โครงสร้างเอกสาร (เรียงลำดับการอ่าน):
Z-YYYYMMDD-{branchCode} + วันที่ (ภาษาไทย, พ.ศ.)Workflow ปิดร้านมาตรฐาน:
💡 ภ.พ.30 friendly: VAT section ของ Z Report ตรงกับ map ใน /reports VAT (§11) — ใช้คู่กันได้ตอนยื่นภาษีรายเดือน
⚠️ Z Report ดูย้อนหลังได้ — เลือกวันที่ที่ DatePicker แล้วเรียกข้อมูลใหม่ (เก็บถาวรในระบบ)
/reports)นอกเหนือจากเอกสารพิมพ์ ระบบยัง export รายงานเป็น Excel ได้ 6 ประเภท:
@page margin: 12mm ในตัวเอง)📦 แพ็คเกจ: Enterprise เท่านั้น
ในแพ็คเกจ Enterprise ระบบจะ ลบเครื่องหมาย "MobileHub" / "AJ Software Dev." อัตโนมัติ จาก:
→ เอกสารและหน้าจอทั้งหมดจะเหมือน "ระบบของร้านคุณเอง" ไม่มี branding ของ MobileHub ปรากฏให้ลูกค้าเห็น
💡 เหมาะกับธุรกิจขนาดใหญ่ที่ต้องการแบรนด์ดิ้งของตัวเอง (เช่น Aj Mobile Group ใช้ pos.ajmobile.com แทน mobilehub.ajsoftwaredev.com)
📍 หน้า: /portal/tickets
👤 สิทธิ์: ทุก Role
วัตถุประสงค์: ยื่น Ticket เพื่อขอความช่วยเหลือหรือรายงานปัญหาไปยังทีมงาน MobileHub
ขั้นตอนสร้าง Ticket:
สถานะ Ticket:
| สถานะ | สี | ความหมาย |
|---|---|---|
| OPEN | น้ำเงิน | รอทีมงานรับเรื่อง |
| IN_PROGRESS | เหลือง | ทีมงานกำลังดำเนินการ |
| RESOLVED | เขียว | แก้ไขแล้ว |
| CLOSED | เทา | ปิด Ticket |
📍 หน้า: /portal/announcements
👤 สิทธิ์: ทุก Role
วัตถุประสงค์: รับข่าวสารประกาศจากทีมงาน MobileHub — อัปเดต, การบำรุงรักษา, โปรโมชั่น
ฟีเจอร์:
📍 หน้า: /portal/billing
👤 สิทธิ์: OWNER, ADMIN
วัตถุประสงค์: ดูสถานะ Subscription ปัจจุบัน ประวัติการชำระเงิน ดาวน์โหลดใบเสร็จ
ข้อมูลที่แสดง:
ขั้นตอนชำระค่าบริการ:
สถานะการชำระ:
| สถานะ | คำอธิบาย |
|---|---|
| PENDING | รอชำระเงิน |
| SLIP_UPLOADED | อัปโหลด Slip แล้ว รอตรวจสอบ |
| APPROVED | ยืนยันแล้ว |
| REJECTED | ปฏิเสธ (Slip ไม่ถูกต้อง) |
| REFUNDED | คืนเงินแล้ว |
การแจ้งเตือน (real-time bell + Web Push):
เมื่อ admin ตรวจสลิปแล้ว — ระบบจะส่ง notification ไปที่ OWNER + ADMIN ของ tenant ทันที (Socket.IO real-time + Web Push ถ้า subscribe):
| เหตุการณ์ | ข้อความที่ tenant ได้รับ |
|---|---|
| ✅ Admin อนุมัติ | "การชำระเงินได้รับการอนุมัติ — แพ็คเกจ X ฿Y พร้อมใช้งาน" |
| ⚠️ Admin ปฏิเสธ | "สลิปไม่ผ่านการตรวจสอบ — จำนวน ฿Y — เหตุผล + กรุณาอัพโหลดใหม่" |
| 🤖 OCR auto-verify ผ่าน | toast "✓ ตรวจสลิปสำเร็จ — แพ็คเกจของคุณพร้อมใช้งาน" + status APPROVED ทันที |
| 🤖 OCR auto-verify ไม่ผ่าน | toast "อัพโหลดสำเร็จ แต่ตรวจอัตโนมัติไม่ผ่าน (เหตุผล) — รอแอดมินตรวจ" |
คลิก notification จาก bell → deep link ไป /portal/billing ดูสถานะใหม่ + เหตุผลปฏิเสธ (ถ้ามี)
OCR Auto-verify (admin ตั้งค่าได้ที่ /admin/settings → Slip Verify):
ถ้า admin เปิดโหมด ocr_auto ระบบจะส่งสลิปไป EasySlip API ตรวจอัตโนมัติ — ถ้า:
OCR easyslip: amount_mismatch (slip ฿657.43 ≠ expected ฿1499) แล้วตัดสินใจ approve/reject เอง📍 หน้า: /portal/upgrade
👤 สิทธิ์: OWNER, ADMIN
วัตถุประสงค์: ดูและเปรียบเทียบแพ็กเกจ เลือกอัปเกรดหรือดาวน์เกรด
แพ็กเกจที่ให้บริการ:
| แพ็กเกจ | ผู้ใช้ | Branches | Storage | ราคา |
|---|---|---|---|---|
| STARTER | 5 คน | 1 สาขา | 1 GB | ติดต่อ |
| PROFESSIONAL | 20 คน | 5 สาขา | 10 GB | ติดต่อ |
| ENTERPRISE | ไม่จำกัด | ไม่จำกัด | 100 GB | ติดต่อ |
📍 หน้า: /branches
👤 สิทธิ์: OWNER, ADMIN
วัตถุประสงค์: เพิ่ม แก้ไข จัดการสาขาของร้าน
ขั้นตอนเพิ่มสาขาใหม่:
| ฟิลด์ | คำอธิบาย | จำเป็น |
|---|---|---|
| ชื่อสาขา | ชื่อสาขา (เช่น HQ, สาขาลาดพร้าว) | ✅ |
| ที่อยู่ | ที่อยู่สาขา | ✅ |
| เบอร์โทร | เบอร์ติดต่อสาขา | ✅ |
| อีเมล | อีเมลสาขา | ❌ |
| เป็นสาขาหลัก | ตั้งเป็น HQ | ❌ |
⚠️ หมายเหตุ: จำนวนสาขาที่สร้างได้ขึ้นอยู่กับแพ็กเกจ Subscription
📍 หน้า: /users
👤 สิทธิ์: OWNER, ADMIN
วัตถุประสงค์: เพิ่ม แก้ไข จัดการบัญชีผู้ใช้งานและกำหนด Role
ขั้นตอนเพิ่มผู้ใช้ใหม่:
| ฟิลด์ | คำอธิบาย | จำเป็น |
|---|---|---|
| อีเมล | อีเมลสำหรับ Login | ✅ |
| ชื่อ | ชื่อพนักงาน | ✅ |
| นามสกุล | นามสกุลพนักงาน | ✅ |
| เบอร์โทร | เบอร์ติดต่อ | ❌ |
| Role | เลือกได้หลาย Role | ✅ |
| สาขา | สาขาประจำ | ✅ |
| รหัสผ่าน | รหัสผ่านเริ่มต้น | ✅ |
| อัตราค่าแรง/ชั่วโมง | สำหรับคำนวณเงินเดือน | ❌ |
การจัดการ Role:
QR Code พนักงาน:
เปิด/ปิดบัญชี:
📍 หน้า: /masters
👤 สิทธิ์: OWNER, ADMIN, MANAGER
วัตถุประสงค์: จัดการข้อมูลอ้างอิงที่ใช้ทั่วทั้งระบบ เช่น ยี่ห้อ รุ่น สี ประเภทการซ่อม ฯลฯ
รายการ Master Data:
| หัวข้อ | URL | คำอธิบาย |
|---|---|---|
| ยี่ห้อสินค้า | /masters/brands | Apple, Samsung, OPPO ฯลฯ |
| รุ่นสินค้า | /masters/models | iPhone 15, Galaxy S24 ฯลฯ |
| สี | /masters/colors | ดำ, ขาว, ทอง ฯลฯ (พร้อม Color Picker) |
| ความจุ | /masters/storages | 64GB, 128GB, 256GB, 512GB ฯลฯ |
| ตำแหน่งจัดเก็บ | /masters/storage-locations | Shelf A1, ตู้ B ฯลฯ |
| หมวดหมู่อะไหล่ | /masters/spare-part-categories | จอ, แบตเตอรี่, ชาร์จพอร์ต ฯลฯ |
| ประเภทการซ่อม | /masters/repair-types | เปลี่ยนจอ, เปลี่ยนแบต, ซ่อมบอร์ด ฯลฯ |
| สถานะการซ่อม | /masters/repair-statuses | RECEIVED, IN_PROGRESS, COMPLETED ฯลฯ |
| สภาพสินค้า | /masters/product-conditions | NEW, LIKE_NEW, เกรด A, B, C, D (ตำหนิเยอะ ราคาถูก) |
| สถานะสินค้า | /masters/product-statuses | IN_STOCK, RESERVED, SOLD |
| สถานะเงินเดือน | /masters/payroll-statuses | PENDING, APPROVED, PAID |
| สถานะประกัน | /masters/warranty-statuses | ACTIVE, EXPIRED, CLAIMED |
ขั้นตอนเพิ่ม Master Data:
⚠️ หมายเหตุ: ข้อมูลหลักเป็น Tenant-specific — แต่ละร้านมีรายการของตัวเอง ไม่แชร์กับร้านอื่น
📍 หน้า: /settings
👤 สิทธิ์: OWNER, ADMIN
วัตถุประสงค์: ตั้งค่าข้อมูลร้านค้า, เป้าหมายยอดขาย, PromptPay, VAT
ส่วนที่ตั้งค่าได้:
| ส่วน | ฟิลด์ |
|---|---|
| ข้อมูลร้าน | ชื่อร้าน, ที่อยู่, เบอร์โทร, อีเมล, Logo |
| ภาษี | จด VAT หรือไม่ (Toggle), อัตรา VAT (ค่าเริ่มต้น 7%) |
| PromptPay | เบอร์โทร PromptPay สำหรับสร้าง QR |
| เลขประจำตัวผู้เสียภาษี | Tax ID |
| เป้าหมาย | เป้าหมายยอดขายต่อเดือน (บาท) |
| เป้าหมายซ่อม | เป้าหมายจำนวนงานซ่อมต่อเดือน |
💡 เคล็ดลับ: ตั้งค่า PromptPay Phone ก่อนเริ่มขาย เพื่อให้ระบบสร้าง QR Code ได้อัตโนมัติ
📍 หน้า: /audit-logs
👤 สิทธิ์: OWNER, ADMIN
วัตถุประสงค์: ดูบันทึกกิจกรรมทั้งหมดในระบบ — ใครทำอะไร เมื่อไหร่
ข้อมูลที่บันทึก:
| ฟิลด์ | ตัวอย่าง |
|---|---|
| ผู้กระทำ | admin@shop.com |
| การกระทำ | CREATE_PRODUCT, UPDATE_REPAIR, DELETE_USER |
| โมดูล | Product, Repair, User, Sale |
| รายละเอียด | ข้อมูลก่อน-หลังการเปลี่ยนแปลง |
| เวลา | วัน-เวลาตาม Timezone Asia/Bangkok |
| IP Address | IP ของผู้ใช้ |
การใช้งาน:
📍 ไอคอน: Bell 🔔 ด้านบนขวาของหน้าจอ 👤 สิทธิ์: ทุก Role
วัตถุประสงค์: รับการแจ้งเตือนแบบ Real-time สำหรับเหตุการณ์สำคัญในระบบ
ประเภทการแจ้งเตือน:
| ประเภท | ผู้รับ | ตัวอย่าง |
|---|---|---|
| งานซ่อมใหม่ | ADMIN, MANAGER, OWNER | "รับเครื่องซ่อมใหม่: iPhone 15 ลูกค้า สมชาย" |
| สถานะซ่อมเปลี่ยน | ผู้มอบหมายงาน | "งานซ่อม #123 เสร็จแล้ว" |
| ยอดขายใหม่ | ADMIN, MANAGER | "ขายสินค้า: Samsung S24 ฿25,000" |
| เงินเดือนรออนุมัติ | OWNER, ADMIN | "มีเงินเดือนรออนุมัติ 5 รายการ" |
| Stock ต่ำ | ADMIN, MANAGER | "อะไหล่ 'แบตเตอรี่ iPhone 13' เหลือ 2 ชิ้น" |
| ประกันใกล้หมดอายุ | ADMIN, MANAGER | "ประกัน iPhone 14 ของ สมหญิง จะหมดใน 7 วัน" |
| ประกาศจากระบบ | ทุก Role | "📢 ประกาศใหม่: กำหนดอัพเดท..." (จากทีมงาน MobileHub) |
วิธีใช้งาน:
/portal/announcements)💡 เคล็ดลับ: การแจ้งเตือนทำงานแบบ Real-time ผ่าน Socket.IO และบันทึกลง Database เพื่อดูย้อนหลังได้
📍 เปิดได้ที่: Banner ที่ Dashboard (ครั้งแรก) หรือหน้า Profile → การแจ้งเตือน Push 👤 สิทธิ์: ทุกแพ็คเกจ STARTER+ (รวมทั้ง Super Admin)
วัตถุประสงค์: รับแจ้งเตือนเหตุการณ์สำคัญทันที แม้ปิดแท็บหรือปิดเบราว์เซอร์อยู่ — เด้งเหมือน notification ของ LINE/Facebook
อุปกรณ์ที่รองรับ:
วิธีเปิดใช้งาน:
สำหรับ iPhone / iPad:
เปิด-ปิดเองได้ตลอดเวลา:
ไปที่หน้า Profile → การ์ด "การแจ้งเตือน Push" → เลื่อน Switch เปิด/ปิด
กรณี blocked:
ถ้าเผลอกด "Block" → คลิกไอคอน 🔒 ข้างซ้ายของ URL ในเบราว์เซอร์ → การตั้งค่าไซต์ → การแจ้งเตือน → Allow → รีเฟรชหน้า
Multi-device:
Login จาก 3 เครื่อง (เช่น Desktop ที่ร้าน + มือถือคุณ + แท็บเล็ตช่าง) แล้วเปิด Push ทั้ง 3 เครื่อง — ระบบจะส่งแจ้งเตือนทุกเครื่องพร้อมกัน
💡 เคล็ดลับ: Push notifications ทำงานคู่กับ Bell ในระบบ — ถ้าเปิดเว็บอยู่จะได้ทั้ง bell + push (อาจซ้อนกัน), ถ้าปิดเว็บได้แค่ push. ระบบใช้ tag-based grouping ทำให้ notification เหตุการณ์เดียวกันรวมเป็นรายการเดียว ไม่รก
📍 เปิดได้ที่: Banner สีฟ้าด้านล่างจอใน Dashboard (เด้งเองตอน browser พร้อม) หรือเมนู "ติดตั้งแอป" ใน Chrome 👤 สิทธิ์: ทุก Role
วัตถุประสงค์: ติดตั้ง MobileHub เป็นแอปบน Home Screen / Desktop เพื่อให้:
Banner ที่เด้งเอง — Chrome / Edge / Android:
หลังเปิด Dashboard ใช้งาน 2-3 นาที จะเห็น Paper สีฟ้า fixed ด้านล่างจอ ประกอบด้วย:
iPhone / iPad — ติดตั้งผ่าน Safari:
ปุ่ม "ติดตั้งเลย" จะเปลี่ยนเป็น "ดูวิธีติดตั้ง" เมื่อตรวจพบว่าเปิดผ่าน Safari → กดเพื่อเปิด Modal คำแนะนำ 3 ขั้นตอน:
⚠️ iOS ต้องใช้ Safari เท่านั้น ไม่รองรับ Chrome/Firefox บน iOS (ข้อจำกัดของ Apple)
Shortcuts บน Home Screen (Android / iOS):
หลังติดตั้งแล้ว — กดค้างที่ไอคอน MobileHub บน Home Screen → จะเห็น 4 ทางลัด:
/sales ขายสินค้าทันที/repair-intake รับเครื่อง/technician-repairs ดูงานที่มอบหมาย/track ค้นหาสถานะใบรับซ่อมตอนติดตั้งแล้ว:
display-mode: standalone)ถอนการติดตั้ง:
💡 เคล็ดลับ: ติดตั้งบนหลายเครื่องได้ — ที่ร้าน 1, ที่บ้าน 1, มือถือ 1 — ใช้บัญชีเดียวกัน Login จะเข้าถึงข้อมูลเดียวกันทุกเครื่อง
MobileHub ใช้สถาปัตยกรรม Multi-Tenant SaaS ที่ข้อมูลของแต่ละร้านถูกแยกกันอย่างสมบูรณ์ (Tenant Isolation)
หลักการสำคัญ:
tenantId กำกับ(tenantId, username) ไม่ใช่แค่ usernametenantId เพื่อตรวจสอบทุก Requestสิ่งที่แยกกันตาม Tenant:
ตำแหน่ง: Header ด้านบนของหน้า (ทุกหน้า)
วัตถุประสงค์: เลือกสาขาที่ต้องการดูข้อมูล
วิธีใช้:
option "ทุกสาขา" (Multi-Branch Dashboard) — Pro+:
📦 แพ็คเกจ: Professional หรือ Enterprise
MULTI_BRANCH_DASHBOARD และ มีสาขา ≥ 2 (สาขาเดียวจะไม่เห็นเพราะ redundant)💡 STARTER ฿599 มีแค่ 1 สาขา อยู่แล้ว — option นี้จึงเป็นของ Pro/Enterprise ที่มีหลายสาขาเท่านั้น
หมายเหตุ:
Prefix: /api/v1
| Module | Endpoint | Method | คำอธิบาย |
|---|---|---|---|
| Auth | /auth/login | POST | เข้าสู่ระบบ |
| Auth | /auth/register | POST | สมัครใช้งาน |
| Auth | /auth/verify-email | POST | ยืนยัน OTP |
| Products | /products | GET/POST | ดู/เพิ่มสินค้า |
| Sales | /sales | GET/POST | ดู/สร้างการขาย |
| Repairs | /repairs | GET/POST | ดู/สร้างงานซ่อม |
| Customers | /customers | GET/POST | ดู/เพิ่มลูกค้า |
| Payroll | /payroll | GET/POST | ดู/คำนวณเงินเดือน |
| Expenses | /expenses | GET/POST/PUT/DELETE | ดู/บันทึก/แก้ไข/ลบค่าใช้จ่ายดำเนินงาน |
| Expenses | /expenses/summary/by-category | GET | สรุป expense ตามหมวด (สำหรับ chart) |
| Shift | /shift/current | GET | ดูกะที่เปิดอยู่ของ user |
| Shift | /shift | GET | ประวัติกะ (admin/manager: ทั้งสาขา; cashier: ของตัวเอง) |
| Shift | /shift/open | POST | เปิดกะใหม่ — body: openingFloat |
| Shift | /shift/:id/live-totals | GET | preview totals ของกะ OPEN ก่อนปิด |
| Shift | /shift/:id/close | POST | ปิดกะ — body: actualCash + varianceReason |
| POS | /sales/preflight?branchId=... | GET | เช็คว่า user ขายได้ไหม — returns {shiftRequired, hasOpenShift, canSell, ...} |
| Tax CIT | /reports/cit?period=H1|FULL&year=YYYY | GET | คำนวณภาษีนิติบุคคล (CORPORATION only) |
| Tax WHT | /reports/wht?year=YYYY&month=MM | GET | สรุปหัก ณ ที่จ่าย — group by payee + Export CSV |
| Suppliers | /suppliers | GET/POST/PUT/DELETE | ดู/เพิ่ม/แก้/ลบผู้จัดหา |
| Reorders | /reorders | GET/POST | ดู/สร้างคำสั่งซื้ออะไหล่ |
| Reorders | /reorders/low-stock | GET | อะไหล่ที่ต่ำกว่า min stock + suggestedQty |
| Reorders | /reorders/:id/send|receive|cancel | POST | ส่งคำสั่ง/รับเข้า/ยกเลิก |
| Stock Count | /stock-count | GET/POST | ดู/เริ่มรอบนับ |
| Stock Count | /stock-count/:id/items/:itemId | PUT | บันทึก countedQty ของ item |
| Stock Count | /stock-count/:id/complete | POST | ปิดรอบนับ + คำนวณ totals |
| Stock Transfer | /stock-transfer | GET/POST | ดู/ขอโอน |
| Stock Transfer | /stock-transfer/:id/approve|receive|cancel | POST | อนุมัติ + ส่ง/รับเข้า/ยกเลิก |
| Sales Invoice (B2B) | /sales-invoices | GET/POST | ดู/ออก invoice — body: customerId + items + paymentTerms |
| Sales Invoice (B2B) | /sales-invoices/:id/payment | POST | บันทึกรับเงิน — body: amount + paymentMethod |
| Sales Invoice (B2B) | /sales-invoices/:id/cancel | POST | ยกเลิก invoice (ถ้ายังไม่ PAID) |
| Refunds | /sales/refunds/list | GET | list refund ทั้งหมด — filter date/method/search |
| Reports | /reports/:type | GET | ดูรายงาน |
| Dashboard | /dashboard/stats | GET | สถิติ Dashboard |
| Public Tracking | /public/repairs/track/:slug/:repairId | GET | ติดตามสถานะ (ไม่ต้อง auth, masked PII) |
| Public Tracking | /public/repairs/track/:slug/:repairId/verify | POST | ยืนยันด้วย 4 ตัวท้ายเบอร์ → full info |
| Public Tracking | /public/repairs/lookup?code= | GET | ค้นด้วยเลขเดียว ข้าม tenant (Kerry-style) → redirect |
| Public Tracking | /public/tenants/search?q= | GET | autocomplete ชื่อร้าน (deprecated — เหลือไว้สำหรับ Phase 2) |
| ส่วน | เทคโนโลยี | เวอร์ชัน |
|---|---|---|
| Frontend | Next.js | 16 |
| Frontend | React | 19 |
| Frontend | Mantine UI | v8.3 |
| Frontend | Zustand | State Management |
| Frontend | Socket.IO Client | Real-time |
| Backend | Fastify | Node.js Framework |
| Backend | Prisma ORM | PostgreSQL Client |
| Database | PostgreSQL | |
| Real-time | Socket.IO | |
| Auth | JWT | 24h tenant, 12h admin |
| File Upload | Fastify Multipart | สูงสุด 5MB |
| Font | Kanit | Thai Font |
| Timezone | Asia/Bangkok | dayjs |
ไฟล์: docker-compose.yml (root)
# Start production docker-compose up -d # View logs docker-compose logs -f
Services:
backend — Fastify API (port 3001)frontend — Next.js App (port 3000)postgres — PostgreSQL Databasenginx — Reverse Proxy (port 80/443)# Backend cd backend pm2 start ecosystem.config.js # Frontend cd frontend pm2 start ecosystem.config.js
Config:
backend/ecosystem.config.js — Cluster modefrontend/ecosystem.config.js — Cluster modeBackend (backend/.env):
DATABASE_URL=postgresql://...
JWT_SECRET=your-secret-key
PORT=3001
ALLOWED_ORIGINS=https://mobilehub.ajsoftwaredev.com
UPLOAD_DIR=/app/uploads
Frontend (.env.production):
NEXT_PUBLIC_API_URL=https://api.mobilehub.ajsoftwaredev.com
NEXT_PUBLIC_SOCKET_URL=wss://api.mobilehub.ajsoftwaredev.com
💡 หมายเหตุ: การ backup จัดการโดยทีมสนับสนุนระบบ (Super Admin) สามารถติดต่อผ่าน Support Ticket ได้
ผ่าน Command Line (สำหรับผู้ดูแลระบบที่มีสิทธิ์ SSH):
cd /opt/mobilehub bash scripts/backup.sh
# Decrypt backup openssl enc -d -aes-256-cbc -in backup.sql.gz.enc -out backup.sql.gz # Decompress gunzip backup.sql.gz # Restore to PostgreSQL psql -U mobilehub -d mobilehub_db < backup.sql
⚠️ คำเตือน: ก่อน Restore ต้องหยุดระบบก่อน และ Backup ใช้ Encryption Salt จาก BACKUP_ENCRYPTION_SALT ใน .env
| กฎ | รายละเอียด |
|---|---|
| JWT Token | Tenant: 24h, Admin: 12h |
| OTP | Hash ด้วย SHA-256 + สร้างด้วย crypto.randomInt |
| CORS | Production ห้าม Wildcard (*) |
| Body Limit | สูงสุด 1MB (ไฟล์ Upload 5MB แยก) |
| Pagination Cap | สูงสุด 100 รายการต่อหน้า |
| Rate Limit | 100 req/min (global), 10/min (auth), 5/min (register) |
| Upload Path | Validate branchId + path.resolve check |
| Admin Auth | ใช้ adminToken แยกจาก Tenant Token |
| Socket.IO | JWT Auth ก่อน connect, emit เฉพาะ Tenant Room |
| Mass Assignment | Whitelist fields ก่อน Prisma update |
| Error Response | ไม่ expose error.message ใน 500 response |
| ปัญหา | สาเหตุ | วิธีแก้ |
|---|---|---|
| Login ไม่ได้ | Token หมดอายุ | ออกจากระบบแล้วเข้าใหม่ |
| ข้อมูลไม่แสดง | Branch ไม่ถูก | เปลี่ยน Branch ใน Selector |
| QR Kiosk ไม่ทำงาน | Camera Permission | อนุญาตกล้องในเบราว์เซอร์ |
| PromptPay QR ว่าง | ยังไม่ได้ตั้งค่าเบอร์ | ตั้งค่าใน Settings → PromptPay Phone |
| Export Excel ช้า | ข้อมูลมาก | ลดช่วงวันที่ |
| Notification ไม่มา | Socket.IO disconnect | รีเฟรชหน้า |
| Upload ไม่ได้ | ไฟล์ใหญ่เกิน | ขนาดสูงสุด 5MB ต่อไฟล์ |
| หน้าขาว (Error) | JavaScript Error | F5 หรือ Clear Cache |
คู่มือนี้จัดทำสำหรับ MobileHub v2 เวอร์ชัน 2.0 อัปเดตล่าสุด: 27 เมษายน 2569 สอบถามเพิ่มเติม: support@mobilehub.ajsoftwaredev.com
MobileHub v2.0 | คู่มือการใช้งาน | © 2026 AJ Software Dev.
ดาวน์โหลด PDF