ข้ามไปยังเนื้อหาหลัก

ลูกค้า

เมนูลูกค้าเป็นหน้าค้นหาลูกค้า SAP และเป็นจุดเริ่มงาน operation ผู้ใช้ค้นหาลูกค้าตามสาขา ดู profile/ที่อยู่/เครดิต/คะแนน โทรหาลูกค้า เริ่มเอกสารขาย ขอเปิด/ปิดสถานะ เพิ่มที่อยู่ เปิดแผนที่ ตั้งค่าที่อยู่จัดส่งเริ่มต้น และยื่นคำขอแก้พิกัด GPS ได้ ส่วนการแก้ master ลูกค้าจะส่งต่อไปที่เมนูการจัดการลูกค้า

ทางเข้าในแอป​

AppTarget
MobileCustomerList mode default, booking, borrow, หรือ request -> CustomerDetail
POS Terminalsplit menu customer -> CustomerDetailForm

Workflow ภาพรวม​

ปุ่มและตัวควบคุมหน้า List​

ปุ่ม / ControlMobilePOS Terminal
กลับnavigation.goBack() จาก CustomerManagementListHeaderกลับ/ปิดอยู่ใน shell ของ HomeScreen menu/pane
ช่องค้นหาเปลี่ยนค่า search; submit เรียก getCustomerSapList({ page: 1, search, shippingType, routeCode, isRequest })เปลี่ยน listSearch; submit เรียก loadCustomerList({ page: 1, search, shippingType, routeCode })
ล้างคำค้นล้างค่า search เฉพาะ input แล้ว fetch ใหม่เมื่อ submit/refresh ครั้งถัดไปล้าง shared list search ผ่าน split-pane controls
ตัวกรองเส้นทางเปิด modal เลือกเส้นทาง เลือกแล้ว reload page 1 ด้วย routeCodeเปิด route selector ใน ListPane; เลือกแล้วล้าง detail ที่เลือกและ reload page 1 ด้วย routeCode
Tab ประเภทจัดส่งสายส่ง ส่ง shippingType: "1"; หน้าร้าน ส่ง shippingType: "2"; กด tab เดิมซ้ำเพื่อล้าง filterbehavior เดียวกันผ่าน customerShippingType; เลือกแล้ว reload page 1 และล้าง detail
Pull refreshโหลด page 1 ด้วย filter ปัจจุบันโหลด page 1 ด้วย filter ปัจจุบัน
Infinite scrollonEndReached โหลดหน้าถัดไปเมื่อ hasMore เป็นจริงsplit list onLoadMore เรียก loadCustomerList() ด้วย customerPageRef.current
กดแถวลูกค้าเปิด CustomerDetail พร้อม customerId, mode, origin; ถ้าไม่มี customerId จะแสดง errorเลือก row แล้วโหลด getCustomerSplitDetail(item) ไปยัง pane ขวา
Swipe primary actionซ่อนใน request mode; mode ปกติจะเริ่ม action ตาม mode เช่น สร้างใบสั่งขาย ใบจองราคา หรือใบเบิกยืม โดยเช็ก blocked reason และ existing order ก่อนไม่มี swipe action ใน customer list; action สร้างเอกสารอยู่ใน detail pane
เมนูหัวหน้า: เพิ่มลูกค้าใหม่แสดงเมื่อ canShowCreateCustomerMenu; เปิด CustomerManagementEdit แบบ draft ใหม่การเพิ่มลูกค้าอยู่ในเมนู Customer Management ไม่ใช่ header ของ customer split list

ปุ่มและ Action หน้า Detail​

