# Open Bill Spec / Flow

เอกสารนี้สรุปแนวทางออกแบบหน้า `Open Bill` สำหรับระบบ CCW โดยอิงจากพฤติกรรมปัจจุบันของ `booking`, `quick_service`, และ `member`

## 1. Objective

สร้างหน้า `Open Bill` ให้เป็นจุดเริ่มต้นกลางสำหรับพนักงานหน้าร้าน เพื่อ:

- ค้นหาลูกค้าจาก `เบอร์โทร` หรือ `ทะเบียนรถ`
- ลงทะเบียนลูกค้าใหม่และรถใหม่ได้อย่างรวดเร็ว
- แสดงข้อมูลลูกค้าและรถแบบย่อก่อนทำรายการ
- เลือกปลายทางธุรกรรมเป็น `Booking`, `Quick Service`, หรือ `Member Info`

ข้อกำหนดสำคัญ:

- `Quick Service` ยังคงเป็นบิลหน้าร้านนอก `Queue` เหมือนระบบเดิม
- หน้า `Open Bill` ไม่สร้าง `order` เอง
- หน้า `Open Bill` ทำหน้าที่ค้นหา, ลงทะเบียน, ตรวจสอบข้อมูล, และส่งต่อไปยัง flow ปลายทาง

## 2. Scope

### In Scope: Phase 1

- หน้าใหม่ `pages/open_bill.php`
- ค้นหาลูกค้าด้วย exact match จาก `เบอร์โทร` หรือ `ทะเบียนรถ`
- รองรับผลลัพธ์ `ไม่พบ`, `พบ 1 รายการ`, `พบหลายรายการ`
- ลงทะเบียนลูกค้าใหม่และรถใหม่แบบ manual
- แสดงสรุปลูกค้า, รถ, และประวัติล่าสุดแบบย่อ
- ปุ่มปลายทาง `Booking`, `Quick Service`, `Member Info`
- ส่งข้อมูลต่อไปยัง flow ปลายทางแบบ prefill

### Out of Scope: Phase 1

- OCR อ่านป้ายทะเบียน
- AI อ่านยี่ห้อ / รุ่น / สีรถ
- ถ่ายรูปจากกล้องมือถือ
- เก็บรูปรถเป็น profile
- ตาราง `OpenBill` ใหม่
- การส่ง `Quick Service` เข้า `Queue`

## 3. Current System Constraints

ระบบปัจจุบันมี behavior สำคัญที่ต้องคงไว้:

- `Booking` เป็น flow ที่สร้าง `order` และสร้าง `queue` ตอนบันทึกจริง
- `Quick Service` เป็น flow หน้าร้านที่ไม่ส่งงานเข้า `Queue`
- `Member` มี profile, รถหลายคัน, package balance, และ service history อยู่แล้ว
- การค้นหาลูกค้าปัจจุบันใช้ exact match จาก `normalized_phone` หรือ `plate_number`

ผลกระทบต่อการออกแบบ:

- หน้า `Open Bill` ควรเป็น orchestration layer ไม่ใช่ order creation layer
- ควร reuse search และ customer lookup ของเดิมให้มากที่สุด
- ควรแยกการ “ลงทะเบียนลูกค้า/รถ” ออกจากการ “เปิดบิล”

## 4. Product Definition

### 4.1 Definition of Open Bill

`Open Bill` คือหน้ากลางสำหรับ:

1. ค้นหาลูกค้าเดิม
2. ลงทะเบียนลูกค้าใหม่
3. ตรวจสอบข้อมูลลูกค้าและรถ
4. เลือกว่าจะไปทำรายการต่อในช่องทางใด

### 4.2 What Open Bill Does Not Do

`Open Bill` จะไม่:

- รับชำระเงิน
- สร้าง `Booking order` โดยตรง
- สร้าง `Quick Service bill` โดยตรง
- ส่งงานเข้า `Queue`

## 5. Main User Flow

