705 lines
27 KiB
Markdown
705 lines
27 KiB
Markdown
# ERPNext 會計數據結構分析
|
||
|
||
> **日期**: 2026-04-18
|
||
> **版本**: ERPNext v17 (develop branch)
|
||
> **程式碼位置**: `/home/tony/erpnext-analysis/erpnext`
|
||
|
||
---
|
||
|
||
## 目錄
|
||
|
||
1. [環境現狀](#環境現狀)
|
||
2. [核心會計數據模型](#核心會計數據模型)
|
||
3. [GL Entry 總帳分錄結構](#gl-entry-總帳分錄結構)
|
||
4. [主要 Doctype 欄位詳解](#主要-doctype-欄位詳解)
|
||
5. [會計數據導入的 4 種方式](#會計數據導入的-4-種方式)
|
||
6. [基礎資料依賴](#基礎資料依賴)
|
||
7. [自訂 API 開發架構](#自訂-api-開發架構)
|
||
8. [關鍵程式邏輯](#關鍵程式邏輯)
|
||
9. [下一步建議](#下一步建議)
|
||
|
||
---
|
||
|
||
## 環境現狀
|
||
|
||
| 項目 | 狀態 |
|
||
|------|------|
|
||
| **ERPNext 版本** | v17 (develop branch) |
|
||
| **程式碼位置** | `/home/tony/erpnext-analysis/erpnext`、`/home/tony/erpnext/erpnext` |
|
||
| **Frappe Core** | ❌ 未找到 |
|
||
| **Bench 環境** | ❌ 無 `sites/`、無 `bench` 目錄 |
|
||
| **執行中服務** | ❌ 無 ERPNext/Frappe 實例運行 |
|
||
| **可用資源** | PostgreSQL (nexus_postgres:5432)、Qdrant (6333-6334)、Neo4j (7474/7687) |
|
||
| **API 端口** | 8084 (本地 LLM)、8082 (Python 服務) |
|
||
|
||
> **結論**: 目前只能做**靜態結構分析**,要實際開發 API 需要部署 Frappe bench 環境。
|
||
|
||
---
|
||
|
||
## 核心會計數據模型
|
||
|
||
ERPNext 的會計數據透過 **Doctype(文件類型)**組織,核心流程是:
|
||
|
||
```
|
||
交易文件 (Invoice/Payment) → General Ledger (GL Entry) → 總帳/分類帳
|
||
```
|
||
|
||
### 層級關係圖
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ 主交易文件 │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ ┌──────────────────┐ ┌──────────────────┐ ┌───────────────┐ │
|
||
│ │ Sales Invoice │ │ Purchase Invoice │ │ Payment Entry │ │
|
||
│ │ (銷售發票) │ │ (採購發票) │ │ (付款/收款) │ │
|
||
│ └────────┬─────────┘ └────────┬─────────┘ └───────┬───────┘ │
|
||
│ │ │ │ │
|
||
│ ┌────────┴─────────────────────┴─────────────────────┴───────┐ │
|
||
│ │ controller.py (accounts/doctype/...) │ │
|
||
│ │ 自動生成 GL Entry + Payment Ledger Entry │ │
|
||
│ └─────────────────────────────────────────────────────────────┘ │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ 底層分錄 │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ ┌──────────────────┐ ┌──────────────────────────┐ │
|
||
│ │ GL Entry │ │ Payment Ledger Entry │ │
|
||
│ │ (總帳分錄) │ │ (付款分類帳) │ │
|
||
│ │ • 不可手動編輯 │ │ • 不可手動編輯 │ │
|
||
│ │ • 借貸平衡 │ │ • AR/AP 追蹤 │ │
|
||
│ └──────────────────┘ └──────────────────────────┘ │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 主要 Doctype 總覽
|
||
|
||
| 層級 | Doctype | 說明 | 關聯 |
|
||
|------|---------|------|------|
|
||
| **主文件** | `sales_invoice` | 銷售發票 | → GL Entry |
|
||
| **主文件** | `purchase_invoice` | 採購發票 | → GL Entry |
|
||
| **主文件** | `payment_entry` | 付款/收款記錄 | → GL Entry + Payment Ledger |
|
||
| **主文件** | `journal_entry` | 日記帳(手動過帳) | → GL Entry |
|
||
| **主文件** | `pos_invoice` | POS 發票 | → GL Entry |
|
||
| **子表** | `sales_invoice_item` | 發票明細(商品/收入帳戶) | |
|
||
| **子表** | `purchase_invoice_item` | 採購明細(費用帳戶) | |
|
||
| **子表** | `journal_entry_account` | 日記帳分录行 | |
|
||
| **底層** | `gl_entry` | 總帳分錄(最終會計記錄) | 不可手動編輯 |
|
||
| **底層** | `payment_ledger_entry` | 付款分類帳(AR/AP 追蹤) | 不可手動編輯 |
|
||
|
||
---
|
||
|
||
## GL Entry(總帳分錄)結構
|
||
|
||
> ⚠️ **GL Entry 是 ERPNext 會計數據的終極歸宿**,所有交易文件最終都會轉成 GL Entry 記錄。
|
||
|
||
### 完整欄位列表
|
||
|
||
| 欄位 | 類型 | 可空 | 說明 |
|
||
|------|------|------|------|
|
||
| `posting_date` | Date | ✅ | 入帳日期 |
|
||
| `transaction_date` | Date | ✅ | 交易日期 |
|
||
| `account` | Link → Account | ✅ | 會計科目 |
|
||
| `party_type` | Link → DocType | ✅ | 往來對象類型(Customer/Supplier/Employee 等) |
|
||
| `party` | Dynamic Link | ✅ | 往來對象(動態引用 party_type 指向的 Doctype) |
|
||
| `cost_center` | Link → Cost Center | ✅ | 成本中心 |
|
||
| `debit` | Currency | ✅ | 借方金額(公司幣) |
|
||
| `credit` | Currency | ✅ | 貸方金額(公司幣) |
|
||
| `account_currency` | Link → Currency | ✅ | 科目幣別 |
|
||
| `debit_in_account_currency` | Currency | ✅ | 科目幣別借方 |
|
||
| `credit_in_account_currency` | Currency | ✅ | 科目幣別貸方 |
|
||
| `against` | Text | ✅ | 對應科目(簡述) |
|
||
| `against_voucher_type` | Link → DocType | ✅ | 對應憑證類型 |
|
||
| `against_voucher` | Dynamic Link | ✅ | 對應憑證編號 |
|
||
| `voucher_type` | Link → DocType | ✅ | 來源文件類型 |
|
||
| `voucher_no` | Dynamic Link | ✅ | 來源文件編號 |
|
||
| `voucher_detail_no` | Data | ✅ | 來源明細編號(子表行號) |
|
||
| `project` | Link → Project | ✅ | 專案 |
|
||
| `remarks` | Text | ✅ | 備註 |
|
||
| `is_opening` | Select | ✅ | 是否為期初分錄 |
|
||
| `is_advance` | Select | ✅ | 是否為預付款 |
|
||
| `fiscal_year` | Link → Fiscal Year | ✅ | 會計年度 |
|
||
| `company` | Link → Company | ✅ | 公司 |
|
||
| `finance_book` | Link → Finance Book | ✅ | 財務簿 |
|
||
| `to_rename` | Check | ✅ | 待重新編號 |
|
||
| `due_date` | Date | ✅ | 到期日 |
|
||
| `is_cancelled` | Check | ✅ | 是否已取消 |
|
||
| `transaction_currency` | Link → Currency | ✅ | 交易幣別 |
|
||
| `transaction_exchange_rate` | Float | ✅ | 交易匯率 |
|
||
| `debit_in_transaction_currency` | Currency | ✅ | 交易幣別借方 |
|
||
| `credit_in_transaction_currency` | Currency | ✅ | 交易幣別貸方 |
|
||
| `voucher_subtype` | Small Text | ✅ | 憑證子類型 |
|
||
| `debit_in_reporting_currency` | Currency | ✅ | 報表幣別借方 |
|
||
| `credit_in_reporting_currency` | Currency | ✅ | 報表幣別貸方 |
|
||
| `reporting_currency_exchange_rate` | Float | ✅ | 報表幣別匯率 |
|
||
|
||
### 分錄結構要求
|
||
|
||
```
|
||
每筆分录: debit = credit(借貸必須平衡)
|
||
每筆交易: 所有 GL Entry 的 debit 總和 = credit 總和
|
||
```
|
||
|
||
---
|
||
|
||
## 主要 Doctype 欄位詳解
|
||
|
||
### Sales Invoice(銷售發票)
|
||
|
||
#### Header(主文件)核心欄位
|
||
|
||
| 欄位 | 類型 | 必填 | 說明 |
|
||
|------|------|------|------|
|
||
| `naming_series` | Select | ✅ | 編號系列 |
|
||
| `customer` | Link → Customer | ✅ | 客戶 |
|
||
| `posting_date` | Date | ✅ | 入帳日期 |
|
||
| `posting_time` | Time | ✅ | 入帳時間 |
|
||
| `company` | Link → Company | ✅ | 公司 |
|
||
| `tax_category` | Link → Tax Category | ✅ | 稅務類別 |
|
||
| `taxes_and_charges` | Link → Sales Taxes and Charges Template | ✅ | 稅金模板 |
|
||
| `is_return` | Check | ✅ | 是否為退貨 |
|
||
| `return_against` | Data | ✅ | 退回原始發票 |
|
||
| `is_consolidated` | Check | ✅ | 是否為合併發票 |
|
||
| `is_discounted` | Check | ✅ | 是否為折讓發票 |
|
||
| `base_grand_total` | Currency | ✅ | 稅前總額(公司幣) |
|
||
| `base_rounding_adjustment` | Currency | ✅ | 四捨五入調整(公司幣) |
|
||
| `round_total` | Check | ✅ | 是否四捨五入 |
|
||
| `base_rounded_total` | Currency | ✅ | 四捨五入後總額(公司幣) |
|
||
| `grand_total` | Currency | ✅ | 總額 |
|
||
| `rounded_total` | Currency | ✅ | 四捨五入後總額 |
|
||
| `total_taxes_and_charges` | Currency | ✅ | 總稅金 |
|
||
| `total_qty` | Float | ✅ | 總數量 |
|
||
| `status` | Select | ✅ | 狀態(Draft/Submitted/Cancelled/Paid) |
|
||
| `is_pos` | Check | ✅ | 是否為 POS 發票 |
|
||
| `is_return` | Check | ✅ | 是否為退貨 |
|
||
| `update_stock` | Check | ✅ | 是否更新庫存 |
|
||
| `update_billed_amount_in_delivery_note` | Check | ✅ | 是否更新送貨單已計費金額 |
|
||
| `update_billed_amount_in_sales_order` | Check | ✅ | 是否更新訂單已計費金額 |
|
||
| `write_off_amount` | Currency | ✅ | 核銷金額 |
|
||
| `is_opening` | Select | ✅ | 是否為期初 |
|
||
| `amended_from` | Link → Sales Invoice | ✅ | 來源修改 |
|
||
|
||
#### Sales Invoice Item(明細子表)核心欄位
|
||
|
||
| 欄位 | 類型 | 必填 | 說明 |
|
||
|------|------|------|------|
|
||
| `item_code` | Link → Item | ✅ | 商品 |
|
||
| `item_name` | Data | ✅ | 商品名稱 |
|
||
| `uom` | Link → UOM | ✅ | 計量單位 |
|
||
| `conversion_factor` | Float | ✅ | 單位換算係數 |
|
||
| `qty` | Float | ✅ | 數量 |
|
||
| `stock_qty` | Float | ✅ | 庫存單位數量 |
|
||
| `rate` | Currency | ✅ | 單價 |
|
||
| `amount` | Currency | ✅ | 金額 |
|
||
| `base_rate` | Currency | ✅ | 公司幣單價 |
|
||
| `base_amount` | Currency | ✅ | 公司幣金額 |
|
||
| `income_account` | Link → Account | ✅ | 收入科目 |
|
||
| `expense_account` | Link → Account | ❌ | 費用科目 |
|
||
| `cost_center` | Link → Cost Center | ✅ | 成本中心 |
|
||
| `item_tax_template` | Link → Item Tax Template | ✅ | 商品稅金模板 |
|
||
| `warehouse` | Link → Warehouse | ✅ | 倉庫 |
|
||
| `delivery_note` | Link → Delivery Note | ❌ | 送貨單 |
|
||
| `sales_order` | Link → Sales Order | ❌ | 銷售訂單 |
|
||
| `project` | Link → Project | ❌ | 專案 |
|
||
| `is_fixed_asset` | Check | ❌ | 是否為固定資產 |
|
||
| `asset` | Link → Asset | ❌ | 資產編號 |
|
||
| `enable_deferred_revenue` | Check | ❌ | 是否啟用遞延收入 |
|
||
| `service_start_date` | Date | ❌ | 服務開始日期 |
|
||
| `service_end_date` | Date | ❌ | 服務結束日期 |
|
||
|
||
---
|
||
|
||
### Purchase Invoice(採購發票)
|
||
|
||
#### Header 核心欄位(與 Sales Invoice 類似)
|
||
|
||
| 欄位 | 類型 | 必填 | 說明 |
|
||
|------|------|------|------|
|
||
| `supplier` | Link → Supplier | ✅ | 供應商 |
|
||
| `posting_date` | Date | ✅ | 入帳日期 |
|
||
| `company` | Link → Company | ✅ | 公司 |
|
||
| `taxes_and_charges` | Link → Purchase Taxes and Charges Template | ✅ | 稅金模板 |
|
||
| `is_return` | Check | ✅ | 是否為退貨 |
|
||
| `return_against` | Data | ✅ | 退回原始發票 |
|
||
| `grand_total` | Currency | ✅ | 總額 |
|
||
| `base_grand_total` | Currency | ✅ | 公司幣總額 |
|
||
| `update_stock` | Check | ✅ | 是否更新庫存 |
|
||
| `is_paid` | Check | ✅ | 是否為即期付款 |
|
||
| `status` | Select | ✅ | 狀態 |
|
||
|
||
#### Purchase Invoice Item 核心欄位
|
||
|
||
| 欄位 | 類型 | 必填 | 說明 |
|
||
|------|------|------|------|
|
||
| `item_code` | Link → Item | ✅ | 商品 |
|
||
| `qty` | Float | ✅ | 接收數量 |
|
||
| `rejected_qty` | Float | ❌ | 拒收數量 |
|
||
| `stock_qty` | Float | ✅ | 庫存單位數量 |
|
||
| `rate` | Currency | ✅ | 單價 |
|
||
| `amount` | Currency | ✅ | 金額 |
|
||
| `expense_account` | Link → Account | ✅ | 費用科目 |
|
||
| `cost_center` | Link → Cost Center | ✅ | 成本中心 |
|
||
| `warehouse` | Link → Warehouse | ❌ | 接收倉庫 |
|
||
| `rejected_warehouse` | Link → Warehouse | ❌ | 拒收倉庫 |
|
||
| `item_tax_template` | Link → Item Tax Template | ✅ | 商品稅金模板 |
|
||
| `purchase_order` | Link → Purchase Order | ❌ | 採購訂單 |
|
||
| `purchase_receipt` | Link → Purchase Receipt | ❌ | 採購收據 |
|
||
| `project` | Link → Project | ❌ | 專案 |
|
||
| `is_fixed_asset` | Check | ❌ | 是否為固定資產 |
|
||
| `asset_location` | Link → Asset Location | ❌ | 資產位置 |
|
||
|
||
---
|
||
|
||
### Payment Entry(付款/收款)
|
||
|
||
#### Header 核心欄位
|
||
|
||
| 欄位 | 類型 | 必填 | 說明 |
|
||
|------|------|------|------|
|
||
| `payment_type` | Select | ✅ | 付款類型(Receive/Pay/Internal Transfer) |
|
||
| `posting_date` | Date | ✅ | 入帳日期 |
|
||
| `company` | Link → Company | ✅ | 公司 |
|
||
| `party_type` | Link → DocType | ✅ | 對象類型(Customer/Supplier) |
|
||
| `party_name` | Data | ✅ | 對象名稱 |
|
||
| `paid_from` | Link → Account | ✅ | 付款科目(借方) |
|
||
| `paid_from_account_currency` | Link → Currency | ✅ | 付款科目幣別 |
|
||
| `paid_to` | Link → Account | ✅ | 收款科目(貸方) |
|
||
| `paid_to_account_currency` | Link → Currency | ✅ | 收款科目幣別 |
|
||
| `paid_amount` | Currency | ✅ | 支付金額 |
|
||
| `base_paid_amount` | Currency | ✅ | 公司幣支付金額 |
|
||
| `received_amount` | Currency | ✅ | 收到金額 |
|
||
| `base_received_amount` | Currency | ✅ | 公司幣收到金額 |
|
||
| `source_exchange_rate` | Float | ✅ | 來源匯率 |
|
||
| `target_exchange_rate` | Float | ✅ | 目標匯率 |
|
||
| `reference_no` | Data | ❌ | 支票/參考編號 |
|
||
| `reference_date` | Date | ❌ | 支票日期 |
|
||
| `clearance_date` | Date | ❌ | 清償日期 |
|
||
| `mode_of_payment` | Link → Mode of Payment | ❌ | 付款方式 |
|
||
| `bank_account` | Link → Company Bank Account | ❌ | 公司銀行帳戶 |
|
||
| `party_bank_account` | Link → Party Bank Account | ❌ | 對方銀行帳戶 |
|
||
| `status` | Select | ✅ | 狀態 |
|
||
| `amended_from` | Link → Payment Entry | ❌ | 來源修改 |
|
||
|
||
#### Payment Entry Reference(明細子表)
|
||
|
||
| 欄位 | 類型 | 必填 | 說明 |
|
||
|------|------|------|------|
|
||
| `reference_doctype` | Link → DocType | ✅ | 引用文件類型 |
|
||
| `reference_name` | Data | ✅ | 引用文件編號 |
|
||
| `total_amount` | Currency | ✅ | 總金額 |
|
||
| `outstanding_amount` | Currency | ✅ | 未清金額 |
|
||
| `allocated_amount` | Currency | ✅ | 已分配金額 |
|
||
| `payment_term` | Data | ❌ | 付款條件 |
|
||
|
||
---
|
||
|
||
### Journal Entry(日記帳)
|
||
|
||
#### Header 核心欄位
|
||
|
||
| 欄位 | 類型 | 必填 | 說明 |
|
||
|------|------|------|------|
|
||
| `voucher_type` | Select | ✅ | 分录類型 |
|
||
| `naming_series` | Select | ✅ | 編號系列 |
|
||
| `posting_date` | Date | ✅ | 入帳日期 |
|
||
| `company` | Link → Company | ✅ | 公司 |
|
||
| `cheque_no` | Data | ❌ | 支票號碼 |
|
||
| `cheque_date` | Date | ❌ | 支票日期 |
|
||
| `total_debit` | Currency | ✅ | 總借方 |
|
||
| `total_credit` | Currency | ✅ | 總貸方 |
|
||
| `difference` | Currency | ✅ | 差額 |
|
||
| `user_remark` | Small Text | ❌ | 使用者備註 |
|
||
| `multi_currency` | Check | ❌ | 是否多幣別 |
|
||
| `clearance_date` | Date | ❌ | 清償日期 |
|
||
| `is_opening` | Select | ❌ | 是否為期初 |
|
||
| `amended_from` | Link → Journal Entry | ❌ | 來源修改 |
|
||
|
||
#### Journal Entry Account(分录子表)核心欄位
|
||
|
||
| 欄位 | 類型 | 必填 | 說明 |
|
||
|------|------|------|------|
|
||
| `account` | Link → Account | ✅ | 會計科目 |
|
||
| `account_currency` | Link → Currency | ✅ | 科目幣別 |
|
||
| `exchange_rate` | Float | ✅ | 匯率 |
|
||
| `debit_in_account_currency` | Currency | ❌ | 科目幣別借方 |
|
||
| `credit_in_account_currency` | Currency | ❌ | 科目幣別貸方 |
|
||
| `debit` | Currency | ❌ | 公司幣借方 |
|
||
| `credit` | Currency | ❌ | 公司幣貸方 |
|
||
| `cost_center` | Link → Cost Center | ❌ | 成本中心 |
|
||
| `is_advance` | Select | ❌ | 是否為預付款 |
|
||
| `party_type` | Link → DocType | ❌ | 對象類型 |
|
||
| `party` | Dynamic Link | ❌ | 對象 |
|
||
| `project` | Link → Project | ❌ | 專案 |
|
||
| `reference_type` | Link → DocType | ❌ | 參考文件類型 |
|
||
| `reference_name` | Data | ❌ | 參考文件編號 |
|
||
|
||
---
|
||
|
||
## Payment Ledger Entry(付款分類帳)
|
||
|
||
> Payment Ledger Entry 追蹤 AR/AP 的餘額變化,由 ERPNext 自動生成。
|
||
|
||
| 欄位 | 類型 | 說明 |
|
||
|------|------|------|
|
||
| `posting_date` | Date | 入帳日期 |
|
||
| `account_type` | Select | 科目類型 |
|
||
| `account` | Link → Account | 會計科目 |
|
||
| `party_type` | Link → DocType | 對象類型 |
|
||
| `party` | Dynamic Link | 對象 |
|
||
| `voucher_type` | Link → DocType | 來源文件類型 |
|
||
| `voucher_no` | Dynamic Link | 來源文件編號 |
|
||
| `against_voucher_type` | Link → DocType | 對應憑證類型 |
|
||
| `against_voucher_no` | Dynamic Link | 對應憑證編號 |
|
||
| `amount` | Currency | 金額 |
|
||
| `account_currency` | Link → Currency | 科目幣別 |
|
||
| `amount_in_account_currency` | Currency | 科目幣別金額 |
|
||
| `delinked` | Check | 是否已解綁 |
|
||
| `company` | Link → Company | 公司 |
|
||
| `cost_center` | Link → Cost Center | 成本中心 |
|
||
| `project` | Link → Project | 專案 |
|
||
| `due_date` | Date | 到期日 |
|
||
| `finance_book` | Link → Finance Book | 財務簿 |
|
||
| `remarks` | Text | 備註 |
|
||
| `voucher_detail_no` | Data | 明細編號 |
|
||
|
||
---
|
||
|
||
## 會計數據導入的 4 種方式
|
||
|
||
### 方式 A: API 創建交易文件(推薦 ⭐)
|
||
|
||
直接創建 `sales_invoice`、`purchase_invoice`、`payment_entry` 或 `journal_entry`。
|
||
ERPNext 的 `controller` 會自動生成 GL Entry。
|
||
|
||
**優點**:
|
||
- 自動化程度高
|
||
- 觸發完整業務邏輯(庫存、AR/AP、稅務)
|
||
- 可追溯來源文件
|
||
|
||
**缺點**:
|
||
- 需要遵循 ERPNext 的表單結構
|
||
- 外幣交易需要處理匯率
|
||
|
||
**API 示例**:
|
||
```bash
|
||
# 創建 Sales Invoice
|
||
curl -X POST \
|
||
-H "Authorization: token <api_key>:<secret>" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"customer": "Customer Name",
|
||
"posting_date": "2026-04-18",
|
||
"company": "Company Name",
|
||
"items": [
|
||
{
|
||
"item_code": "Item Code",
|
||
"qty": 1,
|
||
"rate": 100,
|
||
"income_account": "Revenue - Company",
|
||
"cost_center": "Main - Company"
|
||
}
|
||
],
|
||
"taxes": [...]
|
||
}' \
|
||
https://<your-erpnext-host>/api/resource/Sales%20Invoice
|
||
|
||
# 提交(Submit)
|
||
curl -X POST \
|
||
-H "Authorization: token <api_key>:<secret>" \
|
||
https://<your-erpnext-host>/api/method/frappe.desk.form.submit/submit?doclist=%5B%22INV-00001%22%5D
|
||
```
|
||
|
||
---
|
||
|
||
### 方式 B: API 直接創建 Journal Entry(最靈活)
|
||
|
||
手動建立日記帳分录,適合批次導入。
|
||
|
||
**優點**:
|
||
- 完全控制借貸分录
|
||
- 適合複雜的會計調整
|
||
- 不受業務流程限制
|
||
|
||
**缺點**:
|
||
- 不會自動更新 AR/AP
|
||
- 不會觸發庫存變動
|
||
- 需要手動處理 Payment Ledger Entry
|
||
|
||
**API 示例**:
|
||
```bash
|
||
curl -X POST \
|
||
-H "Authorization: token <api_key>:<secret>" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"company": "Company Name",
|
||
"posting_date": "2026-04-18",
|
||
"accounts": [
|
||
{
|
||
"account": "Revenue - Company",
|
||
"credit_in_account_currency": 1000,
|
||
"debit_in_account_currency": 0,
|
||
"cost_center": "Main - Company"
|
||
},
|
||
{
|
||
"account": "Cash - Company",
|
||
"debit_in_account_currency": 1000,
|
||
"credit_in_account_currency": 0,
|
||
"cost_center": "Main - Company"
|
||
}
|
||
]
|
||
}' \
|
||
https://<your-erpnext-host>/api/resource/Journal%20Entry
|
||
```
|
||
|
||
---
|
||
|
||
### 方式 C: Data Import(內建工具)
|
||
|
||
ERPNext 內建 Data Import 功能,支援 CSV/JSON 批量導入。
|
||
|
||
**優點**:
|
||
- 無需寫程式碼
|
||
- 支援映射模板
|
||
- 適合歷史數據導入
|
||
|
||
**缺點**:
|
||
- 無法自訂業務邏輯
|
||
- 外幣交易處理較複雜
|
||
- 錯誤處理較弱
|
||
|
||
---
|
||
|
||
### 方式 D: 自訂 API Endpoint
|
||
|
||
在 hooks.py 註冊自訂 API,處理特定業務邏輯。
|
||
|
||
**優點**:
|
||
- 完全控制業務邏輯
|
||
- 可處理複雜轉換
|
||
- 可與外部系統整合
|
||
|
||
**缺點**:
|
||
- 需要維護自訂程式碼
|
||
- 更新 ERPNext 版本時可能衝突
|
||
|
||
---
|
||
|
||
## 基礎資料依賴
|
||
|
||
在導入會計數據前,以下 Doctype 必須先存在:
|
||
|
||
| 基礎資料 | Doctype | 用途 |
|
||
|---------|---------|------|
|
||
| 公司 | `company` | 所有分录的歸屬 |
|
||
| 會計科目 | `account` | 借貸方科目 |
|
||
| 成本中心 | `cost_center` | 成本歸屬 |
|
||
| 客戶 | `customer` | 往來對象 |
|
||
| 供應商 | `supplier` | 往來對象 |
|
||
| 商品 | `item` | 商品/服務 |
|
||
| 會計年度 | `fiscal_year` | 年度設定 |
|
||
| 幣別 | `currency` | 外幣交易 |
|
||
| 銀行帳戶 | `bank_account` | 付款來源 |
|
||
| 倉庫 | `warehouse` | 庫存管理 |
|
||
| 計量單位 | `uom` | 商品單位 |
|
||
| 稅金模板 | `taxes_and_charges_template` | 稅務計算 |
|
||
| 專案 | `project` | 專案管理 |
|
||
| 財務簿 | `finance_book` | 財務簿設定 |
|
||
|
||
### 科目表結構(Chart of Accounts)
|
||
|
||
ERPNext 的科目表是**階層式結構**,類似樹狀:
|
||
|
||
```
|
||
資產 (Asset)
|
||
├── 流動資產 (Current Asset)
|
||
│ ├── 現金 (Cash)
|
||
│ │ ├── 現金 - 公司 (Cash - Company)
|
||
│ │ └── 銀行存款 - 公司 (Bank - Company)
|
||
│ └── 應收帳款 (Accounts Receivable)
|
||
│ └── 應收帳款 - 公司 (Debtors - Company)
|
||
└── 固定資產 (Fixed Asset)
|
||
└── 設備 - 公司 (Equipment - Company)
|
||
|
||
負債 (Liability)
|
||
├── 流動負債 (Current Liability)
|
||
│ └── 應付帳款 (Accounts Payable)
|
||
│ └── 應付帳款 - 公司 (Creditors - Company)
|
||
└── 長期負債 (Long Term Liability)
|
||
|
||
權益 (Equity)
|
||
└── 業主權益 (Capital)
|
||
└── 資本 - 公司 (Capital - Company)
|
||
|
||
收入 (Income)
|
||
└── 營業收入 (Operating Income)
|
||
└── 銷售收入 - 公司 (Sales - Company)
|
||
|
||
支出 (Expense)
|
||
└── 營業支出 (Operating Expense)
|
||
└── 商品成本 - 公司 (Cost of Goods Sold - Company)
|
||
```
|
||
|
||
---
|
||
|
||
## 自訂 API 開發架構
|
||
|
||
### 目錄結構
|
||
|
||
```
|
||
/home/tony/erpnext-analysis/
|
||
├── erpnext/
|
||
│ └── accounts/
|
||
│ ├── api/
|
||
│ │ ├── __init__.py
|
||
│ │ ├── v1/
|
||
│ │ │ ├── __init__.py
|
||
│ │ │ ├── imports.py # 導入 API
|
||
│ │ │ ├── reconciliation.py # 對帳 API
|
||
│ │ │ └── reports.py # 報表 API
|
||
│ │ └── utils.py # 公用函數
|
||
│ ├── doctype/
|
||
│ │ ├── gl_entry/
|
||
│ │ ├── sales_invoice/
|
||
│ │ └── purchase_invoice/
|
||
│ ├── general_ledger.py # 核心 GL 邏輯
|
||
│ └── utils.py # 公用函數
|
||
└── ERPNext_Accounting_Structure.md # 本文件
|
||
```
|
||
|
||
### hooks.py 註冊自訂 API
|
||
|
||
```python
|
||
# erpnext/hooks.py 中加入
|
||
|
||
get_api_versions = lambda: [
|
||
{
|
||
"version": "v1",
|
||
"path": "/api/method/accounts.api.v1.*"
|
||
}
|
||
]
|
||
```
|
||
|
||
### 自訂 API 模組範例
|
||
|
||
```python
|
||
# accounts/api/v1/imports.py
|
||
import frappe
|
||
from frappe import _
|
||
from frappe.utils import nowdate
|
||
|
||
@frappe.whitelist()
|
||
def import_sales_invoice(data):
|
||
"""
|
||
批量導入銷售發票
|
||
:param data: JSON 格式的發票數據
|
||
"""
|
||
invoices = frappe.parse_json(data)
|
||
results = []
|
||
|
||
for inv_data in invoices:
|
||
try:
|
||
invoice = frappe.get_doc({
|
||
"doctype": "Sales Invoice",
|
||
"customer": inv_data.get("customer"),
|
||
"posting_date": inv_data.get("posting_date") or nowdate(),
|
||
"company": inv_data.get("company"),
|
||
"items": [
|
||
{
|
||
"item_code": item.get("item_code"),
|
||
"qty": item.get("qty", 1),
|
||
"rate": item.get("rate"),
|
||
"income_account": item.get("income_account"),
|
||
"cost_center": item.get("cost_center")
|
||
}
|
||
for item in inv_data.get("items", [])
|
||
]
|
||
})
|
||
invoice.insert()
|
||
invoice.submit() # 提交(生成 GL Entry)
|
||
results.append({
|
||
"name": invoice.name,
|
||
"status": "success"
|
||
})
|
||
except Exception as e:
|
||
results.append({
|
||
"customer": inv_data.get("customer"),
|
||
"status": "error",
|
||
"message": str(e)
|
||
})
|
||
|
||
return {"results": results}
|
||
```
|
||
|
||
---
|
||
|
||
## 關鍵程式邏輯
|
||
|
||
### general_ledger.py 核心函數
|
||
|
||
| 函數 | 行號 | 說明 |
|
||
|------|------|------|
|
||
| `make_gl_entries()` | L28 | 創建 GL Entry |
|
||
| `process_gl_map()` | L189 | 處理分錄映射 |
|
||
| `save_entries()` | L407 | 保存分錄 |
|
||
| `make_entry()` | L425 | 創建單筆分錄 |
|
||
| `process_debit_credit_difference()` | L472 | 處理借貸差額 |
|
||
| `make_round_off_gle()` | L550 | 創建四捨五入分錄 |
|
||
| `make_reverse_gl_entries()` | L682 | 創建反向分錄(取消) |
|
||
| `check_freezing_date()` | L794 | 檢查會計凍結日期 |
|
||
| `validate_against_pcv()` | L818 | 驗證與期間關閉憑證 |
|
||
|
||
### accounts/utils.py 核心函數
|
||
|
||
| 函數 | 行號 | 說明 |
|
||
|------|------|------|
|
||
| `get_fiscal_year()` | L63 | 獲取會計年度 |
|
||
| `get_balance_on()` | L202 | 獲取科目餘額 |
|
||
| `get_account_name()` | L1321 | 獲取科目名稱 |
|
||
| `get_company_default()` | L1158 | 獲取公司預設值 |
|
||
| `reconcile_against_document()` | L509 | 文件對帳 |
|
||
| `update_gl_entries_after()` | L1652 | 更新之後的分錄 |
|
||
| `get_voucherwise_gl_entries()` | L1796 | 獲取憑證相關分錄 |
|
||
| `get_stock_accounts()` | L1853 | 獲取庫存科目 |
|
||
| `create_payment_ledger_entry()` | L2135 | 創建付款分類帳 |
|
||
| `update_voucher_outstanding()` | L2158 | 更新憑證未清金額 |
|
||
| `run_ledger_health_checks()` | L2608 | 執行分類帳健康檢查 |
|
||
|
||
---
|
||
|
||
## 下一步建議
|
||
|
||
### 目前狀態
|
||
|
||
你目前**沒有運行中的 ERPNext 實例**,要開發 API 需要:
|
||
|
||
1. **部署環境**: 建立 Frappe bench(需要 Python 3.10+, PostgreSQL, Redis)
|
||
2. **安裝 ERPNext**: `bench get-app erpnext`
|
||
3. **建立公司與會計科目**: 設定 Chart of Accounts
|
||
4. **開發 API**: 在自訂 app 或 ERPNext 目錄下寫自訂 API
|
||
|
||
### 可選方向
|
||
|
||
- **(A)** 繼續靜態分析其他 Doctype 結構(如 Payment Entry 的 reference 機制)
|
||
- **(B)** 規劃 ERPNext bench 部署的步驟和 Docker 設定
|
||
- **(C)** 分析特定場景的導入流程(例如:批量導入發票 → 自動生成 GL Entry)
|
||
|
||
### 推薦做法
|
||
|
||
對於**導入會計數據**的需求,建議優先考慮:
|
||
|
||
1. **少量數據** → 使用方式 A(API 創建交易文件)
|
||
2. **大量歷史數據** → 使用方式 C(Data Import)
|
||
3. **特殊業務邏輯** → 使用方式 D(自訂 API Endpoint)
|
||
4. **複雜調整分录** → 使用方式 B(Journal Entry)
|
||
|
||
---
|
||
|
||
## 參考資源
|
||
|
||
- ERPNext 官方文件: https://docs.erpnext.com/
|
||
- GitHub 原始碼: https://github.com/frappe/erpnext
|
||
- Frappe 框架文件: https://frappeframework.com/docs
|
||
|
||
---
|
||
|
||
> **Generated by Nexus** | 2026-04-18
|