#process#document#doc-flow#numbering#erp_doc_format#advisory-lock
สถานะต่อเนื่องของเอกสาร กราฟโยงเอกสาร และเลขที่เอกสารถัดไป (Doc flow & numbering)
เอกสารใน ERP โยงกันเป็นสาย (ใบขอซื้อ -> ใบสั่งซื้อ -> รับสินค้า -> ชำระ ฯลฯ) หลังบันทึก/ลบ/ยกเลิก/อนุมัติเอกสาร ระบบคำนวณสถานะ last_status, used_status, used_status_2, doc_success, approve_status ของเอกสารนั้นและเอกสารที่มันอ้างถึง จากแถวดิบที่อ้างถึงมันเท่านั้น ทำซ้ำกี่ครั้งผลเหมือนเดิม นอกจากนี้ยังมี route สร้างกราฟโยงเอกสาร (/doc/flow) และ route ขอเลขที่เอกสารถัดไป
ทำงานอย่างไร
1. เครื่องคำนวณสถานะ (doc_flow.go)
- พอร์ตจาก C#
_docFlowThread._docFlowProcess(คอมเมนต์หัวไฟล์ อ้าง cs:1970-3230) docFlowTx(tx, docNos): คิวเอกสาร -> หาtrans_flagทุกตัวของเอกสาร (docTransFlags) ->deriveDocFlowทีละ flag -> หาเอกสารต้นทางที่เอกสารนี้ชี้ไป (docFlowSources) ต่อคิว (ใช้seenกันวน ไม่มีเพดานจำนวน) คืนจำนวนแถวที่สถานะเปลี่ยนderiveDocFlow: ถ้า flag เป็น "เอกสารต้นฉบับที่มีเอกสารยกเลิก" (cancelFlagOf) คำนวณlast_statusก่อน (deriveLastStatus) แล้วใช้กฎของ flag (flowRules[flag]) ผ่านapplyFlowRulelast_statusของต้นฉบับ = 1 เมื่อis_cancel = 1หรือมีเอกสาร flag ยกเลิกที่doc_refชี้มา (กรองcancel_typeตามcancelTypeFilterที่doc_flow.go:234: ยกเลิกรายสินค้าไม่นับเป็นยกเลิกทั้งใบ) แล้วเขียนค่าเดียวกันลงบรรทัด/ซีเรียล/ap_ar/cb ที่เกี่ยวข้อง (ic_trans_detail,ic_trans_serial_number,ap_ar_trans_detail,cb_trans,cb_trans_detail)flowRules(map ต่อ flag) นิยาม SQL ของused,used2, จำนวนบรรทัด/จำนวนรวม/จำนวนที่ถูกลด และโหมดdoc_success(successNew,successExact,successItems,successPR); ตัวอย่างที่อ่านได้จากโค้ด: flag 2 ใบขอซื้อ (อนุมัติ flag 4), 6 ใบสั่งซื้อ (อนุมัติ 8), 30 ใบเสนอราคา, 34 ใบจอง (อนุมัติ 38), 36 ใบสั่งขาย (อนุมัติ 52), 10/11/40/110 มัดจำ/เงินล่วงหน้า (depositRule), 12/315/87/99/250/260 กลุ่มที่ถูกวางบิล (billedRule)approve_status(approveSQL): เอกสารอนุมัติอัตโนมัติ (auto_approved = 1) = 1; มีเอกสารอนุมัติและnot_approve_1 = 0= 1;not_approve_1 = 1= 2; ไม่มีเอกสารอนุมัติ ใช้ผลจากerp_credit_approved_logsหรือค่า ELSE (ใบจอง/ใบสั่งขาย = 1)- การตัดสิน
doc_successใช้*big.Rat(flowDocSuccess,itemsDocSuccess,poUsedUp) ไม่ใช้ float recheckAllDocFlow: ตรวจทั้งบริษัท (คำนวณlast_statusของต้นฉบับทุกใบก่อน เพราะกฎอ่านสถานะของเอกสารอื่น แล้วค่อยใช้กฎของทุก flag); เรียกจากงานสร้างสต็อกใหม่ (service.go:786)- ข้อจำกัดที่โค้ดระบุ (
ponytail): flag ใบเบิก/ขอโอน IC (122/56/124) และ ap_ar_trans 213/235 ยังไม่พอร์ต
2. กราฟโยงเอกสาร (POST /process/doc/flow)
- Input
DocFlowInput:docNo,transFlag,kind; ว่างdocNo-> "กรุณาระบุเลขที่เอกสาร"; สิทธิ์read - ค้นหาทั้งขึ้นและลงจากเอกสารตั้งต้นสูงสุด 6 hop และไม่เกิน 80 เอกสาร (
maxDocs) ผ่านความสัมพันธ์doc_ref,ref_doc_no,billing_no,cb_trans_detail.trans_number(doc_type 5/6) และเช็ค (cb_chq_list) - Output
DocFlowResult:nodes(DocFlowNode:docNo,docDate,transFlag,kind=ic_trans/ap_ar_trans/payment/gl_journal,stage,typeLabel,menuKey,partyCode/Name,amount,paidAmount,remainAmount,status,statusLabel,isCurrent,payBreakdown,glLines) และedges(DocFlowEdge:fromId,toId,relation,amount,lineCount,items) - สถานะ node (
deriveNodeStatus):cancelled(ยกเลิกแล้ว/เอกสารยกเลิก),approved,completed,partial,active; ใบซื้อ/ขายเชื่อ (flag 12/44/315 ตามคอมเมนต์ "Credit Purchase / Sale Invoices") เทียบยอดชำระกับยอดรวมด้วยbig.Rat - ช่องทางชำระใน
payBreakdown: เงินสด, โอน, พร้อมเพย์, เช็ค, บัตร, มัดจำ, รายจ่าย/รายได้อื่น (DocFlowPaySummary)
3. เลขที่เอกสาร (nextDocNo)
- ใช้ร่วมกันระหว่างหน้ายกเลิก/อนุมัติ (ยกเลิกและอนุมัติเอกสาร (Document cancel / approve)) และ route
stocktools/docnonext->Service.NextDocNo - ตารางที่รองรับ (
nextDocNoTables):ic_trans,ap_ar_trans,cb_trans,gl_journal,as_trans,ic_hidden_cost_process;gl_journalไม่กรองtrans_flag(นับเลขตามสมุด) ตารางอื่นกรองตามtransFlagถ้าส่งมา - ลำดับ: รหัสรูปแบบ
codeว่างใช้screenCode; ยังว่างใช้DOC<flag>(หรือDOC) -> อ่านerp_doc_format(format,code) ที่upper(code)หรือscreen_codeตรง; ไม่พบรูปแบบ ใช้@YYMM-#### autoRunPatternแทนโทเค็นวันที่:DD,MM,YYYY,YY, ไทยวว,ดด,ปปปป(พ.ศ. 4 หลัก),ปป, และ@= รหัสรูปแบบ; แถว#ชุดแรกคือหลักเลขรัน- ป้องกันเลขซ้ำ:
pg_advisory_xact_lock(hashtext('docno:' || ตาราง || ':' || prefix))ภายใน transaction แล้วอ่านเลขล่าสุดที่ขึ้นต้นด้วย prefix (กรองด้วย flag)ORDER BY doc_no DESC LIMIT 1->autoRunNext(+1 เติมศูนย์; ล้นความกว้างวนกลับ 1) - เลขที่เอกสารยาวเกิน 25 ตัวอักษรตอบ error "ยาวเกิน 25 ตัวอักษร กรุณาแก้รูปแบบ"
NextDocNoตรวจ: ตารางต้องอยู่ในรายการ,transFlagต้องไม่ติดลบ,docDateต้องเป็น YYYY-MM-DD
จุดที่ต้องระวัง
- เลขที่ที่ route
docnonextคืนเป็นเลขที่ "คาดว่าจะใช้" ไม่ได้จองไว้; ล็อกมีผลเฉพาะตอนสร้างเอกสารยกเลิก/อนุมัติใน transaction เดียวกัน - กราฟเอกสารจำกัด 6 hop / 80 เอกสาร / 200 ความสัมพันธ์ต่อ hop เอกสารที่ไกลกว่านั้นจะไม่ปรากฏ
- ผลลัพธ์ของ
flowRulesขึ้นกับตัวเลือกบริษัทpurchase_request_approve_until_end(โหมดsuccessPR)
ที่มาในโค้ด
backend/internal/application/process/doc_flow.go:9-17- ที่มา C# และหลักการคำนวณจากแถวดิบbackend/internal/application/process/doc_flow.go:91-132-flowRulesและinit()เพิ่มกฎ flag ที่ได้แต่used_status_2backend/internal/application/process/doc_flow.go:146-docFlowTxbackend/internal/application/process/doc_flow.go:180-deriveDocFlowbackend/internal/application/process/doc_flow.go:239-deriveLastStatusbackend/internal/application/process/doc_flow.go:284-approveSQLbackend/internal/application/process/doc_flow.go:470-recheckAllDocFlowbackend/internal/application/process/doc_flow_graph.go:16-103- struct ของกราฟbackend/internal/application/process/doc_flow_graph.go:269-DocFlow(BFS 6 hop,maxDocs = 80)backend/internal/application/process/doc_flow_graph.go:809-deriveNodeStatusbackend/internal/application/process/doc_cancel.go:391-nextDocNo;:460docNoPrefix;:475nextDocSeqbackend/internal/application/process/doc_no_next.go:12-70-NextDocNoและตัวตรวจ inputbackend/internal/application/process/stock_tools.go:701-autoRunPattern;:725autoRunNextbackend/internal/adapter/inbound/http/process/stocktools_handler.go:164- actiondocnonext