ปุ่ม / ActionMobilePOS Terminal
กลับถ้าเปิดฟอร์มเพิ่มที่อยู่จะปิดฟอร์มก่อน ไม่เช่นนั้น navigation.goBack()ปิด detail pane จาก shared pane header
Pull refreshโหลด /customers/:customerId ใหม่ พร้อม addresses และ branchesrefresh detail ผ่าน onRefreshCustomerDetail จาก HomeScreen
เบอร์โทร / ปุ่มโทรเรียก callCustomer(customerId) เพื่อบันทึก /customers/:id/re-call แล้วเปิด tel:{phone}service และ flow เดียวกัน และเช็ก customer ID ก่อนโทร
สร้างใบสั่งขายเช็กสิทธิ์สร้างเอกสารและ getSalesOrderBlockedReason() ถ้ามีใบสั่งขายวันนี้ในสาขาเดียวกันจะถามว่าจะเปิดใบเดิมหรือสร้างใหม่เช็ก blocked reason แล้ว HomeScreen prompt/open sales-order draft หรือสลับไป sales-order detail
ใบจองราคาเช็กสิทธิ์และ blocked reason แล้วเปิด BookingPriceDetail พร้อม bookingPriceId: null และ customerIdสร้าง booking-price draft detail แล้วสลับ active menu ไป bookingPrice
สร้างใบเบิกดูปลาเช็กสิทธิ์และ blocked reason แล้วเปิด BorrowDetail พร้อม borrowId: null และ customerIdสร้าง borrow-fish draft detail แล้วสลับ active menu ไป borrowFish
แก้ไขข้อมูลเปิด CustomerManagementEdit ด้วย customerId ปัจจุบัน โดย guard ด้วย canEditCustomerFromDetailHomeScreen สร้าง customer-management edit draft แล้วสลับไปฟอร์ม customer management
ขอปิดสถานะแสดงเมื่อลูกค้า ACTIVE และมีสิทธิ์ toggle status; confirm แล้วเรียก updateCustomerStatus(customerCode, { status: "INACTIVE" })ยืนยันใน CustomerDetailForm แล้วเรียก service เดียวกัน
ขอเปิดสถานะแสดงเมื่อลูกค้า INACTIVE และมีสิทธิ์ toggle status; confirm แล้วเรียก updateCustomerStatus(customerCode, { status: "ACTIVE" })ยืนยันใน CustomerDetailForm แล้วเรียก service เดียวกัน
เพิ่มที่อยู่เปิดฟอร์มเพิ่มที่อยู่เมื่อมีสิทธิ์ canManageCustomerAddressesเปิด address modal เมื่อ canManageAddresses(user) ผ่าน
อนุมัติคำขอเฉพาะ Mobile request mode; validate ด้วย validateCustomerBeforeApproval({ customer, addresses, branches }) ก่อนเรียก approveCustomerRequest(customerCode)การอนุมัติคำขอสถานะอยู่ในเมนู Customer Activation ไม่ใช่ normal Customer detail
ไม่อนุมัติคำขอเฉพาะ Mobile request mode; เรียก rejectCustomerRequest(customerCode)อยู่ในเมนู Customer Activation
ปุ่มกลับท้ายหน้ากลับหน้าก่อนหน้าไม่มีใน pane; ใช้การปิด pane/เลือกเมนู

ปุ่มและ Action ที่อยู่​

