feat: Add currency conversion functionality in BillingManager to calculate total payments and monthly costs in RUB, improving financial reporting accuracy.
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m46s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m46s
This commit is contained in:
@@ -274,14 +274,35 @@ function BillingManager() {
|
|||||||
.map(s => [s.id, s])
|
.map(s => [s.id, s])
|
||||||
);
|
);
|
||||||
|
|
||||||
// Вычисляем общую сумму последних платежей
|
// Функция конвертации в рубли (должна быть определена до использования)
|
||||||
|
const convertToRUB = (amount, currency) => {
|
||||||
|
if (!amount) return 0;
|
||||||
|
// Курсы получены с базой USD (1 USD = rates[CCY])
|
||||||
|
const rubPerUsd = Number(exchangeRates.RUB) || 1;
|
||||||
|
if (!currency || currency === 'RUB') return amount; // уже в рублях
|
||||||
|
if (currency === 'USD') return amount * rubPerUsd;
|
||||||
|
const ccyPerUsd = Number(exchangeRates[currency]);
|
||||||
|
if (!ccyPerUsd || ccyPerUsd === 0) {
|
||||||
|
// нет курса — возвращаем как есть
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
// amount в валюте CCY -> USD -> RUB
|
||||||
|
const amountUsd = amount / ccyPerUsd;
|
||||||
|
return amountUsd * rubPerUsd;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Вычисляем общую сумму последних платежей в рублях
|
||||||
const totalLastPayments = billingData.reduce((sum, item) => {
|
const totalLastPayments = billingData.reduce((sum, item) => {
|
||||||
return sum + (item.lastPaymentAmount || 0);
|
const amount = item.lastPaymentAmount || 0;
|
||||||
|
const currency = item.lastPaymentCurrency || 'USD';
|
||||||
|
return sum + convertToRUB(amount, currency);
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
// Вычисляем общую сумму месячных затрат
|
// Вычисляем общую сумму месячных затрат в рублях
|
||||||
const totalMonthlyCosts = billingData.reduce((sum, item) => {
|
const totalMonthlyCosts = billingData.reduce((sum, item) => {
|
||||||
return sum + (item.monthlyCost || 0);
|
const amount = item.monthlyCost || 0;
|
||||||
|
const currency = item.monthlyCostCurrency || 'USD';
|
||||||
|
return sum + convertToRUB(amount, currency);
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
// Фильтрация данных
|
// Фильтрация данных
|
||||||
@@ -339,21 +360,7 @@ function BillingManager() {
|
|||||||
}).format(amount);
|
}).format(amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertToRUB(amount, currency) {
|
// convertToRUB уже определена выше, используем её
|
||||||
if (!amount) return 0;
|
|
||||||
// Курсы получены с базой USD (1 USD = rates[CCY])
|
|
||||||
const rubPerUsd = Number(exchangeRates.RUB) || 1;
|
|
||||||
if (!currency || currency === 'RUB') return amount; // уже в рублях
|
|
||||||
if (currency === 'USD') return amount * rubPerUsd;
|
|
||||||
const ccyPerUsd = Number(exchangeRates[currency]);
|
|
||||||
if (!ccyPerUsd || ccyPerUsd === 0) {
|
|
||||||
// нет курса — возвращаем как есть
|
|
||||||
return amount;
|
|
||||||
}
|
|
||||||
// amount в валюте CCY -> USD -> RUB
|
|
||||||
const amountUsd = amount / ccyPerUsd;
|
|
||||||
return amountUsd * rubPerUsd;
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatCurrencyInRUB(amount, currency) {
|
function formatCurrencyInRUB(amount, currency) {
|
||||||
const rubAmount = convertToRUB(amount, currency);
|
const rubAmount = convertToRUB(amount, currency);
|
||||||
@@ -600,7 +607,10 @@ function BillingManager() {
|
|||||||
</span>
|
</span>
|
||||||
<div>
|
<div>
|
||||||
<div className="h3 mb-0 fw-bold">
|
<div className="h3 mb-0 fw-bold">
|
||||||
{formatCurrencyInRUB(totalLastPayments, 'USD')}
|
{new Intl.NumberFormat('ru-RU', {
|
||||||
|
style: 'currency',
|
||||||
|
currency: 'RUB'
|
||||||
|
}).format(totalLastPayments)}
|
||||||
</div>
|
</div>
|
||||||
<div className="text-muted lh-1">всего платежей</div>
|
<div className="text-muted lh-1">всего платежей</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -615,7 +625,10 @@ function BillingManager() {
|
|||||||
</span>
|
</span>
|
||||||
<div>
|
<div>
|
||||||
<div className="h3 mb-0 fw-bold">
|
<div className="h3 mb-0 fw-bold">
|
||||||
{formatCurrencyInRUB(totalMonthlyCosts, 'USD')}
|
{new Intl.NumberFormat('ru-RU', {
|
||||||
|
style: 'currency',
|
||||||
|
currency: 'RUB'
|
||||||
|
}).format(totalMonthlyCosts)}
|
||||||
</div>
|
</div>
|
||||||
<div className="text-muted lh-1">месячные затраты</div>
|
<div className="text-muted lh-1">месячные затраты</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user