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

ลูกค้า

เมนูลูกค้าเป็นหน้าค้นหาลูกค้า 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

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