fixed property tax report

This commit is contained in:
Ali 2025-11-24 15:16:02 +04:00
parent d9ccd76e3a
commit e0f39d96f1
2 changed files with 14 additions and 270 deletions

View File

@ -1,6 +1,3 @@
frappe.query_reports["Property Tax Report"] = {
"filters": [
{
@ -53,29 +50,6 @@ frappe.query_reports["Property Tax Report"] = {
}
return value;
},
"onload": function(report) {
// Добавляем кастомные кнопки
report.page.add_inner_button(__("Export Property Tax Summary"), function() {
export_property_tax_summary(report);
});
report.page.add_inner_button(__("Show Article Categories"), function() {
show_property_tax_categories();
});
// Добавляем информационное сообщение
report.page.add_inner_button(__("About Property Tax"), function() {
show_property_tax_info();
});
},
"after_datatable_render": function(datatable_obj) {
// Добавляем итоговую статистику
setTimeout(() => {
add_property_tax_statistics(datatable_obj);
}, 500);
}
};
@ -132,246 +106,4 @@ function get_property_tax_icon(fieldname) {
} else {
return "📋"; // Остальные
}
}
// Функция показа информации о налоговых статьях
function show_property_tax_info() {
let info_html = '<div class="property-tax-info">';
info_html += '<h4 style="color: #495057; margin-bottom: 15px;">📋 Əmlak Vergisi Maddələri</h4>';
info_html += '<div class="row">';
info_html += '<div class="col-md-6">';
info_html += '<h5 style="color: #0d6efd; margin-bottom: 10px;">🏭 207.3-207.4 Maddələri (Sənaye Parkları)</h5>';
info_html += '<ul style="font-size: 12px; color: #6c757d;">';
info_html += '<li>207.3 - Sənaye parkı rezidenti</li>';
info_html += '<li>207.4 - İdarəedici təşkilat</li>';
info_html += '</ul>';
info_html += '</div>';
info_html += '<div class="col-md-6">';
info_html += '<h5 style="color: #198754; margin-bottom: 10px;">💼 207.5-207.6 Maddələri (İnvestisiya)</h5>';
info_html += '<ul style="font-size: 12px; color: #6c757d;">';
info_html += '<li>207.5 - İnvestisiya təşviqi sənədi</li>';
info_html += '<li>207.6 - KOB klaster şirkətləri</li>';
info_html += '</ul>';
info_html += '</div>';
info_html += '</div>';
info_html += '<div class="row">';
info_html += '<div class="col-md-6">';
info_html += '<h5 style="color: #6610f2; margin-bottom: 10px;">🏦 207.7-207.9 Maddələri (Maliyyə)</h5>';
info_html += '<ul style="font-size: 12px; color: #6c757d;">';
info_html += '<li>207.7 - Aqrarkredit və Sənaye Korporasiyası</li>';
info_html += '<li>207.9 - Kredit təşkilatları</li>';
info_html += '</ul>';
info_html += '</div>';
info_html += '<div class="col-md-6">';
info_html += '<h5 style="color: #fd7e14; margin-bottom: 10px;">⛏️ 207.8-207.11 Maddələri (Xüsusi)</h5>';
info_html += '<ul style="font-size: 12px; color: #6c757d;">';
info_html += '<li>207.8 - Geoloji kəşfiyyat</li>';
info_html += '<li>207.10 - İdxal malları</li>';
info_html += '<li>207.11 - Özəlləşdirilmiş əsas vəsaitlər</li>';
info_html += '</ul>';
info_html += '</div>';
info_html += '</div>';
info_html += '<hr>';
info_html += '<p style="color: #6c757d; font-size: 13px; text-align: center;">';
info_html += 'Bu hesabat Asset-lərdə tax_article sahəsinə əsasən əmlak vergisini bölüşdürür';
info_html += '</p>';
info_html += '</div>';
frappe.msgprint({
title: __("Property Tax Information"),
message: info_html,
wide: true
});
}
// Функция показа категорий налоговых статей
function show_property_tax_categories() {
let categories_html = '<div class="property-tax-categories">';
categories_html += '<h4>🎯 Əmlak Vergisi Kateqoriyaları:</h4>';
categories_html += '<div class="row">';
const categories = [
{name: "🏭 Sənaye Parkları", color: "#0d6efd", articles: ["207.3", "207.4"]},
{name: "💼 İnvestisiya və KOB", color: "#198754", articles: ["207.5", "207.6"]},
{name: "🏦 Maliyyə Təşkilatları", color: "#6610f2", articles: ["207.7", "207.9", "207.12"]},
{name: "⛏️ Geoloji İşlər", color: "#fd7e14", articles: ["207.8"]},
{name: "📦 İdxal Malları", color: "#0dcaf0", articles: ["207.10"]},
{name: "🏛️ Özəlləşdirmə", color: "#6f42c1", articles: ["207.11"]},
{name: "🌾 Torpaq Vergisi", color: "#20c997", articles: ["227.1"]}
];
categories.forEach((category, index) => {
if (index % 2 === 0 && index > 0) {
categories_html += '</div><div class="row">';
}
categories_html += '<div class="col-md-6" style="margin-bottom: 15px;">';
categories_html += `<div style="padding: 15px; border: 2px solid ${category.color}; border-radius: 8px; background: ${category.color}10;">`;
categories_html += `<h5 style="color: ${category.color};">${category.name}</h5>`;
categories_html += '<div style="font-size: 12px; color: #6c757d;">';
category.articles.forEach(article => {
categories_html += `<span style="margin-right: 8px; background: white; padding: 2px 6px; border-radius: 3px; border: 1px solid ${category.color};">VM ${article}</span>`;
});
categories_html += '</div>';
categories_html += '</div>';
categories_html += '</div>';
});
categories_html += '</div>';
categories_html += '</div>';
frappe.msgprint({
title: __("Article Categories"),
message: categories_html,
wide: true
});
}
// Функция экспорта сводки по налоговым статьям
function export_property_tax_summary(report) {
let data = report.data;
let summary = calculate_property_tax_totals(data);
// Создаем CSV с итогами
let csv_content = "Tax Article,Total Asset Cost,Assets Count\n";
summary.forEach(item => {
if (item.total > 0) {
csv_content += `"${item.article}",${item.total},${item.count}\n`;
}
});
// Добавляем общие итоги
let grand_total = summary.reduce((acc, item) => acc + item.total, 0);
let total_assets = data.length;
csv_content += `\n"CƏMİ","${grand_total}","${total_assets}"\n`;
// Скачиваем файл
let blob = new Blob([csv_content], { type: 'text/csv;charset=utf-8' });
let url = window.URL.createObjectURL(blob);
let a = document.createElement('a');
a.href = url;
a.download = 'property_tax_summary_' + frappe.datetime.get_today() + '.csv';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
frappe.show_alert({message: __("Property tax summary exported successfully"), indicator: "green"});
}
// Функция расчета итогов по налоговым статьям
function calculate_property_tax_totals(data) {
let summary = [];
let article_totals = {};
// Получаем все возможные статьи из колонок
data.forEach(row => {
Object.keys(row).forEach(key => {
if (key.startsWith('vm_') && row[key] > 0) {
if (!article_totals[key]) {
article_totals[key] = {total: 0, count: 0};
}
article_totals[key].total += row[key];
article_totals[key].count++;
}
});
});
// Конвертируем в массив
Object.keys(article_totals).forEach(key => {
summary.push({
article: convert_field_key_to_display_name(key),
total: article_totals[key].total,
count: article_totals[key].count
});
});
// Сортируем по общей сумме
summary.sort((a, b) => b.total - a.total);
return summary;
}
// Функция конвертации ключа поля в отображаемое название
function convert_field_key_to_display_name(fieldKey) {
const mapping = {
'vm_207_3': 'VM 207.3',
'vm_207_4': 'VM 207.4',
'vm_207_5': 'VM 207.5',
'vm_207_6': 'VM 207.6',
'vm_207_7': 'VM 207.7',
'vm_207_8': 'VM 207.8',
'vm_207_9': 'VM 207.9',
'vm_207_10': 'VM 207.10',
'vm_207_11': 'VM 207.11',
'vm_207_12': 'VM 207.12',
'vm_227_1': 'VM 227.1'
};
return mapping[fieldKey] || fieldKey.replace(/_/g, '.').replace('vm.', 'VM ');
}
// Функция добавления статистики под таблицу
function add_property_tax_statistics(datatable_obj) {
if (datatable_obj && datatable_obj.data) {
let summary = calculate_property_tax_totals(datatable_obj.data);
let topArticles = summary.slice(0, 10); // Топ 10 статей
let stats_html = '<div class="property-tax-statistics" style="margin-top: 20px; padding: 20px; background: linear-gradient(135deg, #f8f9ff 0%, #fff 100%); border-radius: 8px; border: 2px solid #6610f2; box-shadow: 0 2px 8px rgba(102,16,242,0.1);">';
stats_html += '<h4 style="margin-bottom: 15px; color: #6610f2; display: flex; align-items: center;"><span style="margin-right: 8px;">📊</span> Əmlak Vergisi Statistikası:</h4>';
// Топ статьи
if (topArticles.length > 0) {
stats_html += '<h5 style="color: #495057; margin-bottom: 15px;">🏆 Ən Yüksək Məbləğli Maddələr:</h5>';
stats_html += '<div class="row">';
topArticles.slice(0, 6).forEach((article, index) => {
if (index % 3 === 0 && index > 0) {
stats_html += '</div><div class="row">';
}
let color = get_property_tax_color(Object.keys(datatable_obj.data[0]).find(k => convert_field_key_to_display_name(k) === article.article) || 'vm_other');
stats_html += '<div class="col-md-4" style="margin-bottom: 10px;">';
stats_html += `<div style="padding: 10px; border: 2px solid ${color}; border-radius: 6px; background: white; text-align: center;">`;
stats_html += `<strong style="color: ${color}; font-size: 12px;">${article.article}</strong><br>`;
stats_html += `<span style="font-size: 16px; font-weight: bold; color: ${color};">${article.total.toFixed(2)}</span><br>`;
stats_html += `<small style="color: #6c757d;">${article.count} əmlak</small>`;
stats_html += '</div>';
stats_html += '</div>';
});
stats_html += '</div>';
}
// Общие итоги
let grand_total = summary.reduce((acc, item) => acc + item.total, 0);
let total_articles = summary.length;
let total_assets = datatable_obj.data.length;
stats_html += '<div style="margin-top: 20px; padding: 15px; border-top: 3px solid #6610f2; background: linear-gradient(135deg, #6610f210 0%, #fff 100%);">';
stats_html += '<div class="row text-center">';
stats_html += `<div class="col-md-3"><span style="color: #6610f2; font-size: 14px; font-weight: bold;">📋 Aktiv Maddələr<br><span style="font-size: 18px;">${total_articles}</span></span></div>`;
stats_html += `<div class="col-md-3"><span style="color: #198754; font-size: 14px; font-weight: bold;">💰 Ümumi Məbləğ<br><span style="font-size: 18px;">${grand_total.toFixed(2)}</span></span></div>`;
stats_html += `<div class="col-md-3"><span style="color: #fd7e14; font-size: 14px; font-weight: bold;">🏢 Cəmi Əmlak<br><span style="font-size: 18px;">${total_assets}</span></span></div>`;
stats_html += `<div class="col-md-3"><span style="color: #d63384; font-size: 14px; font-weight: bold;">📈 Orta Məbləğ<br><span style="font-size: 18px;">${total_assets > 0 ? (grand_total / total_assets).toFixed(2) : '0.00'}</span></span></div>`;
stats_html += '</div>';
stats_html += '</div>';
stats_html += '</div>';
// Удаляем предыдущую статистику если есть
$('.property-tax-statistics').remove();
// Добавляем новую статистику
$(stats_html).insertAfter('.datatable');
}
}

View File

@ -47,7 +47,13 @@ def get_data(filters):
full_article_name = tax_article_names_mapping[tax_article_name]
if full_article_name in tax_articles_mapping:
field_key = tax_articles_mapping[full_article_name]
row[field_key] = flt(asset['total_asset_cost'])
asset_cost = flt(asset['total_asset_cost'])
# Для статьи 207.8 применяем коэффициент 75%
if field_key == 'vm_207_8':
asset_cost = asset_cost * 0.75
row[field_key] = asset_cost
# Проверяем industrial_tax_article
elif asset.get('industrial_tax_article'):
@ -56,7 +62,13 @@ def get_data(filters):
full_article_name = tax_article_names_mapping[tax_article_name]
if full_article_name in tax_articles_mapping:
field_key = tax_articles_mapping[full_article_name]
row[field_key] = flt(asset['total_asset_cost'])
asset_cost = flt(asset['total_asset_cost'])
# Для статьи 207.8 применяем коэффициент 75%
if field_key == 'vm_207_8':
asset_cost = asset_cost * 0.75
row[field_key] = asset_cost
# Добавляем строку только если есть tax_article
if asset.get('agricultural_tax_article') or asset.get('industrial_tax_article'):