เมนูการจัดการลูกค้าใช้สร้าง แก้ไข จัดการที่อยู่/สาขา และอนุมัติ customer draft ก่อนข้อมูลลูกค้าจะพร้อมใช้งานเป็น master ลูกค้า SAP เป็น write-side flow ของข้อมูลลูกค้า
ทางเข้าในแอป
| App | Target |
|---|
| Mobile | CustomerManagementList -> detail/edit/address screens |
| POS Terminal | customerManagement -> CustomerManagementDetailForm |
Lifecycle ของ Draft
Workflow พร้อมสิทธิ์
Data และ API Rules
| Operation | Service |
|---|
| List drafts | getCustomerDrafts -> GET /customer-draft?branchId=... |
| Detail | getCustomerDraftById -> GET /customer-draft/:id |
| Create/update profile | createCustomerDraft, updateCustomerDraft |
| Approve/reject | approveCustomerDraft, rejectCustomerDraft(payload) |
| Retry partial SAP approval | retryCustomerDraft -> POST /customer-draft/:id/retry |
| Draft addresses | createCustomerDraftAddress, updateCustomerDraftAddress, deleteCustomerDraftAddress |
| Draft branch links | createCustomerDraftBranch, deleteCustomerDraftBranch |
หมายเหตุสำคัญ:
- list draft ผูกกับ selected branch
- approval เป็นคนละขั้นตอนกับการ save profile/address
- reject ควรส่ง context/เหตุผลตามที่ UI เก็บได้
- draft addresses และ branch links เป็น child resources แก้ profile แล้ว child ไม่เปลี่ยนอัตโนมัติ
- หลัง approve แล้ว การค้นหาใช้งานจริงไปที่ ลูกค้า
กรณีอนุมัติเข้า SAP B1 ไม่สำเร็จและการส่งใหม่
- ลูกค้าใหม่บุคคลธรรมดาจะถูกบันทึกเป็น Draft ก่อนเสมอ หากเลือกอนุมัติเข้า B1 ทันทีแล้วไม่สำเร็จ Mobile จะแจ้ง error แล้ว
replace จากหน้าฟอร์มไปยังหน้ารายละเอียด Draft นั้น ดังนั้นกดย้อนกลับจะกลับรายการ Draft ไม่กลับหน้าฟอร์มเดิม
- หน้ารายละเอียดจะโหลด Draft ใหม่หลังการอนุมัติล้มเหลว แล้วเลือกปุ่มจาก
status ล่าสุดของ server
DRAFT แสดงปุ่ม อนุมัติข้อมูล และ ไม่อนุมัติข้อมูล ส่วน SAP_PARTIAL ซ่อนสองปุ่มนี้และแสดง ส่งข้อมูลอนุมัติอีกครั้ง
- ปุ่มส่งใหม่เรียก
POST /customer-draft/:id/retry; ถ้าสำเร็จจะแจ้งอนุมัติสำเร็จและออกจากหน้ารายละเอียด แต่ถ้าล้มเหลวจะโหลด Draft ใหม่อีกครั้งเพื่อให้ปุ่มตรงกับสถานะบน server
Flow ระดับหน้าและการทำงานของปุ่ม
ข้อมูล Draft แบ่งเป็นข้อมูลหลัก ที่อยู่ และสาขาที่เปิดบิลได้ ซึ่งเป็น child resource คนละชุด ทุกครั้งที่แก้ child ต้องโหลดรายละเอียดหลักใหม่
| ส่วน/ปุ่ม | เงื่อนไขและผลลัพธ์ |
|---|
| สร้าง/แก้ Draft | ต้องมีสิทธิ์จัดการลูกค้า และยังไม่สร้าง SAP customer master ทันที |
| เพิ่ม/แก้ที่อยู่ | เก็บที่อยู่ ประเภท สาขา และ latitude/longitude; พิกัดว่างหรือใช้ไม่ได้ต้องไม่เปิดแผนที่ |
| ลบที่อยู่ | ต้องยืนยัน ลบเฉพาะ child แล้วโหลดหน้าหลักใหม่ |
| เพิ่มสาขาที่เปิดบิล | แสดงเฉพาะสาขาที่ยังไม่ผูก ความสัมพันธ์นี้กำหนดว่าสาขาใดเปิดบิลให้ลูกค้าได้ |
| ลบสาขา | ลบเฉพาะความสัมพันธ์ ไม่ได้ลบสาขาหรือลูกค้า |
| อนุมัติ/ปฏิเสธ | แยกจากสิทธิ์แก้ไข; เมื่อ status = DRAFT จะแสดงปุ่มอนุมัติ/ไม่อนุมัติ การปฏิเสธควรมีเหตุผลสำหรับการแก้ไขรอบถัดไป |
| ส่งข้อมูลอนุมัติอีกครั้ง | เมื่อ status = SAP_PARTIAL จะแสดงเฉพาะผู้มีสิทธิ์อนุมัติ และเรียก POST /customer-draft/:id/retry |
ข้อมูลลูกค้า: บุคคลธรรมดาและนิติบุคคล
การเปลี่ยนประเภทบุคคลมีผลต่อฟอร์มและ payload จริง ไม่ใช่เพียงข้อความแสดงผล
| ข้อมูล/พฤติกรรม | บุคคลธรรมดา (Individual) | นิติบุคคล (company) |
|---|
| ชื่อบังคับ | ชื่อและนามสกุล | ชื่อบริษัท/กิจการ/องค์กรเก็บใน firstname และล้าง lastname |
| Tax ID | ซ่อนและล้างจาก payload | บังคับ เป็นตัวเลข 13 หลัก |
| ความยาวชื่อ | ชื่อและนามสกุลรวมไม่เกิน 200 ตัวอักษร | ชื่อองค์กรไม่เกิน 200 ตัวอักษร |
| สาขาในที่อยู่ | ล้างออกตอน normalize | แสดงบน BillTo; เลือกสำนักงานใหญ่หรือกรอกสาขา |
| ค่าเริ่มต้น BillTo | ไม่มี | ถ้าไม่ระบุจะเป็น 00000 / สำนักงานใหญ่ |
| บันทึกครั้งแรก | เลือกอนุมัติเข้า B1 ทันทีได้เมื่อ validation ผ่าน | เป็น Draft รอตรวจสอบและยังแก้ไขได้ |
| ลูกค้าที่มีใน SAP | สร้างคำขอแก้ไข รอฝ่ายการตลาดอนุมัติ | ใช้ flow เดียวกัน |
ทั้งสองประเภทต้องเลือกประเภทลูกค้า, รู้จักเราจาก, ประเภทจัดส่ง, มีเบอร์หลัก 10 หลัก, มีที่อยู่เปิดบิลและจัดส่งตอนอนุมัติ และมีสาขาที่เปิดบิลได้อย่างน้อยหนึ่งสาขา เบอร์สำรองไม่บังคับแต่ถ้ากรอกต้อง 10 หลัก วันเกิด ฉายา และอีเมลไม่บังคับ โดยปี พ.ศ. จะถูกแปลงเป็น ค.ศ. ก่อนส่ง
ประเภทที่อยู่และข้อมูลที่จำเป็น
| ข้อมูล/กฎ | เงื่อนไข |
|---|
| ประเภท | บังคับ: BillTo (เปิดบิล) หรือ ShipTo (จัดส่ง) |
| ชื่อของที่อยู่ | บังคับและห้ามซ้ำภายในประเภทเดียวกันของลูกค้าคนนี้ ชื่อเดียวกันใช้คนละประเภทได้ |
| ที่อยู่หลัก | บ้านเลขที่/หมู่บ้าน/หมู่, ตำบล, อำเภอ, จังหวัด และรหัสไปรษณีย์บังคับทั้งหมด การค้นหาจะเติมข้อมูลและจัดกรุงเทพฯ เป็น แขวง/เขต |
| รายละเอียด/จุดสังเกต | ไม่บังคับ (checkAddressName) |
| BillTo ของนิติบุคคล | เลือกสำนักงานใหญ่ หรือกรอกทั้งรหัสและชื่อสาขา รหัสเป็นตัวเลขไม่เกิน 5 หลักและเติมศูนย์ด้านหน้า ห้ามกรอกเพียงค่าเดียว |
| บุคคลธรรมดา / ShipTo | ระบบล้างรหัสและชื่อสาขาตอน normalize |
| สายส่ง | บังคับเฉพาะ ShipTo ของลูกค้าสายส่ง (shippingType = 1); BillTo จะล้างค่าสายส่ง |
| พิกัด | บังคับใน ShipTo ของลูกค้าสายส่ง โดย lat/lng ต้องเป็นตัวเลข finite และไม่เป็นศูนย์ทั้งคู่ ใช้ GPS, แผนที่ หรือกรอกเองได้ |
| สร้าง ShipTo อัตโนมัติ | แสดงตอนเพิ่มที่อยู่ใหม่ที่ไม่ใช่ ShipTo สร้าง child แยก ล้างสาขา และตรวจชื่อซ้ำ/สายส่ง/พิกัดอีกครั้ง |
Validation ตอนบันทึกและตอนอนุมัติ
| ขั้นตอน | เงื่อนไข |
|---|
| บันทึก Draft | ตรวจ Header, เบอร์โทร, Tax ID; นิติบุคคลต้องมี BillTo; ลูกค้าสายส่งต้องมี ShipTo พร้อมสายส่งและพิกัด |
| อนุมัติเข้า B1 | ตรวจ Header ซ้ำ, บังคับทั้ง BillTo และ ShipTo สำหรับทุกคน, ตรวจ 6 ฟิลด์ที่อยู่, คู่รหัส/ชื่อสาขา, สายส่ง/พิกัด, ชื่อที่อยู่ซ้ำ และสาขาที่เปิดบิลซ้ำ |
| Error | แสดง 5 ข้อแรกพร้อมจำนวนที่เหลือ และไม่เรียก API อนุมัติจนกว่าจะผ่าน |
กฎสาขาที่เปิดบิลได้
- ลูกค้าใหม่จะเตรียมสาขาที่ Login เป็นสาขาแรกเมื่อจับคู่ข้อมูลได้
- การเพิ่มจะข้ามสาขาที่มีอยู่ และตอนอนุมัติจะตรวจซ้ำทั้ง id, code และชื่อ
- ลบสาขาสุดท้ายไม่ได้ ต้องเหลืออย่างน้อยหนึ่งสาขา
- สาขาที่เปิดบิลได้กำหนดสาขาระบบที่ออกบิล ส่วนสาขาบน
BillTo ของนิติบุคคลใช้ระบุสำนักงานใหญ่/สาขาตามที่อยู่ภาษี ทั้งสองอย่างเป็นคนละข้อมูล
สิทธิ์และ guard
| เรื่อง | รายละเอียด |
|---|
| Terminal menu key | customerManagement |
| deptCode ที่เห็นเมนู | -2, 1, 2, 3, 4, 7, 29, 21, 8, 9, 13, 14, 16, 27, 30 |
| Approval flag | field approveCustomer ของ user เปิดปุ่ม approve/reject |
| เงื่อนไขสาขา | เปิดตามสิทธิ์เมนู customer management และ selected branch |
Mobile vs POS Terminal
| เรื่อง | Mobile | POS Terminal |
|---|
| Navigation | หลาย stack screen สำหรับ list/detail/edit/address | detail form เดียวพร้อม sections/modals |
| แก้ที่อยู่ | address detail screens แยก | section/action ใน CustomerManagementDetailForm |
| Map/location | Mobile ขอ device location/map helpers ได้ | Terminal form มี map/search helper code ตามที่เปิดใช้ |
| Approval | DRAFT แสดงอนุมัติ/ไม่อนุมัติ, SAP_PARTIAL แสดงส่งข้อมูลอนุมัติอีกครั้ง | ใช้ action ตาม status เดียวกันใน split detail form |
Developer Handoff Map
| Area | Code |
|---|
| Mobile stack | apps/mobile/src/screens/customerManagementStack/* |
| Terminal detail | apps/pos-terminal/src/screens/HomeScreen/CustomerManagementDetailForm.tsx |
| Customer services | apps/*/src/services/customers.ts |
| Terminal split data | apps/pos-terminal/src/services/splitMenuData.ts -> customerManagement |
| Permission source | user field approveCustomer และ menu deptCode config |
เอกสารที่เกี่ยวข้อง