ปุ่ม / Actionรายละเอียด
เปิดแผนที่ต้องมีสิทธิ์จัดการที่อยู่และมี latitude/longitude แล้ว เปิด Google Maps URL ด้วย U_BFP_Latitude,U_BFP_Longitude
ตั้งค่าเริ่มต้นใช้ได้เฉพาะ ShipTo; ถ้าเป็น default อยู่แล้วจะไม่ทำอะไร ต้องมี customerCode และ addressId, confirm แล้วเรียก setCustomerDefaultAddress(customerCode, addressId) และ reload detail
ปักหมุด / ขออัปเดตพิกัดต้องมีสิทธิ์จัดการที่อยู่และ addressId; เปิดฟอร์ม GPS request พร้อมพิกัดเดิมและ note; submit เรียก requestCustomerAddressGpsUpdate({ addressId, U_BFP_Latitude, U_BFP_Longitude, note }) แล้วรออนุมัติใน Customer Address Management
ประเภทที่อยู่BillTo คือที่อยู่เปิดบิล; ShipTo คือที่อยู่จัดส่ง; ที่อยู่ใหม่ default เป็น ShipTo
สาขาสำหรับนิติบุคคลMobile มีตัวเลือกสำนักงานใหญ่/สาขาสำหรับ BillTo; สำนักงานใหญ่ใช้ branch code 00000 และชื่อ สำนักงานใหญ่; ถ้าเลือกสาขาต้องมีทั้งรหัสและชื่อสาขา Terminal normalize payload ตามแนวคิดเดียวกัน
ค้นหาที่อยู่เปิด lookup จาก dbAddress แล้วเติมตำบล/อำเภอ/จังหวัด/รหัสไปรษณีย์/block
ดึงพิกัดจากอุปกรณ์ขอ permission ตำแหน่ง แล้วเติม latitude/longitude จาก GPS
เลือกจากแผนที่Mobile ใช้ MapPickerModal; Terminal ใช้ Google Maps WebView ใน modal แล้วนำพิกัดที่เลือกกลับมาเติม latitude/longitude
เลือกสายส่งบังคับเมื่อ customer shippingType === "1" และ address เป็น ShipTo; บันทึกเป็น U_ISS_RouteCode และ U_ISS_RouteName
บันทึกที่อยู่validate สิทธิ์, customerCode, address type, required fields, branch rule ของนิติบุคคล และ route requirement ของลูกค้าสายส่ง จากนั้นเรียก createCustomerAddressByPass(customerCode, payload), reload detail และปิดฟอร์ม
ยกเลิก / ปิดปิด modal/form และ reset state ที่ยังไม่ได้บันทึก

ฟอร์มเพิ่มที่อยู่​

Field / ButtonMobilePOS Terminal
ทางเข้าเพิ่มที่อยู่ปุ่ม เพิ่มที่อยู่ใหม่; เรียก handleOpenAddAddress()ปุ่ม action เพิ่มที่อยู่; เรียก handleOpenAddAddress()
Guard สิทธิ์ใช้ access.canManageCustomerAddresses; ถ้าไม่มีสิทธิ์แสดง คุณไม่มีสิทธิ์เพิ่มที่อยู่ใช้ canManageAddresses(user); ถ้าไม่มีสิทธิ์แสดง error เดียวกัน
ค่าเริ่มต้นเปิดฟอร์มเต็มจอโดยตั้ง addressType: "ShipTo" และล้าง address searchเปิด modal โดยตั้ง addressType: "ShipTo" และล้าง address search
ประเภทที่อยู่radio: ที่อยู่ในการเปิดบิล -> BillTo, ที่อยู่สำหรับจัดส่ง -> ShipToปุ่ม: เปิดบิล -> BillTo, จัดส่ง -> ShipTo
สาขาของนิติบุคคลถ้าเป็นนิติบุคคลและ BillTo Mobile แสดงตัวเลือกสำนักงานใหญ่/สาขา; สำนักงานใหญ่ตั้ง branchCode: "00000", branchName: "สำนักงานใหญ่"; ถ้าเป็นสาขาต้องมีทั้งรหัสและชื่อสาขาTerminal normalize payload แนวเดียวกัน: ถ้าไม่ใช่นิติบุคคลหรือเป็น ShipTo จะเคลียร์ branch fields; legal-entity BillTo ที่ว่างจะ default เป็นสำนักงานใหญ่
ชื่อของที่อยู่Required. บันทึกเป็น addressName
ที่อยู่บ้านเลขที่ / หมู่บ้าน / หมู่Required. บันทึกเป็น street
รายละเอียดเพิ่มเติม / จุดสังเกตOptional. บันทึกเป็น checkAddressName
ค้นหาที่อยู่ไทยเปิด lookup จาก dbAddress; เมื่อเลือกจะเติม block, city, zipCode, U_BFP_Amphur, U_BFP_Tambon
ตำบล / อำเภอ / จังหวัด / รหัสไปรษณีย์Required หลังเลือก lookup หรือกรอกเอง; Mobile แสดงเป็น disabled fields หลัง lookup ส่วน Terminal เป็น text fields ที่แก้ได้
ดึงพิกัดจากอุปกรณ์ปุ่ม ดึงพิกัดจากอุปกรณ์ / ดึงพิกัด; ขอ location permission แล้วเติม U_BFP_Latitude, U_BFP_Longitude
เลือกจากแผนที่ปุ่ม เลือกจากแผนที่; Mobile เปิด MapPickerModal, Terminal เปิด Google Maps WebView; confirm แล้วเติม latitude/longitude
สายส่งRequired เฉพาะ customer shippingType === "1" และ address type เป็น ShipTo; บันทึกเป็น U_ISS_RouteCode, U_ISS_RouteName
บันทึกMobile ปุ่ม บันทึก; Terminal ปุ่ม บันทึกที่อยู่; ทั้งคู่เรียก createCustomerAddressByPass(customerCode, payload)
ยกเลิกMobile ปุ่ม กลับ; Terminal ปุ่ม ยกเลิก; ปิดฟอร์ม/modal และ reset state ที่ยังไม่ได้บันทึก

