Files
erpnext-analysis/ERPNext_Accounting_Structure.md
2026-05-18 18:06:24 +08:00

705 lines
27 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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