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

สินค้า

เมนูสินค้าเป็น inventory lookup ตามสาขา ใช้ร่วมกับใบสั่งขาย ใบจองราคา งานโอนสินค้า รับสินค้าเข้า และคืนสินค้า เมื่อเปิดจากเมนูสินค้า ทั้ง Mobile และ POS Terminal เป็นหน้า lookup แบบ read-only เหมือนกัน Mobile จะแสดงฟอร์มเพิ่มเข้าใบสั่งขายเฉพาะเมื่อ ProductList/ProductDetail ถูกเปิดจาก flow ใบสั่งขายพร้อม orderId หรือ draftOrder; ส่วน POS Terminal เมนูสินค้าปกติอ้างอิงพฤติกรรม standalone ของ Mobile และไม่แสดงฟอร์มเพิ่มสินค้า

สำหรับ developer หน้านี้สำคัญเพราะแสดง shape ของสินค้าแบบเดียวกับที่เอกสารอื่นใช้ต่อ เช่น รหัสสินค้า ชื่อสินค้า คลัง สต๊อก SAP สต๊อกจอง สต๊อกขายได้ ราคา UOM การคุมน้ำหนัก บริษัท สี และ step price

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

AppTarget
MobileProductList -> ProductDetail
POS Terminalproduct -> ProductDetailForm

Workflow ผู้ใช้

Data และ API Flow

เรื่องรายละเอียด
Branch contextทั้งสองแอปเรียก getProductBranchContext() และสาขาที่เลือกต้องมี whsGrpCode; ถ้าไม่มีจะขึ้น error ไม่พบข้อมูลสาขาสำหรับสินค้า
Inventory refreshsyncProductInventory(context, page) สั่ง refresh inventory จาก MST และยิง promotion sync ไป Firebase แบบ fire-and-forget
API สาขาหลักถ้า branchCode === whsGrpCode จะเรียก /products?...&whGrpCode={whsGrpCode}
API สาขาย่อย/non-mainถ้า branch และ warehouse group ไม่ตรงกัน จะเรียก /products/sub-inventories?...&whGrpCode={branchCode}&whsCode={whsGrpCode}
Firebase collectionอ่านสินค้า inventory จาก ${whsGrpCode}-inventories
Warehouse codesทั้งสองแอปใช้ whsGrpCode, PC-{whsGrpCode}, และ NF-{whsGrpCode}
Filter รายการตัด row ที่ price <= 0, กัน itemCode ซ้ำ และ list/detail ต้องมี itemCode ที่ใช้ได้
Step priceDetail โหลด getProductStepPrice({ itemCode, uomCode }) เฉพาะเมื่อ stepPriceFlag เป็นจริง และ flow ขาย/จองราคานำแนวคิดเดียวกันไปใช้เมื่อจำนวนเปลี่ยน
Dummy productsบางเอกสารรวม dummy products สำหรับงานเฉพาะทาง แต่เมนูสินค้าหลักนี้เป็น inventory-product lookup

พฤติกรรมหน้า List

เรื่องMobilePOS Terminal
วิธีโหลดเรียก syncProductInventory() ครั้งแรก แล้ว subscribe Firestore ผ่าน subscribeProductInventory()เรียก getProductSplitList({ page, search, bookingOnly }) และ append page โดย merge id ซ้ำ
Searchค้นใน memory ด้วย itemName และ itemCodeservice ค้นเหมือน Mobile คือใช้เฉพาะ itemName และ itemCode
Tabทั้งหมด และ ติดจอง; tab ติดจองคงไว้เฉพาะสินค้า booking > 0มี tab เดียวกัน; ติดจอง ส่ง bookingOnly: true เข้า split list service
Summaryheader แสดงจำนวนสินค้าทั้งหมดและจำนวนสินค้าที่ติดจองsplit list ใช้ count ของ pane กลาง และรองรับ load more
Refreshpull-to-refresh เรียก syncProductInventory(branchContext)pull-to-refresh และ reload เมนูเรียก split list แบบแบ่งหน้าอีกครั้ง
Empty stateแสดงไม่พบรายการหลังได้ snapshot แรกแล้วใช้ loading/error/empty state กลางของ split-pane

พฤติกรรม Detail และ Action

ActionMobilePOS Terminal
เปิด detailnavigate ไป ProductDetail พร้อม productId, itemCode, itemName, stepPriceFlag, uomCode และ sales-order context ถ้ามีHomeScreen เรียก getProductSplitDetail(item), โหลด detail ด้วย itemCode, แล้วส่ง detail.raw เข้า ProductDetailForm
Refresh detailpull-to-refresh โหลด getProductInventoryDetail(context, productId) และ step price ถ้าจำเป็นdetail refresh จากการเลือก/reload pane; step price ถูกโหลดก่อนส่ง raw record เข้า ProductDetailForm
เพิ่มเข้าใบสั่งขายแสดงเฉพาะเมื่อ ProductList/ProductDetail ถูกเปิดมาพร้อม orderId หรือ draftOrder; validate จำนวน, สร้าง order ก่อนถ้ามีแค่ draftOrder, แล้วเรียก createOrderItem()ไม่แสดงจากเมนูสินค้าปกติ เพื่อให้ตรงกับ standalone Mobile behavior การเพิ่มสินค้าใน terminal อยู่ใน product picker ของ flow ใบสั่งขาย
เงื่อนไขจำนวนจำนวนต้องมากกว่า 0จำนวนต้องมากกว่า 0
เงื่อนไขน้ำหนักสินค้า weight-base เพิ่มหรือแก้ในใบสั่งขายโดยมีน้ำหนัก 0 ได้; ระบบจะตรวจน้ำหนักอีกครั้งเมื่อสร้างใบแจ้งหนี้เงื่อนไขเดียวกัน: สินค้า weight-base บันทึกน้ำหนัก 0 ได้ แต่สร้างใบแจ้งหนี้ไม่ได้จนกว่าน้ำหนักจะไม่เท่ากับ 0
ราคาผู้ใช้แก้ราคาในฟอร์มเพิ่มสินค้าได้ โดย default จาก price ของสินค้าผู้ใช้แก้ราคาในฟอร์มเพิ่มสินค้าได้ โดย default จาก price ของสินค้า
Preview ยอดweight-base: qty * price * weight; ไม่ใช่ weight-base: qty * priceคำนวณเหมือนกัน
ขอบเขต mutationเมนูสินค้าปกติไม่แก้ product master, จำนวน stock หรือ item ใบสั่งขาย ส่วน add action ของ Mobile เป็นบริบทของ route ใบสั่งขาย ไม่ใช่เมนูสินค้าปกติขอบเขต standalone เดียวกัน

