PMaxx · Architecture & UX

Same-day ร้านยาหลายสาขา — บนเอนจินเดิม

โจทย์: ร้านยาหลายสาขา แต่ละสาขาออกบิลเอง + มีใบอนุญาตแยก ต้องการทำ same-day โดยไม่ให้สินค้าชนิดเดียวกันซ้ำหลายใบ และต้องขายผ่าน LINE ได้ด้วย — เอกสารนี้เสนอโมเดลข้อมูล + user journey ที่ smooth ที่สุด

🏥 หลายสาขา = seller แยก (บิล/ใบอนุญาต) 🗂️ Catalog รวมใบเดียว ⚡ Same-day + 📦 ส่งปกติ 💬 LINE (OA เดียว)
💡
แนวคิดหลัก: แยก 3 ชั้นที่ตอนนี้พันกัน — Catalog (ลูกค้าเห็น = ใบเดียว) · Branch Offer/Stock (สต๊อกต่อสาขา จาก NAV) · Seller/สาขา (ใบอนุญาต+ออกบิล). ลูกค้าเห็น catalog เดียว ระบบเลือกสาขา/ผู้ขายให้เบื้องหลัง — เอนจิน multi-vendor เดิม (CombinedOrder / SellerPayout) reuse สำหรับ "บิลแยกต่อสาขา" ได้พอดี

1 · โมเดลข้อมูล — ทำไมสินค้าถึงไม่ซ้ำ

ปัญหาเดิม: 1 สาขา = 1 seller = re-list สินค้าใหม่ → SKU ซ้ำ N ใบ. วิธีแก้: แยก Master Product (การ์ดที่ลูกค้าเห็น มีใบเดียว) ออกจาก Branch Offer (สต๊อก+ราคาต่อสาขา ซ่อนไว้). หน้าร้าน "ยุบ" ทุก offer ของ SKU เดียวกันให้เหลือการ์ดเดียว

