Files
calminer-docs/userguide/processing_opex_planner.md

8.8 KiB

Processing Opex Planner

The Processing 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 → Processing 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

  1. 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.
  2. 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_context in routes/calculations.py.
  3. 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.
  4. 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.
  5. Add optional snapshot notes that persist alongside stored results and appear in the snapshot history UI (planned) and API responses.
  6. Run the calculation with Save & Calculate. The POST handler validates input via ProcessingOpexCalculationRequest, calls services.calculations.calculate_processing_opex, and repopulates the form with normalized data. When validation fails, the page returns a 422 status with component-level alerts.
  7. 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_id or scenario_id is supplied and options[persist] evaluates true (default for HTML form), snapshots are stored via ProjectProcessingOpexSnapshot and ScenarioProcessingOpexSnapshot repositories 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/processing-opex (calculations.processing_opex_form) GET Renders the planner template with defaults and any latest snapshot context for the supplied project/scenario IDs.
/calculations/processing-opex (calculations.processing_opex_submit) POST Accepts form or JSON payload matching ProcessingOpexCalculationRequest, returns HTML or JSON results, and persists snapshots when context is present.

Key schemas and services:

  • schemas.calculations.ProcessingOpexComponentInput, ProcessingOpexParameters, ProcessingOpexCalculationRequest, ProcessingOpexCalculationResult
  • services.calculations.calculate_processing_opex
  • _prepare_opex_context, _persist_opex_snapshots, and related helpers in routes/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 ProcessingOpexCalculationResult, 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 errors and message keys 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_start and period_end fall within the evaluation horizon. Rows outside the horizon are ignored in the timeline though they still influence totals.