Validation ตอนบันทึกที่อยู่​

Checkพฤติกรรมเมื่อไม่ผ่าน
สิทธิ์จัดการที่อยู่แสดง คุณไม่มีสิทธิ์เพิ่มที่อยู่ และไม่ submit
ไม่มี customerCodeแสดง ไม่พบรหัสลูกค้า
ไม่เลือกประเภทที่อยู่แสดง กรุณาเลือกประเภทที่อยู่
field required ไม่ครบแสดง กรุณากรอกข้อมูลที่อยู่ให้ครบ: ...; field required คือชื่อที่อยู่, street, ตำบล, อำเภอ, จังหวัด, รหัสไปรษณีย์
นิติบุคคล BillTo กรอก branch ไม่ครบMobile บังคับให้เลือกสำนักงานใหญ่ หรือกรอกทั้งรหัสสาขาและชื่อสาขา
ลูกค้าสายส่ง + ShipTo แต่ไม่เลือกสายส่งแสดง กรุณาเลือกสายส่งสำหรับที่อยู่นี้
API สำเร็จปิดฟอร์ม/modal, reload detail และแสดง เพิ่มที่อยู่เรียบร้อยแล้ว
API failคง context เดิมและแสดง ไม่สามารถเพิ่มที่อยู่ได้ หรือ error จาก API

การบันทึก / ขออัปเดตพิกัด GPS​

Stepรายละเอียด
เปิดฟอร์มคำขอMobile ปุ่ม ปักหมุดตำแหน่ง; Terminal ปุ่ม ขออัปเดตพิกัด; ทั้งคู่ preload U_BFP_Latitude และ U_BFP_Longitude เดิมถ้ามี
ใช้ตำแหน่งปัจจุบันขอ location permission แล้วเติม latitude/longitude ในฟอร์มคำขอ
Map pickerTerminal toggle map picker ใน CustomerLocationForm; Mobile ใช้ map picker flow ของตัวเอง
หมายเหตุoptional note ส่งเป็น note ให้ผู้อนุมัติ
Submitต้องมี addressId ที่เป็นตัวเลข และ latitude/longitude ไม่ว่าง
APIเรียก requestCustomerAddressGpsUpdate({ addressId, U_BFP_Latitude, U_BFP_Longitude, note })
Resultแสดง ส่งคำขอสำเร็จ กรุณารอการอนุมัติ; การอนุมัติ/ปฏิเสธอยู่ในเมนูจัดการที่อยู่ลูกค้า

การตั้งค่าที่อยู่จัดส่งเริ่มต้น​