flowchart TB
  subgraph SEE["🧑 สิ่งที่ลูกค้าเห็น (หน้าร้าน)"]
    MP["🗂️ Master Product: พารา 500mg
(การ์ดเดียว · เลขทะเบียนยา · flag ยาต้องใบสั่ง)
ป้าย: ⚡ ส่งวันนี้ / 📦 ส่งปกติ"] end subgraph HID["⚙️ สิ่งที่ระบบเก็บเบื้องหลัง (ซ่อน)"] O1["Branch Offer — สาขาสีลม
stock 40 · ราคา 12฿"] O2["Branch Offer — สาขาลาดพร้าว
stock 8 · ราคา 12฿"] O3["Branch Offer — center/คลัง
stock 900 · ส่งทั่วประเทศ"] end subgraph SELL["🏥 Seller = สาขา (นิติบุคคลแยก)"] B1["สาขาสีลม
ใบอนุญาต ขย. + เภสัชกร + ออกบิลเอง"] B2["สาขาลาดพร้าว
ใบอนุญาต ขย. + เภสัชกร + ออกบิลเอง"] B3["center / คลังกลาง"] end MP -->|"aggregate (ยุบให้เหลือใบเดียว)"| O1 MP --> O2 MP --> O3 O1 --- B1 O2 --- B2 O3 --- B3
Entityบทบาทมีกี่ชุดสถานะ
Master Productcatalog ที่ลูกค้าเห็น/ค้นหา1 ต่อ SKUbuild ใหม่
Branch Offer / Stockสต๊อก+ราคาต่อสาขา (sync NAV per-location)N (ต่อสาขา)build (location-stock layer)
Seller = สาขาใบอนุญาต + เภสัชกร + ออกบิล/payoutN (ต่อสาขา)reuse multi-vendor เดิม
Order → sub-order/สาขาบิลแยกต่อสาขา (CombinedOrder)ตามการ routereuse เดิม

2 · User Journey — location-first (กันสับสน)

หัวใจกันสับสน: ถามที่อยู่ก่อน แล้วให้ same-day availability เป็น ป้ายบนสินค้า ไม่ใช่แยกเป็นคนละร้าน. ลูกค้าไม่ต้องเลือกสาขา — ระบบเลือกให้. ใช้ flow เดียวกันทั้งเว็บและ LINE LIFF (OA เดียว)

flowchart TB
  A["เข้าร้าน
(เว็บ / LINE LIFF · OA เดียว)"] --> B["ระบุ/ยืนยันที่อยู่จัดส่ง
(หรือ detect · จำไว้)"] B --> C{"มีสาขา same-day
ถึงที่อยู่นี้ไหม?"} C -->|มี| D["Catalog เดียว
สินค้ามีป้าย ⚡ ส่งวันนี้ / 📦 ส่งปกติ"] C -->|ไม่มี| E["Catalog เดียว (โหมดส่งปกติ)
fulfill จาก center/คลัง"] D --> F["ลูกค้าหยิบใส่ตะกร้า
(อ้าง Master Product ไม่ใช่สาขา)"] E --> F F --> G{"ตะกร้าผสม?
(บางชิ้น same-day ไม่ได้)"} G -->|ไม่| H["Checkout"] G -->|ใช่| I["เสนอทางเลือก:
แยกส่ง (ด่วน+ปกติ) หรือ ส่งปกติทั้งหมด"] I --> H H --> J["ระบบ route อัตโนมัติ
→ สาขาใกล้+มีของ (same-day)
→ center (ปกติ)"] J --> K["จ่าย ChillPay"] K --> L["สาขา(seller) ออกบิลของตัวเอง
เภสัชกรตรวจ/แพ็ก"] L --> M["⚡ ไรเดอร์ same-day / 📦 Shippop"] M --> N["แจ้งเตือน + tracking ทาง LINE"]
⚠️
ไอเดีย "เลือกโหมดก่อน" ของคุณใช้ได้ — แต่ให้แยกแค่ ประสบการณ์ ไม่ใช่ catalog. ถ้าเลือก same-day ให้ถามที่อยู่ทันที ถ้าพื้นที่ไม่รองรับให้สลับเป็นส่งปกติแบบเนียน อย่าปล่อยทางตัน. เหตุที่แนะนำ location-first เพราะ same-day availability ขึ้นกับที่อยู่โดยธรรมชาติ

3 · Swimlane — Same-day หลายสาขา (บิลแยก)

เน้นจุดที่ต่างจากออเดอร์ปกติ: Routing Engine เลือกสาขาที่ fulfill (ตามพิกัด+สต๊อก+cut-off) → สาขานั้นกลายเป็น seller ที่ออกบิลของตัวเอง → ส่งด้วยไรเดอร์ same-day

flowchart LR
  subgraph C["🧑 ลูกค้า"]
    c1["เลือกสินค้า
+ ที่อยู่"] c2["ชำระเงิน"] c9["รับของ + บิลสาขา
+ tracking (LINE)"] end subgraph S["🛒 Storefront / LINE"] s1["Master Product
+ ป้าย ⚡"] s2["Checkout"] end subgraph R["🧭 Routing Engine (build ใหม่)"] r1{"สาขาใกล้+มีของ
+ ใน cut-off?"} r2["assign สาขา = seller"] r3["fallback: center
หรือ ส่งปกติ"] end subgraph B["🏥 สาขา (Seller)"] b1["ออกบิล/ใบกำกับ
ของสาขา"] b2["เภสัชกรตรวจ/แพ็ก"] end subgraph D["🛵 จัดส่ง same-day"] d1["ไรเดอร์ (Delivery Boy เดิม)
หรือ Lalamove/Grab"] end c1 --> s1 --> s2 c2 --> s2 s2 --> r1 r1 -->|ได้| r2 --> b1 --> b2 --> d1 --> c9 r1 -->|ไม่ได้| r3 --> c9

4 · Reuse vs Build — ต้องพัฒนาเพิ่มแค่ไหน

ส่วนสถานะหมายเหตุ
Multi-vendor: บิลแยก/payout ต่อสาขาReuseCombinedOrder, SellerPayout มีอยู่แล้ว
ไรเดอร์ในบ้าน + แอปไรเดอร์ReuseDelivery Boy module + assign + COD
Catalog, cart, checkout, ChillPay, เภสัชกร workflowReuseใช้ engine เดิมทั้งหมด
Catalog unification (ยุบ offer → การ์ดเดียว)Buildงานหลัก แก้เฉพาะหน้าร้าน + ชั้น master product
Location stock ต่อสาขา (จาก NAV)BuildCMS เดิมเก็บสต๊อกต่อสินค้า ไม่ใช่ต่อสาขา
Routing engine (พิกัด+สต๊อก+cut-off → เลือกสาขา)Buildแทน "ลูกค้าเลือก seller เอง"
Same-day delivery (slot/tracking/courier)Buildตามที่คุยไว้ก่อนหน้า
Cart split ข้ามสาขา (ผสม ด่วน+ปกติ)Buildต่อยอด CombinedOrder
สาขา = seller (customer เลือกเอง)เลิกใช้สาเหตุของ SKU ซ้ำ — เปลี่ยนเป็น auto-route
สรุป: ไม่ใช่การรื้อสร้างใหม่ — หลังบ้าน (บิลแยก/ไรเดอร์/checkout) reuse ได้ งาน build จริงคือ catalog unification + location stock + routing ซึ่งเป็นชั้นที่ชัดเจน คุมได้. ความเสี่ยงหลักอยู่ที่ความถูกต้องของ สต๊อกต่อสาขาจาก NAV และ reconciliation บิลแยกต่อสาขา