รับสินค้าจากสาขา
เมนูรับสินค้าจากสาขาใช้รับเอกสารโอนเข้ามายังสาขาที่เลือก หน้านี้รับได้ทั้งรายการที่มากับเอกสารโอน และเพิ่มสินค้าใหม่ในหน้ารับเข้าได้เมื่อผู้ใช้กรอก Container No. หรือทะเบียนรถเพื่อสร้างเลข batch
ทางเข้าในแอป
| App | Target |
|---|---|
| Mobile | TransferInList -> TransferInDetail |
| POS Terminal | transferIn -> TransferInDetailForm |
Workflow หลัก
เส้นทางเพิ่มสินค้าใหม่
ทั้ง Mobile และ Terminal มี flow เพิ่มสินค้าใหม่ในหน้ารับเข้า:
- ผู้ใช้กรอก Container No. หรือทะเบียนรถ
- ระบบดึงเลขท้าย 4 หลัก
- ระบบเปิด inventory ด้วย
getProductBranchContext,syncProductInventoryและ local subscription - รายการสินค้าถูกกรองตามบริษัท และรวม dummy products
- ผู้ใช้กรอกจำนวนมากกว่า 0
- ระบบสร้าง line ใหม่ด้วย
lineNum: -1,isDel: trueแล้วเปิด batch draft ที่ generate ให้ทันที
จุดนี้ต่างจากโอนสินค้าไปสาขา เพราะ Transfer In เพิ่มรายการรับใหม่ได้ แต่ Transfer Out ทำงานกับรายการโอนออกที่มีอยู่เป็นหลัก
กฎ Batch และวันที่
| กฎ | รายละเอียด |
|---|---|
| Container/ทะเบียนรถ | ต้องมี ก่อนเพิ่มสินค้าใหม่หรือสร้าง batch ใหม่ ระบบใช้เลขท้าย 4 หลักเป็น suffix |
| Line จากเอกสารเดิม | batch picker โหลด lot ด้วย getProductLots({ itemCode, whsCode: line.warehouseCode, company }) |
| Line ที่เพิ่มใหม่ | สร้าง batch จาก generateBatchCode(getSelectedWhsGrpCode(branch)) + suffix ที่กรอก |
| ห้าม batch ซ้ำ | ในสินค้า 1 line เลือก batch เดิมซ้ำไม่ได้ |
| จำนวน | จำนวน batch ห้ามติดลบ ส่วนจำนวนตอนเพิ่มสินค้าต้องมากกว่า 0 |
| ยอด lot | ถ้า lot ที่เลือกมี quantity ต้องกรอกไม่เกินยอดคงเหลือของ lot |
| การรับ line เดิม | line จากเอกสารโอนเดิมสามารถ submit โดยไม่มี batch ที่รับจริงได้ ถ้าไม่มี batch quantity ที่มากกว่า 0 payload จะใช้จำนวนเดิมของ line และส่ง batchNumbers: [] |
| กรณี batch รวมเป็น 0 | ถ้า line มี batch แต่รวมจำนวนเป็น 0 ต้องให้ผู้ใช้ confirm แล้วส่งจำนวนเดิมโดยไม่ส่ง batch |
| คลังฝาก | เมื่อ branch.isMain === false ใช้กฎวันที่แบบห้องฝาก โดย due date ห้องฝากต้องมากกว่าวันรับเข้า |
Payload ตอนบันทึก
หมายเหตุสำหรับ developer:
refDocNumเก็บเลขเอกสารโอนต้นทางnumAtCardสร้างจากdocNumต้นทางและ timestamp ปัจจุบัน- warehouse code ที่ส่งถูกสร้างใหม่จาก warehouse group ของสาขาที่เลือก; ถ้า company เป็น
NFFDBและ code ยังไม่ขึ้นต้นNF-จะ prefix เป็นNF- - POS Terminal เก็บ warehouse tab ต้นทางใน list item เป็น
sourceWhsCodeแล้ว fallback ผ่านtoWhsCode/branch context ตอนสร้าง line สินค้าใหม่ receiptDateถูกส่งเป็นadmissionDateด้วยรูปแบบYYYY-MM-DDTHH:mm:sstransferInDueDateถูกส่งเป็นdueDateเฉพาะกรณีคลังฝาก ด้วยรูปแบบYYYY-MM-DDTHH:mm:ss
พจนานุกรมข้อมูลและแหล่งที่มา
ตารางนี้ครอบคลุม field ที่ Mobile และ POS Terminal อ่านหรือส่งใน flow รับจากสาขา. รายการตั้งต้นมาจาก GET /transfers-in?whsCode={selectedWarehouseTab} โดย tab คือ warehouse group ที่เลือกและอาจมี NF- variant; ทั้งสองแอปสร้าง payload เพื่อส่ง POST /transfer-in.
Header
| Field | คืออะไร | ได้มาจาก / กติกาก่อนส่ง |
|---|---|---|
company | รหัสบริษัท | จากเอกสารโอนเข้า API |
docNum | เลขเอกสารโอนต้นทาง | จาก API; ใช้สร้าง numAtCard และเก็บเป็น refDocNum |
docDate, docDueDate, taxDate | วันที่เอกสาร/กำหนดส่ง/ภาษี | จาก API |
toWhsCode | คลังปลายทางที่มากับเอกสาร | จาก API; Terminal ยังเก็บ context tab ต้นทางเป็น sourceWhsCode ภายใน list state |
comments | หมายเหตุเอกสาร | จาก API |
numAtCard | เลขอ้างอิงเอกสารรับเข้า | แอปสร้างเป็น ${docNum}_${เวลาปัจจุบัน DD-MM-YYYY HH:mm} เมื่อ submit |
refDocNum | เลขเอกสารโอนที่อ้างอิง | คัดลอกจาก docNum ของเอกสารต้นทาง |
branchId | ID สาขารับเข้า | selected branch (BranchId) ก่อน, fallback ค่าเอกสาร |
branchCode, branchName | warehouse group code/name ของสาขารับเข้า | selected branch (whsGrpCode/whsGrpName) ก่อน, fallback BranchCode/BranchName หรือค่าเอกสาร |
userCode, userName | ผู้รับสินค้า | user ที่ login ก่อน, fallback ค่าเอกสาร |
payloadBefore | snapshot JSON ก่อนแก้ไข | สร้างจากเอกสารที่เลือกใน detail screen |
Line (lines[])
| Field | คืออะไร | ได้มาจาก / กติกาก่อนส่ง |
|---|---|---|
lineNum | ลำดับ line | จาก API; line ใหม่ใช้ -1; service เรียงก่อนส่ง |
itemCode, itemDescription | รหัสและชื่อสินค้า | line เดิมจาก API; line ใหม่จาก product inventory/dummy product |
grossPrice, grossTotal, unitPrice, lineTotal, vatSum, itemCost, stockValue, discPercent | ราคา ยอด และต้นทุนของ line | จาก API/line ใหม่ แล้วแปลงเป็น number ก่อนส่ง |
quantity | จำนวนรับ | ถ้ามี batch รวมมากกว่า 0 ใช้ยอดรวม batch (cal); ถ้าไม่มี ใช้จำนวนเดิมของ line |
weight | น้ำหนัก | จาก line/product แล้วแปลงเป็น number |
warehouseCode | คลังรับเข้า | สร้างจาก warehouse group ของ selected branch; company NFFDB prefix NF- เมื่อยังไม่มี prefix |
warehouseName | ชื่อคลัง | จาก line เดิมหรือค่าว่างใน line ใหม่ |
vatGroup, grRemarks, costingCode ถึง costingCode5, uomCode, uomEntry | ภาษี, หมายเหตุรับเข้า, cost center และหน่วย | จาก API/ผลิตภัณฑ์; uomEntry แปลงเป็น number |
batchNumbers | lot/batch ที่รับจริง | ส่งเฉพาะเมื่อยอด batch รวมมากกว่า 0; ดูตารางด้านล่าง |
Batch (lines[].batchNumbers[])
| Field | คืออะไร | ได้มาจาก / กติกาก่อนส่ง |
|---|---|---|
batchNumber | เลข lot/batch | line เดิมเลือกจาก lot API; line ใหม่ generate จาก warehouse/date และ suffix container/ทะเบียนรถ หรือผู้ใช้กรอก |
quantity | จำนวนที่รับใน lot | ผู้ใช้กรอก แล้วแปลงเป็น number |
admissionDate | วันที่รับเข้า | ใช้ receiptDate ที่ผู้ใช้เลือก; ส่งเป็น YYYY-MM-DDTHH:mm:ss |
manufacturingDate, expiryDate | วันที่ผลิต/หมดอายุ | มาจาก lot เดิมหรือ batch editor; expiryDate ส่งเป็น string ว่างได้ |
dueDate | วันครบกำหนดห้องฝาก | ใช้ transferInDueDate เฉพาะ selected branch ที่เป็นคลังฝาก/non-main และส่งเป็น YYYY-MM-DDTHH:mm:ss |
สิทธิ์และ guard
| เรื่อง | รายละเอียด |
|---|---|
| Terminal menu key | transferIn |
| deptCode ที่เห็นเมนู | -2, 1, 2, 3, 4, 7, 29, 21, 8, 9, 12, 22, 27, 28 |
| เงื่อนไขสาขา | allowNonMainBranch = true; ถ้าเลือกคลังสาขา non-main เมนูเปิดได้แม้ deptCode ไม่อยู่ในชุด stock menu |
| Full non-main access | ผู้ใช้ที่มีสิทธิ์ full access ของ non-main warehouse ผ่าน menu access ของกลุ่ม stock นี้ได้ |
| Context รายการ | หน้ารายการผูกกับ warehouse/context tab ที่เลือก |
Mobile vs POS Terminal
| เรื่อง | Mobile | POS Terminal |
|---|---|---|
| Product inventory | ใช้ product branch context subscription | ใช้ pattern context/subscription เดียวกัน |
| เพิ่มสินค้า | picker เต็มจอและ quantity modal | modal ใน split-pane detail |
| วันที่ | มี receipt date และ deposit due date picker | มี receipt date และ deposit due date picker |
| หลังบันทึก | go back ถ้าทำได้ ไม่งั้น replace list | refresh list แล้วปิด detail |
Developer Handoff Map
| Area | Code |
|---|---|
| Mobile detail | apps/mobile/src/screens/transferInStack/transferInDetailScreen/index.tsx |
| Mobile helpers | apps/mobile/src/screens/transferInStack/helpers.ts |
| Terminal detail | apps/pos-terminal/src/screens/HomeScreen/TransferInDetailForm.tsx |
| Mobile service | apps/mobile/src/services/transferIn.ts |
| Terminal service | apps/pos-terminal/src/services/transferIns.ts |
| Product inventory | services/products.ts |