```mermaid
flowchart TD
    A[Open Bill] --> B[Search by phone or plate]
    B --> C{Search result}
    C -->|No match| D[Show new customer form]
    C -->|One match| E[Load customer and car summary]
    C -->|Multiple matches| F[Show selection list]
    F --> E
    D --> G[Save customer and car]
    G --> E
    E --> H{Choose destination}
    H --> I[Booking]
    H --> J[Quick Service]
    H --> K[Member Info]
```

## 6. Screen Layout

หน้า `Open Bill` ควรแบ่งเป็น 3 ส่วนหลัก

### Section A: Search Panel

องค์ประกอบ:

- ช่องค้นหา 1 ช่อง ใช้ได้ทั้ง `เบอร์โทร` และ `ทะเบียนรถ`
- ปุ่ม `ค้นหา`
- ปุ่ม `ลงทะเบียนลูกค้าใหม่`
- พื้นที่แสดง feedback เช่น `กำลังค้นหา`, `ไม่พบข้อมูล`, `พบหลายรายการ`

หมายเหตุ:

- ใช้ AJAX search endpoint เดิม
- ถ้าพบหลายรายการให้แสดงรายการลูกค้า/รถให้เลือกทันที

### Section B: Customer / Vehicle Summary

องค์ประกอบ:

- ชื่อลูกค้า
- เบอร์โทร
- ประเภทลูกค้า `member / guest`
- ทะเบียนรถ
- จังหวัด
- ยี่ห้อ
- รุ่น
- สี
- สรุปประวัติล่าสุด เช่น วันที่ใช้บริการล่าสุด, จำนวนรถ, จำนวนครั้งเข้าใช้บริการ

พฤติกรรม:

- ถ้ายังไม่มีลูกค้าถูกเลือก ส่วนนี้ hidden หรือ disabled
- ถ้าเพิ่งลงทะเบียนลูกค้าใหม่ ให้แสดงข้อมูลที่บันทึกสำเร็จแล้วทันที

### Section C: Transaction Actions

องค์ประกอบ:

- ปุ่ม `ไปที่ Booking`
- ปุ่ม `ไปที่ Quick Service`
- ปุ่ม `ดูข้อมูลสมาชิก`

กติกา:

- ปุ่มจะแสดงตามสิทธิ์ของผู้ใช้
- ถ้ายังไม่มี `customer/car` ที่เลือกอยู่ ปุ่มทั้งหมด disabled

## 7. Screen States

### State 1: Initial

- แสดงเฉพาะ search panel
- summary และ action panel ยังไม่เปิด

### State 2: Searching

- ปิดปุ่มค้นหาชั่วคราว
- แสดงข้อความ `Searching...`

### State 3: No Match

- แสดงข้อความ `ไม่พบลูกค้า`
- เปิดฟอร์มลงทะเบียนลูกค้าใหม่
- action panel ยังไม่พร้อมใช้งานจนกว่าจะบันทึกสำเร็จ

### State 4: Single Match

- โหลดข้อมูลลูกค้าและรถอัตโนมัติ
- แสดง summary
- เปิด action panel

### State 5: Multiple Matches

- แสดงรายการที่พบ เช่น `ชื่อลูกค้า / เบอร์ / ทะเบียน / ยี่ห้อรุ่น`
- ให้พนักงานเลือก record ที่ต้องการ
- เมื่อเลือกแล้วเข้าสู่ state `Single Match`

### State 6: New Customer Saved

- บันทึก `customer` และ `car` สำเร็จ
- แสดง summary ของลูกค้าใหม่
- เปิด action panel

## 8. New Customer Registration Flow

```mermaid
flowchart LR
    A[Click New Customer] --> B[Enter customer and car fields]
    B --> C[Validate required fields]
    C -->|Invalid| D[Show validation error]
    C -->|Valid| E[Save customer and car]
    E --> F[Show saved summary]
    F --> G[Enable Booking / Quick Service / Member Info]
```

### Required Fields

- `customer_name`
- `plate_number`

### Recommended Required Fields

- `phone` สำหรับลูกค้าสมาชิก
- `province`

### Optional Fields

- `brand`
- `model`
- `color`
- `vehicle_type`

## 9. Destination Flow Rules

### 9.1 Booking

เมื่อกด `ไปที่ Booking`

- ส่งข้อมูลลูกค้าและรถไป `pages/booking.php`
- หน้า `booking.php` ต้อง prefill ข้อมูลลูกค้า/รถให้ทันที
- การสร้าง `order` และ `queue` เกิดตอนกดบันทึกใน flow `Booking` เท่านั้น

Expected behavior:

- ถ้าเป็นลูกค้าเดิม ใช้ record เดิม
- ถ้าเป็นลูกค้าใหม่ที่เพิ่งบันทึกจาก `Open Bill` ให้ prefill ข้อมูลทันที

### 9.2 Quick Service

เมื่อกด `ไปที่ Quick Service`

- ส่งข้อมูลลูกค้าและรถไป `pages/quick_service.php`
- หน้า `quick_service.php` ต้อง prefill customer/car context
- `Quick Service` ยังคงเป็นบิลหน้าร้านนอก `Queue`

Expected behavior:

- ไม่มีการสร้าง `queue`
- ยังรองรับ hold bill / payment / receipt แบบเดิม

### 9.3 Member Info

เมื่อกด `ดูข้อมูลสมาชิก`

- ส่งไป `pages/member.php`
- เปิด profile view ของลูกค้าที่เลือก
- ถ้ามีหลายคัน ควรส่ง `customer_id` และ `car_id` ไปด้วยเมื่อมีค่า

## 10. Data Model Decision

### 10.1 Phase 1: No New OpenBill Table

สำหรับ phase แรก ไม่ควรสร้างตาราง `OpenBill`

เหตุผล:

- ระบบมี `orders.order_source` รองรับปลายทางอยู่แล้ว
- หน้า `Open Bill` ยังไม่สร้าง transaction เอง
- การเพิ่มตารางใหม่จะเพิ่มภาระ migration โดยยังไม่ให้ business value เพิ่มทันที

### 10.2 Existing Tables Used

- `customers`
- `cars`
- `orders`
- `queue`

### 10.3 Note About Plate Uniqueness

ปัจจุบัน `cars.plate_number` ถูก unique ทั้งระบบ

ผลกระทบ:

- ถ้าธุรกิจต้องรองรับทะเบียนซ้ำต่างจังหวัดในอนาคต โครงสร้างนี้อาจไม่พอ
- phase นี้ยังคงใช้ behavior เดิมก่อน
- ถ้าจะรองรับ OCR จังหวัดจริงในอนาคต ควรพิจารณาแก้เป็น uniqueness แบบ `plate_number + province`

## 11. Reuse Strategy

### Reuse Existing Search

ใช้ของเดิม:

- `config/customer_lookup.php`
- `process/search_customer.php`

### Reuse Existing Booking Flow

ใช้ของเดิม:

- `pages/booking.php`
- `process/save_booking.php`

### Reuse Existing Quick Service Flow

ใช้ของเดิม:

- `pages/quick_service.php`
- `process/save_quick_service.php`

### Reuse Existing Member Profile Flow

ใช้ของเดิม:

- `pages/member.php`

## 12. Prefill Contract

เพื่อให้ `Open Bill` ใช้งานได้จริง จำเป็นต้องกำหนด contract สำหรับการส่งต่อข้อมูล

### Booking Prefill

ควรส่งต่อได้อย่างน้อย:

- `customer_name`
- `phone`
- `plate_number`
- `province`
- `vehicle_type`
- `brand`
- `model`
- `color`

รูปแบบที่ใช้ได้:

- query string
- session flash old input

### Quick Service Prefill

ควรเพิ่มการรองรับ prefill จาก `Open Bill` อย่างน้อย:

- `customer_id`
- `car_id`
- `customer_mode`
- `customer_name`
- `phone`
- `plate_number`
- `province`
- `brand`
- `model`
- `color`

หมายเหตุ:

- ปัจจุบัน `quick_service.php` รองรับ old input หลัง POST เป็นหลัก
- phase implementation ต้องเพิ่ม GET prefill หรือ POST bridge จาก `Open Bill`

### Member Prefill

ควรส่ง:

- `view=profile`
- `customer_id`
- `car_id` เมื่อมีค่า
- `q` เป็นเบอร์โทรหรือทะเบียน เพื่อให้ search state สอดคล้องกับ profile ที่เปิด

## 13. Permission Rules

### Access Rule for Open Bill Page

หน้า `Open Bill` ควรเข้าได้เมื่อผู้ใช้มีสิทธิ์อย่างน้อยหนึ่งข้อ:

- `booking`
- `quick_service`
- member area access

### Action Button Visibility

- แสดงปุ่ม `Booking` เมื่อมีสิทธิ์ `booking`
- แสดงปุ่ม `Quick Service` เมื่อมีสิทธิ์ `quick_service`
- แสดงปุ่ม `Member Info` เมื่อเข้า member area ได้

### Recommendation

phase แรกไม่จำเป็นต้องเพิ่ม permission key ใหม่ `open_bill`

เหตุผล:

- ลดงาน migration ของตำแหน่งและสิทธิ์
- ใช้ role เดิมควบคุมปลายทางได้ทันที

## 14. UX Rules

- ใช้คำอธิบายสั้นและชัดสำหรับพนักงานหน้าร้าน
- เน้นปุ่มใหญ่ กดง่ายบน tablet
- ถ้าค้นหาไม่พบ ต้องมีทางไปต่อได้ทันที ไม่ dead end
- ถ้าพบหลายรายการ ต้องช่วยให้แยกคันรถได้เร็ว
- summary ต้องอ่านเร็วกว่าเปิดหน้า `Member` เต็ม

ข้อความแนะนำ:

- `ค้นหาด้วยเบอร์โทรหรือทะเบียนรถ`
- `ไม่พบข้อมูลลูกค้า กรุณาลงทะเบียนลูกค้าใหม่`
- `พบหลายรายการ กรุณาเลือกข้อมูลที่ถูกต้อง`
- `ตรวจสอบข้อมูลลูกค้าและรถก่อนเลือกช่องทางทำรายการ`

## 15. Acceptance Criteria

### AC-01 Search Existing Customer

- เมื่อค้นหาด้วยเบอร์หรือทะเบียนที่มีในระบบ
- ระบบต้องแสดงลูกค้าและรถที่ตรงกัน
- และเปิดปุ่มปลายทางตามสิทธิ์ผู้ใช้

### AC-02 Search No Match

- เมื่อค้นหาด้วยข้อมูลที่ไม่พบ
- ระบบต้องเปิดฟอร์มลงทะเบียนลูกค้าใหม่
- และยังไม่เปิดปุ่มปลายทางจนกว่าจะบันทึกสำเร็จ

### AC-03 Multiple Matches

- เมื่อค้นหาแล้วพบหลายรายการ
- ระบบต้องแสดง list ให้ผู้ใช้เลือก
- และโหลด record ที่เลือกเข้า summary ได้

### AC-04 Open Booking

- เมื่อเลือกปลายทาง `Booking`
- ระบบต้องพาไปหน้า `booking.php`
- และ prefill ข้อมูลลูกค้า/รถได้ถูกต้อง

### AC-05 Open Quick Service

- เมื่อเลือกปลายทาง `Quick Service`
- ระบบต้องพาไปหน้า `quick_service.php`
- และ prefill ข้อมูลลูกค้า/รถได้ถูกต้อง
- และไม่มีการสร้าง `queue`

### AC-06 Open Member Info

- เมื่อเลือก `Member Info`
- ระบบต้องเปิด profile ของลูกค้าที่เลือกได้ถูกต้อง

## 16. Recommended Implementation Plan

### Phase 1A: Spec + Routing + UI Shell

- สร้าง `docs/open-bill-spec.md`
- สร้าง `pages/open_bill.php`
- เพิ่ม nav entry ไปหน้า `Open Bill`
- เพิ่ม safe page allowlist ถ้าจำเป็น

### Phase 1B: Search + Selection

- reuse `process/search_customer.php`
- แสดงผล `0 / 1 / many matches`
- สร้าง summary panel และ action panel

### Phase 1C: New Customer Save

- เพิ่ม process สำหรับบันทึกลูกค้า/รถจาก `Open Bill`
- หรือแยก helper กลางสำหรับ upsert customer/car แล้ว reuse ร่วมกับ `Booking`

### Phase 1D: Destination Prefill

- ทำ booking prefill ให้ชัดเจน
- เพิ่ม quick service prefill contract
- ใช้ member profile route ที่มีอยู่แล้ว

### Phase 2: AI / OCR

- เพิ่ม upload image
- เพิ่ม OCR plate
- เพิ่ม AI detection brand/model/color
- เพิ่ม field รูปใน schema

## 17. Technical Task Checklist

- [ ] สร้าง `pages/open_bill.php`
- [ ] เพิ่ม helper เช็กสิทธิ์เข้า `Open Bill`
- [ ] เพิ่ม navigation link สำหรับ `Open Bill`
- [ ] เชื่อม AJAX search กับ `process/search_customer.php`
- [ ] สร้าง UI สำหรับ multiple match selection
- [ ] สร้าง summary card ลูกค้า/รถ
- [ ] สร้าง action card สำหรับ `Booking / Quick Service / Member Info`
- [ ] สร้าง flow ลงทะเบียนลูกค้าใหม่
- [ ] แยก helper บันทึก `customer/car` หรือสร้าง process ใหม่
- [ ] เพิ่ม booking prefill contract จาก `Open Bill`
- [ ] เพิ่ม quick service prefill contract จาก `Open Bill`
- [ ] ทดสอบ member profile handoff
- [ ] เพิ่ม smoke test สำหรับ `Open Bill`

## 18. Risks / Open Questions

### Risk 1: Plate Uniqueness

หากมีข้อมูลทะเบียนซ้ำต่างจังหวัดในอนาคต flow นี้อาจเลือก record ผิดได้ เพราะ schema ปัจจุบัน unique แค่ `plate_number`

### Risk 2: Duplicate Customer Registration

ถ้าค้นหาไม่พบเพราะกรอกเบอร์หรือทะเบียนไม่ตรง format อาจเกิดการลงทะเบียนซ้ำได้ จึงควรใช้ normalize และ feedback ที่ชัดเจน

### Risk 3: Quick Service Prefill Gap

`quick_service.php` ยังไม่ได้ออกแบบสำหรับรับ context มาจาก `Open Bill` ผ่าน GET โดยตรง จึงต้องเติมส่วนนี้ใน implementation

### Open Question

- ต้องการให้ `Open Bill` รองรับ guest flow โดยตรงหรือไม่
- ต้องการให้ `Open Bill` เป็นหน้าเริ่มต้นหลักแทน `booking.php` สำหรับบาง role หรือไม่
- ต้องการแสดงประวัติล่าสุดกี่รายการใน summary panel

## 19. Recommended Next Step

ลำดับการพัฒนาที่แนะนำ:

1. ทำ `pages/open_bill.php` เป็น UI shell และ search flow ก่อน
2. ทำ handoff ไป `Booking`, `Quick Service`, `Member Info`
3. ค่อยเพิ่ม new customer save
4. ค่อยเพิ่ม AI / OCR ใน phase ถัดไป
