166 lines
9.8 KiB
Python
166 lines
9.8 KiB
Python
from dateutil.relativedelta import relativedelta
|
|
from lxml import etree
|
|
from markupsafe import Markup
|
|
|
|
from odoo import _, fields, models
|
|
from odoo.tools import date_utils, file_open
|
|
|
|
|
|
class ItalianReportCustomHandler(models.AbstractModel):
|
|
_name = 'l10n_it.monthly.tax.report.handler'
|
|
_inherit = 'account.tax.report.handler'
|
|
_description = 'Italian Monthly Tax Report Custom Handler'
|
|
|
|
def print_tax_report_to_xml(self, options):
|
|
view_id = self.env.ref('l10n_it_reports.monthly_tax_report_xml_export_wizard_view').id
|
|
return {
|
|
'name': _('XML Export Options'),
|
|
'view_mode': 'form',
|
|
'views': [[view_id, 'form']],
|
|
'res_model': 'l10n_it_reports.monthly.tax.report.xml.export.wizard',
|
|
'type': 'ir.actions.act_window',
|
|
'target': 'new',
|
|
'context': dict(self.env.context, l10n_it_reports_monthly_tax_report_options=options),
|
|
}
|
|
|
|
def export_tax_report_to_xml(self, options):
|
|
xml_export_data = self._get_xml_export_data(options)
|
|
xml_content = self.env["ir.qweb"]._render("l10n_it_reports.tax_report_export_template", xml_export_data)
|
|
xml_content = Markup("""<?xml version="1.0" encoding="UTF-8" standalone="yes"?>""") + xml_content
|
|
xml_content = xml_content.encode()
|
|
|
|
with file_open("l10n_it_reports/data/xml_export/validation/fornituraIvp_2018_v1.xsd", 'rb') as xsd:
|
|
xsd_schema = etree.XMLSchema(etree.parse(xsd))
|
|
try:
|
|
xsd_schema.assertValid(etree.fromstring(xml_content))
|
|
except etree.DocumentInvalid as xml_errors:
|
|
self.env['bus.bus']._sendone(
|
|
self.env.user.partner_id,
|
|
'simple_notification',
|
|
{
|
|
'type': 'warning',
|
|
'title': _('XML Validation Error'),
|
|
'message': _(
|
|
"Some values will not pass the authority's validation, please check them before submitting your file: %s",
|
|
[error.path.split(":")[-1] for error in xml_errors.error_log]
|
|
),
|
|
'sticky': True,
|
|
},
|
|
)
|
|
|
|
return {
|
|
"file_name": f"IT{xml_export_data['taxpayer_code']}_LI_{xml_export_data['identificativo']}.xml",
|
|
"file_content": xml_content,
|
|
"file_type": "xml",
|
|
}
|
|
|
|
def _get_xml_export_data(self, options):
|
|
options_date_to = fields.Date.from_string(options["date"]["date_to"])
|
|
report = self.env["account.report"].browse(options["report_id"])
|
|
company = report._get_sender_company_for_export(options)
|
|
quarterly = self.env.company.account_return_periodicity == 'trimester'
|
|
colname_to_idx = {col['expression_label']: idx for idx, col in enumerate(options.get('columns', []))}
|
|
|
|
if quarterly:
|
|
report_lines_data_per_month = {0: {}}
|
|
quarter_report_lines = report._get_lines(options)
|
|
quarter_report_expressions = self.env['account.report.expression'].search([('report_line_id', 'in', [line['columns'][0]['report_line_id'] for line in quarter_report_lines])])
|
|
|
|
quarter_report_expressions_by_line = quarter_report_expressions.grouped('report_line_id')
|
|
for line, expressions in quarter_report_expressions_by_line.items():
|
|
line_dict = next(report_line for report_line in quarter_report_lines if report_line['name'] == line.name)
|
|
expressions_by_label = expressions.grouped('label')
|
|
debit_expression = expressions_by_label.get('debit')
|
|
credit_expression = expressions_by_label.get('credit')
|
|
if debit_expression and credit_expression:
|
|
debit_value = line_dict['columns'][colname_to_idx['debit']]['no_format']
|
|
report_lines_data_per_month[0][f'{debit_expression.report_line_id.code}a'] = f"{debit_value:.2f}".replace(".", ",") if debit_value else False
|
|
credit_value = line_dict['columns'][colname_to_idx['credit']]['no_format']
|
|
report_lines_data_per_month[0][f'{credit_expression.report_line_id.code}b'] = f"{credit_value:.2f}".replace(".", ",") if credit_value else False
|
|
elif (bool(debit_expression) ^ bool(credit_expression)):
|
|
value = line_dict['columns'][colname_to_idx[(debit_expression or credit_expression).label]]['no_format']
|
|
report_lines_data_per_month[0][line.code] = f"{value:.2f}".replace(".", ",") if value else False
|
|
else:
|
|
quarter_months = list(date_utils.date_range(*date_utils.get_quarter(options_date_to)))
|
|
report_lines_data_per_month = {date.month: {} for date in quarter_months}
|
|
for date in quarter_months:
|
|
date_from = date
|
|
date_to = date_utils.end_of(date, 'month')
|
|
at_date_options = report.get_options({
|
|
'selected_variant_id': report.id,
|
|
'date': {
|
|
'date_from': date_from,
|
|
'date_to': date_to,
|
|
'mode': 'range',
|
|
'filter': 'custom',
|
|
},
|
|
})
|
|
monthly_report_lines = report._get_lines(at_date_options)
|
|
monthly_report_expressions = self.env['account.report.expression'].search([('report_line_id', 'in', [line['columns'][0]['report_line_id'] for line in monthly_report_lines])])
|
|
|
|
monthly_report_expressions_by_line = monthly_report_expressions.grouped('report_line_id')
|
|
for line, expressions in monthly_report_expressions_by_line.items():
|
|
line_dict = next(report_line for report_line in monthly_report_lines if report_line['name'] == line.name)
|
|
expressions_by_label = expressions.grouped('label')
|
|
debit_expression = expressions_by_label.get('debit')
|
|
credit_expression = expressions_by_label.get('credit')
|
|
if debit_expression and credit_expression:
|
|
debit_value = line_dict['columns'][colname_to_idx['debit']]['no_format']
|
|
report_lines_data_per_month[date.month][f'{debit_expression.report_line_id.code}a'] = f"{debit_value:.2f}".replace(".", ",") if debit_value else False
|
|
credit_value = line_dict['columns'][colname_to_idx['credit']]['no_format']
|
|
report_lines_data_per_month[date.month][f'{credit_expression.report_line_id.code}b'] = f"{credit_value:.2f}".replace(".", ",") if credit_value else False
|
|
elif (bool(debit_expression) ^ bool(credit_expression)):
|
|
value = line_dict['columns'][colname_to_idx[(debit_expression or credit_expression).label]]['no_format']
|
|
report_lines_data_per_month[date.month][line.code] = f"{value:.2f}".replace(".", ",") if value else False
|
|
|
|
identificativo = self.env['ir.sequence'].next_by_code('l10n_it_reports.identificativo')
|
|
if not identificativo:
|
|
self.env['ir.sequence'].create({
|
|
'name': "IT Periodic VAT XML Export Identificativo",
|
|
'code': "l10n_it_reports.identificativo",
|
|
'padding': 5,
|
|
})
|
|
identificativo = self.env['ir.sequence'].next_by_code('l10n_it_reports.identificativo')
|
|
|
|
return {
|
|
"supply_code": "IVP18",
|
|
"declarant_fiscal_code": options["declarant_fiscal_code"],
|
|
"declarant_role_code": options["declarant_role_code"],
|
|
"id_sistema": options["id_sistema"],
|
|
"identificativo": identificativo,
|
|
"taxpayer_code": company.l10n_it_codice_fiscale,
|
|
"tax_year": options_date_to.year,
|
|
"vat_number": "".join([char for char in report.get_vat_for_export(options) if char.isdigit()]),
|
|
"parent_company_vat_number": options["parent_company_vat_number"],
|
|
"last_month": (options_date_to - relativedelta(months=1)).month,
|
|
"company_code": options["company_code"],
|
|
"intermediary_code": options["intermediary_code"],
|
|
"submission_commitment": options["intermediary_code"] and int(options["submission_commitment"]),
|
|
"commitment_date": options["intermediary_code"] and fields.Date.from_string(options["commitment_date"]).strftime("%d%m%Y"),
|
|
"intermediary_signature": options["intermediary_code"] and 1,
|
|
"quarter": date_utils.get_quarter_number(options_date_to) if quarterly else 0,
|
|
"monthly_data": {
|
|
month: {
|
|
"total_active_operations": month_vals["VP2"],
|
|
"total_passive_operations": month_vals["VP3"],
|
|
"vat_payable": month_vals["VP4"],
|
|
"vat_deducted": month_vals["VP5"],
|
|
"vat_due": month_vals["VP6a"],
|
|
"vat_credit": month_vals["VP6b"],
|
|
"previous_debt": month_vals["VP7"],
|
|
"previous_period_credit": month_vals["VP8"],
|
|
"previous_year_credit": month_vals["VP9"],
|
|
"eu_self_payments": month_vals["VP10"],
|
|
"tax_credits": month_vals["VP11"],
|
|
"due_interests": month_vals["VP12"],
|
|
"method": int(options["method"]),
|
|
"advance_payment": month_vals["VP13"],
|
|
"amount_to_be_paid": month_vals["VP14a"],
|
|
"amount_in_credit": month_vals["VP14b"],
|
|
"subcontracting": month_vals["xml_subcontracting"] and 1,
|
|
"exceptional_events": month_vals["xml_exceptional_events"] and 1,
|
|
"extraordinary_operations": month_vals["xml_extraordinary_operations"] and 1,
|
|
} for month, month_vals in report_lines_data_per_month.items()
|
|
}
|
|
}
|