WMS หยิบ-แพ็ค-ส่ง และการตัดสต็อกคลังจริง
แท็บ "1. หยิบ · แพ็ค · ขนส่ง (Pick & Pack)" ของ ระบบคลังสินค้า WMS ภาพรวม (SYS-06 Smart WMS) ทำงานกับตาราง wms_fulfillment_order หนึ่งแถวต่อหนึ่งใบงาน (เลขใบงาน wms_doc_no ผูกกับเลขใบกำกับขาย erp_inv_doc_no) ผู้ใช้กดเลื่อนสถานะทีละขั้นและแนบรูปหลักฐานของขั้นนั้น
ใบงานมาจากไหน
- ใบงานที่ส่งมาจากร้านค้าส่ง
/market: ตอนลูกค้ายืนยันสั่งซื้อ ระบบเขียนแถวmarket_b2b_order+wms_fulfillment_order(เริ่มที่ stagePICKING) +tms_delivery_stopใน transaction เดียวกัน - ฐาน
bcdemoมีใบงานตัวอย่างใส่ให้ตอน seed ฐานอื่นเริ่มว่าง (ดู WMS สต็อกคลังจริง เทียบสต็อกบัญชี และโซน/ช่องเก็บ (Stock Ledger Reconcile))
สถานะและกติกา
เส้นทาง POST /api/v1/wms/fulfillment (Next proxy /api/wms/fulfillment) รับ JSON หรือ multipart (ฟอร์มสูงสุด 32 MB):
- บังคับ
wms_doc_noถ้าไม่ส่งตอบ 400 "กรุณาระบุเลขที่ใบงานคลัง" ถ้าไม่พบใบงานตอบ 404 "ไม่พบใบงานคลังที่ระบุ" - ลำดับสถานะ:
WAITING_PICK→PICKING→PACKED→SHIPPEDถ้าไม่ส่งnext_stageระบบเลือกขั้นถัดไปให้เอง (สถานะอื่นที่ไม่รู้จักถูกพาไปSHIPPED) - ช่องที่ไม่ส่งมาจะเติมค่า: ผู้หยิบ/ขนส่งใช้ค่าเดิมของใบงาน, เลขพัสดุ
TH-WMS-<เวลา>, จำนวนกล่อง 2, น้ำหนัก 14.5 กก. - หน้าจอมีตัวเลือกขนาดกล่องมาตรฐาน (
THAI_BOX_SIZESเช่น BOX-S, BOX-M, BOX-L)
รูปหลักฐานต่อขั้น
- ผู้ใช้แนบหลายรูปได้ ระบบเก็บลง MinIO (โฟลเดอร์
wms_evidence) และเก็บ key + ป้ายกำกับ + เวลา ลงคอลัมน์evidence_photos_json(รายละเอียดที่ WMS รับเข้า ย้ายช่อง ตรวจนับ และรูปหลักฐาน (CreateMovement)) - ถ้าไม่ได้แนบรูปและขั้นเป็น PICKING/PACKED/SHIPPED (หรือส่ง
generate_sample_photo) ระบบสร้างรูปตัวอย่าง 2-4 รูปให้อัตโนมัติ ดังนั้นใบงานที่ไม่มีรูปจริงก็อาจมีรูปตัวอย่างอยู่ในอัลบั้ม
เมื่อเลื่อนเป็น SHIPPED (ตัดสต็อกจริง)
ทุกอย่างรันใน ExecBatch ชุดเดียว (transaction) ถ้าขั้นใดพังจะไม่มีกรณีที่ใบงานเป็น SHIPPED แต่สต็อกไม่ถูกตัด:
UPDATE wms_fulfillment_order(stage, ผู้หยิบ, ขนส่ง, เลขพัสดุ, กล่อง, น้ำหนัก, รูป, หมายเหตุ)WmsBinOpeningSQLตั้งยอดยกมา (OPENING) ของสินค้า x ช่อง ถ้ายังไม่มี- บันทึก
wms_movement_logประเภทOUTBOUND_SHIPเลขที่WMS-SHP-<เวลา>ปลายทาง "DOCK-OUT (ขึ้นรถขนส่ง)" พร้อมยอดก่อน/หลัง WmsBinRebuildSQLสร้างphysical_qtyของช่องใหม่จากสมุดความเคลื่อนไหว- ลด
reserved_pick_qtyลงเท่าจำนวนที่ส่ง UPDATE market_b2b_order SET order_status='SHIPPED_IN_TRANSIT'ตามwms_doc_noUPDATE tms_delivery_stop SET stop_status='IN_TRANSIT'เฉพาะจุดส่งที่ยังPENDING_LOAD
ยอดจอง (reserved) ที่โชว์บน Overview คำนวณใหม่ทุกครั้งจากใบงานที่ยังไม่ SHIPPED (WAITING_PICK, PICKING, PACKED) ต่อสินค้า ถ้าไม่มีใบงานค้างจึงใช้ค่า reserved_pick_qty ที่เก็บไว้ในช่อง
เงื่อนไข: ทำเฉพาะตอนเปลี่ยน "เข้า" SHIPPED จากสถานะอื่น เรียกซ้ำเมื่อเป็น SHIPPED แล้วจะไม่ตัดซ้ำ ฝั่ง TMS มีทางลัดที่ปิดใบงานคลังให้เองเมื่อส่งมอบสำเร็จ ดู TMS เที่ยวรถ จุดส่งมอบ และ e-POD (UpdateDeliveryPod / CreateTripDispatch)
การสแกนบนหน้าจอ
ช่องสแกนบาร์โค้ดในแท็บนี้ตรวจฝั่งเบราว์เซอร์เท่านั้น (handleBarcodeScanSubmit): รหัสที่ตรงกับช่องเก็บของใบงานหรือขึ้นต้นด้วย A-/B-/C- ถือว่าสแกนช่องแล้ว รหัสที่ตรงสินค้า/เลขใบงาน หรือยาวตั้งแต่ 3 ตัวอักษรขึ้นไป นับเป็นสแกนสินค้า +1 (ไม่เกินจำนวนในใบงาน) และมีปุ่ม "ยืนยันทั้งหมด" ผลการสแกนไม่ถูกส่งไปเก็บที่เซิร์ฟเวอร์
ที่มาในโค้ด
backend/internal/adapter/inbound/http/wms/handler.go:217-260ตัวจัดการAdvanceFulfillmentและอ่านฟอร์ม;:308-362ตรวจwms_doc_no, หาใบงาน, เลือกขั้นถัดไป, ค่าตั้งต้นbackend/internal/adapter/inbound/http/wms/handler.go:376-409เก็บรูปลง MinIO และสร้างรูปตัวอย่างbackend/internal/adapter/inbound/http/wms/handler.go:458-523ชุดคำสั่ง transaction ตอน SHIPPEDbackend/internal/adapter/inbound/http/wms/handler.go:923-946และ:1029-1031ยอดจองจากใบงานที่ยังไม่ส่งbackend/internal/adapter/inbound/http/market/handler.go:660-730สั่งซื้อ /market สร้างใบงานคลังและจุดส่ง TMSfrontend/wms/WmsDashboard.tsx:183ขนาดกล่อง;:508-549ตรรกะสแกน;:588-700เรียก/api/wms/fulfillment- ดูเพิ่ม: ระบบคลังสินค้า WMS ภาพรวม (SYS-06 Smart WMS) · WMS สต็อกคลังจริง เทียบสต็อกบัญชี และโซน/ช่องเก็บ (Stock Ledger Reconcile) · TMS เที่ยวรถ จุดส่งมอบ และ e-POD (UpdateDeliveryPod / CreateTripDispatch) · API โมดูลธุรกิจ /api/v1/{dashboard,crm,ai,wms,tms,procure,etax,market,autocare} (Business module endpoints) · ขายถึงรับเงิน (Order-to-Cash)