แถบสรุปสินค้าหลายหน่วยนับ (MultiUnitPackSummaryBar)
แถบสีเขียวอ่อนใต้ตารางรายการสินค้า แสดงเมื่อในเอกสารมีสินค้าที่มีหลายหน่วยนับ ทำ 3 อย่าง: (1) แสดงจำนวนในเอกสารและยอดคงเหลือของสินค้าเป็นข้อความทอนหน่วย เช่น "5 ห่อ x 3 โหล x 8 กล่อง" (2) บอกว่าแถวที่กรอกเป็นหน่วยใหญ่ เท่ากับกี่หน่วยฐาน (3) มีช่องคำนวณจำนวนหน่วยรองเป็นหน่วยฐาน พร้อมปุ่มเขียนผลกลับลงแถวรายการ ตารางที่อยู่เหนือแถบนี้ดู ตารางรายการสินค้า/จำนวนเงินในเอกสาร (TransItemGrid) ความหมายของตัวตั้ง/ตัวหารดู หน่วยนับ ตัวตั้ง/ตัวหาร และหน่วยนับขนาน (unit / stand_value / divide_value / unit_type) และ ขายเป็นกล่อง/โหล แต่สต็อกนับเป็นชิ้น ระบบแปลงหน่วยยังไง
เปิดจากไหน
- จอเอกสารทั่วไป (จอบันทึกเอกสารธุรกรรม มุมมองผู้ใช้ (UniversalTransScreen)): ต่อท้ายตารางในแท็บรายการ ส่ง
lines= แถวสินค้าของเอกสาร,transFlag,docNo,isEditing(UniversalTransScreen.tsx:3840-3844) - จอสินค้าคงเหลือยกมา (สินค้า/วัตถุดิบคงเหลือยกมา (StockBeginningBalanceScreen)): อยู่ใต้ตารางในแท็บ "รายละเอียด" (
activeTab === "detail",StockBeginningBalanceScreen.tsx:2341, 3030-3057) ส่งlines=detailRowsและtransFlag= 54 - ถ้าไม่มีสินค้าที่เข้าเงื่อนไขในเอกสาร ส่วนประกอบนี้ไม่ขึ้นอะไรเลย (
MultiUnitPackSummaryBar.tsx:250)
สินค้าที่ขึ้นในแถบ
สินค้าหนึ่งตัวขึ้นการ์ดของตัวเองเมื่อทั้งสองข้อจริง (MultiUnitPackSummaryBar.tsx:158-165):
- เป็นสินค้า
unit_type= 1 (หลายหน่วยนับ) หรือ 3 (หลายหน่วยนับและหน่วยนับคู่) หรือมีแถวหน่วยในic_unit_useมากกว่า 1 (ป้ายชื่อประเภทอยู่ที่ItemDetail2Screen.tsx:194: 0 หน่วยนับเดียว, 1 หลายหน่วยนับ, 2 หน่วยนับคู่, 3 ทั้งสองอย่าง) - มีแถวหน่วยที่ใช้งานอยู่ (
status= 1) ใน หน่วยนับที่ใช้ของสินค้า (ic_unit_use) อย่างน้อย 1 แถว
สินค้าที่รหัสซ้ำกันหลายบรรทัดในเอกสารรวมเป็นการ์ดเดียว (จับคู่รหัสตัวพิมพ์ใหญ่, :68-79)
ข้อมูลที่อ่านจากฐานข้อมูล
อ่านผ่านประตูคิวรี queryList (POST /api/query/list, frontend/src/lib/query-client.ts:16-20) 2 คิวรีขนานกัน ทุกครั้งที่ชุดรหัสสินค้าหรือเลขที่เอกสารเปลี่ยน (MultiUnitPackSummaryBar.tsx:93-137):
ic_inventory:code,name_1,unit_type,unit_costและunit_standard(ตัดเอาส่วนก่อนเครื่องหมาย~),balance_qty(:95-102)ic_unit_use(JOIN ข้อมูลหน่วยนับ (ic_unit) เอาชื่อหน่วย):code,stand_value,divide_value,row_order,statusเฉพาะstatus= 1 (:103-114)
ยอด "คงเหลือ" คือ ic_inventory.balance_qty ของสินค้า ไม่แยกคลัง/ที่เก็บ (:99, :218) การเปลี่ยนจำนวน/หน่วยในแถวคำนวณใหม่ทันทีโดยไม่ query ซ้ำ (useMemo ที่ :139-248)
วิธีคำนวณ
- อัตราของแต่ละหน่วย =
stand_value/divide_value(ค่าที่เป็น 0 ถือเป็น 1,:167-171) - หน่วยฐาน = หน่วยที่อัตราน้อยที่สุด (
:172-176) หน่วยรอง (ใช้ในช่องคำนวณ) = หน่วยที่อัตราน้อยเป็นอันดับถัดไปที่รหัสไม่ซ้ำหน่วยฐาน (:177-184) ดังนั้นสินค้า 3 หน่วย (ห่อ, โหล, กล่อง) หน่วยรองคือ "โหล" ไม่ใช่ "กล่อง" - ยอดเอกสารเป็นหน่วยฐาน = ผลรวมของ จำนวน x อัตรา ของทุกแถวสินค้านั้น ข้ามแถวที่จำนวนเป็น 0 อัตราดูจากแถวหน่วยที่ตรงกับ
unit_codeของแถว ถ้าไม่พบใช้stand_value/divide_valueที่อยู่ในแถว ถ้าไม่มีก็ 1 ปัดผลที่ทศนิยม 6 ตำแหน่ง (:190-217) ใช้เลขทศนิยมของ JavaScript เพราะเป็นจำนวนสินค้า ไม่ใช่จำนวนเงิน - แถวที่ไม่ใช่หน่วยฐาน ได้ป้ายสีม่วงคราม "คำนวณกลับเป็น<หน่วยฐาน>: 2 โหล = 24 ห่อ" (
:209-215, :287-294) - ข้อความอัตราของหน่วย เช่น "1 ห่อ · 1 โหล = 12 ห่อ · 1 กล่อง = 60 ห่อ" (
:220-228, :281-286) - ข้อความทอนหน่วย มาจาก
formatPackingBreakdown(ยอดหน่วยฐาน, หน่วย, "asc")(frontend/src/lib/numeric.ts:950-1020): ใช้หน่วยที่statusไม่เป็น 0 และอัตรามากกว่า 0 ถ้ามีหน่วยใดตั้งrow_orderมากกว่า 0 จะใช้เฉพาะหน่วยเหล่านั้น เรียงจากหน่วยใหญ่ไปเล็ก หน่วยใหญ่ใช้จำนวนเต็มที่ใส่ได้ หน่วยเล็กที่สุดรับเศษที่เหลือ (ทศนิยมตามตัวเลือกจำนวนของระบบ) แล้วเรียงเล็กไปใหญ่ต่อกันด้วยxยอดติดลบขึ้นหน้าด้วย "-" ยอดเป็น 0 ได้ข้อความว่าง ตัวอย่างตามอัลกอริทึม: ยอด 521 ห่อ (12 ห่อ = 1 โหล, 60 ห่อ = 1 กล่อง) → 8 กล่อง = 480, เหลือ 41 → 3 โหล = 36, เหลือ 5 → "5 ห่อ x 3 โหล x 8 กล่อง"
ที่แสดงในการ์ดแต่ละสินค้า
| ส่วน | แสดงเมื่อ | ข้อความ |
|---|---|---|
| รหัส, ชื่อสินค้า, ข้อความอัตราหน่วย | เสมอ | :281-286 |
| ป้ายคำนวณกลับเป็นหน่วยฐาน | มีแถวที่ใช้หน่วยไม่ใช่หน่วยฐาน | :287-294 |
| ช่อง "คำนวณ <หน่วยรอง> → <หน่วยฐาน>" | มีหน่วยรอง | :297-322 ดูหัวข้อถัดไป |
| "ยอดเอกสารนี้: ... (รวม N หน่วยฐาน)" | เอกสารทั่วไป และยอดเอกสาร ไม่เป็น 0 | :382-392 |
| "คงเหลือ ... (N หน่วยฐาน)" | เอกสารทั่วไป เสมอ (ยอดเป็น 0 ขึ้น "คงเหลือ 0 <หน่วยฐาน>") ส่วนในวงเล็บแสดงเมื่อยอดไม่เป็น 0 | :393-404 |
| "ยอดตรวจนับ: คงเหลือ ..." และ "คงเหลือ ..." | เอกสารตรวจนับ/ขอตรวจนับ (flag 76 หรือ 276, isStockCount :252) |
:353-379 ยอดตรวจนับใช้ยอดเอกสาร ถ้าเอกสารว่างใช้ยอดคงเหลือแทน และกลับกันกับช่องคงเหลือ |
หัวแถบเปลี่ยนตามชนิดเอกสาร: เอกสารตรวจนับ "สรุปยอดตรวจนับและคงเหลือหลายหน่วยนับ (ทอนหน่วย)" เอกสารอื่น "สรุปสินค้าหลายหน่วยนับ (ทอนหน่วย & คำนวณกลับเป็นหน่วยต้นทุน)" (:263-267) ชนิดเอกสารตรวจนับดู ตรวจนับสินค้า (Stock Count) และ ขอตรวจนับสินค้า (Stock Count Request)
ช่องคำนวณและปุ่มแปลง
- ช่องกรอก "จำนวน <หน่วยรอง>" เป็นช่องข้อความธรรมดา (ไม่ใช่ช่องตัวเลขของระบบ) รับ
,ได้ ข้อความที่ไม่ใช่ตัวเลขนับเป็น 0 (:272-273, :302-314) ผลคำนวณ "= N <หน่วยฐาน>" ขึ้นเมื่อค่ามากกว่า 0 ค่าที่พิมพ์เก็บในสถานะของจอเท่านั้น ไม่บันทึกกับเอกสาร (:84, :315-322) - ปุ่ม "แปลงเป็น <หน่วยฐาน> (N)" ขึ้นเมื่อกำลังแก้ไขเอกสาร และจอส่งตัวรับมาให้ (
isEditing && onConvertToBaseUnit,:323-350) ค่าที่ส่งคือผลจากช่องคำนวณถ้ามีค่า ไม่เช่นนั้นเป็นยอดเอกสารเป็นหน่วยฐาน (:327-328) ปุ่มใช้ไม่ได้เมื่อทั้งสองเป็น 0 (:337) - จอเอกสารทั่วไป (
UniversalTransScreen.tsx:3845-3865): หาแถวแรกของสินค้านั้น ตั้งหน่วยเป็นหน่วยฐาน,stand_value/divide_value/ratio= 1, จำนวน = ค่าที่แปลงได้ ฟังก์ชันแก้แถว (patchItemLine,:2096-2103) คำนวณยอดเงินของแถวใหม่เพราะมีqtyใน patch ถ้าเป็นเอกสารกลุ่มgridBackendส่งแถวไปให้ backend คำนวณซ้ำด้วย (commitGridLines,:3859-3864) - จอสินค้าคงเหลือยกมา (
StockBeginningBalanceScreen.tsx:3036-3056): แถวแรกของสินค้านั้น ตั้งหน่วยฐาน, ตัวตั้ง/ตัวหาร/อัตรา = 1, จำนวน = ค่าที่แปลงได้ และsum_amount= จำนวน x ราคาเดิม ปัดที่ 2 ตำแหน่งด้วยmulDec(ข้อความทศนิยม ไม่ใช้ float)
ข้อควรระวัง
- ปุ่มแปลงแก้แค่ หน่วย ตัวตั้ง/ตัวหาร และจำนวน ของแถวแรก ไม่แปลงราคาต่อหน่วย ยอดเงินของแถวจึงเปลี่ยนตามจำนวน x ราคาเดิม ผู้กรอกต้องตรวจราคาให้ตรงหน่วยฐานเอง
- ปุ่มแปลงเขียนทับ เฉพาะแถวแรก ของสินค้านั้น แต่ค่าตั้งต้นของปุ่ม (เมื่อช่องคำนวณว่าง) คือยอดรวมทุกแถวของสินค้านั้น ถ้าสินค้าเดียวกันอยู่หลายบรรทัด แถวอื่นยังอยู่ในเอกสารต่อ จึงควรตรวจผลรวมหลังกดปุ่ม (อ่านจากโค้ด
UniversalTransScreen.tsx:3845-3858และMultiUnitPackSummaryBar.tsx:186-216, :327-328ยังไม่ได้ทดสอบกับข้อมูลจริง) - ข้อความทอนหน่วยแสดงโดยแทนทุกตัวอักษร
xด้วย " x " (:360, :372, :387, :397) ชื่อหน่วยที่มีตัว x (เช่น Box) จะถูกตัดคำตรงนั้นด้วย (อ่านจากโค้ด ยังไม่ได้ทดสอบ) - ยอดคงเหลือมาจาก
ic_inventory.balance_qtyระดับสินค้า ไม่ใช่ยอดตามคลังที่เลือกในแถว ถ้าต้องการยอดตามคลัง/ที่เก็บใช้ปุ่มเช็คสต็อกในตาราง ดู ป๊อปอัปซีเรียล ล็อต ยอดคงเหลือ ประวัติ สินค้าทดแทน (SerialNumberModal / LotModal / StockBalanceModal / ItemHistoryModal / ItemReplacementModal) - สินค้า
unit_type0 หรือ 2 ที่มีแถวหน่วยในic_unit_useเพียงแถวเดียว ไม่ขึ้นในแถบนี้ - หน่วยและอัตราตั้งที่จอสินค้า (ข้อมูลสินค้าเพิ่มเติม 16 ส่วน (ItemDetail2Screen)) และทะเบียนหน่วยนับ (กำหนดหน่วยนับสินค้า (UnitScreen)) แถบนี้เพียงอ่านค่า ไม่แก้
ที่มาในโค้ด
frontend/account/transaction/MultiUnitPackSummaryBar.tsx::14-46ชนิดข้อมูลและ props;:61-84ส่วนประกอบ/รหัสสินค้าไม่ซ้ำ;:86-137โหลดข้อมูล;:139-248คำนวณสรุป;:250-267ซ่อนเมื่อไม่มีสินค้า/หัวแถบ;:270-295การ์ดสินค้า;:297-352ช่องคำนวณและปุ่มแปลง;:353-406ข้อความยอดfrontend/src/lib/numeric.ts:937-1020(PackingUnitSpec,formatPackingBreakdown)frontend/account/transaction/UniversalTransScreen.tsx:3840-3866,:2096-2103;frontend/account/transaction/StockBeginningBalanceScreen.tsx:3030-3057frontend/account/master/ItemDetail2Screen.tsx:194(ชื่อประเภทหน่วยนับ)- ดูเพิ่ม: สารบัญหน้าจอทั้งหมดของ BC Ai Account (ต้นไม้เมนู → หน้าจอ → โน้ต) · จอเอกสารธุรกรรมแบบเดียวกันทุกจอ (UniversalTransScreen) · ตัวเลข เงิน ภาษี และปี พ.ศ. ฝั่ง frontend (numeric.ts) · หน่วยนับที่ใช้ของสินค้า (ic_unit_use)