โจทย์: ร้านยาหลายสาขา แต่ละสาขาออกบิลเอง + มีใบอนุญาตแยก ต้องการทำ same-day โดยไม่ให้สินค้าชนิดเดียวกันซ้ำหลายใบ และต้องขายผ่าน LINE ได้ด้วย — เอกสารนี้เสนอโมเดลข้อมูล + user journey ที่ smooth ที่สุด
ปัญหาเดิม: 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 Product | catalog ที่ลูกค้าเห็น/ค้นหา | 1 ต่อ SKU | build ใหม่ |
| Branch Offer / Stock | สต๊อก+ราคาต่อสาขา (sync NAV per-location) | N (ต่อสาขา) | build (location-stock layer) |
| Seller = สาขา | ใบอนุญาต + เภสัชกร + ออกบิล/payout | N (ต่อสาขา) | reuse multi-vendor เดิม |
| Order → sub-order/สาขา | บิลแยกต่อสาขา (CombinedOrder) | ตามการ route | reuse เดิม |
หัวใจกันสับสน: ถามที่อยู่ก่อน แล้วให้ 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"]
เน้นจุดที่ต่างจากออเดอร์ปกติ: 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
| ส่วน | สถานะ | หมายเหตุ |
|---|---|---|
| Multi-vendor: บิลแยก/payout ต่อสาขา | Reuse | CombinedOrder, SellerPayout มีอยู่แล้ว |
| ไรเดอร์ในบ้าน + แอปไรเดอร์ | Reuse | Delivery Boy module + assign + COD |
| Catalog, cart, checkout, ChillPay, เภสัชกร workflow | Reuse | ใช้ engine เดิมทั้งหมด |
| Catalog unification (ยุบ offer → การ์ดเดียว) | Build | งานหลัก แก้เฉพาะหน้าร้าน + ชั้น master product |
| Location stock ต่อสาขา (จาก NAV) | Build | CMS เดิมเก็บสต๊อกต่อสินค้า ไม่ใช่ต่อสาขา |
| Routing engine (พิกัด+สต๊อก+cut-off → เลือกสาขา) | Build | แทน "ลูกค้าเลือก seller เอง" |
| Same-day delivery (slot/tracking/courier) | Build | ตามที่คุยไว้ก่อนหน้า |
| Cart split ข้ามสาขา (ผสม ด่วน+ปกติ) | Build | ต่อยอด CombinedOrder |
| สาขา = seller (customer เลือกเอง) | เลิกใช้ | สาเหตุของ SKU ซ้ำ — เปลี่ยนเป็น auto-route |