fix: экспорт конфига через GetByUUIDNoAuth, формат чисел с запятой как разделителем
- ExportConfigCSV и ExportConfigPricingCSV: GetByUUID → GetByUUIDNoAuth,
чтобы не падать с ErrConfigForbidden на конфигах с чужим OriginalUsername
- ConfigurationGetter: добавлен GetByUUIDNoAuth в интерфейс
- Шаблоны: toLocaleString('en-US') → 'ru-RU' во всех местах отображения цен;
процентные значения: .toFixed(1) → .toFixed(1).replace('.', ',')
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -247,7 +247,7 @@ function renderConfigs(configs) {
|
||||
|
||||
configs.forEach(c => {
|
||||
const date = new Date(c.created_at).toLocaleDateString('ru-RU');
|
||||
const total = c.total_price ? '$' + c.total_price.toLocaleString('en-US', {minimumFractionDigits: 2}) : '—';
|
||||
const total = c.total_price ? '$' + c.total_price.toLocaleString('ru-RU', {minimumFractionDigits: 2}) : '—';
|
||||
const serverCount = c.server_count ? c.server_count : 1;
|
||||
const author = c.owner_username || (c.user && c.user.username) || '—';
|
||||
const projectName = c.project_uuid && projectNameByUUID[c.project_uuid]
|
||||
@@ -258,7 +258,7 @@ function renderConfigs(configs) {
|
||||
let pricePerUnit = '—';
|
||||
if (c.total_price && serverCount > 0) {
|
||||
const unitPrice = c.total_price / serverCount;
|
||||
pricePerUnit = '$' + unitPrice.toLocaleString('en-US', {minimumFractionDigits: 2});
|
||||
pricePerUnit = '$' + unitPrice.toLocaleString('ru-RU', {minimumFractionDigits: 2});
|
||||
}
|
||||
|
||||
html += '<tr class="hover:bg-gray-50">';
|
||||
|
||||
@@ -2584,7 +2584,7 @@ function formatDiffPercent(baseTotal, compareTotal, compareLabel) {
|
||||
}
|
||||
const pct = ((baseTotal - compareTotal) / compareTotal) * 100;
|
||||
const sign = pct > 0 ? '+' : '';
|
||||
return `${sign}${pct.toFixed(1)}% от ${compareLabel}`;
|
||||
return `${sign}${pct.toFixed(1).replace('.', ',')}% от ${compareLabel}`;
|
||||
}
|
||||
|
||||
function getTotalClass(current, references) {
|
||||
@@ -2709,7 +2709,7 @@ function calculateCustomPrice() {
|
||||
|
||||
// Show discount info
|
||||
discountInfoEl.classList.remove('hidden');
|
||||
discountPercentEl.textContent = discountPercent.toFixed(1) + '%';
|
||||
discountPercentEl.textContent = discountPercent.toFixed(1).replace('.', ',') + '%';
|
||||
|
||||
// Update discount color based on value
|
||||
const discountEl = discountPercentEl;
|
||||
@@ -4272,7 +4272,7 @@ function applyCustomPrice(table) {
|
||||
if (est <= 0) return '';
|
||||
const pct = ((est - custom) / est * 100);
|
||||
const sign = pct >= 0 ? '-' : '+';
|
||||
return ` (${sign}${Math.abs(pct).toFixed(1)}%)`;
|
||||
return ` (${sign}${Math.abs(pct).toFixed(1).replace('.', ',')}%)`;
|
||||
};
|
||||
const _pctClass = (custom, est) => custom <= est ? 'text-green-600' : 'text-red-600';
|
||||
|
||||
@@ -4365,7 +4365,7 @@ function setPricingCustomPriceFromVendor() {
|
||||
const totalEl = document.getElementById('pricing-total-buy-vendor');
|
||||
if (hasAny) {
|
||||
document.getElementById('pricing-custom-price-buy').value = total.toFixed(2);
|
||||
const pct = estimateTotal > 0 ? ` (-${((estimateTotal - total) / estimateTotal * 100).toFixed(1)}%)` : '';
|
||||
const pct = estimateTotal > 0 ? ` (-${((estimateTotal - total) / estimateTotal * 100).toFixed(1).replace('.', ',')}%)` : '';
|
||||
totalEl.textContent = formatCurrency(total) + pct;
|
||||
totalEl.className = totalEl.className.replace(/\btext-(?:green|red)-\d+\b/g, '').trim();
|
||||
totalEl.classList.add(total <= estimateTotal ? 'text-green-600' : 'text-red-600');
|
||||
|
||||
@@ -243,7 +243,7 @@
|
||||
const descMax = stock ? 30 : 60;
|
||||
|
||||
const html = items.map(item => {
|
||||
const price = item.price.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
||||
const price = item.price.toLocaleString('ru-RU', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
||||
const description = item.lot_description || '-';
|
||||
const truncatedDesc = description.length > descMax ? description.substring(0, descMax) + '...' : description;
|
||||
|
||||
|
||||
@@ -339,7 +339,7 @@ function escapeHtml(text) {
|
||||
|
||||
function formatMoneyNoDecimals(value) {
|
||||
const safe = Number.isFinite(Number(value)) ? Number(value) : 0;
|
||||
return '$' + Math.round(safe).toLocaleString('en-US');
|
||||
return '$' + Math.round(safe).toLocaleString('ru-RU');
|
||||
}
|
||||
|
||||
function resolveProjectTrackerURL(projectData) {
|
||||
|
||||
@@ -81,7 +81,7 @@ function escapeHtml(text) {
|
||||
}
|
||||
|
||||
function formatMoney(v) {
|
||||
return '$' + (v || 0).toLocaleString('en-US', {minimumFractionDigits: 2});
|
||||
return '$' + (v || 0).toLocaleString('ru-RU', {minimumFractionDigits: 2});
|
||||
}
|
||||
|
||||
function formatDateTime(value) {
|
||||
|
||||
Reference in New Issue
Block a user