# 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 | ### 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 │ └── 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 -u -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} ```