รายละเอียดการซื้อ/การขาย 4 ช่อง (BuySaleInformationScreen)
หน้าจอวิเคราะห์ "ลูกค้า/เจ้าหนี้รายหนึ่งซื้อหรือขายอะไรไปบ้าง" แบ่งเป็น 4 ช่อง (quadrant) ในจอเดียว ใช้คอมโพเนนต์เดียวกัน 2 โหมด: ขาย (mode="sale") และซื้อ (mode="buy") (BuySaleInformationScreen.tsx:27-40) หัวไฟล์อ้างว่าพอร์ตมาจากหน้าจอ C# SMLERPICInfo._buyAndSaleInformation (บรรทัด 1-10 ของไฟล์) ต่างจากรายงานอื่นที่เป็นตระกูล จอรายงานกลาง (Universal Report Screen) ตรงที่หน้าจอนี้ ไม่ผ่าน backend report engine แต่ยิง SQL จากเบราว์เซอร์ผ่าน queryList (ดู ตัวเรียก API และตัวประกอบ SQL ฝั่งเบราว์เซอร์ (api-client, query-client, sml-query-builder))
วิธีเปิด (และข้อควรระวังเรื่องเมนู)
- registry มี 2 คีย์ที่ชี้มาที่จอนี้:
menu_po_buy_information(รหัสเก่า 3.8.7 ชื่อ "รายละเอียดการซื้อ") และmenu_so_sale_information(รหัสเก่า 4.10.22 ชื่อ "รายละเอียดการขาย") เปิดเป็นแท็บ (mode: "tab") (screenRegistry.tsx:741-765) - แต่ใน
smlMenu.jsonปัจจุบัน ไม่มีเมนูใบที่ชื่อสองคีย์นี้ —smlMenu.tsทำ alias ให้สองชื่อนี้ชี้ไปที่menu_po_report_purchase(3049 "รายงานการซื้อสินค้า/ตั้งหนี้") และmenu_so_report_invoice(4045 "รายงานการขายสินค้าและบริการ") (smlMenu.ts:212-213) ซึ่งทั้งสองเมนูเป็นใบประเภท RPT เปิดด้วยUniversalReportScreen(จอรายงานกลาง (UniversalReportScreen)) ไม่ใช่จอนี้ - ผลคือในเมนูปัจจุบันไม่พบทางเปิดจอ 4 ช่องนี้โดยตรง ค้นทั้ง
frontend/(ไม่รวม.next/) ไม่พบโค้ดอื่นที่เปิดสองคีย์นี้ นอกจาก registry เอง ถือเป็น จอที่ลงทะเบียนไว้แต่ไม่มีเมนูชี้ (ดูตารางความไม่สอดคล้องใน สารบัญหน้าจอทั้งหมดของ SML Ai Account (ต้นไม้เมนู → หน้าจอ → โน้ต))
หน้าตาและการทำงาน
หัวจอเขียนว่า "หน้าจอวิเคราะห์ข้อมูลการขายและลูกหนี้" หรือ "…การซื้อและเจ้าหนี้" พร้อมรหัสลูกค้า — ชื่อที่เลือกอยู่ (บรรทัด 204-207) แถบเครื่องมือมีปุ่ม "ประมวลผลใหม่" (โหลดรายชื่อใหม่) และ "ปิดหน้าจอ" (แสดงเมื่อมี onClose) (บรรทัด 213-217) ตามด้วยรหัสเมนูและชื่อจอ
ช่องซ้ายบน: รายชื่อลูกหนี้ / เจ้าหนี้
- ช่องค้นหา "ค้นหารหัส/ชื่อลูกหนี้..." (หรือ "…เจ้าหนี้...") ใช้ ILIKE กับ
codeและname_1โดย escape อักขระ% _ \ให้เป็นตัวอักษรธรรมดา และผ่านescapeSql(บรรทัด 63-69) กด Enter หรือปุ่มแว่นขยายได้ - ช็อกบ็อกซ์ "เฉพาะมียอดซื้อ/ขาย" กรองใน SQL ก่อน LIMIT (บรรทัด 74, 259) เพื่อไม่ให้รายการที่มียอดหล่นหายไปนอก 100 แถวแรก
- ตารางคอลัมน์ รหัส / ชื่อลูกหนี้ (ชื่อเจ้าหนี้) / ยอดขายสะสม (ยอดซื้อสะสม) (บรรทัด 271) ดึงเฉพาะผู้ที่
COALESCE(status,0)=0เรียงตามรหัส สูงสุด 100 แถว (บรรทัด 76-82) คลิกแถวเพื่อเลือก ครั้งแรกที่โหลดเสร็จจะเลือกแถวแรกให้เอง (บรรทัด 93-97) - ตารางต้นทาง: ลูกหนี้ ทะเบียนลูกหนี้/ลูกค้า (ar_customer) / เจ้าหนี้ ทะเบียนเจ้าหนี้/ผู้ขาย (ap_supplier)
ช่องซ้ายล่าง: สรุปสถานะวงเงินและเอกสาร
การ์ด "สรุปสถานะวงเงินและเอกสาร (รหัสที่เลือก)" แสดง วงเงินเครดิต (credit_money ของ master), จำนวนบิลขาย/ซื้อ (n ใบ) พร้อมยอดรวม, เช็คในมือ (n ใบ) พร้อมยอด และโทรศัพท์ติดต่อ (บรรทัด 305-327) ตัวเลขดึงตอนเลือกรายการ (loadCustDetails บรรทัด 105-171)
ช่องขวาบน: รายการสินค้า + ประวัติบิลของสินค้า
- "รายการสินค้าที่ขาย/ซื้อ" (หัวกริดบรรทัด 340) คอลัมน์ รหัสสินค้า / ชื่อสินค้า / จำนวน / มูลค่ารวม รวมจาก
ic_trans_detailต่อรหัสสินค้า เรียงตามมูลค่ารวมมากไปน้อย สูงสุด 100 รายการ ชื่อสินค้าใช้ชื่อในบรรทัดเอกสารก่อน ถ้าว่างใช้ชื่อจากic_inventory(บรรทัด 110-121) คลิกแถวเพื่อเลือกสินค้า (บรรทัด 358) - "ประวัติบิลของสินค้า <รหัส>" (หัวกริดบรรทัด 381) คอลัมน์ วันที่ / เลขที่เอกสาร / จำนวน / ราคา / รวมเงิน ของสินค้าที่เลือกกับลูกค้าที่เลือก เรียงใหม่สุดก่อน สูงสุด 50 แถว (บรรทัด 177-199, 381)
- เลือกลูกค้าใหม่แล้วระบบเลือกสินค้าแรกในรายการให้ทันที (
setSelectedItemCode(firstItem)บรรทัด 158)
ช่องขวาล่าง: สรุปยอดรายเดือน 12 เดือน แยกตามปี
ตารางปี (ใหม่สุดก่อน) × ม.ค.–ธ.ค. + "รวมทั้งปี" ใช้ SUM(CASE WHEN EXTRACT(MONTH …)) ต่อปีของ doc_date (บรรทัด 134-151, 423-437) ถ้าไม่มีข้อมูลขึ้น "ไม่มีข้อมูลรายเดือน" (บรรทัด 444)
เอกสารที่นับ (trans_flag)
- โหมดขาย:
44, 46, 36— ขาย (SI/SIP), 46 (SA), สั่งขาย (บรรทัด 39) ชื่อ flag ตามตาราง รหัสชนิดเอกสาร trans_flag และทิศทางสต็อก (Trans Flag Map) (ชื่อไทยของ 14 และ 46 ตารางนั้นระบุว่ายังไม่ยืนยัน) - โหมดซื้อ:
12, 14, 310— ซื้อ/ตั้งหนี้, 14 (PA), ทยอยรับสินค้า (บรรทัด 39) - ทุกคิวรีหลักกรอง
COALESCE(last_status,0)=0(ตัดเอกสารยกเลิก — ดู สถานะยกเลิก/อนุมัติเอกสาร (last_status / approve_status / cancel flag)) และจับคู่ลูกค้าด้วยic_trans.cust_codeตารางหลัก หัวเอกสารสินค้า/ซื้อ/ขาย (ic_trans) / รายการสินค้าในเอกสาร (ic_trans_detail) / ทะเบียนสินค้า (ic_inventory)
ข้อควรระวัง
- นับใบสั่งขาย (36) รวมกับใบขาย (44) ในยอดเดียวกัน ถ้าสั่งขายแล้วออกใบขายต่อ ยอดสะสมอาจซ้ำสองเท่า และไม่นับ 48 (รับคืน/ลดหนี้) หรือ 144 (ใบกำกับเต็มรูป) จึงไม่ใช่ยอดขายสุทธิ ฝั่งซื้อไม่นับ 16 (ส่งคืน/ลดหนี้) ด้วย (บรรทัด 39 เทียบ รหัสชนิดเอกสาร trans_flag และทิศทางสต็อก (Trans Flag Map))
- ประวัติบิลของสินค้า (50 แถว) ไม่กรอง
last_statusต่างจากอีก 4 คิวรีที่ตัดเอกสารยกเลิก — บิลที่ยกเลิกแล้วอาจโผล่ในช่องนี้ (คิวรีบรรทัด 177-195) - สรุปเช็คในมือไม่กรองตาม
chq_typeกรองเพียงap_ar_codeตรงกับรหัสที่เลือก และstatus=0(บรรทัด 129-133) เช็คทั้งรับและจ่ายของรหัสนั้นปนกัน ดูตาราง ทะเบียนเช็ค/บัตรเครดิต/กระเป๋าเงิน (cb_chq_list) - ยิง SQL จากเบราว์เซอร์ (ข้อยกเว้นของหลัก "รายงานผ่าน backend") สอดคล้องกับ ตัวเรียก API และตัวประกอบ SQL ฝั่งเบราว์เซอร์ (api-client, query-client, sml-query-builder)
- โหลดรายชื่อซ้ำเกินจำเป็น:
loadCustomersมีkeyword,onlyWithDebtและselectedCustในรายการ deps ของuseCallback(บรรทัด 99) และuseEffectเรียกซ้ำทุกครั้งที่ฟังก์ชันเปลี่ยน (บรรทัด 101-103) จึงเกิดการค้นหาทุกครั้งที่พิมพ์ทีละตัวอักษร และโหลดรายชื่อใหม่ทุกครั้งที่คลิกเลือกแถว (คิวรีมี subquery SUM ต่อลูกค้า 100 ราย) - ตัวเลขเงินแสดงด้วย
formatMoneyDisplay(…, getSmlDecimals(…))จากสตริง::textของ SQL ไม่ผ่าน JS float จริง แต่.filter(Number(balance_amount) > 0)ของโหมด "เฉพาะมียอด" แปลงเป็น Number เพื่อเปรียบเทียบกับศูนย์เท่านั้น (บรรทัด 93) ดูหลักใน ตัวเลข เงิน ภาษี และปี พ.ศ. ฝั่ง frontend (numeric.ts) - สรุปสถานะ "วงเงินเครดิต" เป็นค่า master ไม่ใช่ยอดคงค้างจริง จึงไม่ใช้ตัดสินได้ว่าเกินวงเงินหรือไม่ เทียบกับหน้าที่ตรวจวงเงินจริงใน ป๊อปอัปราคาขาย ต้นทุน และอนุมัติวงเงินเครดิต (PriceFormulaModal / PriceInfoModal / CostLockModal / CreditApproveModal)
ที่มาในโค้ด
- ตัวคอมโพเนนต์ โหมด flag และตาราง master:
frontend/account/report/BuySaleInformationScreen.tsx:27-40 - โหลดรายชื่อ (ILIKE, balance subquery, LIMIT 100):
…/BuySaleInformationScreen.tsx:63-103 - โหลดรายละเอียดลูกค้า (สินค้า, ยอดบิล, เช็ค, รายเดือน):
…/BuySaleInformationScreen.tsx:105-171 - ประวัติบิลของสินค้า (LIMIT 50):
…/BuySaleInformationScreen.tsx:173-199 - ส่วนหน้าจอ (หัว, ปุ่ม, 4 ช่อง):
…/BuySaleInformationScreen.tsx:202-450 - ลงทะเบียน 2 คีย์:
frontend/account/tabs/screenRegistry.tsx:741-765 - alias ไปเมนูรายงานปัจจุบัน:
frontend/src/config/smlMenu.ts:212-213 - ดูภาพรวมจอรายงานทั้งหมดที่ จอรายงานกลาง (Universal Report Screen) และผังเมนูที่ สารบัญหน้าจอทั้งหมดของ SML Ai Account (ต้นไม้เมนู → หน้าจอ → โน้ต)