Field สำคัญสำหรับ Developer

Fieldใช้ทำอะไร
idFirestore document ID ที่ mobile ใช้เปิด detail; terminal detail โหลดข้อมูลล่าสุดด้วย itemCode
itemCode / itemNameidentity หลักของสินค้าใน list, detail และ payload item ทุกเอกสาร
whsCode / warehouseCodeจำเป็นเมื่อเพิ่มสินค้าในใบสั่งขาย ใบจองราคา โอนสินค้า และรับสินค้าเข้า ถ้าขาดมักทำให้ downstream screen บันทึกไม่ได้
price, salUomCode, salUomEntryใช้สร้างราคาและ UOM ของ line item
onHand, booking, available stockUI แสดง stock SAP, stock จอง และ stock ขายได้จาก onHand - booking; เอกสารอื่นใช้ประกอบ validation stock/booking
weight, weightBaseFlagกำหนดว่าสินค้าขายเป็นหน่วยนับหรือคุมน้ำหนัก สินค้า weight-base มีน้ำหนัก 0 ในใบสั่งขายได้ แต่ต้องระบุน้ำหนักไม่เท่ากับ 0 ก่อนสร้างใบแจ้งหนี้
stepPriceFlag / step price rowsใช้แสดง tiered price และใช้เลือกราคาใน sales/booking เมื่อจำนวนเปลี่ยน
colorใช้ทำสี card/list/detail เพื่อแยกกลุ่มสินค้า ถ้า hex ไม่ถูกต้องจะ fallback เป็น accent ของ theme
company fieldsเอกสารบางหน้าอาจใช้ field บริษัทเพื่อกรองสินค้าที่เข้ากัน แต่ search ของเมนูสินค้าตรงกับ Mobile คือใช้ชื่อ/รหัสสินค้า

สิทธิ์และ Guard

เรื่องรายละเอียด
Mobile menu permissionhome menu ใช้ชุด deptCode เดียวกับ terminal: -2, 1, 2, 3, 4, 7, 29, 21, 8, 9, 12, 20, 22, 23, 27, 28, 13, 16
Terminal menu keyproduct
Terminal menu permissionMENU_PRODUCT ใช้ -2, 1, 2, 3, 4, 7, 29, 21, 8, 9, 12, 20, 22, 23, 27, 28, 13, 16
เงื่อนไขสาขาเมนูสินค้าไม่ได้บังคับเฉพาะสาขาหลัก แต่ต้องมี selected branch product context และ whsGrpCode
สิทธิ์เพิ่มเข้าใบสั่งขายMobile แสดงฟอร์มเพิ่มสินค้าเฉพาะเมื่อเปิดมาจาก flow ใบสั่งขายพร้อม orderId หรือ draftOrder ส่วน POS Terminal ไม่เปิด action นี้จากเมนูสินค้าปกติ การเพิ่ม item อยู่ใน flow ใบสั่งขาย
Product mutationเมนูนี้ไม่มี create/update/delete product master การเปลี่ยนจำนวนสินค้าเกิดผ่าน document flow อื่นเท่านั้น

Mobile vs POS Terminal

เรื่องMobilePOS Terminal
Navigationproduct stack เฉพาะเมนูHomeScreen split-pane menu key product
Listlist จาก snapshot พร้อม search, tab, summary count, pull refreshsplit list แบบแบ่งหน้า พร้อม search, tab, load more, pull refresh
Detaildetail เต็มจอ มี pull refresh และ bottom add form เมื่อมีบริบทdetail ด้านขวา มี add card เมื่อมีสิทธิ์
Add actionเฉพาะเมื่อเปิดจาก Mobile sales-order route contextไม่เปิดจากเมนูสินค้าปกติ
Reuseproduct picker components ใน document stacksshared product picker/detail patterns ใน HomeScreen

Developer Handoff Map

AreaCode
Mobile list/detailapps/mobile/src/screens/productStack/productListScreen, productDetailScreen
Mobile home permissionapps/mobile/src/screens/homeScreen/index.tsx -> MENU_PRODUCT
Terminal detailapps/pos-terminal/src/screens/HomeScreen/ProductDetailForm.tsx
Terminal home wiringapps/pos-terminal/src/screens/HomeScreen/index.tsx, DetailPane.tsx, ListPane.tsx
Terminal split dataapps/pos-terminal/src/services/splitMenuData.ts -> getProductSplitList, getProductSplitDetail
Product serviceapps/*/src/services/products.ts
Picker reuseOrderFlowShared, BookingProductPicker, inventory transfer forms

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