fix(web): пересчитывать «Баланс API» на дашборде в базовую валюту
KPI складывал балансы аккаунтов в разных валютах как есть (46,8 EUR + 1120 RUB показывалось как 1166,80 ₽). Теперь каждый баланс переводится в базовую валюту с учётом курса хостера. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
No files matched your search
@@ -35,7 +35,7 @@ import { StatusBadge } from '@/components/status-badge'
|
|||||||
|
|
||||||
import { computeInventoryHealth } from '@/lib/inventory-health'
|
import { computeInventoryHealth } from '@/lib/inventory-health'
|
||||||
import { buildAtRiskAccounts, type AtRiskAccount } from '@/lib/account-health'
|
import { buildAtRiskAccounts, type AtRiskAccount } from '@/lib/account-health'
|
||||||
import { formatInBaseCurrency, normalizeRatesPayload, vpsStatusLabel, convertVpsMonthlyBurnToBase, formatCurrency } from '@/lib/format'
|
import { formatInBaseCurrency, normalizeRatesPayload, vpsStatusLabel, convertVpsMonthlyBurnToBase, convertWithProviderRate, formatCurrency } from '@/lib/format'
|
||||||
import { providerByIdMap } from '@/lib/billmanager'
|
import { providerByIdMap } from '@/lib/billmanager'
|
||||||
import { exportActiveVpsCsv } from '@/lib/export-csv'
|
import { exportActiveVpsCsv } from '@/lib/export-csv'
|
||||||
import {
|
import {
|
||||||
@@ -245,6 +245,20 @@ function DashboardPage() {
|
|||||||
const expiringCount = stats?.expiringWithin7Days ?? 0
|
const expiringCount = stats?.expiringWithin7Days ?? 0
|
||||||
const issuesCount = issues.length
|
const issuesCount = issues.length
|
||||||
const providerById = providerByIdMap(snap.providers)
|
const providerById = providerByIdMap(snap.providers)
|
||||||
|
// Each account's balance is in its own currency — sum after converting, not raw (EUR + RUB ≠ ₽).
|
||||||
|
const balanceBase = snap.providerAccounts.reduce((sum, a) => {
|
||||||
|
if (a.balanceApi == null || !Number.isFinite(Number(a.balanceApi))) return sum
|
||||||
|
return (
|
||||||
|
sum +
|
||||||
|
convertWithProviderRate(
|
||||||
|
Number(a.balanceApi),
|
||||||
|
a.balanceCurrency || a.currency || baseCur,
|
||||||
|
providerById.get(a.providerId),
|
||||||
|
snap.settings,
|
||||||
|
ratesData,
|
||||||
|
).value
|
||||||
|
)
|
||||||
|
}, 0)
|
||||||
const monthlyBurnBase = activeVps.reduce(
|
const monthlyBurnBase = activeVps.reduce(
|
||||||
(sum, item) =>
|
(sum, item) =>
|
||||||
sum +
|
sum +
|
||||||
@@ -295,12 +309,7 @@ function DashboardPage() {
|
|||||||
{
|
{
|
||||||
id: 'balance',
|
id: 'balance',
|
||||||
label: 'Баланс API',
|
label: 'Баланс API',
|
||||||
value: formatInBaseCurrency(
|
value: formatCurrency(balanceBase, baseCur),
|
||||||
stats?.totalBalanceApi ?? 0,
|
|
||||||
baseCur,
|
|
||||||
snap.settings,
|
|
||||||
ratesData,
|
|
||||||
),
|
|
||||||
icon: <WalletIcon className="size-4" />,
|
icon: <WalletIcon className="size-4" />,
|
||||||
iconClassName: 'text-success',
|
iconClassName: 'text-success',
|
||||||
to: '/accounts',
|
to: '/accounts',
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 97 KiB |
|
Before Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 141 KiB |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 167 KiB |
|
Before Width: | Height: | Size: 121 KiB |