ใบเบิกยืม
ใบเบิกยืมเป็น flow สำหรับเบิกสินค้า/ปลาออกไปก่อนเข้าสู่การขายปกติ จึงคล้ายใบสั่งขายตรงที่เริ่มจากลูกค้า สาขา/คลัง รายการสินค้า จำนวน และภายหลังสามารถแปลงเป็นใบสั่งขายได้ จุดที่ต่างคือประเภทการเบิก เงื่อนไขวันที่มาเบิก/ทะเบียนรถของ SPEC ในสาขาย่อย จำนวนที่คาดว่าจะซื้อ การรับงาน/ตัดสต๊อก การ retry เมื่อ sub-borrow ล้มเหลว และการ convert ไปใบสั่งขาย
จุดเข้าใช้งาน
| แอป | หน้าจอ |
|---|---|
| Mobile | BorrowList -> BorrowDetail |
| POS Terminal | borrowFish -> BorrowDetailForm ใน HomeScreen |
ประเภทการเบิก
| Type | ความหมาย |
|---|---|
SPEC | ให้ลูกค้าดู |
MARKET | เดินตลาด |
VIDEO | ถ่ายวีดีโอ |
SEMINAR | สัมมนา |
DESTROY | ทำลาย |
LAB | วิจัย |
ต้องเลือกประเภทก่อนเพิ่มสินค้า ถ้าเป็นสาขาย่อยและจะเปลี่ยนเป็น SPEC แต่มีสินค้าอยู่แล้ว ระบบจะบล็อกและให้ลบสินค้าออกก่อน เพราะ SPEC มีเงื่อนไขเพิ่มเรื่องวันที่มาเบิกและทะเบียนรถลูกค้า
สถานะเอกสาร
Flow การทำงาน
เงื่อนไขหัวเอกสาร
| หัวข้อ | พฤติกรรม |
|---|---|
| ลูกค้า | ใบเบิกเริ่มจากลูกค้าที่เลือก และเก็บ customer code/name |
| สาขาและกลุ่มคลัง | payload ส่ง branchId, whGrpCode, whGrpName จากสาขา/เอกสาร |
| ประเภทการเบิก | ต้องเลือกก่อนเพิ่มสินค้าและก่อน confirm |
| หมายเหตุ | เก็บใน notes และแก้ได้เมื่อ draft ยัง editable |
dateOfPickup | ส่งเฉพาะประเภท SPEC; ถ้าไม่ใช่ SPEC จะส่งเป็น null |
| ทะเบียนรถลูกค้า | สำหรับสาขาย่อย SPEC ต้องกรอกก่อนเพิ่มสินค้า |
| การล็อกวันที่มาเบิก | สาขาย่อย SPEC แก้วันที่ไม่ได้เมื่อมีสินค้าแล้ว |
| วันที่ย้อนหลัง | Mobile บล็อกวันที่มาเบิกที่น้อยกว่าวันปัจจุบัน |
เงื่อนไขสินค้าและจำนวน
กฎสำคัญของสินค้า:
| กฎ | สาขาหลัก | สาขาย่อย |
|---|---|---|
| จำนวนที่คาดว่าจะซื้อ | ไม่บังคับ payload เป็น 0/undefined | บังคับ และต้องมากกว่า 0 |
| จำนวนต่อบรรทัด | เฉพาะ SPEC (ให้ลูกค้าดู) สูงสุด 3 ชิ้น; ประเภทอื่นไม่มี limit ต่อบรรทัด | สูงสุด 5 ชิ้นทุกประเภท |
| จำนวนรายการสินค้า | เฉพาะ SPEC สูงสุด 3 รายการ; ประเภทอื่นไม่มี limit จำนวนรายการ | ไม่มี guard จำกัด 3 รายการใน UI |
SPEC วันที่/ทะเบียนรถ | ไม่ถูกบังคับด้วย branch guard นี้ | ต้องกรอกก่อนเพิ่มสินค้า |
| รูปแบบจำนวน | จำนวนเต็มบวกเท่านั้น | จำนวนเต็มบวกเท่านั้น |
| stock guard | ตอนเพิ่มตรวจ onHand - booking; ตอนแก้ใช้ stock ที่เหลือรวมจำนวนเดิมของ item นั้น | เหมือนกัน |
payload ของ item สร้างจาก product inventory เช่น product code/name, qty, expectedQty, price, amount, weight, warehouse, company, tax/VAT, UOM, weight-base flag, step-price flag และ editPriceBy = null
การแก้ไขสินค้าเดิม
การแก้ item ทำได้เฉพาะตอนเอกสารยังเป็น draft ที่แก้ได้ เมื่อแก้ ระบบโหลด inventory ปัจจุบันจาก product code แล้วคำนวณ maxEditableStock = availableStock + originalQty หากเป็นสินค้าเดิม เพื่อให้ผู้ใช้คงจำนวนเดิมหรือลดจำนวนได้ แต่ยังกันไม่ให้จำนวนสุดท้ายเกิน stock
สำหรับสาขาย่อย expectedQty ยังบังคับมากกว่า 0 และ limit จำนวนต่อบรรทัดยังคงเป็นไม่เกิน 5 ชิ้นทุกประเภท ส่วนสาขาหลักจำกัดไม่เกิน 3 ชิ้นเฉพาะ SPEC; ประเภทอื่นไม่จำกัดจำนวนต่อบรรทัด ทุกประเภทยังต้องเป็นจำนวนเต็มบวกและไม่เกิน stock ที่ใช้ได้
Product Picker และการแสดงสินค้ารายการแรก
- ถ้าใบเบิกมี
borrowIdแล้ว การเพิ่มสินค้าจะไม่แสดง loading แบบเต็มหน้าจอที่บังหน้า detail และ product picker จะยังเปิดอยู่หลังเพิ่มสำเร็จ เพื่อให้เลือกเพิ่มได้ต่อเนื่อง - Draft ใหม่ใช้การ persist สองช่วง: สร้าง header ของใบเบิกก่อน ใช้
borrowIdที่ API คืนกลับมาเป็น identity สำหรับสร้าง item แล้วจึงสร้างสินค้ารายการแรก borrowNoเป็นเลขเอกสารสำหรับแสดงผล ไม่ใช้แทนborrowIdในการสร้าง item- หลังสร้างสินค้ารายการแรก ระบบจะ refresh detail/list ของใบเบิก และ sync route ด้วย identity ที่ได้กลับมา ทำให้เห็น header และสินค้ารายการแรกทันที ไม่ต้องรอเพิ่มสินค้ารายการที่สอง
- Mobile และ POS Terminal ใช้พฤติกรรมการ persist เดียวกัน
Confirm, Accept, Complete, Retry
ตอน confirm ระบบจะบันทึกหัวเอกสารล่าสุดก่อน แล้วเรียก confirmBorrow หลังจาก confirm แล้วการแก้แบบ draft จะถูกล็อกตามสถานะ การ complete จะเรียก approveBorrow ถ้าไม่มี failed sub-borrow แต่ถ้า hasFailedSubBorrow เป็น true ปุ่ม complete จะกลายเป็น retry และเรียก retryBorrow
แปลงเป็นใบสั่งขาย
ปุ่ม convert แสดงเมื่อเข้าเงื่อนไขครบ:
| เงื่อนไข | ค่าที่ต้องเป็น |
|---|---|
| สาขา | สาขาย่อย |
| ประเภทการเบิก | SPEC |
| สถานะ | DONE |
การ convert เรียก convertBorrow(borrowId) และควรส่งบริบทลูกค้า สาขา/คลัง สินค้า จำนวน expected quantity และราคาเข้าสู่ flow ใบสั่งขาย หลัง convert สถานะจะเป็น CONVERTED
การพิมพ์
มี 2 เส้นทางพิมพ์:
| เอกสาร | พฤติกรรม |
|---|---|
| Borrow pack | พิมพ์เอกสารใบเบิกฝั่งลูกค้า/แพ็กสินค้า |
| Borrow storage | พิมพ์เอกสารใบเบิกฝั่งคลัง |
ทั้งสองปุ่มต้องมีสินค้าอย่างน้อย 1 รายการ การพิมพ์ไม่เปลี่ยนสถานะเอกสารเอง
สิทธิ์และ Guard
| สิทธิ์ | กฎ |
|---|---|
| Terminal menu key | borrowFish |
| deptCode ที่เห็นเมนู | -2, 1, 2, 3, 4, 7, 29, 21, 8, 9, 12, 13, 14, 30, 16, 20, 22, 23, 27, 28 |
| สร้างใบเบิก | Admin หรือ dept -2, 1, 2, 4, 7, 8, 9, 13, 16, 21, 29 |
| ยกเลิก/ลบใบเบิก | Admin; เจ้าของเอกสารเมื่อสถานะ NEW; หรือแผนก/ผู้ใช้ที่อนุญาตเมื่อสถานะ NEW หรือ WAITING |
| แผนกยกเลิก | -2, 1, 2, 4, 9; dept 8 และ 22 override ได้ใน NEW/WAITING |
| user code override ยกเลิก | 008045, 012521, 012508, 008051, 012388, 012428, 008060 |
| B1 processing | Admin หรือ dept 2, 8, 12, 22, 28 |
| Owner processing | เจ้าของเอกสาร process ได้ถ้า borrow type ไม่ใช่ DESTROY |
| Main branch processing | สาขาหลักต้องมีสิทธิ์ B1 processing |
| แก้ draft | สถานะต้องเป็น NEW และผู้ใช้เป็นเจ้าของ draft หรือเอกสารยังไม่ persist |
| แก้ประเภทการเบิก | ทำได้ก่อน persist หรือโดยเจ้าของเอกสาร |
Mobile vs POS Terminal
| หัวข้อ | Mobile | POS Terminal |
|---|---|---|
| การนำทาง | borrow stack list/detail | HomeScreen split-pane menu borrowFish |
| Product flow | borrow detail screen และ product-flow hook | borrow detail form, panels, product picker |
| บันทึกหัวเอกสาร | บันทึกผ่าน borrow service เมื่อ detail เดิมเปลี่ยน | บันทึก raw detail ผ่าน HomeScreen handlers |
| Validation | business rules เดียวกันใน mobile components | business rules เดียวกันใน HomeScreen handlers |
| พิมพ์ | printBorrowPack, printBorrowStorage | ใช้ print utilities เดียวกัน |
| Convert | เรียก convertBorrow แล้ว refresh detail | เรียก convertBorrow แล้ว refresh split list/detail |
API และ Data Map
| Operation | Service |
|---|---|
| List | getBorrows |
| Detail | getBorrowDetail(borrowId) |
| Create/update/delete header | createBorrow, updateBorrow, deleteBorrow |
| Item CRUD | createBorrowItem, updateBorrowItem, deleteBorrowItem |
| Confirm | confirmBorrow |
| Accept | acceptBorrow |
| Complete/cut stock | approveBorrow |
| Retry failed sub-borrow | retryBorrow |
| Convert to sales order | convertBorrow |
Developer Handoff Map
| ส่วน | โค้ด |
|---|---|
| Mobile permissions/helpers | apps/mobile/src/utils/borrow.ts |
| Mobile list/detail | apps/mobile/src/screens/borrowStack/borrowListScreen, borrowDetailScreen |
| Mobile product flow | apps/mobile/src/screens/borrowStack/borrowDetailScreen/useBorrowProductFlow.ts |
| Terminal permissions/panels | apps/pos-terminal/src/screens/HomeScreen/BorrowPanels.tsx |
| Terminal detail | apps/pos-terminal/src/screens/HomeScreen/BorrowDetailForm.tsx |
| Terminal handlers | apps/pos-terminal/src/screens/HomeScreen/index.tsx |
| Services | apps/*/src/services/borrow.ts |
| Converted target | เอกสารใบสั่งขายและ order services |