แคตาล็อกสินค้าพร้อมตัวเลือกและชุดสินค้า: สคีมาและรูปแบบ UI
ออกแบบแคตาล็อกสินค้าพร้อมตัวเลือกและชุดสินค้า โดยมีกฎ SKU ชัดเจน ตรรกะสต็อก และรูปแบบ UI ที่ป้องกันการเลือกผิดพลาดและการขายเกินสต็อก

ทำไมตัวเลือกและบันเดิลถึงยุ่งได้เร็ว
แคตาล็อกดูเรียบง่ายเมื่อสินค้าทุกชิ้นเป็นไอเท็มเดียวที่มีราคาเดียวและจำนวนสต็อกเดียว แต่พอเพิ่มสี ขนาด ระยะเวลาสมาชิก หรือบรรจุภัณฑ์ตามภูมิภาค ความเรียบง่ายนั้นก็พังลง ตาราง “Products” เดียวไม่สามารถตอบคำถามพื้นฐานได้อีกต่อไป: สิ่งที่เราขายกันแน่ และเราจะติดตามมันอย่างไร?
ผู้ซื้อก็คาดหวังว่ารายละเอียดต้องถูกต้อง พวกเขาต้องการเลือกตัวเลือก เห็นราคาทันที และรู้ว่าสิ่งที่เลือกส่งได้วันนี้ไหม ถ้าหน้าบอก “มีสินค้า” แต่ขนาดที่เลือกหมด ความเชื่อมั่นจะลดเร็วมาก ถ้าราคาเปลี่ยนแปลงตอนชำระเงินเท่านั้น ตั๋วซัพพอร์ตและการคืนสินค้าจะตามมา
บันเดิลเพิ่มความซับซ้อนอีกชั้น เพราะมันดูเหมือนสินค้าแต่ทำงานเหมือนกฎ “ชุดเริ่มต้น” อาจรวมขวดหนึ่ง ปั๊มหนึ่ง และชุดไส้กรอง ความพร้อมของมันขึ้นกับชิ้นส่วน และต้นทุนกับการรายงานยังต้องสมเหตุสมผล
สัญญาณที่บอกว่าแคตาล็อกเริ่มมีปัญหา:
- คุณสร้าง SKU ซ้ำเพื่อแทนตัวเลือก
- ยอดสต็อกรู้สึกผิดพลาด โดยเฉพาะหลังการขายบันเดิล
- หน้าจอแอดมินกลายเป็นรายการยาวของไอเท็มที่คล้ายกัน
- ส่วนลดและภาษีทำงานกับไอเท็มเดี่ยวแต่พังกับชุด
- รายงานตอบไม่ได้ว่า "จริงๆ ขายอะไรไปบ้าง"
การแก้คือวินัยมากกว่าความเฉลียว: แบบจำลองข้อมูลที่คงที่ และรูปแบบ UI ที่ทำให้การเลือกตัวเลือกและการแสดงความพร้อมชัดเจนทั้งสำหรับลูกค้าและทีมของคุณ
คำศัพท์แบบง่าย: ตัวเลือก, รุ่นสินค้า, SKU, บันเดิล
เมื่อคนพูดถึง “variants” มักจะสับสนกับแนวคิดหลายอย่าง การนิยามคำให้ชัดตั้งแต่ต้นจะทำให้การตัดสินใจ (สคีมา, UI, สต็อก) ง่ายขึ้นมาก
ทีมส่วนใหญ่ใช้คำนิยามเหล่านี้:
- Option (ตัวเลือก): การเลือกที่ผู้ซื้อทำ เช่น ขนาดหรือสี
- Option value (ค่าตัวเลือก): หนึ่งค่าภายในตัวเลือก เช่น ขนาด = M หรือ สี = ดำ
- Variant (รุ่นสินค้า): การผสมค่าตัวเลือกที่แน่นอน เช่น ขนาด M + สีดำ
- SKU: หน่วยที่ขายได้ที่คุณติดตามในงานปฏิบัติการและสต็อก รุ่นหนึ่งมักแมปกับ SKU หนึ่ง แต่มิใช่เสมอไป
- Bundle / kit / multipack: สินค้าที่ประกอบด้วยสินค้าชิ้นอื่น Bundle เป็นกลุ่มการตลาด (ส่วนประกอบสามารถขายแยกได้) Kit เป็นชุดที่ต้องส่งพร้อมกัน Multipack เป็นการซ้ำไอเท็มเดียวกัน (เช่น ถุงเท้า 3 ชิ้น)
ID ก็สับสนได้ในทางปฏิบัติ internal ID คือที่ฐานข้อมูลใช้ SKU คือรหัสปฏิบัติการ (ใช้ในการหยิบสินค้ากำหนดสต็อก และรายงาน) barcode (UPC/EAN) คือสิ่งที่เครื่องสแกนอ่านได้ หนึ่ง SKU อาจมีหลายบาร์โค้ด (แต่ละภูมิภาค) และบางชิ้นอาจไม่มีบาร์โค้ดเลย
กฎง่ายๆ ในการตัดสินใจว่าสิ่งใดควรเป็นรุ่นที่ขายได้: ถ้ามันมีราคา สต็อก น้ำหนัก หรือกฎการจัดส่งต่างไป ให้จัดเป็นรุ่นที่ขายได้ ตัวอย่าง เสื้อยืดเดียวกันไซส์ M และ XL มักต้องมีการนับสต็อกแยก ดังนั้นควรเป็น SKU แยกกัน
ตัดสินใจว่าแคตาล็อกของคุณต้องรองรับอะไร
ก่อนเลือกสคีมา ให้เริ่มจากคำถามที่ธุรกิจต้องตอบทุกวัน เมื่อใครสักคนดูไอเท็ม คุณสามารถตอบอย่างมั่นใจไหม: ว่ามีสินค้าพร้อมไหม ราคาเท่าไร จะส่งอย่างไร และกฎภาษีใช้ยังไง
วิธีคิดที่ใช้ได้คือการตัดสินใจว่าแต่ละ “ข้อเท็จจริง” อยู่ที่ไหน วางข้อเท็จจริงที่ใช้ร่วมกันบนระดับสินค้า และวางข้อเท็จจริงที่เปลี่ยนแปลงบนรุ่น (variant) ถ้าคุณผสมกัน คุณจะต้องแก้บั๊กเดียวกันสองที่
คำถามที่มักตัดสินฟิลด์ระดับสินค้า vs ระดับรุ่น:
- ถ้ามันเปลี่ยนตามขนาด/สี/วัสดุ ให้เก็บไว้ที่รุ่น
- ถ้ามันเป็นจริงสำหรับทุกการผสมค่า ให้เก็บที่สินค้า
- ถ้าคุณรายงานต่อ SKU (ยอดขาย กำไร การคืน) ให้เก็บที่รุ่น
- ถ้าการดำเนินงานใช้มันเพื่อหยิบ/แพ็ค/จัดส่ง ให้เก็บที่ SKU
- ถ้ามันสามารถสกัดได้อย่างปลอดภัย (เช่น ชื่อแสดงจากค่าตัวเลือก) ให้สกัดและเก็บแหล่งที่มาที่เดียว
เก็บแหล่งข้อมูลจริงไว้ที่เดียว ตัวอย่างเช่น ห้ามเก็บ “ราคา” ทั้งที่สินค้าและรุ่นยกเว้นบทบาทชัดเจน (เช่น สินค้ามี MSRP, รุ่นมีราคาขายจริง)
วางแผนสำหรับการเปลี่ยนแปลง คุณอาจเพิ่มตัวเลือกใหม่ในภายหลัง (เช่น “ความยาว”), ปิดรุ่นหนึ่ง หรือรวม SKU หลังการเปลี่ยนซัพพลายเออร์ ทุกอย่างจะราบรื่นขึ้นเมื่อรุ่นเป็นเรคคอร์ดชั้นหนึ่ง ไม่ใช่แค่ป้ายกำกับ
ถ้าคุณสร้างใน AppMaster การตั้งชื่อตารางให้ชัดเจนใน Data Designer จะช่วยให้การบำรุงรักษาง่ายขึ้นเมื่อความต้องการเปลี่ยน
สคีมาที่ใช้ได้จริงสำหรับสินค้าและรุ่น
สคีมาที่สะอาดจะทำให้แคตาล็อกเข้าใจได้เมื่อสินค้าง่าย ๆ กลายเป็นหลายสิบตัวเลือกที่ขายได้ เป้าหมายคือแยกการเลือก (สิ่งที่ผู้ซื้อเลือก) ออกจากไอเท็มที่ขายได้จริง (สิ่งที่คุณสต็อกและส่ง)
ชุดเอนทิตี้ที่เชื่อถือได้:
- Product: ไอเท็มหลัก (ชื่อ คำอธิบาย ยี่ห้อ หมวดภาพเริ่มต้น)
- Option: ประเภทการเลือก (Size, Color)
- OptionValue: ค่าที่อนุญาต (Small, Medium, Red, Blue)
- Variant: หน่วยที่ขายได้ (การผสมค่าหนึ่งชุด)
- VariantOptionValue: ตารางเชื่อมที่เชื่อม Variant กับ OptionValues ที่เลือก
ความเป็นเอกลักษณ์ของรุ่นเป็นจุดที่หลายแคตาล็อกพัง วิธีที่ปลอดภัยที่สุดคือ normalization: บังคับให้มี OptionValue หนึ่งค่า ต่อ Option สำหรับแต่ละ Variant และป้องกันการผสมซ้ำ ถ้าคุณอยากได้ความเร็วด้วย ให้เก็บ “variant key” ที่คำนวณไว้ เช่น color=red|size=m (หรือแฮชของมัน) บน Variant และบังคับให้ unique ต่อ Product
เก็บฟิลด์ที่เปลี่ยนตามการผสมไว้ที่ Variant ไม่ใช่ Product: SKU, barcode, ราคา, ราคาก่อนลด, ต้นทุน, น้ำหนัก, ขนาด, สถานะ (active/discontinued), และรูปภาพ (ภาพหลักหนึ่งภาพหรือชุดภาพเล็ก)
สำหรับแอตทริบิวต์พิเศษ (เช่น “วัสดุ” หรือ “คำแนะนำการดูแล”) หลีกเลี่ยงการเพิ่มคอลัมน์ใหม่เรื่อย ๆ ฟิลด์ JSONB บน Product หรือ Variant ทำงานได้ดีใน PostgreSQL คู่กับเลเยอร์การตรวจสอบเล็ก ๆ ในแอปของคุณ
กฎ SKU ที่คงทนเมื่อเวลาผ่านไป
SKU คือไอดีของหน่วยที่ขายได้ที่คุณสัญญาว่าจะคงที่ ควรตอบคำถามเดียว: “ไอเท็มชิ้นไหนที่เราขายไป?” มันไม่ควรพยายามบรรจุชื่อการตลาด ข้อความตัวเลือกทั้งหมด ฤดูกาล หรือเรื่องราวทั้งมวล หากคุณใส่ความหมายมากเกินไป มันจะยากที่จะเปลี่ยนเมื่อเวลาผ่านไปโดยไม่ทำให้รายงานพัง
ตัดสินแต่เนิ่น ๆ ว่าจะให้ SKU กำหนดโดยคนหรือสร้างอัตโนมัติ SKU แบบแมนนวลปลอดภัยกว่าเมื่อคุณมี ERP บาร์โค้ด หรือ SKU ผู้ส่งที่ต้องตรงกัน SKU ที่สร้างอัตโนมัติปลอดภัยกว่าเมื่อคุณมีรุ่นจำนวนมากและต้องการความสม่ำเสมอ แต่ต้องแน่ใจว่ากฎจะไม่เปลี่ยนกลางปี ทางเลือกกลาง ๆ คือมี base SKU คงที่ที่คุณควบคุม แล้วต่อด้วยซัฟฟิกสั้น ๆ ที่สร้างอัตโนมัติสำหรับแอตทริบิวต์รุ่น
กฎที่อ่านง่ายและอยู่รอดการเติบโต:
- ให้ SKU คงที่หลังจากมีคำสั่งแล้ว ห้ามแก้ไข SKU เก่าโดยการเปลี่ยนชื่อ
- แยก internal ID ออกจาก SKU ใช้ SKU สำหรับคน ID สำหรับฐานข้อมูล
- ใช้พรีฟิกสั้น ๆ สำหรับตระกูลสินค้า (เช่น TSH, MUG) ไม่ใช่คำเต็ม
- หลีกเลี่ยงความหมายที่เปลี่ยนได้ (เช่น “2026” หรือ “SUMMER”) เว้นแต่ว่าธุรกิจของคุณใช้แบบนั้นจริง
SKU ที่เลิกใช้ไม่ควรถูกลบ ทำเครื่องหมายเป็น inactive เก็บประวัติราคา และยังให้เลือกดูได้ในคำสั่งเก่า การคืนเงิน และรายงาน ถ้าคุณแทนที่ SKU ให้เก็บการอ้างอิง "replaced by" เพื่อให้ซัพพอร์ตตามรอยได้
กฎการตรวจสอบป้องกันการพังช้า ๆ เมื่อเวลาผ่านไป: บังคับความเป็นเอกลักษณ์ของ SKU ข้ามไอเท็มที่ขายได้ทั้งหมด อนุญาตเฉพาะตัวอักษร ตัวเลข และขีดกลาง กำหนดความยาวสูงสุดชัดเจน (บ่อยครั้ง 20-32 ตัวอักษร) และสงวนพรีฟิกสำหรับกรณีพิเศษ (เช่น “BND-” สำหรับบันเดิล)
ใน AppMaster การตรวจสอบเหล่านี้ใส่ได้ทั้งเป็นข้อจำกัดข้อมูลและ Business Process ที่บล็อกการบันทึกเมื่อกฎถูกละเมิด
ตรรกะสต็อกที่เกินกว่าแค่มี/ไม่มี
สต็อกซับซ้อนเมื่อตัว “สินค้าเดียว” อาจหมายถึงหลายหน่วยที่ขายได้ ก่อนเขียนกฎ ให้เลือกหน่วยสต็อก: คุณติดตามสต็อกที่ระดับสินค้า ระดับรุ่น หรือตามทั้งสองระดับ?
ถ้าลูกค้าเลือกขนาดหรือสี ระดับรุ่นมักปลอดภัยกว่า เสื้อหนึ่งตัวอาจดู “มีสต็อก” โดยรวม แต่รุ่น Small-Blue อาจหมด สต็อกระดับสินค้าเหมาะกับไอเท็มที่รุ่นไม่เปลี่ยนสิ่งที่คุณเก็บจริง ๆ (เช่น ไลเซนส์ดิจิทัล) บางทีมเก็บทั้งสองระดับ: ระดับสินค้าเพื่อรายงาน ระดับรุ่นเพื่อการขาย
การป้องกันการขายเกินไม่ได้เกี่ยวกับธงเดียว แต่มักต้องมีหลายสถานะ ระบบสต็อกส่วนใหญ่ต้องการการสำรอง (reserve หน่วยชั่วคราวสำหรับรถเข็นหรือคำสั่งที่ยังไม่ชำระ), backorder (อนุญาตขายพร้อมระบุวันที่จัดส่ง), buffer สต็อก (ปริมาณซ่อนเพื่อครอบคลุมความล่าช้าในการซิงค์), และการอัปเดตแบบอะตอมมิก (ลดสต็อกพร้อมกับยืนยันคำสั่งในการดำเนินการเดียว)
กรณีขอบเขตมักเป็นแหล่งที่มาของ “สต็อกปริศนา” การคืนสินค้าควรเติมสต็อกกลับหลังตรวจสอบรับของ ไม่ใช่ตอนที่สร้างป้ายคืนของเสียของ ชิ้นเสียหายควรย้ายไปสถานะหรือตำแหน่งแยกต่างหากเพื่อไม่ให้ปรากฏว่าเป็นขายได้ การปรับสต็อกต้องมีบันทึกตรวจสอบ (ใครเปลี่ยนอะไรและทำไม) โดยเฉพาะเมื่อหลายช่องทางอัปเดตสต็อก
บันเดิลและชุดสินค้ามีกฎสำคัญหนึ่งข้อ: อย่าลดจำนวนของเรคคอร์ด “บันเดิล” ถ้าบันเดิลนั้นแค่เป็นการรวมรายการ ให้ลดสต็อกของชิ้นส่วนที่เป็นส่วนประกอบแทน 3-pack ควรลดสามหน่วยของ SKU เดียวกัน ส่วน kit ควรลดหนึ่งหน่วยของแต่ละชิ้น
ตัวอย่าง: “Starter Kit” ประกอบด้วยขวด 1 และไส้กรอง 2 ถ้าคุณมีขวด 10 ใบและไส้กรอง 15 ชิ้น ความพร้อมของ kit คือ 7 เพราะไส้กรองจำกัด จำนวนคณิตศาสตร์จากส่วนประกอบช่วยให้รายงาน การคืนสินค้า และการเติมสต็อกสอดคล้อง
ใน AppMaster สิ่งนี้แมปได้ชัดเจนกับตารางรุ่นใน Data Designer และตรรกะการสำรอง/การลดสต็อกใน Business Process Editor ดังนั้นการเช็คเอาต์แต่ละครั้งจะปฏิบัติตามกฎเดียวกัน
การจำลองบันเดิลและชุดสินค้าโดยไม่ทำให้รายงานพัง
บันเดิลคือจุดที่แคตาล็อกมักไหลไปสู่กรณีพิเศษ วิธีที่ง่ายที่สุดคือมองบันเดิลเป็นไอเท็มที่ขายได้แบบปกติ แล้วแนบรายการส่วนประกอบที่ชัดเจน
โครงสร้างที่สะอาดคือ: Product (ไอเท็มขายได้) บวก BundleLines แต่ละ BundleLine ชี้ไปยัง SKU ของส่วนประกอบ (หรือสินค้า + รุ่นที่จำเป็น) และเก็บปริมาณ คำสั่งยังแสดงเป็น “หนึ่งไอเท็ม” แต่คุณขยายเป็นชิ้นส่วนเมื่อคุณต้องการต้นทุน สต็อก และรายละเอียดการจัดส่ง
การตั้งค่าบันเดิลส่วนใหญ่เข้ากับหนึ่งในรูปแบบ:
- Fixed bundle (kit): ส่วนประกอบและปริมาณคงที่เสมอ
- Configurable bundle: ลูกค้าเลือกจากส่วนประกอบที่อนุญาตได้ (ยังบันทึกเป็น BundleLines บนคำสั่ง)
- Virtual bundle: กลุ่มการตลาด (มักไม่มีผลต่อสต็อก) เหมาะสำหรับการแสดงสินค้าโดยไม่บังคับตรรกะการจัดส่ง
การตั้งราคาเป็นจุดที่ทีมมักทำให้รายงานพัง ตัดสินแต่เนิ่น ๆ ว่าสิ่งใดปรากฏบนบรรทัดคำสั่ง และอะไรเป็นข้อมูลของรายงานมาร์จิ้นและสต็อก แนวทางที่พบได้บ่อยคือ ราคาบันเดิลคงที่ ผลรวมของชิ้นส่วน หรือผลรวมที่ลดราคาโดยมีเงื่อนไขต่อชิ้น (เช่น เลือก 3 ชิ้น ถูกชิ้นที่ถูกสุดลด 50%)
สต็อกควรเข้มงวดเท่า ๆ กัน: kit จะพร้อมขายก็ต่อเมื่อทุกส่วนประกอบที่จำเป็นมีในปริมาณเพียงพอ สำหรับการรายงาน ให้เก็บมุมมองการขายสองมุม:
- Sold item: SKU ของบันเดิล (สำหรับรายได้ อัตราแปลง และการตลาด)
- Consumed components: ขยาย BundleLines (สำหรับการเคลื่อนย้ายสต็อก, COGS, และรายการหยิบของ)
ใน AppMaster สิ่งนี้เข้ากับโครงสร้างได้โดยธรรมชาติ: ตาราง Bundle บวกแถว BundleLine และ Business Processes ที่ขยายส่วนประกอบตอนเช็คเอาต์และเขียนทั้งการขายบันเดิลและการบริโภคส่วนประกอบในธุรกรรมเดียว
รูปแบบ UI สำหรับการเลือกตัวเลือกและรุ่น
UI ตัวเลือกที่ดีทำให้คนเดินต่อไปได้ UI ที่แย่ทำให้เดา พลาด และจากไป จุดสำคัญคือแนะนำผู้ซื้อไปยังรุ่นที่ซื้อได้จริงตั้งแต่ต้น ขณะที่แสดงชัดว่าการเลือกเปลี่ยนอะไรบ้าง
ฝั่งลูกค้า: แสดงตัวเลือกก่อน แล้วค่อยแสดงรุ่น
รูปแบบที่เชื่อถือได้คือแสดงตัวเลือก (Size, Color, Material) แล้วคำนวณและแสดงเฉพาะตัวเลือกที่ยังเป็นไปได้
แทนที่จะให้ลูกค้าเลือกการผสมใด ๆ แล้วล้มเหลวตอนกดใส่ตะกร้า ให้ปิดการเลือกที่เป็นไปไม่ได้ทันทีเมื่อผู้ใช้เลือกแล้ว ตัวอย่าง: เมื่อเลือก Color = Black ขนาดที่ไม่มีในสีดำควรถูกปิด (ไม่ถูกลบ) เพื่อให้ลูกค้าเข้าใจว่าสิ่งใดไม่มี
เมื่อการเลือกเปลี่ยน ให้ปรับส่วนที่สำคัญที่สุด: ราคา (รวมราคาลดและส่วนลดบันเดิลใด ๆ), รูปภาพหลัก (แมทช์สีหรือสไตล์ที่เลือก), สถานะสต็อก (สต็อกรุ่นที่ตรงกับการเลือก ไม่ใช่สต็อกสินค้าโดยรวม), ประมาณการจัดส่ง (ถ้ามีความแตกต่างตามรุ่น), และถ้าต้องการ SKU หรือ “Item code” เพื่อการซัพพอร์ต
ทำให้ส่วนติดต่อสงบ แสดงกลุ่มตัวเลือกไม่กี่กลุ่มในครั้งเดียว หลีกเลี่ยง dropdown ยาวเมื่อ swatch หรือปุ่มทำงานได้ดี และทำให้การเลือกปัจจุบันเด่นชัด
ฝั่งแอดมิน: แก้ไขรุ่นเหมือนสเปรดชีท
ในแอดมิน คนต้องการความเร็วไม่ใช่หน้าตา ตารางรุ่นทำงานได้ดี: แต่ละแถวคือ SKU แต่ละคอลัมน์คือ option หรือกฎ (ราคา บาร์โค้ด น้ำหนัก สต็อก active/inactive) เพิ่มการกระทำแบบกลุ่มสำหรับงานทั่วไปเช่นอัปเดทราคา เปลี่ยนสถานะ หรือมอบหมายรูปภาพ
ถ้าคุณสร้างใน AppMaster การตั้งค่าที่ใช้งานได้จริงคือกริดผูกกับตาราง Variant พร้อมตัวกรอง (ค่า option, สถานะ active, สต็อกต่ำ) และแอ็กชันอัปเดตเป็นกลุ่มที่ตรวจสอบกฎก่อนบันทึก
ขั้นตอนทีละขั้น: การเลือกรุ่นและการตรวจสอบความพร้อมของบันเดิล
ฟลว์การเลือกควรรู้สึกเรียบง่าย แต่ต้องมีกฎเข้มงวดด้านใน เป้าหมายคือรู้เสมอว่า SKU ใดผู้ซื้อกำลังกำหนดค่า และมันซื้อได้จริงหรือไม่
การเลือกรุ่น (สินค้าเดี่ยว)
โหลดมากกว่าแค่ชื่อสินค้าและรูปภาพ คุณต้องการชุดค่าตัวเลือกทั้งหมด (Size, Color) และรายการการผสมรุ่นที่มีอยู่เป็น SKU
ฟลว์ที่เชื่อถือได้:
- ดึงข้อมูลสินค้า ตัวเลือก และรุ่นทั้งหมดที่มีอยู่ (หรือแมปแบบย่อของการผสมที่เป็นไปได้)
- เก็บการเลือกปัจจุบันของผู้ซื้อ (เช่น: Size=M, Color=Black) และอัปเดตทุกคลิก
- หลังการเปลี่ยนแต่ละครั้ง ค้นหารุ่นที่ตรงโดยเปรียบเทียบค่าตัวเลือกที่เลือกกับรายการรุ่นของคุณ
- ถ้ามีการแมตช์และรุ่นนั้นซื้อได้ (active, ราคาตั้ง, ไม่ถูกบล็อก) ให้เปิดใช้งานปุ่ม "ใส่ตะกร้า"
- ถ้าไม่มีการแมตช์ ให้คงปุ่ม "ใส่ตะกร้า" ปิดและนำทางผู้ซื้อไปสู่ตัวเลือกที่ถูกต้อง
รายละเอียด UI เล็ก ๆ ที่ป้องกันความหงุดหงิด: ปิดค่าตัวเลือกที่เป็นไปไม่ได้ทันทีเมื่อเลือกก่อนหน้า ถ้า Size=M มีแค่สีดำ ให้แสดงสีอื่นเป็นใช้งานไม่ได้เมื่อเลือก M
ความพร้อมของบันเดิล (ชุดสินค้าที่ประกอบจากส่วน)
สำหรับบันเดิล “มีสต็อก” ไม่ได้เป็นตัวเลขเดียว มันขึ้นกับส่วนประกอบ กฎปกติคือ:
bundle_available = minimum over components of floor(component_stock / component_qty_per_bundle)
ตัวอย่าง: "Starter Kit" ต้องการขวด 1 และไส้กรอง 2 ถ้าคุณมีขวด 10 และไส้กรอง 9 ความพร้อมคือ min(floor(10/1)=10, floor(9/2)=4) = 4 ชุด
ข้อความผิดพลาดควรชัดเจน เลือกคำว่า "เหลือเพียง 4 ชุด (ไส้กรองจำกัดบันเดิลนี้)" แทนที่จะบอกว่า "สินค้าหมด" ใน AppMaster การตรวจสอบแบบนี้นิยามง่ายใน Business Process: หารุ่นที่แมตช์ก่อน แล้วคำนวณขีดจำกัดบันเดิล แล้วคืนสถานะที่ชัดเจนให้ UI แสดง
ข้อผิดพลาดและกับดักที่พบบ่อย
แคตาล็อกพังเมื่อคุณออกแบบสำหรับ “ทุกอย่างที่อาจมี” แทนที่จะเป็น “สิ่งที่จะขายจริง” วิธีที่เร็วที่สุดที่จะทำให้ตัวเองติดกับมุมคือสร้างการผสมตัวเลือกทั้งหมดล่วงหน้า แล้วพยายามทำความสะอาดเมื่อแคตาล็อกโตขึ้น
การสร้างรุ่นที่ไม่มีวันสต็อกเป็นกับดักคลาสสิก ถ้าคุณมี 4 สี x 6 ขนาด x 3 วัสดุ นั่นคือ 72 รุ่น ถ้าแค่ 10 ที่ขายจริง 62 เรคคอร์ดที่เหลือจะสร้างความยุ่งเหยิง เชิญให้เกิดความผิดพลาด และชะลอการรายงาน
การตั้งราคาก็เป็นแหล่งบั๊กเงียบๆ ปัญหาเริ่มเมื่อราคาเดียวกันเก็บไว้หลายที่ (สินค้า, รุ่น, ตารางราคา, ตารางโปรโมชัน) โดยไม่มีแหล่งความจริงเดียว กฎง่าย ๆ ช่วยได้: เก็บราคาพื้นฐานครั้งเดียว แล้วเก็บการยกเว้นเฉพาะที่จำเป็นจริง ๆ (เช่น รุ่นหนึ่งมีราคาต่างออกไป)
บันเดิลและชุดสินค้าล้มเหลวด้านสต็อกเมื่อคุณลดทั้งบันเดิลและส่วนประกอบ ถ้าคุณขาย "Starter Kit" ที่มีขวด 1 และไส้กรอง 2 การลบ 1 kit แล้วลบขวด 1 และไส้กรอง 2 จะทำให้สต็อกหายเร็วกว่าที่ควร เก็บบันเดิลเป็นไอเท็มที่ขายได้ แต่คำนวณความพร้อมและการลดสต็อกจากส่วนประกอบ
เครื่องมือแอดมินทำความเสียหายได้ถ้ามันอนุญาตข้อมูลไม่ถูกต้อง ใส่เสากั้นเร็ว ๆ:
- ป้องกัน SKU ซ้ำ แม้แต่กับไอเท็มที่เก็บถาวร
- ขอให้แต่ละรุ่นมีค่าตัวเลือกครบทุกค่า (ห้าม "ขาดไซส์")
- ป้องกันสองรุ่นแชร์การผสมค่าตัวเลือกเดียวกัน
- ตรวจสอบส่วนประกอบบันเดิล (ห้ามปริมาณเป็นศูนย์ ห้ามขาด SKU)
สุดท้าย วางแผนสำหรับการเปลี่ยน เพิ่มตัวเลือกใหม่ภายหลัง (เช่น "Width" สำหรับรองเท้า) เป็นการโยกย้ายข้อมูล ไม่ใช่แค่ติ๊ก ออกแบบว่าจะเกิดอะไรกับรุ่นที่มีอยู่ ค่าตั้งต้นถูกตั้งอย่างไร และคำสั่งเก่ายังเก็บสแนปช็อตของ SKU และค่าตัวเลือกเดิมอย่างไร
ตรวจสอบด่วนก่อนปล่อย
ก่อนปล่อย ให้รันผ่านสิ่งที่จะพังจริง ๆ: หาการหา SKU การอัปเดตสต็อก และการบล็อกการซื้อที่เป็นไปไม่ได้
ให้แน่ใจว่า SKU ที่ขายได้ทุกชิ้นหาง่าย การค้นหาควรพบตามชื่อ รหัส SKU บาร์โค้ด/GTIN และแอตทริบิวต์สำคัญ (เช่น ขนาดหรือสี) ถ้าคุณใช้การสแกนในคลัง ทดสอบการสแกนจริงและยืนยันว่ามันลงที่ SKU ที่ถูกต้องไม่ใช่แค่สินค้าพาเรนต์
เข้มงวดว่าเหตุการณ์การเปลี่ยนสต็อกเกิดขึ้นที่ไหน เลือกแหล่งความจริงเดียว (ตรรกะการเคลื่อนย้ายสต็อกของคุณ) และมั่นใจว่าเหตุการณ์ทุกอย่างเรียกใช้มัน: คำสั่ง ยกเลิก คืนเงิน การปรับด้วยมือ และการประกอบชุด ถ้าสต็อกแก้ไขได้จากสองหน้าจอหรือสองเวิร์กโฟลว์ การเบี่ยงเบนเป็นสิ่งที่แน่นอน
การตรวจสอบก่อนปล่อยที่ควรทำ:
- เลือกตัวเลือกใน UI และยืนยันว่าการผสมที่เป็นไปไม่ได้ถูกบล็อกตั้งแต่ก่อนกดใส่ตะกร้า ไม่ใช่เจอที่ชำระเงิน
- สำหรับบันเดิล ยืนยันว่าความพร้อมถูกขับเคลื่อนโดยส่วนประกอบที่ขาดแคลนที่สุดและปริมาณที่ถูกต้อง (แบตเตอรี่ 2 ก้อนต่อชุดจะทำให้ความพร้อมลดลงเป็นครึ่ง)
- เลิกใช้งาน SKU และยืนยันว่ามันหายไปจากการเรียกดูและผลการค้นหา แต่ยังแสดงถูกต้องในคำสั่ง เก่า ใบแจ้งหนี้ และรายงาน
- สร้างคำสั่งทดสอบ ยกเลิก แล้วสร้างอีกครั้ง สต็อกควรกลับและถูกจองใหม่อย่างสะอาด
ถ้าคุณสร้างใน AppMaster ให้เก็บกฎการอัปเดตสต็อกใน Business Process เดียวและเรียกใช้จากทุกเส้นทาง นิสัยเดียวนี้ป้องกันบั๊กสต็อกส่วนใหญ่
ตัวอย่างสถานการณ์และขั้นตอนถัดไปแบบปฏิบัติ
สมมติร้านเสื้อผ้าที่ยังต้องการแคตาล็อกจริงจัง
คุณขายเสื้อยืดหนึ่งแบบมีสองตัวเลือก: Size (S, M, L) และ Color (Black, White) แต่ละการผสมที่ซื้อได้เป็นรุ่นแยกที่มี SKU ราคา (ถ้าจำเป็น) และสต็อกของตัวเอง
ในสคีมา เก็บหนึ่ง Product record สำหรับ “Classic T-shirt”, สอง Option records (Size, Color), และหลาย Variant records แต่ละ Variant เก็บค่าตัวเลือกที่เลือก (เช่น: Size=M, Color=Black) และ SKU (เช่น: TSH-CL-M-BLK). สต็อกถูกติดตามที่ระดับ Variant ไม่ใช่ระดับ Product
บน UI ให้จำกัดทางเลือกและป้องกันทางตัน รูปแบบที่สะอาดคือ: แสดงสีทั้งหมดก่อน แล้วแสดงแค่ขนาดที่มีสำหรับสีที่เลือก ถ้า “White + L” ไม่มี ให้ไม่อนุญาตให้เลือกหรือแสดงเป็นปิดพร้อมหมายเหตุชัดเจน
ตอนนี้เพิ่มบันเดิล: “Gift Set” ที่ประกอบด้วย:
- 1x Classic T-shirt (รุ่นใดก็ได้)
- 1x Sticker pack (SKU ธรรมดา)
ความพร้อมของบันเดิลถูกจำกัดโดยส่วนประกอบที่แคบที่สุด ถ้า Sticker pack มีสต็อก 5 คุณไม่สามารถขายบันเดิลเกิน 5 ถึงแม้เสื้อจะมีเหลือ หากบันเดิลต้องการรุ่นเสื้อเฉพาะ (เช่น Black M) ความพร้อมของบันเดิลคือ min(StickerPackStock, BlackMStock)
ขั้นตอนปฏิบัติถัดไปใน AppMaster:
- สร้างตารางใน Data Designer (Products, Options, OptionValues, Variants, VariantOptionValues, Inventory, Bundles, BundleComponents)
- นำฟังก์ชัน “ค้นหารุ่นที่ถูกต้อง” และ “คำนวณความพร้อมบันเดิล” มาลงใน Business Process Editor
- สร้างเว็บและแอปมือถือจากโปรเจ็กต์เดียวกัน โดยใช้กฎการกรองรุ่นและการคำนวณความพร้อมเดียวกันทุกที่
ถ้าคุณต้องการทางลัดสำหรับสร้างต้นแบบแบบ end-to-end, AppMaster (appmaster.io) ถูกออกแบบมาเพื่อสร้างแอปครบชุดพร้อมโลจิกทางธุรกิจจริง ซึ่งเป็นสิ่งที่การเลือกรุ่นและกฎสต็อกบันเดิลต้องการ


