เมนูย้ายสินค้าตู้แช่ใช้ย้าย stock จาก warehouse group ของสาขาปัจจุบันไปยังคลัง/ตู้แช่ปลายทาง เป็น flow แบบเอกสาร: บันทึก header ก่อน, เพิ่ม/แก้/ลบรายการสินค้า, ระบุ batch ให้ครบ แล้วจึงส่งเอกสารเข้า B1
ทางเข้าในแอป
| App | Target |
|---|
| Mobile | TransferWarehouseList -> TransferWarehouseDetail |
| POS Terminal | transferWarehouse -> TransferWarehouseDetailForm |
Lifecycle ของเอกสาร
Workflow พร้อมเงื่อนไข
| กฎ | รายละเอียด |
|---|
| ต้องเลือกคลัง | ต้องมี whsCode และ whsName ของคลัง/ตู้แช่ปลายทางก่อนบันทึก |
| เปลี่ยนบริษัท | Mobile block การเปลี่ยนบริษัทหลังมี item แล้ว ถ้าต้องเปลี่ยนต้องลบรายการสินค้าออกให้หมดก่อน |
| ข้อมูลเจ้าของ | Header เก็บ branch, warehouse group, user code, responsible user, company, destination warehouse, notes และยอดรวม |
| Create vs update | ถ้ายังไม่มี transferBranchId จะ create header; ถ้ามีแล้วจะ patch header เดิม |
| รายการคลังปลายทาง | ตัวเลือก warehouse/sub-warehouse ปลายทางกรอง record ที่เป็น NF-/DR- ออกก่อนแสดง |
กฎ Item และ Batch
| กฎ | รายละเอียด |
|---|
| สิทธิ์แก้ item | เฉพาะเจ้าของเอกสารเท่านั้นที่เพิ่ม/แก้/ลบ item ได้ ส่วนการเลือก batch ขึ้นกับ canUserPickBatch(user) |
| item ที่มี batch เดิม | ถ้า item มี batch แล้ว ห้ามเพิ่มจำนวนมากกว่าจำนวนเดิม Mobile จะ trim batch เดิมเมื่อลดจำนวน |
| จำนวนสินค้า | จำนวนย้ายต้องมากกว่า 0 |
| ต้องมี batch | เมื่อ user ต้องเลือก batch ต้องมีอย่างน้อย 1 batch และทุก batch ต้องมีเลข batch กับจำนวนมากกว่า 0 |
| ยอด batch | เมื่อบังคับ batch ยอดรวม batch ต้องเท่ากับจำนวนย้ายของ item พอดี |
| ห้าม batch ซ้ำ | ใน item เดียวกันห้ามมี batch number ซ้ำ |
| ยอดคงเหลือ lot | สินค้าที่ไม่ใช่ dummy ห้ามใส่จำนวนเกินยอดคงเหลือของ lot ที่เลือก |
| วันที่ | ตรวจ expiry/due date ก่อนบันทึก ถ้าเปิดเงื่อนไข transfer due date/deposit logic ต้องให้ due date มากกว่าวันรับเข้า |
| Dummy item | dummy transfer item ใช้ batch ที่ generate/manual ได้ ไม่ต้อง lookup lot |
| warehouse code ใน payload | item payload ส่งทั้งคลังปลายทาง warehouseCode และคลังต้นทาง fromWarehouseCode โดย normalize ตามกฎ warehouse-code ของบริษัท |
กฎการส่ง B1
Service / API
| Operation | Service |
|---|
| List | GET /transfer-branches?page=...&branchId=...&whGrpCode=... ผ่าน getTransferWarehouses โดยส่ง whGrpCode ของ warehouse group ที่ผู้ใช้ login อยู่เพื่อกรองรายการ |
| Detail | GET /transfer-branches/:id ผ่าน getTransferWarehouseById |
| Header create | POST /transfer-branches ผ่าน createTransferWarehouse |
| Header update | PATCH /transfer-branches/:id ผ่าน updateTransferWarehouse |
| Header delete | DELETE /transfer-branches/:id ผ่าน deleteTransferWarehouse |
| Item create/update/delete | createTransferWarehouseItem, updateTransferWarehouseItem, deleteTransferWarehouseItem |
| Integration ปลายทาง | sendTransferWarehouseToB1(transferBranchId) |
ใน service มี DISABLE_TRANSFER_WAREHOUSE_MUTATION_API สำหรับเปลี่ยน mutation เป็น dry-run cache ได้ ตอนโค้ดที่ตรวจอยู่ค่านี้เป็น false
พจนานุกรมข้อมูลและแหล่งที่มา
เมนูนี้ต่างจากสามเมนูข้างต้น เพราะแอปสร้างและแก้ header/item เองผ่าน REST API โดยตรง ไม่ได้รับเอกสารต้นทางจาก MST. รายการใช้ GET /transfer-branches (กรองด้วย selected branchId และ whGrpCode), รายละเอียดใช้ GET /transfer-branches/:id, แล้วบันทึก header และ item ตามตารางนี้
| Field | คืออะไร | ได้มาจาก / กติกาก่อนส่ง |
|---|
transferBranchId, transferBranchNo, createdAt | ID, เลข และเวลาสร้างเอกสาร | backend คืนหลัง create/list/detail; ไม่ส่งใน create/update payload |
whsCode, whsName | รหัสและชื่อคลัง/ตู้แช่ปลายทาง | ผู้ใช้เลือกจาก warehouse picker; ต้องมีทั้งคู่ |
companyCode, companyName | รหัสและชื่อบริษัท | ผู้ใช้เลือก; ถ้าว่างใช้ค่า default จาก getCompanyOption |
notes | หมายเหตุเอกสาร | ผู้ใช้กรอก |
branchId, branchName | สาขาที่สร้างเอกสาร | selected branch (BranchId/branchId, BranchName fallback whsGrpName) |
amount | ยอดรวมเอกสาร | แอปส่ง 0 ใน header payload ปัจจุบัน |
whGrpCode, whGrpName | warehouse group ของผู้สร้าง | selected branch |
userCode | รหัสเจ้าของเอกสาร | user ที่ login |
userResponsible | ชื่อผู้รับผิดชอบ | ชื่อ + นามสกุล user; Terminal fallback userName/username |
priceList | price list สำหรับ B1 | ค่าคงที่ -2 |
Item (POST/PATCH /transfer-branches/:id/items)
| Field | คืออะไร | ได้มาจาก / กติกาก่อนส่ง |
|---|
id | ID item | backend คืนใน detail; ใช้เลือก endpoint update/delete; ไม่ส่งใน item payload |
productCode, productName | รหัสและชื่อสินค้า | ผู้ใช้เลือกจาก product inventory หรือ dummy item |
warehouseCode | คลังปลายทางของ item | คลังที่ผู้ใช้เลือกใน header/item แล้ว normalize ตามกฎบริษัทก่อนส่ง |
fromWarehouseCode | คลังต้นทางของ item | ค่าเดิมของ item ก่อน; fallback selected whsGrpCode; normalize ตามกฎบริษัทก่อนส่ง |
qty, price | จำนวนย้ายและราคาต่อหน่วย | ผู้ใช้กรอก/มาจาก product; แปลงเป็น number; qty ต้องมากกว่า 0 |
UOMCode, UOMEntry | หน่วยและ ID หน่วย | จาก product/item; UOMEntry fallback 0 |
remark | หมายเหตุ item | ผู้ใช้กรอก |
batchNumbers | batch ที่ย้าย | ผู้ใช้เลือก lot หรือกรอกสำหรับ dummy; ต้องครบตามสิทธิ์/กฎ batch |
Batch (items[].batchNumbers[])
| Field | คืออะไร | ได้มาจาก / กติกาก่อนส่ง |
|---|
batchNumber, quantity | เลขและจำนวน batch | ผู้ใช้เลือก/กรอก; quantity แปลงเป็น number และยอดรวมต้องเท่ากับ qty เมื่อบังคับเลือก batch |
admissionDate | วันที่รับเข้า | อ่าน addmisionDate/admissionDate ของ batch เดิมได้; เมื่อส่งใช้ admissionDate เป็น YYYY-MM-DDTHH:mm:ss |
manufacturingDate, expiryDate | วันที่ผลิต/หมดอายุ | batch เดิมหรือวันปัจจุบันเป็น fallback |
dueDate | วันครบกำหนด | จาก batch editor และส่งเป็น YYYY-MM-DDTHH:mm:ss |
สิทธิ์และ guard
| เรื่อง | รายละเอียด |
|---|
| Terminal menu key | transferWarehouse |
| deptCode ที่เห็นเมนู | -2, 1, 2, 3, 4, 7, 29, 21, 8, 9, 12, 13, 16, 20, 22, 23, 27, 28 |
| เงื่อนไขสาขา | allowNonMainBranch = true; ผู้ใช้คลังสาขาย้าย stock ภายในสาขาได้ |
| Full non-main access | ผู้ใช้ที่มีสิทธิ์ full access ของ non-main warehouse ผ่าน menu access ได้ |
| เจ้าของเอกสาร | ผู้ใช้ที่สร้าง/บันทึกเอกสารเป็นเจ้าของสิทธิ์แก้ item และส่ง B1 |
| สิทธิ์เลือก batch | canUserPickBatch(user) คุมสิทธิ์ระบุ batch rows; deptCode ปัจจุบันคือ 2, 4, 8, 12, 22, 28, 29 |
Mobile vs POS Terminal
| เรื่อง | Mobile | POS Terminal |
|---|
| Detail | stack detail screen | detail form ใน HomeScreen |
| Header save | ensureTransferBranch / handleSaveHeader | saveHeader ระหว่าง submit item |
| Guard บริษัท | block เปลี่ยนบริษัทเมื่อมี item แล้ว | ใช้เจตนาเดียวกันใน detail flow |
| Batch picker | โหลด lot ด้วย source warehouse ที่แปลงตาม company | โหลด lot จาก warehouse group/company ของสาขา |
| ส่ง B1 | ต้องเป็นเจ้าของ + item/batch ครบ | ใช้กฎเจ้าของ + ความครบเดียวกัน |
Developer Handoff Map
| Area | Code |
|---|
| Mobile detail | apps/mobile/src/screens/transferWarehouseStack/transferWarehouseDetailScreen/index.tsx |
| Mobile service | apps/mobile/src/services/transferWarehouse.ts |
| Terminal detail | apps/pos-terminal/src/screens/HomeScreen/TransferWarehouseDetailForm.tsx |
| Terminal service | apps/pos-terminal/src/services/transferWarehouse.ts |
| Product lot lookup | services/common.ts / getProductLots |
| Product inventory | services/products.ts |
เอกสารที่เกี่ยวข้อง