supplychain/README.md

194 lines
7.8 KiB
Markdown
Raw 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.

# Supplychain Module
Supplier and Reseller Management module for Sage platform.
## Overview
Manages the complete supply chain workflow for reseller/distributor organizations:
- **Operators** manage suppliers and supply contracts with product-level discount terms
- **Sales** manage sub-resellers (tier-2 distributors) and distribution agreements with product-level discount terms
- **Sales ledger** records transactions and calculates supply/distribution amounts for accounting
## Architecture
### Tables
| Table | Description |
|-------|-------------|
| `suppliers` | Supplier master data (contact, bank, tax info) |
| `supply_contracts` | Supply contracts between reseller and supplier |
| `supply_contract_items` | Product-level discount details per supply contract |
| `sub_resellers` | Sub-reseller (tier-2 distributor) master data |
| `distribution_agreements` | Distribution agreements between reseller and sub-reseller |
| `distribution_agreement_items` | Product-level discount details per distribution agreement |
| `sales_ledger` | Sales transaction records with calculated amounts |
| `platform_supply_relations` | Platform-level org-to-org supply relationships (P0) |
| `platform_supply_products` | Product details within platform supply relations (P0) |
| `product_supplier_mapping` | Unified product-to-supplier mapping across internal/external (P0) |
### P0 Platform Supply Chain (2026-06)
Enables supply chain relationships between organizations on the Sage platform:
- **platform_supply_relations**: Links two organizations (supplier ↔ buyer) with cooperation type (distribution/agency/direct-supply), settlement mode (discount/commission/fixed), and contract period
- **platform_supply_products**: Product-level pricing within a supply relation — supply price, retail price, discount, commission rate, min order qty
- **product_supplier_mapping**: Unified view mapping any product to its supplier(s), whether internal (platform org) or external (suppliers table), with preferred supplier flag
Key business APIs:
- `query_platform_suppliers.dspy` — List platform orgs available as suppliers (excludes current user's org)
- `query_platform_products.dspy` — List active products owned by a supplier org
- `import_supplier_product.dspy` — Import a supplier's product into buyer's mapping (creates product_supplier_mapping record)
### Discount Calculation Logic
`calculate_sale_amounts()` API is called during product sales:
1. Finds active supply contract for the supplier (filtered by date and status)
2. Looks up product-specific discount in contract items (priority: exact product > product type > default)
3. Finds active distribution agreement for the sub-reseller
4. Looks up product-specific discount in agreement items (same priority)
5. Calculates: supply_amount = total * supply_discount, distribution_amount = total * distribution_discount, profit = distribution - supply
### Role-Based Access
- `reseller.operator` — manage suppliers, supply contracts, and contract items
- `reseller.sale` — manage sub-resellers, distribution agreements, and agreement items
- `reseller.accountant` — view and manage sales ledger entries
## Directory Structure
```
supplychain/
├── supplychain/
│ ├── __init__.py # Package init
│ └── init.py # Module init + ServerEnv registration
├── wwwroot/
│ ├── index.ui # Module entry point
│ ├── menu.ui # Navigation menu
│ ├── provider_recharge.ui # 供应商充值页(主题约定:卡片用 css:card
│ │ # 不硬编码暗色,跟随宿主 data-theme 双主题2026-09-08 修复)
│ └── api/ # CRUD API endpoints (.dspy files)
├── models/ # Table definitions (JSON)
├── json/ # CRUD definitions (JSON)
├── init/ # Initialization data
├── pyproject.toml
├── build.sh
└── README.md
```
## Sage Integration
### 1. Install module
```bash
cd ~/repos/sage/pkgs
git clone https://git.opencomputing.cn/yumoqing/supplychain
cd supplychain
../../py3/bin/pip install .
```
### 2. Generate DDL and apply to database
```bash
cd ~/repos/sage/pkgs/supplychain/models
../../py3/bin/json2ddl mysql . > mysql.ddl.sql
mysql -h <db_host> -u <db_user> -p sage < mysql.ddl.sql
```
### 3. Generate CRUD UI files
```bash
cd ~/repos/sage/pkgs/supplychain/json
../../py3/bin/xls2ui -m ../models -o ../wwwroot supplychain *.json
```
### 4. Link wwwroot
```bash
cd ~/repos/sage/wwwroot
ln -sf ../pkgs/supplychain/wwwroot supplychain
```
### 5. Register module in Sage
Add to `~/repos/sage/app/sage.py`:
```python
from supplychain.init import load_supplychain
# In init():
load_supplychain()
```
### 6. Register RBAC permissions
Add to `~/repos/sage/load_path.py`:
```
/supplychain logined
/supplychain/index.ui logined
/supplychain/menu.ui any
/supplychain/suppliers_list logined
/supplychain/suppliers_list/index.ui logined
/supplychain/supply_contracts_list logined
/supplychain/supply_contracts_list/index.ui logined
/supplychain/supply_contract_items_list logined
/supplychain/supply_contract_items_list/index.ui logined
/supplychain/sub_resellers_list logined
/supplychain/sub_resellers_list/index.ui logined
/supplychain/distribution_agreements_list logined
/supplychain/distribution_agreements_list/index.ui logined
/supplychain/distribution_agreement_items_list logined
/supplychain/distribution_agreement_items_list/index.ui logined
/supplychain/sales_ledger_list logined
/supplychain/sales_ledger_list/index.ui logined
/supplychain/api/suppliers_create.dspy logined
/supplychain/api/suppliers_update.dspy logined
/supplychain/api/suppliers_delete.dspy logined
/supplychain/api/supply_contracts_create.dspy logined
/supplychain/api/supply_contracts_update.dspy logined
/supplychain/api/supply_contracts_delete.dspy logined
/supplychain/api/supply_contract_items_create.dspy logined
/supplychain/api/supply_contract_items_update.dspy logined
/supplychain/api/supply_contract_items_delete.dspy logined
/supplychain/api/sub_resellers_create.dspy logined
/supplychain/api/sub_resellers_update.dspy logined
/supplychain/api/sub_resellers_delete.dspy logined
/supplychain/api/distribution_agreements_create.dspy logined
/supplychain/api/distribution_agreements_update.dspy logined
/supplychain/api/distribution_agreements_delete.dspy logined
/supplychain/api/distribution_agreement_items_create.dspy logined
/supplychain/api/distribution_agreement_items_update.dspy logined
/supplychain/api/distribution_agreement_items_delete.dspy logined
/supplychain/api/sales_ledger_create.dspy logined
/supplychain/api/sales_ledger_update.dspy logined
/supplychain/api/sales_ledger_delete.dspy logined
```
Then run:
```bash
cd ~/repos/sage && ./py3/bin/python load_path.py
```
### 7. Restart Sage
```bash
cd ~/repos/sage && ./stop.sh && ./start.sh
```
## API for External Modules
Other modules can call `calculate_sale_amounts()` to compute supply/distribution amounts during sales:
```python
env = ServerEnv()
result = await env.calculate_sale_amounts(request, {
"resellerid": org_id,
"sub_reseller_id": sub_reseller_id, # optional
"supplier_id": supplier_id, # optional
"prodtypeid": product_type_id,
"productid": product_id,
"quantity": qty,
"unit_price": price,
})
# Returns: {contract_id, agreement_id, total_amount, supply_discount, supply_amount, distribution_discount, distribution_amount, profit_amount}
```
## Deployment Checklist
1. Execute DDL: `models/mysql.ddl.sql` — creates 3 new tables (platform_supply_relations, platform_supply_products, product_supplier_mapping)
2. Init appcodes: Run `init/data.json` inserts for 6 appcode groups
3. Build CRUD UI: `bash build.sh`
4. Register RBAC: `~/repos/sage/py3/bin/python scripts/load_path.py` (or central load_path.py)
5. Restart Sage