Add ERPNext Accounting Structure Analysis

This commit is contained in:
tony-claw
2026-05-18 18:06:24 +08:00
parent 1b616e5870
commit b4e068471b

View File

@@ -0,0 +1,704 @@
# 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. **少量數據** → 使用方式 AAPI 創建交易文件)
2. **大量歷史數據** → 使用方式 CData Import
3. **特殊業務邏輯** → 使用方式 D自訂 API Endpoint
4. **複雜調整分录** → 使用方式 BJournal Entry
---
## 參考資源
- ERPNext 官方文件: https://docs.erpnext.com/
- GitHub 原始碼: https://github.com/frappe/erpnext
- Frappe 框架文件: https://frappeframework.com/docs
---
> **Generated by Nexus** | 2026-04-18