docs: 补全 README(复式记账引擎/15张表/load_accounting注入清单/记账三步同事务铁律)

This commit is contained in:
yumoqing 2026-09-07 11:42:17 +08:00
parent 411d1017cf
commit 6c45f8e798

141
README.md
View File

@ -1,2 +1,141 @@
# accounting
# accounting — 记账模块
## 模块定位
Sage 平台的**核心记账引擎**:以复式记账(借/贷双腿)为基础,围绕
「科目subject→ 账户account→ 明细acc_detail/ 余额acc_balance/ 流水
accounting_log」的账务体系向上提供开户、充值、消费、账单、总账、日结、信用额度、
多币种汇率等能力。
记账的定义 = **写分录明细 + 写账务日志 + 修改账户余额**,三步缺一不可,且余额更新与
透支/信用额度校验必须和明细写入在**同一数据库事务上下文**内完成(原子性铁律)。
模块形态Python 包 `accounting`(业务逻辑)+ `models/`(表定义)+ `json/`CRUD 定义)
+ `wwwroot/`(页面/dspy 端点)+ `init/data.json`(种子数据)+ `scripts/`RBAC 注册)。
宿主应用sage 主应用)通过 `load_accounting()` 把所有类与函数注入 `ServerEnv`
供其他模块product、supplychain、unipay 等)跨模块调用。
核心业务文件:`accounting_config.py`Accounting 配置类)/ `openaccount.py`(开户)/
`recharge.py`(充值 RechargeBiz/ `consume.py`(消费记账)/ `bill.py`write_bill 账单)/
`ledger.py`(总账)/ `dayend_balance.py`(日结) / `settle.py`+`settledate.py`(结算)/
`creditlimit.py`(信用额度)/ `exchange.py`(多币种汇率换算)/ `stats.py`(统计)/
`order_to_bill.py`(订单转账单)。
## 表清单models/*.json
| 表名 | 说明 | 关键字段 |
|---|---|---|
| `subject` | 科目表 | name, balance_side(余额方向), subjecttype |
| `account` | 机构账户表 | accounting_orgid, orgid, org1id, currency, subjectid, balance_at, max_detailno |
| `acc_balance` | 账户余额表 | accountid, acc_date, balance |
| `acc_detail` | 账户明细表(分录) | accountid, acc_no, acc_date, acc_timestamp, acc_dir(借/贷), summary, amount |
| `accounting_log` | 账务流水表 | accountid, acc_date, acc_timestamp, acc_dir, summary, amount, billid |
| `account_config` | 账户配置表(参与方类型→科目) | subjectid, partytype, party1type |
| `accounting_config` | 记账配置表(驱动分录双腿) | action, accounting_orgtype, accounting_dir, orgtype, org1type, subjectid, amt_pattern |
| `bill` | 账单 | customerid, resellerid, productid, resourceid, orderid, business_op, amount |
| `bill_detail` | 账单明细 | accounting_orgid, billid, description, participantid, participanttype, subjectname, accounting_dir |
| `biz_order` | 业务订单 | customerid, resellerid, order_date, order_status, business_op, amount, currency |
| `biz_orderdetail` | 业务订单明细 | orderid, productid, product_cnt, prod_config, list_amount, trans_amount, currency |
| `ledger` | 总账表 | accounting_orgid, subjectid, acc_date, d_balance(借方), c_balance(贷方), currency, exchange_rate |
| `credit_limit` | 信用额度表 | accountid, orgid, grant_orgid(授信方,多租户), credit_limit, used_credit, available_credit, valid_from |
| `currency` | 币种 | name, symbol, decimal_places, is_base, status |
| `exchange_rate` | 汇率表 | from_currency, to_currency, buy_rate, sell_rate, mid_rate, effective_date |
种子数据(`init/data.json`appcodes/appcodes_kv 码表 + subject 科目 +
account_config + accounting_config 记账配置 + currency + exchange_rate 初始汇率。
信用额度建表 SQL 另见 `sql/credit_limit.sql`;多币种迁移见
`scripts/multi_currency_migration.sql`
## 对外 API / dspy 端点wwwroot/
**api/(多币种管理端)**
- `currency_create/update/delete.dspy` — 币种维护
- `exchange_rate_create/update/delete.dspy` — 汇率维护
- `fetch_forex_rates.dspy` — 拉取外部外汇牌价
**credit_limit/(信用额度管理)**
- `add/update/delete/get_credit_limit.dspy` — 额度 CRUD
- `credit_manage.ui` / `credit_overview.ui` / `hub.ui` — 管理/总览页面
- `api/credit_summary.dspy``api/set_customer_credit.dspy`(+`set_credit_form.ui`) —
额度汇总与客户授信设置
**账务页面端点wwwroot/ 根)**
- `myaccounts.dspy/.ui``mybalance.dspy``accdetail.dspy/.ui` — 我的账户/余额/明细
- `billing.dspy/.ui``billing_download.dspy` — 账单查询与下载
- `get_user_balance.dspy``oca.dspy``usermenu.ui``error_accounting.ui`
- 开户端点:`open_owner_accounts.dspy` / `open_provider_accounts.dspy` /
`open_reseller_accounts.dspy` / `open_reseller_provider_accounts.dspy` /
`open_customer_accounts.dspy` / `open_customer_accounts_with_orgid.dspy`
- 代充值:`proxy_recharge.ui` + `proxy_recharge_submit.dspy`
- 统计 widget`stat_account_count.ui` / `stat_month_consumption.ui` /
`stat_today_consumption.ui` / `stat_total_balance.ui`
CRUD 定义在 `json/`account/acc_balance/acc_detail/accounting_log/accounting_config/
account_config/subject/credit_limit/currency_list/exchange_rate_list其中
`json/build.sh``xls2ui -m ../models -o ../wwwroot accounting *.json` 从模型生成
wwwroot 页面——**改 CRUD 走 json 定义重新生成,勿手改产物**。
## load 注册函数
宿主在初始化时调用:
```python
from accounting.init import load_accounting
load_accounting()
```
`load_accounting()` 把以下能力注入 `ServerEnv`(跨模块可见):
- **配置/业务类**`Accounting`(记账配置类)、`RechargeBiz`(充值业务)
- **记账函数**`consume_accounting``recharge_accounting``write_bill`
- **开户函数**`openOwnerAccounts` / `openProviderAccounts` / `openResellerAccounts` /
`openCustomerAccounts` / `openRetailRelationshipAccounts`
- **查询函数**`getAccountBalance``getCustomerBalance``getAccountByName`
`get_account_total_amount``get_accdetail``all_my_accounts``get_accounting_stats`
- **信用额度**`get_credit_limit_for_account``update_used_credit``set_credit_limit`
`get_credit_stats``get_my_credit_list``get_all_customer_credits` + 三个 web 包装
`get_credit_stats_web` / `get_my_credits_web` / `get_all_credits_web`,供 Jinja2 .ui 用)
- **多币种**`get_exchange_rate``convert_currency``convert_to_base`
`get_user_currency``BASE_CURRENCY`
数据库名通过宿主注册的 `get_module_dbname('accounting')` 解析(跨宿主复用时表前缀/库名
映射的关键钩子)。独立调试可跑 `app/acc.py`(自带 webapp + RegisterFunction 的最小宿主)。
## 宿主集成(部署)
1. **安装**`./py3/bin/pip install pkgs/accounting`setup.py 打包,包名 accounting
版本见 `accounting/version.py`)。宿主 `import_init.py` 的 INIT_MODULES 需包含本模块
以导入 `init/data.json` 种子数据(码表/科目/记账配置)。
2. **入口调用**:宿主初始化处 `import` 后显式调用 `load_accounting()`
3. **RBAC 注册**`./py3/bin/python pkgs/accounting/scripts/load_path.py [--add-only]`
(自动定位宿主根:含 py3+wwwroot把 wwwroot 全部 .ui/.dspy 路径注册进 permission
表并给角色授权)。注册后 redis db0 FLUSHDB 刷 RBAC 缓存即生效。
4. **建表**models/*.json 经 json2ddl 生成 DDL 部署期执行;运行期禁止 schema 变更。
信用额度增量见 `sql/credit_limit.sql`,多币种迁移见 `scripts/multi_currency_migration.sql`
5. **菜单**:新页面需在 sage 主仓库 `wwwroot/global_menu.ui` 加菜单入口。
6. **i18n**:词条在 `i18n/{zh,en,jp,ko}`,部署时合并进宿主。
新功能四件套核查(缺一即不可见/不可用):`init.py` ServerEnv 暴露 →
`scripts/load_path.py` RBAC 路径 → 宿主 `global_menu.ui` 菜单 → `json/<表>.json` CRUD 定义。
## 部署注意
1. **余额更新不是可选项**:只写 acc_detail 不改 account/acc_balance 的实现按定义就是
不完整记账;透支/信用额度校验必须与明细写入同一事务上下文。
2. **数据隔离**:查询类端点(如 get_accdetail必须按 `orgid` 过滤,防止按 accountid
越权枚举他人账务——新增查询端点照抄该模式。
3. **信用额度多租户**`grant_orgid` 区分授信方;管理端读全部、客户端只读本机构视图,
迁移按 `sql/credit_limit.sql` 执行。
4. **pip 非 editable 安装**:改码后必须重新 `pip install` 到宿主 py3 再重启,
只 git pull 仓库不会更新 site-packages可用文件 md5 对比确认加载版本)。
5. **sage 核心记账引擎 vs sageapi 网关是两层**:本仓库是核心引擎(复式记账/双腿/科目),
sageapi 只是轻量 API 网关credit_limit 等逻辑两层都可能需要但实现方式不同,勿混淆。
6. **先读全模块再改**PFBiz → Accounting → leg_accounting 是完整既有体系,加功能前先读
`accounting_config.py` / `creditlimit.py` / `consume.py`,勿发明平行实现。
7. RBAC 精确 path 匹配,父路径不覆盖子路径;新增 dspy 必须逐条注册,否则 403。
设计文档见 `docs/平台类系统记账子系统.docx`;测试脚本见 `test/`
open_account.py / recharge.py / run_test.py