Files
calminer-docs/specifications/price_calculation.md
zwitschi 29f16139a3 feat: documentation update
- Completed export workflow implementation (query builders, CSV/XLSX serializers, streaming API endpoints, UI modals, automated tests).
- Added export modal UI and client script to trigger downloads directly from dashboard.
- Documented import/export field mapping and usage guidelines in FR-008.
- Updated installation guide with export environment variables, dependencies, and CLI/CI usage instructions.
2025-11-11 18:34:02 +01:00

156 lines
8.9 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.
# Product Price Calculation Specification
## 1. Purpose
Provide a detailed reference for calculating product sale prices across supported metals, including adjustments for ore grade, recovery rate, moisture, and impurities. This document extends the initial variable list with explicit formula definitions, validation rules, and example workflows.
## 2. Scope
- Applies to primary commodity outputs (e.g., copper, gold, lithium) cited in scenario models.
- Supports integration into scenario profitability pipelines and exportable reporting.
- Covers penalties/credits based on quality metrics (water content, impurity assays) and market adjustments.
## 3. Inputs & Parameters
| Symbol | Name | Description | Units / Domain | Validation |
| ------------- | ----------------------- | ---------------------------------------------------- | ---------------------------- | ----------------------- |
| $M$ | Metal | Commodity identifier (e.g., `copper`, `gold`) | Enum `MetalType` | Required |
| $Q_{ore}$ | Ore tonnage processed | Total ore mass entering processing | metric tonnes | $Q_{ore} > 0$ |
| $G$ | Head grade | Percentage of target metal in ore (mass fraction) | % (0100) | $0 < G \leq 100$ |
| $R$ | Recovery rate | Plant recovery efficiency | % (0100) | $0 < R \leq 100$ |
| $T$ | Treatment charge | Base processing fee negotiated with smelter/refiner | currency / tonne concentrate | $T \geq 0$ |
| $S$ | Smelting charge | Additional fee tied to concentrate handling | currency / tonne concentrate | $S \geq 0$ |
| $M_{moist}$ | Moisture content | Percentage water in concentrate | % (0100) | $0 \leq M_{moist} < 40$ |
| $M_{imp}^{i}$ | Impurity content | For impurity _i_ (e.g., As, Pb, Zn) measure mass ppm | ppm | $0 \leq M_{imp}^{i}$ |
| $F_{moist}$ | Moisture penalty factor | Currency impact per excess moisture percentage | currency / % | Optional |
| $F_{imp}^{i}$ | Impurity penalty factor | Currency impact per ppm over threshold | currency / ppm | Optional |
| $Adj_{prem}$ | Premiums/credits | Adders (e.g., gold credits in copper concentrate) | currency | Optional |
| $FX$ | FX rate | Convert pricing currency to scenario currency | currency conversion rate | $FX > 0$ |
## 4. Derived Values
1. **Metal content** (payable basis):
$$ Q*{metal} = Q*{ore} \times \frac{G}{100} \times \frac{R}{100} $$
2. **Payable mass after deductions** (if contractual payable is <100%): Introduce payable percentage $K_M$ (default 100%).
$$ Q*{pay} = Q*{metal} \times \frac{K_M}{100} $$
3. **Gross revenue** in reference currency:
$$ Rev*{gross}^{ref} = Q*{pay} \times P\_{ref} $$
4. **Treatment and smelting charges**:
$$ Charges = T + S $$
5. **Moisture penalty** (if moisture exceeds threshold $M_{moist}^{thr}$):
$$ Pen*{moist} = \max(0, M*{moist} - M*{moist}^{thr}) \times F*{moist} $$
6. **Impurity penalty** (sum over impurities with thresholds $M_{imp}^{i,thr}$):
$$ Pen*{imp} = \sum_i \max(0, M*{imp}^{i} - M*{imp}^{i,thr}) \times F*{imp}^{i} $$
7. **Net revenue before premiums**:
$$ Rev*{net}^{ref} = Rev*{gross}^{ref} - Charges - Pen*{moist} - Pen*{imp} $$
8. **Apply premiums/credits**:
$$ Rev*{adj}^{ref} = Rev*{net}^{ref} + Adj\_{prem} $$
9. **Convert to scenario currency**:
$$ Rev*{adj} = Rev*{adj}^{ref} \times FX $$
## 5. Workflow Examples
### 5.1 Copper Concentrate
- Ore feed $Q_{ore} = 100,000$ t, head grade $G = 1.2\%$, recovery $R = 90\%$.
- Reference price $P_{ref} = \$8,500$/t, payable percentage $K_M = 96\%$.
- Treatment and smelting charges $T+S = \$100/t$ concentrate equivalent.
- Moisture threshold 8%, actual 10%, penalty factor $F_{moist} = \$3,000$ per %.
- Arsenic impurity: threshold 0 ppm (premium for As-free), actual 100 ppm, penalty factor $F_{imp}^{As} = \$2$ per ppm.
Calculations:
1. $Q_{metal} = 100,000 \times 0.012 \times 0.9 = 1,080$ t.
2. $Q_{pay} = 1,080 \times 0.96 = 1,036.8$ t.
3. $Rev_{gross}^{ref} = 1,036.8 \times 8,500 = \$8,812,800$.
4. $Pen_{moist} = (10 - 8) \times 3,000 = \$6,000$.
5. $Pen_{imp} = (100 - 0) \times 2 = \$200$.
6. $Rev_{net}^{ref} = 8,812,800 - 100,000 - 6,000 - 200 = \$8,706,600$.
7. Assume premiums $Adj_{prem} = \$50,000$, FX = 1.0 → final $Rev_{adj} = \$8,756,600$.
### 5.2 Gold Doré
- Ore feed 50,000 t, head grade 2.5 g/t (convert to % mass: 0.00025%), recovery 92%.
- Reference price $P_{ref} = \$1,900$/oz, convert to per tonne of metal ($1\ \text{oz} = 0.0311035 \text{kg}$).
- Treat $Q_{metal}$ in kilograms or troy ounces as implementation convenience.
- No moisture/impurity penalties; add refining charge 1.5% of revenue.
Implementation note: Provide conversion helpers for precious metals (grams per tonne to ounces, etc.).
## 6. Validation & Error Handling
- Ensure required inputs are provided; raise descriptive validation errors per scenario when data missing.
- Bound checks for percentage inputs; clamp or reject values outside (0,100].
- Penalty factors default to zero if not configured; log warnings if impurities exceed supported list.
- FX rate defaults to 1.0 when scenario currency matches reference currency; enforce positive values.
## 7. Data Sources & Configuration
- Reference prices sourced from market data integration (e.g., LME, LBMA). Provide placeholder configuration until connectors exist.
- Penalty thresholds and factors configurable per smelter contract; persisted in the `pricing_settings` tables (`pricing_settings`, `pricing_metal_settings`, `pricing_impurity_settings`).
- The default configuration lives in the `pricing_settings` row with slug `default`. `services.bootstrap.bootstrap_pricing_settings` runs during FastAPI startup (and via `scripts/initial_data.py`) to ensure this row exists and mirrors the configured baseline metadata.
- Runtime consumers obtain metadata through the FastAPI dependency `dependencies.get_pricing_metadata`, which loads the persisted defaults with impurity overrides. If the requested slug is missing, the dependency reseeds the table from `Settings.pricing_metadata()` before returning a fresh `PricingMetadata` instance.
- Deployment environments can still influence the initial bootstrap by setting the following environment variables **before the database is seeded**. They are only read when creating or reseeding the `default` record:
| Environment Variable | Default | Bootstrap Usage |
| ------------------------------------------- | ------- | ------------------------------------------------------------------------------- |
| `CALMINER_PRICING_DEFAULT_PAYABLE_PCT` | `100.0` | Initial payable percentage stored in the default pricing settings row. |
| `CALMINER_PRICING_DEFAULT_CURRENCY` | `USD` | Initial currency recorded in the persisted metadata (can be set to `null`). |
| `CALMINER_PRICING_MOISTURE_THRESHOLD_PCT` | `8.0` | Initial moisture threshold applied when seeding the database. |
| `CALMINER_PRICING_MOISTURE_PENALTY_PER_PCT` | `0.0` | Initial moisture penalty factor captured in the persisted configuration record. |
Operators should update the database record (or project-specific overrides) after bootstrap to align with active smelter contracts. Subsequent application restarts reuse the stored values without re-reading environment variables.
## 8. Output Schema
Define structured result for integration:
```json
{
"metal": "copper",
"ore_tonnage": 100000,
"head_grade_pct": 1.2,
"recovery_pct": 90,
"payable_metal_tonnes": 1036.8,
"reference_price": 8500,
"gross_revenue": 8812800,
"moisture_penalty": 6000,
"impurity_penalty": 200,
"treatment_smelt_charges": 100000,
"premiums": 50000,
"net_revenue": 8756600,
"currency": "USD"
}
```
## 9. Dependencies & Next Steps
- Align with FR-006 (performance monitoring) to collect calculation metrics.
- Coordinate with reporting requirements to expose inputs/outputs in exports.
- Next implementation steps: build pricing service module, integrate with scenario evaluation, and author unit tests using example data above.# Variables for Price Calculation
## Variables
- Base Percentage Ore Content
- Increase per Percentage Ore Content
- Price per Unit Weight
## Penalties
- Moisture
- Impurities
## Price Calculation Formula
The revenue from product sales can be modeled as:
`Revenue = (Quantity Sold * Price per Unit) - Penalties`