- Updated data model documentation to clarify relationships between projects, scenarios, and profitability calculations. - Introduced a new guide for data import/export templates, detailing CSV and Excel workflows for profitability, capex, and opex data. - Created a comprehensive field inventory for data import/export, outlining input fields, derived outputs, and snapshot columns. - Renamed "Initial Capex Planner" to "Capex Planner" and "Processing Opex Planner" to "Opex Planner" for consistency across user guides. - Adjusted access paths and related resources in user guides to reflect the new naming conventions. - Improved clarity and consistency in descriptions and instructions throughout the user documentation.
8.5 KiB
8.5 KiB
Opex Planner
The Opex Planner captures recurring operational costs, applies escalation/discount assumptions, and persists calculation snapshots for projects and scenarios. It satisfies the Operational Expenditure tooling defined in FR-014.
Access Paths
- Workspace sidebar: Navigate to Workspace → Opex Planner.
- Scenario detail header: Use the Processing Opex Planner button to open the planner pre-loaded with the active project/scenario context.
Prerequisites
- Authenticated CalMiner account with viewer or higher access to the target project or scenario.
- Baseline scenario/project metadata (currency, discount rate, primary resource) to seed form defaults when IDs are provided.
Planner Workflow
- Open the planner via the sidebar or scenario action. Query parameters (
project_id,scenario_id) load project and scenario metadata plus the latest persisted snapshot, when available. - Review defaults in the global parameters panel. Currency, discount rate, evaluation horizon, and persist toggle derive from the scenario, project, or system defaults surfaced by
_prepare_opex_contextinroutes/calculations.py. - Capture opex components in the components table. Each row records the details listed in the Component Fields table below. Rows support dynamic add/remove interactions and inline validation messages for missing data.
- Adjust global parameters such as escalation percentage, discount rate, evaluation horizon, and whether escalation applies to the timeline. Parameter defaults derive from the active scenario, project, or environment configuration.
- Add optional snapshot notes that persist alongside stored results and appear in the snapshot history UI (planned) and API responses.
- Run the calculation with Save & Calculate. The POST handler validates input via
OpexCalculationRequest, callsservices.calculations.calculate_opex, and repopulates the form with normalized data. When validation fails, the page returns a 422 status with component-level alerts. - Review results in the summary cards and detailed breakdowns: total annual opex, per-ton cost, category totals, escalated timeline table, and the normalized component listing. Alerts surface validation issues or component-level notices above the table.
Component Fields
| Field | Description | Notes |
|---|---|---|
category |
Cost grouping (labor, materials, energy, maintenance, other). |
Drives category totals and stacked charts. |
name |
Descriptive label for the component. | Displayed in breakdown tables and persisted snapshots. |
unit_cost |
Cost per unit in the selected currency. | Decimal, >= 0. |
quantity |
Units consumed per frequency period. | Decimal, >= 0. |
frequency |
Recurrence cadence (daily, weekly, monthly, quarterly, annually). |
Controls timeline expansion scaling. |
currency |
ISO-4217 currency code. | Must match parameters currency when persisting. |
period_start |
First evaluation period (1-indexed) to include the component. | Optional; defaults to 1. |
period_end |
Final evaluation period to include the component. | Optional; defaults to evaluation horizon. |
notes |
Free-form text stored with the component. | Optional; hidden by default in HTML form. |
Global Parameters
| Parameter | Purpose |
|---|---|
currency_code |
Normalized currency for totals and timeline. |
escalation_pct |
Annual escalation applied to eligible components when apply_escalation is true. |
discount_rate_pct |
Discount rate surfaced for downstream profitability workflows. |
evaluation_horizon_years |
Number of years to expand the timeline. |
apply_escalation |
Boolean flag enabling escalation across the timeline. |
persist (options) |
Persists the calculation when project/scenario context is present. |
snapshot_notes (options) |
Optional metadata attached to stored snapshots. |
Persistence Behaviour
- When
project_idorscenario_idis supplied andoptions[persist]evaluates true (default for HTML form), snapshots are stored viaProjectOpexSnapshotandScenarioOpexSnapshotrepositories before rendering the response. - Snapshot payloads capture normalized component entries, parameters, escalation settings, calculated totals, and optional notes, enabling historical comparison and downstream profitability inputs.
- JSON clients can disable persistence by sending
"options": {"persist": false}or omit identifiers for ad hoc calculations.
API Reference
| Route | Method | Description |
|---|---|---|
/calculations/opex (calculations.opex_form) |
GET | Renders the planner template with defaults and any latest snapshot context for the supplied project/scenario IDs. |
/calculations/opex (calculations.opex_submit) |
POST | Accepts form or JSON payload matching OpexCalculationRequest, returns HTML or JSON results, and persists snapshots when context is present. |
Key schemas and services:
schemas.calculations.OpexComponentInput,OpexParameters,OpexCalculationRequest,OpexCalculationResultservices.calculations.calculate_opex_prepare_opex_context,_persist_opex_snapshots, and related helpers inroutes/calculations.py
Example JSON Request
{
"components": [
{
"category": "energy",
"name": "Processing Plant Power",
"unit_cost": "480.00",
"quantity": "1.0",
"frequency": "monthly",
"currency": "USD",
"period_start": 1,
"period_end": 12
}
],
"parameters": {
"currency_code": "USD",
"escalation_pct": "3.0",
"discount_rate_pct": "8.0",
"evaluation_horizon_years": 10,
"apply_escalation": true
},
"options": {
"persist": true,
"snapshot_notes": "Baseline processing OPEX"
}
}
The response payload mirrors OpexCalculationResult, returning normalized components, aggregated totals, timeline series, and snapshot metadata when persistence is enabled.
Troubleshooting
- Validation errors: The planner surfaces field-level issues above the component table. JSON responses include
errorsandmessagekeys mirroring Pydantic validation output. - Currency mismatch: All component rows must share the same currency. Adjust row currencies or the default currency in the parameters panel to resolve mismatches enforced by the service layer.
- Timeline coverage: Ensure
period_startandperiod_endfall within the evaluation horizon. Rows outside the horizon are ignored in the timeline though they still influence totals.