fix(web): корректная валюта VPS в отчётах по месячным расходам
Docker / build (push) Failing after 23s
Docker / build (push) Failing after 23s
Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -18,7 +18,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@cfdm
|
||||
import type { ReactNode } from 'react'
|
||||
|
||||
import type { Vps, Provider, Payment, Settings, RatesData } from '@/types/entities'
|
||||
import { convertCurrency, formatCurrency, monthKey, toIsoCurrency } from '@/lib/format'
|
||||
import { convertCurrency, convertVpsMonthlyBurnToBase, formatCurrency, monthKey, toIsoCurrency } from '@/lib/format'
|
||||
import { providerByIdMap } from '@/lib/billmanager'
|
||||
import { EmptyState } from '@/components/empty-state'
|
||||
|
||||
@@ -51,13 +51,8 @@ export function MonthlyExpenseChart({
|
||||
|
||||
const monthlyByAccount = new Map<string, number>()
|
||||
for (const v of vps) {
|
||||
if (v.status !== 'active') continue
|
||||
const provider = providerById.get(v.providerId)
|
||||
const monthly = Number(v.monthlyRate || 0)
|
||||
const daily = Number(v.dailyRate || 0)
|
||||
const burn = v.tariffType === 'daily' ? daily * 30 : monthly
|
||||
const fromCurrency = toIsoCurrency(provider?.baseCurrency || v.currency || baseCurrency)
|
||||
const converted = convertCurrency(burn, fromCurrency, baseCurrency, ratesData)
|
||||
const converted = convertVpsMonthlyBurnToBase(v, provider, settings, ratesData)
|
||||
monthlyByAccount.set(v.providerAccountId, (monthlyByAccount.get(v.providerAccountId) ?? 0) + converted)
|
||||
}
|
||||
|
||||
|
||||
@@ -314,6 +314,25 @@ export function formatInProviderCurrency(
|
||||
return formatCurrency(converted.value, converted.currency)
|
||||
}
|
||||
|
||||
/** Месячный burn-rate VPS, сконвертированный в базовую валюту приложения. */
|
||||
export function convertVpsMonthlyBurnToBase(
|
||||
vps: Pick<Vps, 'status' | 'tariffType' | 'dailyRate' | 'monthlyRate' | 'currency' | 'providerId'>,
|
||||
provider: Provider | null | undefined,
|
||||
appSettings: Settings[] | Settings | null | undefined,
|
||||
ratesData: RatesData | null,
|
||||
): number {
|
||||
if (vps.status !== 'active') return 0
|
||||
const settings: Partial<Settings> = Array.isArray(appSettings)
|
||||
? (appSettings[0] ?? {})
|
||||
: (appSettings ?? {})
|
||||
const autoConvert = settings.autoConvert !== false
|
||||
const burn = vpsTariffMonthlyBurn(vps)
|
||||
if (!Number.isFinite(burn) || burn <= 0) return 0
|
||||
if (!autoConvert) return burn
|
||||
const fromCurrency = effectiveVpsTariffCurrency(vps as Vps, provider)
|
||||
return convertWithProviderRate(burn, fromCurrency, provider, appSettings ?? null, ratesData).value
|
||||
}
|
||||
|
||||
export function monthKey(dateString: string): string {
|
||||
const date = new Date(dateString)
|
||||
if (Number.isNaN(date.getTime())) return ''
|
||||
|
||||
@@ -9,7 +9,8 @@ import { SectionCards } from '@/components/section-cards'
|
||||
import { ChartsGrid, MonthlyExpenseChart, PaymentsPieChart, MonthlyTrendChart } from '@/components/domain/charts'
|
||||
import { exportVpsCsv } from '@/lib/export-csv'
|
||||
|
||||
import { normalizeRatesPayload, formatCurrency } from '@/lib/format'
|
||||
import { convertVpsMonthlyBurnToBase, formatCurrency, normalizeRatesPayload } from '@/lib/format'
|
||||
import { providerByIdMap } from '@/lib/billmanager'
|
||||
|
||||
export const Route = createFileRoute('/_auth/reports')({
|
||||
loader: ({ context: { queryClient } }) =>
|
||||
@@ -63,22 +64,22 @@ function ReportsPage() {
|
||||
}
|
||||
>
|
||||
{(snap) => {
|
||||
const monthly = snap.vps
|
||||
.filter((v) => v.status === 'active')
|
||||
.reduce((acc, v) => {
|
||||
const burn =
|
||||
v.tariffType === 'daily' ? Number(v.dailyRate || 0) * 30 : Number(v.monthlyRate || 0)
|
||||
return acc + burn
|
||||
}, 0)
|
||||
const providerById = providerByIdMap(snap.providers)
|
||||
const baseCurrency = (snap.settings[0]?.baseCurrency ?? 'RUB').toUpperCase()
|
||||
const monthly = snap.vps.reduce(
|
||||
(acc, v) =>
|
||||
acc + convertVpsMonthlyBurnToBase(v, providerById.get(v.providerId), snap.settings, ratesData),
|
||||
0,
|
||||
)
|
||||
return (
|
||||
<>
|
||||
<SectionCards
|
||||
items={[
|
||||
{
|
||||
label: 'Расход/мес',
|
||||
value: formatCurrency(monthly, snap.vps[0]?.currency ?? 'RUB'),
|
||||
value: formatCurrency(monthly, baseCurrency),
|
||||
icon: <TrendingUpIcon className="size-4" />,
|
||||
hint: 'в валюте VPS',
|
||||
hint: `в ${baseCurrency}`,
|
||||
},
|
||||
{
|
||||
label: 'Платежей',
|
||||
|
||||
Reference in New Issue
Block a user