added new totals to vat allocation

This commit is contained in:
Ali 2026-02-09 15:07:33 +04:00
parent 22f68b5073
commit c5fe07a20d
3 changed files with 201 additions and 43 deletions

View File

@ -1236,41 +1236,80 @@ function recalculate_totals_manually(frm) {
// Новая функция для расчета итогов по tax templates
function calculate_tax_template_totals(frm) {
// Reset totals
// Reset allocated totals
frm.doc.total_edv_daxil_18 = 0;
frm.doc.total_edv_azadolma = 0;
frm.doc.total_edv_0 = 0;
frm.doc.total_edv_18 = 0;
frm.doc.total_allocated_sum = 0;
// Reset unallocated totals
frm.doc.total_edv_daxil_18_unallocated = 0;
frm.doc.total_edv_azadolma_unallocated = 0;
frm.doc.total_edv_0_unallocated = 0;
frm.doc.total_edv_18_unallocated = 0;
frm.doc.total_unallocated_sum = 0;
// Calculate totals from sales invoice table (only current month)
for (let si_row of frm.doc.sales_invoice_table || []) {
let allocated = si_row.allocated_amount || 0;
if (allocated <= 0) continue;
let unallocated = si_row.unallocated_amount || 0;
let template = (si_row.item_tax_template || '').trim();
// Match by template name prefix (template may have company suffix like "ƏDV 18% - js")
if (template.startsWith('ƏDV daxil 18%')) {
frm.doc.total_edv_daxil_18 += allocated;
if (allocated > 0) {
frm.doc.total_edv_daxil_18 += allocated;
}
if (unallocated > 0) {
frm.doc.total_edv_daxil_18_unallocated += unallocated;
}
} else if (template.startsWith('ƏDV-dən azadolma')) {
frm.doc.total_edv_azadolma += allocated;
if (allocated > 0) {
frm.doc.total_edv_azadolma += allocated;
}
if (unallocated > 0) {
frm.doc.total_edv_azadolma_unallocated += unallocated;
}
} else if (template.startsWith('ƏDV 0%')) {
frm.doc.total_edv_0 += allocated;
if (allocated > 0) {
frm.doc.total_edv_0 += allocated;
}
if (unallocated > 0) {
frm.doc.total_edv_0_unallocated += unallocated;
}
} else if (template.startsWith('ƏDV 18%')) {
frm.doc.total_edv_18 += allocated;
if (allocated > 0) {
frm.doc.total_edv_18 += allocated;
}
if (unallocated > 0) {
frm.doc.total_edv_18_unallocated += unallocated;
}
}
// Add to total sums
if (allocated > 0) {
frm.doc.total_allocated_sum += allocated;
}
if (unallocated > 0) {
frm.doc.total_unallocated_sum += unallocated;
}
// Add to total sum
frm.doc.total_allocated_sum += allocated;
}
// Refresh the total fields
// Refresh the allocated total fields
frm.refresh_field('total_edv_daxil_18');
frm.refresh_field('total_edv_azadolma');
frm.refresh_field('total_edv_0');
frm.refresh_field('total_edv_18');
frm.refresh_field('total_allocated_sum');
// Refresh the unallocated total fields
frm.refresh_field('total_edv_daxil_18_unallocated');
frm.refresh_field('total_edv_azadolma_unallocated');
frm.refresh_field('total_edv_0_unallocated');
frm.refresh_field('total_edv_18_unallocated');
frm.refresh_field('total_unallocated_sum');
}
function format_currency(value) {

View File

@ -28,6 +28,16 @@
"column_break_totals_2",
"total_edv_0",
"column_break_totals_3",
"unallocated_totals_section",
"total_edv_18_unallocated",
"column_break_unallocated_1",
"total_edv_daxil_18_unallocated",
"column_break_unallocated_2",
"total_edv_azadolma_unallocated",
"column_break_unallocated_3",
"total_edv_0_unallocated",
"column_break_unallocated_4",
"total_unallocated_sum",
"amended_from"
],
"fields": [
@ -164,6 +174,63 @@
{
"fieldname": "column_break_lpuu",
"fieldtype": "Column Break"
},
{
"fieldname": "unallocated_totals_section",
"fieldtype": "Section Break",
"label": "Sales Invoice Unallocated Totals by Tax Template"
},
{
"fieldname": "total_edv_18_unallocated",
"fieldtype": "Currency",
"label": "\u018fDV 18% (Unallocated)",
"precision": "2",
"read_only": 1
},
{
"fieldname": "column_break_unallocated_1",
"fieldtype": "Column Break"
},
{
"fieldname": "total_edv_daxil_18_unallocated",
"fieldtype": "Currency",
"label": "\u018fDV daxil 18% (Unallocated)",
"precision": "2",
"read_only": 1
},
{
"fieldname": "column_break_unallocated_2",
"fieldtype": "Column Break"
},
{
"fieldname": "total_edv_azadolma_unallocated",
"fieldtype": "Currency",
"label": "\u018fDV-d\u0259n azadolma (Unallocated)",
"precision": "2",
"read_only": 1
},
{
"fieldname": "column_break_unallocated_3",
"fieldtype": "Column Break"
},
{
"fieldname": "total_edv_0_unallocated",
"fieldtype": "Currency",
"label": "\u018fDV 0% (Unallocated)",
"precision": "2",
"read_only": 1
},
{
"fieldname": "column_break_unallocated_4",
"fieldtype": "Column Break"
},
{
"bold": 1,
"fieldname": "total_unallocated_sum",
"fieldtype": "Currency",
"label": "Total Unallocated Amount",
"precision": "2",
"read_only": 1
}
],
"index_web_pages_for_search": 1,

View File

@ -18,20 +18,30 @@ class VATallocation(Document):
def validate_unique_year_month(self):
"""
Ensure only one VAT allocation document exists per year and month
Ensure only one submitted VAT allocation document exists per year and month
- Multiple draft documents can exist for the same period
- Only one document can be submitted for a given period
- Cannot create/save draft if a submitted document already exists
"""
if not self.year or not self.month:
return
existing = frappe.db.exists({
# Check for existing submitted documents with same year and month (excluding current document)
existing_submitted = frappe.db.exists({
'doctype': 'VAT allocation',
'year': self.year,
'month': self.month,
'name': ['!=', self.name]
'name': ['!=', self.name],
'docstatus': 1 # Only check submitted documents
})
if existing:
frappe.throw(_(f"VAT allocation for {self.month} {self.year} already exists: {existing}"))
if existing_submitted:
if self.docstatus == 1:
# Trying to submit, but another submitted document exists
frappe.throw(_(f"VAT allocation for {self.month} {self.year} is already submitted: {existing_submitted}"))
else:
# Trying to save draft, but a submitted document exists
frappe.throw(_(f"Cannot create/modify draft: VAT allocation for {self.month} {self.year} is already submitted: {existing_submitted}"))
def recalculate_totals_from_links(self):
"""
@ -108,33 +118,54 @@ class VATallocation(Document):
"""
Calculate totals by tax template from sales invoice table
"""
# Reset totals
# Reset allocated totals
self.total_edv_daxil_18 = 0
self.total_edv_azadolma = 0
self.total_edv_0 = 0
self.total_edv_18 = 0
self.total_allocated_sum = 0
# Reset unallocated totals
self.total_edv_daxil_18_unallocated = 0
self.total_edv_azadolma_unallocated = 0
self.total_edv_0_unallocated = 0
self.total_edv_18_unallocated = 0
self.total_unallocated_sum = 0
# Calculate totals - only from current month table
for si_row in self.sales_invoice_table:
allocated = Decimal(str(si_row.allocated_amount or 0))
if allocated <= 0:
continue
unallocated = Decimal(str(si_row.unallocated_amount or 0))
template = (si_row.item_tax_template or '').strip()
# Match by template name prefix (template may have company suffix like "ƏDV 18% - js")
if template.startswith('ƏDV daxil 18%'):
self.total_edv_daxil_18 = float(Decimal(str(self.total_edv_daxil_18 or 0)) + allocated)
if allocated > 0:
self.total_edv_daxil_18 = float(Decimal(str(self.total_edv_daxil_18 or 0)) + allocated)
if unallocated > 0:
self.total_edv_daxil_18_unallocated = float(Decimal(str(self.total_edv_daxil_18_unallocated or 0)) + unallocated)
elif template.startswith('ƏDV-dən azadolma'):
self.total_edv_azadolma = float(Decimal(str(self.total_edv_azadolma or 0)) + allocated)
if allocated > 0:
self.total_edv_azadolma = float(Decimal(str(self.total_edv_azadolma or 0)) + allocated)
if unallocated > 0:
self.total_edv_azadolma_unallocated = float(Decimal(str(self.total_edv_azadolma_unallocated or 0)) + unallocated)
elif template.startswith('ƏDV 0%'):
self.total_edv_0 = float(Decimal(str(self.total_edv_0 or 0)) + allocated)
if allocated > 0:
self.total_edv_0 = float(Decimal(str(self.total_edv_0 or 0)) + allocated)
if unallocated > 0:
self.total_edv_0_unallocated = float(Decimal(str(self.total_edv_0_unallocated or 0)) + unallocated)
elif template.startswith('ƏDV 18%'):
self.total_edv_18 = float(Decimal(str(self.total_edv_18 or 0)) + allocated)
if allocated > 0:
self.total_edv_18 = float(Decimal(str(self.total_edv_18 or 0)) + allocated)
if unallocated > 0:
self.total_edv_18_unallocated = float(Decimal(str(self.total_edv_18_unallocated or 0)) + unallocated)
# Add to total sum
self.total_allocated_sum = float(Decimal(str(self.total_allocated_sum or 0)) + allocated)
# Add to total sums
if allocated > 0:
self.total_allocated_sum = float(Decimal(str(self.total_allocated_sum or 0)) + allocated)
if unallocated > 0:
self.total_unallocated_sum = float(Decimal(str(self.total_unallocated_sum or 0)) + unallocated)
def validate_allocations(self):
"""
@ -1005,33 +1036,54 @@ def calculate_tax_template_totals(self):
"""
Calculate totals by tax template from sales invoice table
"""
# Reset totals
# Reset allocated totals
self.total_edv_daxil_18 = 0
self.total_edv_azadolma = 0
self.total_edv_0 = 0
self.total_edv_18 = 0
self.total_allocated_sum = 0
# Reset unallocated totals
self.total_edv_daxil_18_unallocated = 0
self.total_edv_azadolma_unallocated = 0
self.total_edv_0_unallocated = 0
self.total_edv_18_unallocated = 0
self.total_unallocated_sum = 0
# Calculate totals - only from current month table
for si_row in self.sales_invoice_table:
allocated = Decimal(str(si_row.allocated_amount or 0))
if allocated <= 0:
continue
unallocated = Decimal(str(si_row.unallocated_amount or 0))
template = (si_row.item_tax_template or '').strip()
# Match by template name
if template == 'ƏDV daxil 18%':
self.total_edv_daxil_18 = float(Decimal(str(self.total_edv_daxil_18 or 0)) + allocated)
if allocated > 0:
self.total_edv_daxil_18 = float(Decimal(str(self.total_edv_daxil_18 or 0)) + allocated)
if unallocated > 0:
self.total_edv_daxil_18_unallocated = float(Decimal(str(self.total_edv_daxil_18_unallocated or 0)) + unallocated)
elif template == 'ƏDV-dən azadolma':
self.total_edv_azadolma = float(Decimal(str(self.total_edv_azadolma or 0)) + allocated)
if allocated > 0:
self.total_edv_azadolma = float(Decimal(str(self.total_edv_azadolma or 0)) + allocated)
if unallocated > 0:
self.total_edv_azadolma_unallocated = float(Decimal(str(self.total_edv_azadolma_unallocated or 0)) + unallocated)
elif template == 'ƏDV 0%':
self.total_edv_0 = float(Decimal(str(self.total_edv_0 or 0)) + allocated)
if allocated > 0:
self.total_edv_0 = float(Decimal(str(self.total_edv_0 or 0)) + allocated)
if unallocated > 0:
self.total_edv_0_unallocated = float(Decimal(str(self.total_edv_0_unallocated or 0)) + unallocated)
elif template == 'ƏDV 18%':
self.total_edv_18 = float(Decimal(str(self.total_edv_18 or 0)) + allocated)
# Add to total sum
self.total_allocated_sum = float(Decimal(str(self.total_allocated_sum or 0)) + allocated)
if allocated > 0:
self.total_edv_18 = float(Decimal(str(self.total_edv_18 or 0)) + allocated)
if unallocated > 0:
self.total_edv_18_unallocated = float(Decimal(str(self.total_edv_18_unallocated or 0)) + unallocated)
# Add to total sums
if allocated > 0:
self.total_allocated_sum = float(Decimal(str(self.total_allocated_sum or 0)) + allocated)
if unallocated > 0:
self.total_unallocated_sum = float(Decimal(str(self.total_unallocated_sum or 0)) + unallocated)
@frappe.whitelist()
def get_payment_entries_previous_months(year, month, customers=None, min_amount=None, max_amount=None):