tax exempt now in formula for land tax decl

This commit is contained in:
Ali 2025-11-28 16:20:49 +04:00
parent 4f69e9bc6c
commit fd54a5e9f2
2 changed files with 64 additions and 31 deletions

View File

@ -153,12 +153,14 @@ function group_and_create_agricultural_rows_silent(frm, table_fieldname, assets,
grouped_assets[group_key] = { grouped_assets[group_key] = {
asset: asset, asset: asset,
total_area: 0, total_area: 0,
total_tax_exempt_area: 0,
count: 0, count: 0,
asset_names: [] asset_names: []
}; };
} }
grouped_assets[group_key].total_area += (asset.area || 0); grouped_assets[group_key].total_area += (asset.area || 0);
grouped_assets[group_key].total_tax_exempt_area += (asset.tax_exempt_area || 0);
grouped_assets[group_key].count += 1; grouped_assets[group_key].count += 1;
grouped_assets[group_key].asset_names.push(asset.name); grouped_assets[group_key].asset_names.push(asset.name);
}); });
@ -262,7 +264,8 @@ function calculate_agricultural_tax_for_row_silent(row, asset, total_area, group
cadastral_district_name: asset.cadastral_district_name, cadastral_district_name: asset.cadastral_district_name,
quality_groups: asset.quality_groups, quality_groups: asset.quality_groups,
agricultural_land_purpose: asset.agricultural_land_purpose, agricultural_land_purpose: asset.agricultural_land_purpose,
agricultural_purpose_name: agricultural_purpose_name agricultural_purpose_name: agricultural_purpose_name,
tax_exempt_area: group_info.total_tax_exempt_area || 0
}, },
callback: function(response) { callback: function(response) {
if (response.message && 'tax_amount' in response.message) { if (response.message && 'tax_amount' in response.message) {
@ -402,15 +405,6 @@ function fill_industrial_row_fields(row, asset, total_area, group_info) {
} }
function calculate_industrial_tax_for_row_silent(row, asset, total_area, group_info, callback) { function calculate_industrial_tax_for_row_silent(row, asset, total_area, group_info, callback) {
let tax_exempt_area = group_info.total_tax_exempt_area || 0;
let taxable_area = total_area - tax_exempt_area;
if (taxable_area <= 0) {
row.vergiməbləğimanatla = 0;
callback();
return;
}
if (!asset.territorial_unit_name || !asset.industrial_land_purpose) { if (!asset.territorial_unit_name || !asset.industrial_land_purpose) {
callback(); callback();
return; return;
@ -419,9 +413,10 @@ function calculate_industrial_tax_for_row_silent(row, asset, total_area, group_i
frappe.call({ frappe.call({
method: 'taxes_az.taxes_az.doctype.land_tax_declaration.land_tax_declaration.calculate_industrial_tax', method: 'taxes_az.taxes_az.doctype.land_tax_declaration.land_tax_declaration.calculate_industrial_tax',
args: { args: {
area_sqm: taxable_area, area_sqm: total_area,
territorial_unit_name: asset.territorial_unit_name, territorial_unit_name: asset.territorial_unit_name,
industrial_land_purpose: asset.industrial_land_purpose industrial_land_purpose: asset.industrial_land_purpose,
tax_exempt_area: group_info.total_tax_exempt_area || 0
}, },
callback: function(response) { callback: function(response) {
if (response.message && 'tax_amount' in response.message) { if (response.message && 'tax_amount' in response.message) {

View File

@ -59,13 +59,31 @@ def get_doctype_fields_info():
return {'error': str(e)} return {'error': str(e)}
@frappe.whitelist() @frappe.whitelist()
def calculate_agricultural_tax(area_value, cadastral_district_name, quality_groups, agricultural_land_purpose, agricultural_purpose_name=None): def calculate_agricultural_tax(area_value, cadastral_district_name, quality_groups, agricultural_land_purpose, agricultural_purpose_name=None, tax_exempt_area=None):
try: try:
if area_value is None: if area_value is None:
frappe.throw("Area value is required") frappe.throw("Area value is required")
area_float = float(area_value) area_float = float(area_value)
# Вычитаем освобожденную от налогов площадь
if tax_exempt_area:
try:
exempt_float = float(tax_exempt_area)
area_float = max(0, area_float - exempt_float)
except (ValueError, TypeError):
frappe.log_error(f"Invalid tax_exempt_area value: {tax_exempt_area}")
# Если вся площадь освобождена, возвращаем 0
if area_float <= 0:
return {
'tax_amount': 0,
'calculation_details': {
'area_sqm': area_float,
'formula': 'All area is tax-exempt'
}
}
# Для неиспользуемых земель: Area × 2% # Для неиспользуемых земель: Area × 2%
if agricultural_purpose_name == 'Təyinatı üzrə istifadə edilməyən kənd təsərrüfatı torpaqları üzrə hesablanmış vergi məbləği': if agricultural_purpose_name == 'Təyinatı üzrə istifadə edilməyən kənd təsərrüfatı torpaqları üzrə hesablanmış vergi məbləği':
result = area_float * 0.02 result = area_float * 0.02
@ -83,7 +101,7 @@ def calculate_agricultural_tax(area_value, cadastral_district_name, quality_grou
if not cadastral_district_name or not quality_groups or not agricultural_land_purpose: if not cadastral_district_name or not quality_groups or not agricultural_land_purpose:
frappe.throw("Not all fields are filled for calculation") frappe.throw("Not all fields are filled for calculation")
hectare_value = float(area_value) hectare_value = area_float
score = get_cadastral_score(cadastral_district_name, quality_groups) score = get_cadastral_score(cadastral_district_name, quality_groups)
markup = get_markup_coefficient(agricultural_land_purpose) markup = get_markup_coefficient(agricultural_land_purpose)
result = hectare_value * score * markup result = hectare_value * score * markup
@ -137,12 +155,31 @@ def get_markup_coefficient(agricultural_land_purpose):
return coefficient return coefficient
@frappe.whitelist() @frappe.whitelist()
def calculate_industrial_tax(area_sqm, territorial_unit_name, industrial_land_purpose): def calculate_industrial_tax(area_sqm, territorial_unit_name, industrial_land_purpose, tax_exempt_area=None):
try: try:
if area_sqm is None or not territorial_unit_name or not industrial_land_purpose: if area_sqm is None or not territorial_unit_name or not industrial_land_purpose:
frappe.throw("Not all fields are filled for calculation") frappe.throw("Not all fields are filled for calculation")
area_sqm_float = float(area_sqm) area_sqm_float = float(area_sqm)
# Вычитаем освобожденную от налогов площадь
if tax_exempt_area:
try:
exempt_float = float(tax_exempt_area)
area_sqm_float = max(0, area_sqm_float - exempt_float)
except (ValueError, TypeError):
frappe.log_error(f"Invalid tax_exempt_area value: {tax_exempt_area}")
# Если вся площадь освобождена, возвращаем 0
if area_sqm_float <= 0:
return {
'tax_amount': 0,
'calculation_details': {
'area_sqm': area_sqm_float,
'formula': 'All area is tax-exempt'
}
}
score_data = get_industrial_land_scores(territorial_unit_name, industrial_land_purpose) score_data = get_industrial_land_scores(territorial_unit_name, industrial_land_purpose)
calculation_result = calculate_industrial_land_formula(area_sqm_float, score_data) calculation_result = calculate_industrial_land_formula(area_sqm_float, score_data)
@ -250,6 +287,7 @@ def get_assets_for_year(asset_type, year):
'quality_groups', 'quality_groups',
'agricultural_land_purpose', 'agricultural_land_purpose',
'area', 'area',
'tax_exempt_area',
'purchase_date' 'purchase_date'
] ]
else: else: