PMaxx · Phase 1 · Frontend

Same-day Phase 1 — เลือกสาขาตามพิกัด

Phase 1 เน้นหน้าบ้าน: ลูกค้าเลือกสาขาตามพิกัดก่อน → ช้อปทีละสาขา (สินค้าไม่ซ้ำโดยธรรมชาติ) → order เข้าสาขาโดยตรง → เภสัชกรจัดยา เรียกรถเอง และอัปเดตสถานะด้วยมือ (ยังไม่ต่อ API ขนส่ง / ยังไม่ sync NAV). เน้นจุด fallback ให้ครบเพื่อไม่ให้เกิดทางตัน

📍 เลือกสาขาตามพิกัด 🗂️ สินค้าใบเดียว (ดูทีละสาขา) 🛵 เรียกรถเอง + อัปเดตสถานะมือ 💬 LINE OA เดียว
💡
ทำไม Phase 1 ถึงเบา: การให้ลูกค้าเลือกสาขาก่อนแล้วช้อป "ทีละสาขา" ทำให้เห็นสินค้าใบเดียวโดยธรรมชาติ — ไม่ต้อง build master-product aggregation. ใช้ multi-vendor เดิม + เพิ่มแค่ "ประตูเลือกสาขาตามพิกัด" กับ "สถานะส่งแบบ manual"

1 · Config: Seller = สาขา

เพิ่ม field ในโปรไฟล์ seller เพื่อให้ระบบรู้ว่าเป็นสาขา + คำนวณพื้นที่ให้บริการได้

Fieldตัวอย่างใช้ทำอะไร
is_branchtrueระบุว่า seller นี้เป็นสาขา
same_day_enabledtrueสาขานี้เปิด same-day ไหม
lat / lng13.7563 / 100.5018พิกัดสาขา (คำนวณระยะ haversine)
service_radius_km5รัศมีที่ส่ง same-day ถึง
cutoff_time18:00สั่งหลังนี้ = จัดส่งวันถัดไป
open_hours09:00–20:00เวลาเปิด-ปิดสาขา

2 · User Journey (fallback ครบทุกจุด)

โหนดสีที่แตกออก = fallback กันทางตัน: ไม่มีสาขาในพื้นที่, นอกเวลา/เลย cut-off, และสินค้าหมด

flowchart TB
  A["เข้าร้าน (เว็บ / LINE LIFF)"] --> B["ระบุที่อยู่จัดส่ง → geocode เป็น lat/lng
(LINE: ใช้ share location ได้)"] B --> C{"มีสาขา same-day
ในรัศมีไหม?"} C -->|ไม่มี| F1["🔻 fallback: เสนอ 'ส่งปกติ' จาก center
หรือแจ้ง 'พื้นที่นี้ยังไม่มี same-day'"] C -->|มี| D{"อยู่ในเวลาเปิด
+ ก่อน cut-off?"} D -->|ไม่| F2["🔻 fallback: 'สั่งได้พรุ่งนี้'
หรือ สลับเป็นส่งปกติ"] D -->|ใช่| E{"เจอกี่สาขา?"} E -->|1 สาขา| G["เข้า catalog สาขานั้น"] E -->|หลายสาขา| H["เลือกสาขา (default = ใกล้สุด)
+ ปุ่มเปลี่ยนสาขา"] H --> G G --> I["ช้อปใน catalog สาขา
(สินค้าใบเดียว = stock สาขานั้น)"] I --> J{"มีสินค้าที่ต้องใบสั่ง?"} J -->|ใช่| K["อัปโหลดใบสั่ง → เภสัชกรตรวจ"] J -->|ไม่| L["ไป checkout"] K --> L L --> M{"ของยังมี stock?"} M -->|หมด| F3["🔻 fallback: แจ้ง 'สินค้าหมด'
เอาออก / เลือกใหม่"] M -->|มี| N["จ่าย ChillPay (prepaid)"] N --> O["order เข้าสาขาโดยตรง"] O --> P["ติดตามสถานะทาง LINE"]
⚠️
3 จุด fallback ที่ห้ามลืม: (1) นอกรัศมี → ส่งปกติ/center · (2) นอกเวลา/เลย cut-off → นัดพรุ่งนี้ · (3) ของหมด → เลือกใหม่. ทุกจุดต้องมีทางไปต่อ ไม่ปล่อยหน้าจอตัน

3 · Swimlane — Phase 1 (เรียกรถเอง)

เน้นว่าใครทำอะไร: Branch Selector ล็อกสาขา → สาขา(seller)รับออเดอร์ใน POS → เภสัชกรจัดยา เรียกรถเอง และอัปเดตสถานะด้วยมือ ซึ่งยิงแจ้งเตือนกลับ LINE

flowchart LR
  subgraph C["🧑 ลูกค้า"]
    c1["ที่อยู่ + เลือกสินค้า"]
    c2["จ่ายเงิน (prepaid)"]
    c9["รับยา
เห็นสถานะทาง LINE"] end subgraph S["🛒 Storefront / LINE"] s1["เลือกสาขาตามพิกัด"] s2["catalog สาขา + checkout"] end subgraph R["📍 Branch Selector (build)"] r1{"ในรัศมี + เปิด
+ ใน cut-off?"} r2["ล็อกสาขา = seller"] r3["🔻 fallback:
center/ส่งปกติ หรือ นัดพรุ่งนี้"] end subgraph B["💊 สาขา / เภสัชกร (POS)"] b1["รับออเดอร์"] b2["ตรวจใบสั่ง (ถ้ามี) + จัดยา"] b3["อัปเดตสถานะเอง
+ กรอกชื่อ/เบอร์คนขับ"] b4["ปิดงาน: แนบรูป/OTP"] end subgraph D["🛵 คนขับ (เรียกเอง)"] d1["ส่งถึงบ้าน"] end c1 --> s1 --> r1 r1 -->|ได้| r2 --> s2 r1 -->|ไม่ได้| r3 --> s2 c2 --> s2 s2 --> b1 --> b2 --> b3 --> d1 --> b4 b3 -. แจ้งเตือน .-> c9 b4 -. ส่งสำเร็จ .-> c9

4 · สถานะจัดส่ง (manual — ไม่มี API ขนส่ง)

เภสัชกรเลื่อนสถานะเองในหน้า order/POS ทุกครั้งที่เปลี่ยน → ยิงแจ้งเตือน LINE ให้ลูกค้าอัตโนมัติ (Phase 1 ยังไม่มีแผนที่ real-time — ข้อความสถานะพอ)

flowchart LR
  S0["🆕 รับออเดอร์
(จ่ายแล้ว)"] --> S1["💊 กำลังจัดยา"] S1 --> S2["🛵 กำลังจัดส่ง
(กรอกชื่อ/เบอร์คนขับ)"] S2 --> S3["✅ ส่งสำเร็จ
(แนบรูป / OTP)"] S0 -. ปัญหา .-> SX["❌ ยกเลิก / คืนเงิน"] S1 -. ปัญหา .-> SX
🔔
ทุกการเปลี่ยนสถานะ → แจ้ง LINE: "ร้านรับออเดอร์แล้ว" → "กำลังจัดยา" → "กำลังจัดส่ง (คนขับ: คุณ… เบอร์…)" → "ส่งสำเร็จ". การแนบรูป/OTP ตอนส่งสำเร็จสำคัญมากกับธุรกิจยา

5 · Reuse vs Build (Phase 1)

ส่วนสถานะหมายเหตุ
Multi-vendor seller + order เข้า sellerReuseของเดิมมีอยู่แล้ว
Catalog / cart / checkout / ChillPayReuseใช้ engine เดิม
POS + order status + LINE notify + rx-flagReusePos controller มีอยู่
Config fields บน seller (lat/lng/radius/cutoff/same_day)Buildงานเล็ก
หน้าเลือกสาขาตามพิกัด (geocode + haversine + list + fallback)Buildงานหลัก Phase 1
Gate: ล็อกสาขาก่อนเข้า catalog (scope = สาขาที่เลือก)Buildทำให้สินค้าไม่ซ้ำ
สถานะจัดส่ง manual + กรอกคนขับ + แนบหลักฐาน → LINEBuildไม่ต่อ API ขนส่ง
Product master กลางให้สาขา importBuild (แนะนำ)กัน data entry ซ้ำ 15 สาขา
NAV sync / master aggregation / courier API / live GPS / cart splitPhase 2+เลื่อนออกไป
สาขา = seller (ลูกค้าเลือกเอง จากทั้งหมด)เลิกใช้สาเหตุ SKU ซ้ำ — แทนด้วยเลือกตามพิกัด
⚠️
จุดต้องคิดให้ดีที่สุด: (1) fallback เมื่อไม่มีสาขาในพื้นที่ — กันทางตัน · (2) product master กลาง — กัน data entry ระเบิดเมื่อมีหลายสาขา · (3) ผูก location กับที่อยู่จัดส่ง ไม่ใช่ GPS ดิบ