Ruleรายละเอียด
การแสดงปุ่มMobile แสดง ตั้งเป็นค่าเริ่มต้น เฉพาะ row ShipTo ใน address action area; Terminal แสดง ตั้งค่าเริ่มต้น เมื่อ address ยังไม่เป็น default และซ่อนใน default row
สิทธิ์ต้องมีสิทธิ์จัดการที่อยู่ ถ้าไม่มีจะแสดง คุณไม่มีสิทธิ์ตั้งค่าที่อยู่เริ่มต้น
ประเภทที่อยู่ตั้ง default ได้เฉพาะ ShipTo; BillTo จะได้ข้อความ ตั้งค่าเริ่มต้นได้เฉพาะที่อยู่จัดส่ง
เป็น default อยู่แล้วไม่ยิง API ถือเป็น no-op
ID ที่ต้องมีต้องมี customerCode และ addressId; ถ้าไม่มีจะแสดง ไม่พบข้อมูลที่อยู่ที่ต้องการแก้ไข
APIเรียก setCustomerDefaultAddress(customerCode, addressId)
สำเร็จreload detail และแสดง ตั้งค่าที่อยู่จัดส่งเริ่มต้นเรียบร้อยแล้ว

Data และ API Flow​

เรื่องรายละเอียด
List APIgetCustomerSapList() เรียก /customers?page={page}&pageLimit={PAGESIZE}&search={search}&shippingType={shippingType}&branchId={branchId}&routeCode={routeCode}
Request-mode listMobile request mode เพิ่ม isRequest=1; customer list ปกติไม่ส่งค่านี้
Detail APIgetCustomerSapById(customerId) เรียก /customers/:customerId และต้องได้ profile fields, addresses, branches
Profile by codegetCustomerSapByCode(customerCode) เรียก /customers/:customerCode/profile; ใช้ใน flow อื่นที่เริ่มจาก customer code
Point balancegetCustomerPointBalance(customerCode) เรียก /customers/:customerCode/point-balance; ใช้ใน flow ใบสั่งขาย/สิทธิประโยชน์ที่ต้องอ่านยอดคะแนนล่าสุด
Re-call loggingcallCustomer(customerId) post /customers/:customerId/re-call ก่อนเปิดโทรศัพท์
Status requestupdateCustomerStatus(customerCode, { status }) patch /customers/:customerCode/status เป็น workflow คำร้อง ไม่ใช่การเปลี่ยนสถานะเงียบ ๆ ใน UI
Address bypasscreateCustomerAddressByPass(customerCode, payload) patch /customers/:customerCode/addresses
GPS update requestrequestCustomerAddressGpsUpdate(payload) post /customer-draft/address-lat-lng
Default addresssetCustomerDefaultAddress(customerCode, addressId) patch /customers/:customerCode/addresses/:addressId/default
อนุมัติคำขอลูกค้าMobile request mode เรียก approveCustomerRequest(customerCode) -> PATCH /customers/:customerCode/approve; POS Terminal ใช้ service เดียวกันใน Customer Activation
ปฏิเสธคำขอลูกค้าMobile request mode เรียก rejectCustomerRequest(customerCode) -> PATCH /customers/:customerCode/reject; POS Terminal ใช้ service เดียวกันใน Customer Activation
อัปเดต GPS ที่อยู่โดยตรงupdateCustomerAddressGps(customerCode, addressId, payload) patch /customers/:customerCode/addresses/:addressId; ใช้ใน flow ขนส่งที่เกี่ยวข้อง ส่วนหน้า Customer ใช้ flow ขออนุมัติด้านบน
คะแนน/เครดิตdetail แสดง tier, point, pointToNextTier, nextTierName, credit total, credit limit และ available credit-note amount เมื่อมีใน payload

ตัวอย่าง Request Payload​

ตัวอย่างด้านล่างตัด API host และ header Content-Type ที่ใช้ร่วมกันออก และตัด PATH ออกจาก URL เช่นเดียวกับตาราง endpoint ด้านบน ค่า ID และข้อมูลลูกค้าเป็นข้อมูลสมมติเท่านั้น สำหรับ endpoint GET จะไม่มี JSON request body โดย query string และ path parameter คือ input ของ request

