Flow ครบวงจรตั้งแต่ลูกค้าติดต่อ จนถึงปิด Job และสรุปกำไร
| # | ขั้นตอน | URL จริง | สถานะ |
|---|---|---|---|
| 1 | สร้างใบเสนอราคา | /finance/quotations/new | ทำได้createQuotationAction |
| 2 | ส่งแบบให้ลูกค้าอนุมัติ | /portal/[token]/job/[jobId] | ทำได้portalRespondDesignAction (ลูกค้าอนุมัติแบบผ่าน Portal) |
| 3 | รับเงินมัดจำ | /finance/invoices/[id]/pay | ทำได้recordPaymentAction (รับมัดจำ) |
| 4 | มอบหมายงาน | /tasks/new | บางส่วนมอบหมายงาน/assign ✅; แจ้ง LINE = outbox seam (รอ LINE_CHANNEL_ACCESS_TOKEN) |
| 5 | ช่างติดตั้ง | /my-work/check-in | ทำได้GPS check-in + geofence 500m |
| 6 | ถ่ายรูปหลังติดตั้ง | /my-work/log/[logId] | ทำได้ถ่ายรูปก่อน/หลัง อัปขึ้น Storage |
| 7 | ลูกค้ารับงาน | /my-work/log/[logId] | ทำได้addSignoffAction (ลูกค้าเซ็นรับงานดิจิตอล) |
| 8 | วางบิล | /finance | บางส่วนcreateInvoiceAction ✅; ส่ง Line/Email = seam (Email ยิงได้ถ้ามี RESEND_API_KEY) |
| 9 | รับเงิน | /finance/payments/[paymentId] | ทำได้recordPaymentAction + ใบเสร็จพิมพ์ได้ |
| 10 | ปิด Job | /jobs/[jobId] | ทำได้closeJobAction/changeJobStatusAction + getJobCostSummary (สรุปกำไร) |
สรุป: ทำได้เต็มวงจรตั้งแต่เสนอราคา → ปิดงาน + สรุปกำไร (พิสูจน์ด้วย e2e ที่รันกับ Supabase จริง). ติดเฉพาะการยิงแจ้งเตือน LINE/Email จริง (step 4, 8) ที่เป็น seam — บันทึกลง outbox ได้เลย แต่ส่งออกจริงต่อเมื่อใส่ API key.
ลูกค้าขอแก้ไข 3 รอบ → เกินรอบฟรี → แจ้งค่าแก้ไข → จบงาน
| # | ขั้นตอน | URL จริง | สถานะ |
|---|---|---|---|
| 1 | สร้างใบเสนอราคา | /finance/quotations/new | ทำได้createQuotationAction |
| 2 | ส่งแบบครั้งแรก | /portal/[token]/job/[jobId] | ทำได้ส่งแบบครั้งแรก → ลูกค้าดู Proof (portalRespondDesignAction) |
| 3 | รอบ 1: แก้ไขครั้งที่ 1 | /portal/[token]/job/[jobId] | ทำได้รอบ 1: ลูกค้ากดขอแก้ → status เป็น revision + เก็บคอมเมนต์ในไทม์ไลน์ |
| 4 | รอบ 2: แก้ไขครั้งที่ 2 | /portal/[token]/job/[jobId] | ทำได้รอบ 2: วน customer_review ↔ revision ได้ไม่จำกัดรอบ |
| 5 | รอบ 3+: แจ้งค่าแก้ไข | /jobs/[jobId] | ทำได้รอบ 3+ แจ้งค่าแก้ไขอัตโนมัติ — revision domain service นับรอบจากไทม์ไลน์ + คิดค่าแก้ไขเมื่อเกินโควตาฟรี 2 รอบ |
| 6 | Final Approve | /portal/[token]/job/[jobId] | ทำได้Final Approve → status design_approved |
| 7 | รับเงินมัดจำ | /finance/invoices/[id]/pay | ทำได้recordPaymentAction (รับมัดจำ) |
| 8 | มอบหมายงาน | /tasks/new | ทำได้มอบหมายงาน/assign (แจ้ง LINE = outbox seam) |
| 9 | ติดตั้ง | /my-work/check-in | ทำได้GPS check-in + geofence |
| 10 | ถ่ายรูปหลังติดตั้ง | /my-work/log/[logId] | ทำได้ถ่ายรูปหลังติดตั้ง อัปขึ้น Storage |
| 11 | ลูกค้ารับงาน | /my-work/log/[logId] | ทำได้addSignoffAction (ลูกค้าเซ็นรับงาน) |
| 12 | วางบิล (รวมค่าแก้ไข) | /finance | ทำได้createInvoiceAction + ค่าแก้ไขที่คำนวณได้นำมาออกบิลตามยอด (amount free-form) |
| 13 | รับเงิน | /finance/payments/[paymentId] | ทำได้recordPaymentAction + ใบเสร็จ |
| 14 | ปิด Job | /jobs/[jobId] | ทำได้ปิดงาน + ไทม์ไลน์เก็บประวัติ revision ครบ + badge สรุปจำนวนรอบแก้ไข |
สรุป: ทำได้ครบวงจรแก้ไขหลายรอบ — วน customer_review ↔ revision + เก็บคอมเมนต์ลูกค้าทุกครั้ง, นับรอบแก้ไขจากไทม์ไลน์ และแสดง 'ค่าแก้ไข' อัตโนมัติเมื่อเกินโควตาฟรี (revision domain service). ค่าแก้ไขที่คำนวณได้นำไปออกใบแจ้งหนี้ตามยอดได้.
ลูกค้างานเร่ง → ติดตั้งด่วน → ช่างลา → หาช่างใหม่ → จบงาน
| # | ขั้นตอน | URL จริง | สถานะ |
|---|---|---|---|
| 1 | Quick Quote ด่วน | /finance/quotations/new | ทำได้ออกใบเสนอราคาได้ทันที (ยังไม่มี template 'quick quote' สำเร็จรูป) |
| 2 | รับเงินมัดจำ | /finance/invoices/[id]/pay | ทำได้recordPaymentAction (รับมัดจำ) |
| 3 | ตั้ง Priority สูงสุด | /jobs/[jobId]/edit | ทำได้ตั้ง Job priority (ด่วนมาก/สูง/…) → urgent ขึ้นบนสุดของคิวงานในรายการ /jobs |
| 4 | มอบหมายงานด่วน | /tasks/new | ทำได้มอบหมายงานด่วน/assign (แจ้ง LINE = outbox seam) |
| 5 | ช่างเร่งติดตั้ง | /my-work/check-in | ทำได้ช่างเร่ง check-in GPS |
| 6 | ช่างลาฉุกเฉิน | /my-work/profile | ทำได้ช่างกดลา (myRequestLeaveAction) → PM อนุมัติ (reviewLeaveAction); แจ้งเตือนทันที = seam |
| 7 | หาช่างว่างด่วน | /map | ทำได้แผง 'ช่างว่าง/Workload' บนหน้าแผนที่ — เรียงช่างจากว่างที่สุด (งานค้างน้อย + ไม่ลาวันนี้) |
| 8 | Re-assign งาน | /tasks/[taskId] | ทำได้เปลี่ยนผู้รับผิดชอบ (updateTaskAction เปลี่ยน assigneeId); แจ้ง LINE = seam |
| 9 | ช่างคนใหม่ติดตั้ง | /my-work/check-in | ทำได้ช่างคนใหม่ check-in |
| 10 | ถ่ายรูปหลังติดตั้ง | /my-work/log/[logId] | ทำได้ถ่ายรูปหลังติดตั้ง |
| 11 | ลูกค้ารับงาน | /my-work/log/[logId] | ทำได้addSignoffAction (ลูกค้าเซ็นรับงาน) |
| 12 | วางบิล | /finance | ทำได้createInvoiceAction (ส่ง Line/Email = seam) |
| 13 | รับเงิน | /finance/payments/[paymentId] | ทำได้recordPaymentAction + ใบเสร็จ |
| 14 | ปิด Job | /jobs/[jobId] | ทำได้ปิดงาน + เก็บประวัติ (รวมการ reassign ในไทม์ไลน์) |
สรุป: ทำได้ครบวงจรงานเร่ง: Job priority + คิว (urgent ขึ้นบนสุดของรายการ), ช่างลา (myRequestLeaveAction) + อนุมัติ, แผง 'ช่างว่าง/Workload' บนหน้าแผนที่ (workload domain service เรียงจากว่างที่สุด + เช็คลาวันนี้) ช่วยหาช่างแทน, แล้วเปลี่ยนผู้รับผิดชอบผ่านแก้ Task. แจ้งเตือน LINE ยังเป็น seam.
รับงานใหญ่ → เบิกวัสดุหลายรายการ → ติดตั้ง → สรุปต้นทุน
| # | ขั้นตอน | URL จริง | สถานะ |
|---|---|---|---|
| 1 | สร้างใบเสนอราคา | /finance/quotations/new | ทำได้createQuotationAction (คิดต้นทุนวัสดุเบื้องต้นผ่านรายการในใบเสนอราคา) |
| 2 | ลูกค้าอนุมัติแบบ | /portal/[token]/job/[jobId] | ทำได้ลูกค้าอนุมัติแบบ (portalRespondDesignAction) |
| 3 | มอบหมายงาน | /tasks/new | ทำได้มอบหมายงาน/assign (แจ้ง LINE = seam) |
| 4 | เบิกวัสดุครั้งที่ 1 | /inventory/[materialId]/issue | บางส่วนเบิกวัสดุครั้งที่ 1 (issueStockAction) — เบิกผ่านฟอร์มได้ แต่ยังไม่มี 'สแกน QR' |
| 5 | Stock อัพเดท | /inventory/[materialId] | ทำได้Stock อัพเดทอัตโนมัติ (ตัด stock + บันทึกต้นทุนวัสดุต่องาน) |
| 6 | เบิกวัสดุครั้งที่ 2 | /inventory/[materialId]/issue | ทำได้เบิกวัสดุครั้งที่ 2 |
| 7 | แจ้งเตือน Stock ต่ำ | /inventory | ทำได้แจ้งเตือนวัสดุใกล้หมด (lowStock filter/badge) |
| 8 | ติดตั้ง | /my-work/check-in | ทำได้ช่าง check-in GPS |
| 9 | ถ่ายรูปหลังติดตั้ง | /my-work/log/[logId] | ทำได้ถ่ายรูปหลังติดตั้ง |
| 10 | ลูกค้ารับงาน | /my-work/log/[logId] | ทำได้addSignoffAction (ลูกค้าเซ็นรับงาน) |
| 11 | วางบิล | /finance | ทำได้createInvoiceAction (ส่ง Line/Email = seam) |
| 12 | รับเงิน | /finance/payments/[paymentId] | ทำได้recordPaymentAction + ใบเสร็จ |
| 13 | สรุปต้นทุนงาน | /jobs/[jobId] | ทำได้สรุปต้นทุน/กำไรต่องาน (getJobCostSummary — วัสดุ+แรง vs รายได้) |
| 14 | ปิด Job | /jobs/[jobId] | ทำได้ปิดงาน + เก็บประวัติต้นทุน |
สรุป: วงจรงานเบิกวัสดุเยอะทำได้จริง: เบิกวัสดุ (issueStockAction) ตัด stock อัตโนมัติ + ผูกต้นทุนกับงาน, แจ้งเตือนของใกล้หมด (lowStock), สรุปต้นทุน/กำไรต่องาน (getJobCostSummary). ที่ยังไม่มี: ⚠️ การ 'สแกน QR' ตอนเบิก — เบิกผ่านฟอร์ม (เลือกวัสดุ+จำนวน) ได้ปกติ แต่ยังไม่มีตัวสแกน QR/บาร์โค้ด.
ลูกค้าประจำรายใหญ่ → ดูประวัติย้อนหลัง → ใช้ Template → จบไว
| # | ขั้นตอน | URL จริง | สถานะ |
|---|---|---|---|
| 1 | เจ้าของเช็คลูกค้า VIP | /dashboard | ทำได้widget 'ลูกค้ารายใหญ่ (VIP)' บนแดชบอร์ด เรียงตามยอดใช้จ่าย (customers.getTopBySpend) |
| 2 | ลูกค้าดูประวัติเอง | /portal/[token] | ทำได้ลูกค้าเปิด Portal ดูงานเก่าทั้งหมดได้เอง |
| 3 | ใช้ Template สำเร็จรูป | /finance/quotations/new?templateId=… | ทำได้Quick Quote — ปุ่ม 'ทำซ้ำ' บนใบเสนอราคา prefill รายการจาก template เดิม |
| 4 | ส่งแบบอนุมัติ | /portal/[token]/job/[jobId] | ทำได้ส่งแบบให้ลูกค้าอนุมัติ (portalRespondDesignAction) |
| 5 | มอบหมายงาน | /tasks/new | ทำได้มอบหมายงาน (เลือกช่างคนเดิมได้) |
| 6 | VIP Priority | /jobs/[jobId]/edit | ทำได้ตั้ง Job priority สูง + tag ลูกค้า VIP (customer.tags) |
| 7 | ติดตั้ง | /my-work/check-in | ทำได้ช่าง check-in |
| 8 | ถ่ายรูปหลังติดตั้ง | /my-work/log/[logId] | ทำได้ถ่ายรูปหลังติดตั้ง |
| 9 | ลูกค้ารับงาน | /my-work/log/[logId] | ทำได้addSignoffAction (รับงาน) — ปิดงานแล้วระบบส่งข้อความขอบคุณอัตโนมัติ |
| 10 | ส่งแบบสอบถาม | /jobs/[jobId] | ทำได้ปิดงาน → ส่งขอบคุณ + ลิงก์ให้คะแนนอัตโนมัติเข้า outbox (closeJobAction + feedback_survey) |
| 11 | ลูกค้าให้คะแนน | /portal/[token]/job/[jobId] | ทำได้ลูกค้าให้คะแนน (portalSubmitFeedback + avgRating) |
| 12 | วางบิล | /finance | ทำได้createInvoiceAction (ส่ง = seam) |
| 13 | รับเงิน | /finance/payments/[paymentId] | ทำได้recordPaymentAction + ใบเสร็จ |
| 14 | ปิด Job | /customers/[customerId] | ทำได้ปิดงาน + แต้มสะสม/tier VIP คำนวณจากยอดใช้จ่ายจริง (loyalty service) แสดงบนหน้าลูกค้า |
สรุป: ทำได้ครบวงจรลูกค้า VIP: widget 'ลูกค้ารายใหญ่' บน Dashboard (getTopBySpend), Quick Quote ทำซ้ำใบเสนอราคาจาก template, แต้มสะสม+tier (loyalty service จากยอดใช้จ่ายจริง), ส่งขอบคุณ+แบบให้คะแนนอัตโนมัติเมื่อปิดงาน (outbox), Portal ดูประวัติ/อนุมัติ/ให้คะแนน. หมายเหตุ: การยิงจริงเป็น seam (รอ key); แต้มเป็นแบบ derived จากยอดใช้จ่าย.
ช่างติดตั้ง → เจอปัญหา → แจ้งเจ้าของ → แก้ไข → จบงาน
| # | ขั้นตอน | URL จริง | สถานะ |
|---|---|---|---|
| 1 | สร้างใบเสนอราคา | /finance/quotations/new | ทำได้createQuotationAction |
| 2 | ลูกค้าอนุมัติ | /portal/[token]/job/[jobId] | ทำได้ลูกค้าอนุมัติแบบ |
| 3 | มอบหมายงาน | /tasks/new | ทำได้มอบหมายงาน (LINE = seam) |
| 4 | เริ่มติดตั้ง | /my-work/check-in | ทำได้ช่างเริ่มติดตั้ง (check-in) |
| 5 | เจอปัญหา! แจ้งเจ้าของ | /field-work/[logId]/issue | ทำได้เจอปัญหา → reportIssueAction (รูป + ระดับความรุนแรง); แจ้งเจ้าของทาง LINE = seam |
| 6 | เจ้าของดูรายละเอียด | /field-work/[logId] | ทำได้เจ้าของดูรายละเอียดปัญหา + รูป + GPS check-in |
| 7 | เจ้าของสั่งการ | /field-work/[logId] | ทำได้เจ้าของสั่งการ/อนุมัติ → resolveIssueAction (ทำเครื่องหมาย 'แก้ไขแล้ว') |
| 8 | อนุมัติค่าใช้จ่าย | /field-work/[logId] | ทำได้อนุมัติค่าใช้จ่าย = resolve ปัญหา; ต้นทุนเพิ่มจริงผ่านการเบิกวัสดุ → job cost |
| 9 | เบิกวัสดุเพิ่ม | /inventory/[materialId]/issue | ทำได้เบิกวัสดุเพิ่ม (issueStock) ตัด stock + เพิ่มต้นทุนงาน |
| 10 | ช่างแก้ไขต่อ | /my-work/check-in | ทำได้ช่างแก้ไขต่อ |
| 11 | ถ่ายรูปหลังติดตั้ง | /my-work/log/[logId] | ทำได้ถ่ายรูปหลังติดตั้ง |
| 12 | ลูกค้ารับงาน | /my-work/log/[logId] | ทำได้addSignoffAction (ลูกค้ารับงาน) |
| 13 | วางบิล (รวมค่าแก้ไข) | /finance | ทำได้createInvoiceAction รวมค่าวัสดุ+ค่าแก้ไข (ส่ง = seam) |
| 14 | รับเงิน | /finance/payments/[paymentId] | ทำได้recordPaymentAction + ใบเสร็จ |
| 15 | สรุปต้นทุนงาน | /jobs/[jobId] | ทำได้สรุปต้นทุนจริงรวมค่าแก้ไข (getJobCostSummary) |
| 16 | ปิด Job | /jobs/[jobId] | ทำได้ปิดงาน + เก็บประวัติปัญหา |
สรุป: ทำได้ครบวงจรงานมีปัญหาหน้างาน: ช่างรายงานปัญหา+รูป+ระดับความรุนแรง (reportIssue), เจ้าของดูรายละเอียด/GPS/รูปที่หน้า field-work, กด 'อนุมัติ/แก้ไขแล้ว' (resolveIssueAction ใหม่), เบิกวัสดุเพิ่ม → ต้นทุนเพิ่มเข้า job cost อัตโนมัติ, สรุปกำไรจริง. แจ้งเตือน LINE เป็น seam.
งานเสร็จ → ลูกค้าไม่พอใจ → ร้องเรียน → แก้ไข → ประเมินใหม่
| # | ขั้นตอน | URL จริง | สถานะ |
|---|---|---|---|
| 1 | สร้างใบเสนอราคา | /finance/quotations/new | ทำได้createQuotationAction |
| 2 | ลูกค้าอนุมัติ | /portal/[token]/job/[jobId] | ทำได้ลูกค้าอนุมัติแบบ |
| 3 | มอบหมายงาน | /tasks/new | ทำได้มอบหมายงาน |
| 4 | ติดตั้ง | /my-work/check-in | ทำได้ช่างติดตั้ง (check-in) |
| 5 | ถ่ายรูปหลังติดตั้ง | /my-work/log/[logId] | ทำได้ถ่ายรูปหลังติดตั้ง |
| 6 | ลูกค้ารับงาน | /my-work/log/[logId] | ทำได้addSignoffAction (ลูกค้ารับงาน) |
| 7 | วางบิล | /finance | ทำได้createInvoiceAction (ส่ง = seam) |
| 8 | รับเงิน | /finance/payments/[paymentId] | ทำได้recordPaymentAction + ใบเสร็จ |
| 9 | ปิด Job | /jobs/[jobId] | ทำได้ปิดงาน (closeJobAction) — ส่งแบบสอบถามอัตโนมัติเข้า outbox |
| 10 | ลูกค้าร้องเรียน! | /portal/[token]/job/[jobId] | ทำได้ลูกค้าร้องเรียน! → portalSubmitComplaintAction (เฉพาะงานที่ปิดแล้ว) — complaints module ใหม่ |
| 11 | เจ้าของรับเรื่อง | /jobs/[jobId] | ทำได้เจ้าของรับเรื่อง → แผงร้องเรียนบนหน้างาน, resolveComplaintAction (open → in_progress) |
| 12 | ดูประวัติงาน | /jobs/[jobId] | ทำได้ดูประวัติงาน + ไทม์ไลน์ + รายละเอียดร้องเรียน |
| 13 | ส่งช่างแก้ไข | /tasks/new | ทำได้ส่งช่างแก้ไข (มอบหมาย/นัด) — complaint อยู่สถานะกำลังแก้ไข |
| 14 | ช่างแก้ไขปัญหา | /my-work/check-in | ทำได้ช่างแก้ไขปัญหา — field-work check-in ได้แม้งานปิดแล้ว |
| 15 | ถ่ายรูปหลังแก้ไข | /my-work/log/[logId] | ทำได้ถ่ายรูปหลังแก้ไข |
| 16 | ลูกค้ายืนยันงาน | /my-work/log/[logId] | ทำได้ลูกค้ายืนยันงาน (addSignoff) |
| 17 | ส่งแบบสอบถาม | /jobs/[jobId] | ทำได้ส่งแบบสอบถาม — auto-survey ตอนปิดงาน (หรือส่งซ้ำผ่าน outbox) |
| 18 | ประเมินความพอใจ | /portal/[token]/job/[jobId] | ทำได้ประเมินความพอใจ — portalSubmitFeedback (canLeaveFeedback อนุญาตหลังปิดงาน) |
| 19 | ปิด Job (สมบูรณ์) | /jobs/[jobId] | ทำได้ปิด Job สมบูรณ์ → resolveComplaintAction (in_progress → resolved + หมายเหตุ) |
สรุป: ทำได้ครบวงจรหลังการขาย: ลูกค้าร้องเรียนผ่าน Portal หลังปิดงาน (complaints module ใหม่ — closed-only), เจ้าของรับเรื่อง→ดำเนินการ→แก้ไขแล้ว บนหน้างาน, ช่างลงงานแก้ไขได้แม้งานปิด (field-work ไม่ผูกสถานะ), ส่งแบบสอบถามอัตโนมัติตอนปิดงาน, ลูกค้าให้คะแนนหลังปิดได้ (canLeaveFeedback). แจ้งเตือน LINE เป็น seam.
งานสติ๊กเกอร์ติดทั้งอาคาร → แบ่งส่ง 3 งวด → เก็บเงินตามความคืบหน้า
| # | ขั้นตอน | URL จริง | สถานะ |
|---|---|---|---|
| 1 | สร้างใบเสนอราคา (3 งวด) | /finance/quotations/new | ทำได้ใบเสนอราคา + เงื่อนไขชำระ 3 งวด (paymentTerms); ตั้งบิลตามงวดด้วยใบแจ้งหนี้ 3 ใบ |
| 2 | ลูกค้าอนุมัติแบบ | /portal/[token]/job/[jobId] | ทำได้ลูกค้าอนุมัติแบบ |
| 3 | มอบหมายทีมใหญ่ | /tasks/new | ทำได้มอบหมายทีมใหญ่ — สร้างหลาย Task/ผู้รับผิดชอบแยกกลุ่ม |
| 4 | เบิกวัสดุงวด 1 | /inventory/[materialId]/issue | ทำได้เบิกวัสดุงวด 1 |
| 5 | ติดตั้งชั้น 1-5 | /my-work/check-in | ทำได้ติดตั้งชั้น 1-5 |
| 6 | ถ่ายรูปงวด 1 | /my-work/log/[logId] | ทำได้ถ่ายรูปงวด 1 |
| 7 | ตรวจสอบงวด 1 | /tasks/new | ทำได้ตรวจสอบงวด 1 — Task ประเภท 'ตรวจคุณภาพ' (quality_check) |
| 8 | วางบิลงวด 1 (30%) | /finance | ทำได้วางบิลงวด 1 (30%) → createInvoice เลือกประเภท 'มัดจำ' + จำนวนเงิน |
| 9 | รับเงินงวด 1 | /finance/invoices/[id]/pay | ทำได้รับเงินงวด 1 |
| 10 | เบิกวัสดุงวด 2 | /inventory/[materialId]/issue | ทำได้เบิกวัสดุงวด 2 |
| 11 | ติดตั้งชั้น 6-10 | /my-work/check-in | ทำได้ติดตั้งชั้น 6-10 |
| 12 | ถ่ายรูปงวด 2 | /my-work/log/[logId] | ทำได้ถ่ายรูปงวด 2 |
| 13 | ตรวจสอบงวด 2 | /tasks/new | ทำได้ตรวจสอบงวด 2 (quality_check) |
| 14 | วางบิลงวด 2 (40%) | /finance | ทำได้วางบิลงวด 2 (40%) → createInvoice ประเภท 'ระหว่างงาน' |
| 15 | รับเงินงวด 2 | /finance/invoices/[id]/pay | ทำได้รับเงินงวด 2 |
| 16 | เบิกวัสดุงวด 3 | /inventory/[materialId]/issue | ทำได้เบิกวัสดุงวด 3 |
| 17 | ติดตั้งชั้น 11-15 | /my-work/check-in | ทำได้ติดตั้งชั้น 11-15 |
| 18 | ถ่ายรูปงวด 3 | /my-work/log/[logId] | ทำได้ถ่ายรูปงวด 3 + ตรวจสุดท้าย (quality_check) |
| 19 | ตรวจสอบสุดท้าย | /my-work/log/[logId] | ทำได้ลูกค้ารับงานทั้งหมด (addSignoff) |
| 20 | ลูกค้ารับงานทั้งหมด | /finance | ทำได้วางบิลงวด 3 (30%) → createInvoice ประเภท 'งวดสุดท้าย' |
| 21 | วางบิลงวด 3 (30%) | /finance/payments/[paymentId] | ทำได้รับเงินงวดสุดท้าย |
| 22 | รับเงินงวดสุดท้าย | /jobs/[jobId] | ทำได้สรุปแต่ละงวด — รายได้ต่องวดจากใบแจ้งหนี้ 3 ใบ + กำไรรวมงาน (getJobCostSummary) |
| 23 | สรุปต้นทุนแต่ละงวด | /jobs/[jobId] | ทำได้ปิด Job ใหญ่ + เก็บประวัติ milestone (ไทม์ไลน์) |
| 24 | ปิด Job ใหญ่ | — | — |
สรุป: ทำได้ครบวงจรงานแบ่งส่งหลายงวด: ออกใบแจ้งหนี้แยกงวดได้จริง (เลือกประเภท มัดจำ/ระหว่างงาน/สุดท้าย + จำนวนเงิน บนหน้างาน) → เก็บเงินตามความคืบหน้า, QC แต่ละงวดด้วย Task ประเภท 'ตรวจคุณภาพ', เบิกวัสดุ/ติดตั้ง/ถ่ายรูปต่องวด, สรุปกำไรงานใหญ่. หมายเหตุ: รายได้ดูแยกต่องวดได้ (3 ใบแจ้งหนี้) แต่ต้นทุนสรุปรวมทั้งงาน (ไม่ตัดต่องวด).
เบิกวัสดุกลางงาน → ระบบเตือน stock หมด → สั่งซื้อด่วน → รับของ → จบงาน
| # | ขั้นตอน | URL จริง | สถานะ |
|---|---|---|---|
| 1 | สร้างใบเสนอราคา | /finance/quotations/new | ทำได้createQuotationAction |
| 2 | ลูกค้าอนุมัติแบบ | /portal/[token]/job/[jobId] | ทำได้ลูกค้าอนุมัติแบบ |
| 3 | มอบหมายงาน | /tasks/new | ทำได้มอบหมายงาน |
| 4 | เบิกวัสดุ | /inventory/[materialId]/issue | ทำได้เบิกวัสดุ (issueStock) — ระบบเตือนวัสดุใกล้หมด |
| 5 | แจ้งเตือน Stock หมด | /inventory | ทำได้แจ้งเตือน Stock ต่ำ (lowStock filter/badge) |
| 6 | สร้าง PO สั่งซื้อด่วน | /purchase-orders/new | ทำได้สร้าง PO สั่งซื้อด่วน → createPurchaseOrderAction (เลือกซัพพลายเออร์/วัสดุ/จำนวน/ราคา) |
| 7 | รับวัสดุเข้า Stock | /purchase-orders | ทำได้รับวัสดุเข้า Stock → 'รับของเข้าคลัง' (receivePurchaseOrder → receiveStock + ตัด avg cost) |
| 8 | ช่างติดตั้ง | /my-work/check-in | ทำได้ช่างติดตั้ง (check-in GPS) |
| 9 | ถ่ายรูปหลังติดตั้ง | /my-work/log/[logId] | ทำได้ถ่ายรูปหลังติดตั้ง |
| 10 | ลูกค้ารับงาน | /my-work/log/[logId] | ทำได้addSignoffAction (ลูกค้ารับงาน) |
| 11 | วางบิล | /finance | ทำได้createInvoiceAction (ส่ง = seam) |
| 12 | รับเงิน | /finance/payments/[paymentId] | ทำได้recordPaymentAction + ใบเสร็จ |
| 13 | ปิด Job | /jobs/[jobId] | ทำได้ปิดงาน + เก็บประวัติ stock issue |
สรุป: ทำได้ครบวงจรวัสดุไม่พอ → สั่งซื้อด่วน: เบิกวัสดุ→แจ้งเตือนของใกล้หมด, สร้างใบสั่งซื้อ (PO module ใหม่) ไปซัพพลายเออร์, กด 'รับของเข้าคลัง' → เพิ่ม stock อัตโนมัติ (reuse receiveStock) + PO เป็น 'รับแล้ว', แล้วติดตั้งต่อ→ปิดงาน. หมายเหตุ: PO เป็นแบบวัสดุเดียวต่อใบ; ส่ง PO ให้ซัพพลายเออร์จริงเป็น seam.
ลูกค้าบริษัทใหญ่ 5 สาขา → แยกทีม → ติดตาม progress แยกสาขา → รวม invoice บิลเดียว
| # | ขั้นตอน | URL จริง | สถานะ |
|---|---|---|---|
| 1 | สร้าง Quote รวมหลายสาขา | /finance/quotations/new | ทำได้Quote รวมหลายสาขา (แต่ละสาขาเป็นรายการในใบเสนอราคา) |
| 2 | ลูกค้าอนุมัติแบบ | /portal/[token]/job/[jobId] | ทำได้ลูกค้าอนุมัติแบบเดียวใช้ทุกสาขา |
| 3 | แยก Job ตามสาขา | /jobs/new | ทำได้แยก Job ตามสาขา → สร้างงานลูกแล้วเลือก 'งานแม่' (parent_job_id) |
| 4 | มอบหมายทีมตามโซน | /tasks/new | ทำได้มอบหมายทีมตามโซน → assign Task ต่อสาขา |
| 5 | ติดตาม Progress แต่ละสาขา | /jobs/[jobId] | ทำได้ติดตาม Progress แต่ละสาขา → แผง 'สาขาย่อย' + 'เสร็จ X/N สาขา' บนหน้างานแม่ |
| 6 | ทีมติดตั้งสาขาที่ 1-2 | /my-work/check-in | ทำได้ทีมติดตั้งสาขา 1-2 (check-in ต่อสาขา) |
| 7 | ทีมติดตั้งสาขาที่ 3-4 | /my-work/check-in | ทำได้ทีมติดตั้งสาขา 3-4 |
| 8 | ทีมติดตั้งสาขาที่ 5 | /my-work/check-in | ทำได้ทีมติดตั้งสาขา 5 |
| 9 | ยืนยันงานครบทุกสาขา | /jobs/[jobId] | ทำได้ยืนยันครบทุกสาขา → แผงสรุป 'เสร็จ N/N สาขา' |
| 10 | รวม Invoice เป็นบิลเดียว | /finance | ทำได้รวม Invoice เป็นบิลเดียว → ออกใบแจ้งหนี้ที่งานแม่ใบเดียว (JobFinancePanel) |
| 11 | รับเงิน + ปิด Job | /finance/payments/[paymentId] | ทำได้รับเงิน + ปิด Job ทั้งหมด |
สรุป: ทำได้ครบวงจรงานหลายสาขา: โครงสร้างงานแม่/สาขาย่อย (parent_job_id), แยกงานตามสาขาโดยเลือก 'งานแม่' ตอนสร้างงาน, ติดตาม progress แต่ละสาขา + 'เสร็จ X/N สาขา' บนหน้างานแม่, มอบหมายทีม/ติดตั้ง/ยืนยันต่อสาขา, ออกบิลรวมที่งานแม่ใบเดียว. หมายเหตุ: บิลรวม = ออกใบแจ้งหนี้ที่งานแม่ (ไม่รวมต้นทุนลูกอัตโนมัติ).
เช่าพื้นที่ติดสติ๊กเกอร์โฆษณา 3 เดือน → เก็บเงินรายเดือน → ต่อสัญญาหรือรื้อถอน
| # | ขั้นตอน | URL จริง | สถานะ |
|---|---|---|---|
| 1 | สร้างสัญญาเช่า | /rentals/new | ทำได้สร้างสัญญาเช่า (createRentalContractAction) |
| 2 | ลูกค้าอนุมัติแบบ | /portal/[token]/job/[jobId] | ทำได้ลูกค้าอนุมัติแบบ/artwork |
| 3 | ติดตั้งสติ๊กเกอร์ | /rentals/[contractId] | ทำได้ติดตั้งสติ๊กเกอร์ → สัญญาเริ่ม (active); ใช้ field-work ถ้าผูกกับงาน |
| 4 | เช็คเดือนที่ 1 | /rentals/[contractId] | ทำได้เช็คเดือนที่ 1 + เก็บค่าเช่า (recordRentalCheckAction) |
| 5 | เช็คเดือนที่ 2 | /rentals/[contractId] | ทำได้เช็คเดือนที่ 2 + เก็บค่าเช่า |
| 6 | เช็คเดือนที่ 3 | /rentals/[contractId] | ทำได้เช็คเดือนที่ 3 + เก็บค่าเช่า |
| 7 | ต่อสัญญาหรือรื้อถอน | /rentals/[contractId] | ทำได้ต่อสัญญา (renew) หรือ รื้อถอน (close) — ปุ่มบนหน้าสัญญา |
| 8 | รื้อถอนสติ๊กเกอร์ | /rentals/[contractId] | ทำได้รื้อถอนสติ๊กเกอร์ → ปิดสัญญา (+ field-work ถ้าผูกงาน) |
| 9 | ตรวจรับพื้นที่ | /rentals/[contractId] | ทำได้ตรวจรับพื้นที่ → บันทึกตอนปิดสัญญา |
| 10 | ปิดสัญญา | /rentals/[contractId] | ทำได้ปิดสัญญา + คืนมัดจำ (closeRentalContractAction → deposit_refunded) |
สรุป: ทำได้ครบวงจรเช่าพื้นที่โฆษณา: สร้างสัญญาเช่า (rental module ใหม่ — พื้นที่/ค่าเช่า/มัดจำ/ระยะเวลา), เช็ครายเดือน + เก็บค่าเช่า (recordCheck), ต่อสัญญา (renew) หรือ ปิดสัญญา + คืนมัดจำ (close). หมายเหตุ: ติดตั้ง/รื้อถอนใช้ field-work เสริมถ้าผูกกับงาน; แกนคือสัญญา + เช็ครายเดือน.