財務會計自動聯動機制

這是平台預建資料底座中最有價值、也最難自己重建的一塊:業務動作與會計帳務的自動連動

當業務、倉庫或人資完成日常作業時,系統會在背景自動產生與更新會計傳票與帳單。您的應用程式不需要知道會計科目怎麼帶、稅率怎麼算、沖銷怎麼配對——呼叫一個 ctx.erp 方法,整條鏈就跑完了。

這些引擎對所有入口一視同仁:不論資料從 Custom App、REST API 還是主控台寫進來,連動都照樣發生。


1. 銷售開票連動

觸發:在已確認的銷售訂單上建立發票 SDKctx.erp.create_invoice(order_id)

系統自動:

  • 抓取訂單明細、待開票數量、單位售價與折扣
  • 查詢產品分類,帶出預設的收入科目稅率
  • 產生銷項發票草稿

多張訂單合併開票order_id 可以傳入清單。傳清單時會把所有訂單的明細彙總進同一張發票,要求全部屬於同一客戶、同一組織。這解掉了月結客戶「一個月的訂單開一張發票」的常見需求。

找不到訂單或無可開票明細時回傳空值,不會產生半套資料。


2. 採購進項連動

觸發:在採購訂單上建立帳單 SDKctx.erp.create_bill(order_id)

系統自動:

  • 比對「已收貨數量」減去「已開帳數量」
  • 只針對已到貨但未開帳的差額產生進項帳單草稿
  • 借方帶入產品分類對應的費用科目,貸方帶入應付帳款

這道差額計算是防重複請款的關鍵——分批到貨時不會重複開帳。

同樣支援多張訂單合併成一張帳單(需同供應商、同組織)。


3. 存貨即時計價

觸發:庫存移動狀態變更為完成 SDKctx.erp.validate_picking(id) 會連帶觸發

若產品分類設定為即時計價,系統會依「移動數量 × 單位成本」計算存貨價值,並直接產生已過帳狀態的存貨計價傳票

方向分錄
入庫(供應商/生產 → 內部庫位)借:存貨科目 貸:應付暫估科目或費用科目
出庫(內部庫位 → 客戶/生產)借:銷貨成本科目 貸:存貨科目

意義:損益表上的銷貨成本與資產負債表上的存貨價值在庫存變動當下就更新,不需要等月底盤點。


4. 薪資結算連動

SDKctx.erp.confirm_payroll_run(id) / ctx.erp.cancel_payroll_run(id)

動作自動發生
確認結算產生應付薪資與社保費用傳票——底薪、津貼、雇主負擔部分自動記入對應的費用科目與應付代收款科目
撤銷結算自動產生沖銷分錄,把原先立帳的傳票沖掉,維持帳務正確

撤銷會產生沖銷而不是刪除原傳票,這是為了保留完整的帳務軌跡。

這兩個方法會回傳產生的傳票資訊,您的應用程式可以據此顯示結果或做後續處理。


5. 收付款與發票沖銷

觸發:收付款單過帳 SDKctx.erp.confirm_payment(id);補跑用 ctx.erp.reconcile_payment(id)

系統自動:

  1. 建立收付款日記帳傳票。若借貸方有極微小差額(通常來自四捨五入),自動產生平衡分錄並過帳
  2. 先進先出自動沖銷:搜尋該客戶或供應商所有未結清的發票與帳單,以先進先出順序將付款金額核銷到餘額上,產生部分或完全核銷紀錄
  3. 推導付款狀態:發票餘額歸零時標記為已付清,否則標記為部分付款

reconcile_payment 用於補跑——已過帳但因故未完成沖銷的付款可以事後補上,不需要沖掉重來。


從應用程式使用這些引擎

def execute(ctx):
    # 找出本月該開票的月結訂單
    orders = ctx.db.query('sale_orders', filters=[
        {'column': 'customer_id', 'op': 'eq', 'value': ctx.params['customer_id']},
        {'column': 'state', 'op': 'eq', 'value': 'sale'},
        {'column': 'invoice_status', 'op': 'eq', 'value': 'to invoice'},
    ])

    if not orders:
        return ctx.response.json({'message': '本期無待開票訂單'})

    # 合併成一張發票 —— 科目、稅率、明細全部自動帶入
    result = ctx.erp.create_invoice([o['id'] for o in orders])

    ctx.response.json({
        'invoice_id': result['invoice_id'],
        'merged_orders': len(orders),
    })

這段程式碼沒有任何一行在處理會計科目或稅率——那些由引擎負責。


使用時的注意事項

科目設定是前提。引擎會從產品分類讀取預設的收入與費用科目。分類未設定科目時,開票會失敗或落在預設科目上。建議在導入初期就把產品分類的科目設定完整。

即時計價要開啟。存貨計價只在產品分類設定為即時計價時才產生傳票。採用定期計價的分類不會自動產生。

這些方法是高風險 scopectx.erp.* 的每個方法各自對應獨立的 scope,全部屬於高風險等級——授權時需要擁有者當場密碼再驗證。這是刻意的:這些方法會直接影響帳務。

簽核會攔截。若相關資料表設有簽核流程,這些動作會被攔截並等候核准,通過後才實際執行。