รายชื่อลูกค้า​

GET /customers?page=1&pageLimit=32&sort=DESC&sortBy=CreatedAt&search=%E0%B8%9A%E0%B8%A3%E0%B8%B4%E0%B8%A9%E0%B8%B1%E0%B8%97%20%E0%B9%80%E0%B8%AD&shippingType=1&branchId=101&routeCode=R001

ถ้าเป็น request mode จะเพิ่ม &isRequest=1:

GET /customers?page=1&pageLimit=32&sort=DESC&sortBy=CreatedAt&search=&shippingType=&branchId=101&routeCode=&isRequest=1

รายละเอียดลูกค้า​

GET /customers/12345

Profile ลูกค้าจากรหัสลูกค้า​

GET /customers/C000123/profile

ยอดคะแนนลูกค้า​

GET /customers/C000123/point-balance

บันทึกการโทรซ้ำ (Re-call)​

POST /customers/12345/re-call
Content-Type: application/json

{}

ขอเปลี่ยนสถานะลูกค้า​

PATCH /customers/C000123/status
Content-Type: application/json

{
"status": "INACTIVE"
}

ถ้าขอเปิดลูกค้าที่ปิดอยู่ ให้ใช้ "ACTIVE"

เพิ่มที่อยู่ลูกค้า​

PATCH /customers/C000123/addresses
Content-Type: application/json

{
"addressType": "ShipTo",
"branchCode": "",
"branchName": "",
"checkAddressName": "ใกล้ตลาดตัวอย่าง",
"addressName": "บ้านลูกค้าตัวอย่าง",
"street": "99/9 หมู่ 4",
"block": "ต.สุรศักดิ์ อ.ศรีราชา",
"city": "จ.ชลบุรี",
"country": "TH",
"zipCode": "20110",
"visOrder": "",
"U_BFP_Amphur": "อ.ศรีราชา",
"U_BFP_Tambon": "ต.สุรศักดิ์",
"U_ISS_RouteCode": "R001",
"U_ISS_RouteName": "สายส่งศรีราชา",
"U_BFP_Latitude": "13.173200",
"U_BFP_Longitude": "100.931500"
}

ถ้าเป็น BillTo ของนิติบุคคล ให้ส่งสาขาที่เลือกใน branchCode และ branchName; สำนักงานใหญ่ใช้ "00000" และ "สำนักงานใหญ่" และที่อยู่ BillTo ต้องล้างค่า route ส่วนลูกค้าสายส่งที่เป็น ShipTo ต้องมี U_ISS_RouteCode และ U_ISS_RouteName

ขออัปเดตพิกัด GPS ของที่อยู่​

POST /customer-draft/address-lat-lng
Content-Type: application/json

{
"addressId": 9876,
"U_BFP_Latitude": "13.173200",
"U_BFP_Longitude": "100.931500",
"note": "ขอแก้พิกัดหน้าร้านจากตำแหน่งล่าสุด"
}

addressId ส่งเป็นตัวเลข ส่วน latitude และ longitude ส่งเป็น string และ note ปล่อยเป็นค่าว่างได้

ตั้งที่อยู่จัดส่งเริ่มต้น​

PATCH /customers/C000123/addresses/9876/default
Content-Type: application/json

{}

อนุมัติคำขอลูกค้า​

PATCH /customers/C000123/approve
Content-Type: application/json

{}

ปฏิเสธคำขอลูกค้า​

PATCH /customers/C000123/reject
Content-Type: application/json

{}

อัปเดต GPS ที่อยู่โดยตรง (flow ขนส่งที่เกี่ยวข้อง)​

PATCH /customers/C000123/addresses/9876
Content-Type: application/json

{
"U_BFP_Latitude": "13.173200",
"U_BFP_Longitude": "100.931500"
}

endpoint นี้ไม่ใช่เส้นทาง submit ปกติของหน้า Customer เพราะหน้า Customer จะส่งคำขอ GPS เพื่อรออนุมัติแทน

