Skip to content

Add billing currency filter to Data Explorer dashboard (#2093)#2103

Merged
RolandKrummenacher merged 6 commits intodevfrom
fix/2093-dashboard-multi-currency
Apr 22, 2026
Merged

Add billing currency filter to Data Explorer dashboard (#2093)#2103
RolandKrummenacher merged 6 commits intodevfrom
fix/2093-dashboard-multi-currency

Conversation

@RolandKrummenacher
Copy link
Copy Markdown
Collaborator

@RolandKrummenacher RolandKrummenacher commented Apr 21, 2026

Summary

Adds a Currency parameter to the FinOps hub Data Explorer dashboard so cost totals and savings KPIs can be scoped to a single billing currency. Implements Phase 1 items 1 + 2 of #2093; remaining items (Phase 1 item 3, savings-plan FX distortion, Phase 2 USD normalization) continue to be tracked there.

Why

The dashboard aggregates BilledCost / EffectiveCost / ContractedCost / ListCost across rows without any BillingCurrency awareness. For any tenant with more than one billing currency (EA→MCA transitions, M&A, CSP partners with customers in multiple currencies, multi-cloud via FOCUS), the resulting totals and savings rates are mathematically invalid — currencies get summed as if they were comparable numbers.

The CostsPlus base query feeds ~74 of the 86 dashboard queries, so adding the filter there propagates the fix everywhere downstream with minimal blast radius.

Changes

1. New selectedBillingCurrency parameter (displayed as Currency)

  • Scalar, string, sourced from distinct BillingCurrency over the hub's configured retention window.
  • Wired into the CostsPlus base query as | where isempty(selectedBillingCurrency) or BillingCurrency == selectedBillingCurrency, immediately after the time-range filter. Inherited by all ~74 downstream tile queries through CostsPlus and its derived base variables (CostsThisMonth, CostsLastMonth, CostsByMonth, CostsByDay, CostsByDayAHB).
  • Same filter also applied to the one tile that bypassed CostsPlus — the Summary of list, contracted, and effective cost alignment data-quality table on the Data ingestion page (queries Costs() directly).

2. Conditional ⚠️ All option — implicit mixed-currency warning

Rather than adding a separate warning tile (no clean place on the dense Summary page), the warning is embedded into the parameter dropdown itself:

  • Single-currency tenants: dropdown shows only their currency. No "All" option, no noise.
  • Multi-currency tenants: dropdown opens with ⚠️ All as the default. The warning is visible the instant the dashboard loads, and picking any specific currency removes it automatically.

This is done via a synthetic row unioned into the parameter query only when dcount(BillingCurrency) > 1, with an empty BillingCurrency value that the filter treats as "no filter applied".

Scope / what this PR does NOT do

Phase 1 item 3 from the issue (replace sum(ListCost) - sum(EffectiveCost) patterns with sum(x_TotalSavings) etc.) is intentionally out of scope — orthogonal to currency handling and warrants independent review of whether the row-level clamped savings columns actually produce different totals.

Phase 2 (USD normalization toggle) is also deferred — blocked on x_*InUsd column coverage across ingestion paths per the issue.

Coverage audit

All 87 queries in the dashboard were reviewed:

  • ✅ 86 of 87 inherit the filter through CostsPlus (directly or via the five derived base variables).
  • .show cluster extents queries (ingestion row counts) — no cost aggregation, no currency risk.
  • ✅ Settings/metadata queries (HubSettings, range) — no cost data.
  • ✅ The parameter-population query — intentionally unfiltered so the dropdown can list all currencies.
  • ✅ The one outlier that queried Costs() directly (data-quality tile on the ingestion page) — now also filtered.

Test plan

  • Open the dashboard in ADX against a single-currency environment; confirm the Currency chip shows that currency only, no "All", and totals are unchanged vs. pre-PR.
  • Open against a multi-currency environment; confirm the Currency chip defaults to ⚠️ All and the warning symbol is visible in the parameter bar.
  • Switch the Currency filter to a specific currency in the multi-currency environment; confirm all tiles (including the cost-alignment diagnostic table on the Data ingestion page) scope correctly.
  • Revert the Currency filter to "⚠️ All"; confirm totals return to the mixed (pre-PR) behavior, with the warning marker now visible in the dropdown.
  • npm run build passes (already verified).

🤖 Generated with Claude Code

Aggregating cost columns across multiple BillingCurrency values
produces mathematically invalid totals and savings rates. This adds
a "Billing currency" query-based parameter sourced from distinct
BillingCurrency values in Costs_v1_2 and applies it as a filter in
the CostsPlus base query so it propagates to all downstream queries.

Defaults to "All" to preserve existing behavior for single-currency
customers; multi-currency customers can now filter to a single
currency for correct results.

Addresses #2093 (Phase 1, item 1).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Roland Krummenacher and others added 2 commits April 21, 2026 14:33
- Rename the "Billing currency" parameter display name to "Currency".
- Apply the currency filter to the "Summary of list, contracted, and
  effective cost alignment" data-quality tile on the Data ingestion
  page. That tile queried the Costs() function directly, bypassing
  CostsPlus, and aggregated cost columns across currencies.

All other dashboard queries inherit the filter through the CostsPlus
chain (CostsThisMonth / CostsLastMonth / CostsByMonth / CostsByDay /
CostsByDayAHB all derive from CostsPlus).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the built-in "All" option with a conditional synthetic row
in the parameter query. When the data contains more than one billing
currency, the dropdown surfaces "⚠️ All" as the first entry, which
is also the default. Selecting it applies no filter (mixed totals),
so the warning marker is shown exactly when the dashboard would
otherwise display mathematically invalid aggregates.

Single-currency tenants see only their currency — no "All", no noise.

Defaults change from kind=all to kind=query-result so the first row
from the parameter query is selected; ordering guarantees the "⚠️ All"
row comes first when it exists.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@RolandKrummenacher RolandKrummenacher added this to the v14 milestone Apr 21, 2026
Roland Krummenacher and others added 2 commits April 21, 2026 15:05
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@RolandKrummenacher
Copy link
Copy Markdown
Collaborator Author

@copilot resolve the merge conflicts in this pull request

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Needs: Review 👀 PR that is ready to be reviewed Tool: FinOps hubs Data pipeline solution

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Data Explorer dashboard: multi-currency support — savings and cost KPIs silently produce wrong results

4 participants