สิทธิ์และ Guard​

เรื่องMobilePOS Terminal
สิทธิ์เข้าเมนูcustomer menu ปกติใช้ CUSTOMER_MENU_DEPT_CODES: -2, 1, 2, 3, 4, 7, 8, 9, 13, 14, 16, 21, 27, 29, 30 รวม admin/full non-main warehouse accessTerminal MENU_CUSTOMER: -2, 1, 2, 3, 4, 7, 29, 21, 8, 9, 13, 14, 27, 30, 16
สิทธิ์ request modeCUSTOMER_REQUEST_DEPT_CODES: 2, 4, 7, 16, 29 รวม admin/full non-main warehouse accessเมนูแยก customerActivation ใช้ MENU_CAN_ACTIVE_CUSTOMER: 2, 4, 7, 16, 29
สร้างเอกสารจากลูกค้าMobile ใช้ sales-order access สำหรับ primary actions และมี customer action dept codes -2, 1, 2, 4, 7, 8, 9, 13, 29canCreateCustomerDocument() อนุญาต admin/full non-main warehouse access หรือ dept codes -2, 1, 2, 4, 7, 8, 9, 13, 16, 21, 29
ขอเปิด/ปิดสถานะMobile ใช้ customer action permission และแสดงปุ่มตามสถานะ active/inactiveTerminal ใช้ CUSTOMER_ACTION_DEPT_CODES: -2, 1, 2, 4, 7, 8, 9, 13, 29 รวม admin
จัดการที่อยู่Mobile อนุญาต admin/full non-main warehouse access หรือ dept codes 13, 14, 30Terminal อนุญาต admin หรือ dept codes 13, 14, 30
แก้จาก detailMobile เปิดตาม canEditCustomerFromDetail สำหรับ customer action usersTerminal แสดงแก้ไขเมื่อผ่าน status-action permission
ลูกค้า/เอกสารถูก blockการสร้างเอกสารเรียก getSalesOrderBlockedReason(customer, user) ก่อนเริ่ม order/booking/borrow
Existing orderสร้างใบสั่งขายจะเช็ก getExistingCustomerOrderForBranch(customer, branch) แล้วถามเปิดใบเดิมหรือสร้างใหม่

Mobile vs POS Terminal​

เรื่องMobilePOS Terminal
Navigationstack screen เฉพาะและใช้ route paramsHomeScreen split-pane list/detail; action สลับ active menu และโหลด draft detail
Customer modesdefault, booking, borrow, requestnormal customer menu; งาน request/activation แยกเป็น customerActivation
Action จาก listกด row และ swipe primary actionกด row เท่านั้น; action อยู่ใน detail pane
สร้างเอกสารnavigate ไป detail screen ของเอกสารปลายทางbuild draft detail แล้วเปลี่ยน active menu เป็นเอกสารปลายทาง
ฟอร์มที่อยู่full-screen form ภายใน CustomerDetailmodal form ใน pane ขวา
Map pickerใช้ shared/native MapPickerModalใช้ Google Maps WebView ใน modal

Developer Handoff Map​

AreaCode
Mobile list/detailapps/mobile/src/screens/customerStack/customerListScreen, customerDetailScreen
Mobile permissionsapps/mobile/src/utils/customerPermissions.ts
Mobile copy/modesapps/mobile/src/screens/customerStack/config.ts
Terminal detailapps/pos-terminal/src/screens/HomeScreen/CustomerDetailForm.tsx
Terminal list/detail wiringapps/pos-terminal/src/screens/HomeScreen/index.tsx, DetailPane.tsx, ListPane.tsx
Terminal split dataapps/pos-terminal/src/services/splitMenuData.ts -> getCustomerSplitList, getCustomerSplitDetail
Customer serviceapps/*/src/services/customers.ts
Address helpersapps/mobile/src/utils/customerAddress.ts, terminal local helpers in CustomerDetailForm.tsx

เอกสารที่เกี่ยวข้อง​