Odoo18-Base/addons/l10n_it_edi_withholding/tests/test_withholding.py
2025-01-06 10:57:38 +07:00

314 lines
14 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import datetime
from collections import namedtuple
from odoo import fields
from odoo.tests import tagged
from odoo.exceptions import ValidationError
from odoo.addons.l10n_it_edi.tests.common import TestItEdi
@tagged('post_install_l10n', 'post_install', '-at_install')
class TestWithholdingAndPensionFundTaxes(TestItEdi):
@classmethod
def setUpClass(cls):
super().setUpClass()
def find_tax_by_ref(ref_name):
return cls.env['account.chart.template'].with_company(cls.company).ref(ref_name)
cls.withholding_sale_tax = find_tax_by_ref('20vwc')
cls.withholding_sale_tax_23 = find_tax_by_ref('23vwo')
cls.pension_fund_sale_tax = find_tax_by_ref('4vcp')
cls.enasarco_sale_tax = find_tax_by_ref('enasarcov')
cls.withholding_purchase_tax_23 = find_tax_by_ref('23awo')
cls.enasarco_purchase_tax = find_tax_by_ref('enasarcoa')
cls.inps_tax = find_tax_by_ref('4vinps')
cls.zero_tax = cls.env['account.tax'].with_company(cls.company).create({
'name': 'ZeroTax',
'sequence': 31,
'type_tax_use': 'sale',
'amount': 0.0,
'amount_type': 'percent',
'l10n_it_exempt_reason': 'N2.2',
'l10n_it_law_reference': 'Fatture emesse o ricevute da contribuenti forfettari o minimi',
})
cls.withholding_sale_line = {
'name': 'withholding_line',
'quantity': 1,
'tax_ids': [(6, 0, [
cls.withholding_sale_tax.id,
cls.company.account_sale_tax_id.id,
])]
}
cls.pension_fund_sale_line = {
'name': 'pension_fund_line',
'quantity': 1,
'tax_ids': [(6, 0, [
cls.withholding_sale_tax.id,
cls.pension_fund_sale_tax.id,
cls.company.account_sale_tax_id.id,
])]
}
cls.enasarco_sale_line = {
'name': 'enasarco_line',
'quantity': 1,
'tax_ids': [(6, 0, [
cls.enasarco_sale_tax.id,
cls.withholding_sale_tax_23.id,
cls.company.account_sale_tax_id.id,
])]
}
cls.inps_sale_line = {
'name': 'inps_line',
'quantity': 1,
'tax_ids': [(6, 0, [cls.inps_tax.id, cls.zero_tax.id])]
}
invoice_data = cls.get_real_client_invoice_data()
cls.withholding_tax_invoice = cls.env['account.move'].with_company(cls.company).create({
'move_type': 'out_invoice',
'company_id': cls.company.id,
'partner_id': cls.italian_partner_a.id,
'invoice_date': datetime.date(2022, 3, 24),
'invoice_date_due': datetime.date(2022, 3, 24),
'invoice_line_ids': [
(0, 0, {
**cls.withholding_sale_line,
'name': name,
'price_unit': price,
}) for (name, price) in invoice_data.lines
],
})
cls.pension_fund_tax_invoice = cls.env['account.move'].with_company(cls.company).create({
'move_type': 'out_invoice',
'company_id': cls.company.id,
'partner_id': cls.italian_partner_a.id,
'invoice_date': datetime.date(2022, 3, 24),
'invoice_date_due': datetime.date(2022, 3, 24),
'invoice_line_ids': [
(0, 0, {
**cls.pension_fund_sale_line,
'name': name,
'price_unit': price,
}) for (name, price) in invoice_data.lines
]
})
cls.enasarco_tax_invoice = cls.env['account.move'].with_company(cls.company).create({
'move_type': 'out_invoice',
'company_id': cls.company.id,
'partner_id': cls.italian_partner_a.id,
'invoice_date': datetime.date(2022, 3, 24),
'invoice_date_due': datetime.date(2022, 3, 24),
'invoice_line_ids': [
(0, 0, {
**cls.enasarco_sale_line,
'name': name,
'price_unit': price,
}) for (name, price) in invoice_data.lines
]
})
cls.inps_tax_invoice = cls.env['account.move'].with_company(cls.company).create({
'move_type': 'out_invoice',
'company_id': cls.company.id,
'partner_id': cls.italian_partner_a.id,
'invoice_date': datetime.date(2022, 3, 24),
'invoice_date_due': datetime.date(2022, 3, 24),
'invoice_line_ids': [
(0, 0, {
**cls.inps_sale_line,
'name': name,
'price_unit': price,
}) for (name, price) in invoice_data.lines
]
})
cls.withholding_tax_invoice._post()
cls.pension_fund_tax_invoice._post()
cls.enasarco_tax_invoice._post()
cls.inps_tax_invoice._post()
cls.module = 'l10n_it_edi_withholding'
@classmethod
def get_real_client_invoice_data(cls):
data = {
'lines': [
('Ordinary accounting service for the year', 350.0),
('Balance deposit for the past year', 300.0),
('Ordinary accounting service for the trimester', 50.0),
('Electronic invoices management', 50.0),
],
'base': 750.0,
'tax_amount': 165.0,
'with_tax': 915.0,
'withholding_amount': 150.0,
'with_withholding': 765.0,
'pension_fund_amount': 30.0,
'with_pension_fund': 951.6,
'tax_amount_with_pension_fund': 171.6,
'payment_amount': 801.6,
}
return namedtuple('ClientInvoice', data.keys())(**data)
def test_withholding_tax_constraints(self):
with self.assertRaises(ValidationError):
self.withholding_sale_tax.amount = 10
with self.assertRaises(ValidationError):
self.withholding_sale_tax.l10n_it_withholding_type = False
with self.assertRaises(ValidationError):
self.withholding_sale_tax.l10n_it_withholding_reason = False
with self.assertRaises(ValidationError):
self.company.account_sale_tax_id.l10n_it_withholding_type = "RT02"
####################################################
# WITHHOLDING TAX
####################################################
def test_withholding_taxes_export(self):
"""
Invoice
-------------------------------------------------------------
Ordinary accounting service for the year 350.00
Balance deposit for the past year 300.00
Ordinary accounting service for the trimester 50.00
Electronic invoices management 50.00
-------------------------------------------------------------
Total untaxed: 750.00
Withholding: 20% of Untaxed Amount -150.00
VAT: 22% of Untaxed Amount 165.00
Document total: Untaxed Amount + VAT 915.00
Payment amount: Document total - Withholding 765.00
"""
self._assert_export_invoice(self.withholding_tax_invoice, 'withholding_tax_invoice.xml')
def test_withholding_taxes_import(self):
invoice = self._assert_import_invoice('IT00470550013_withh.xml', [{
'invoice_date': fields.Date.from_string('2022-03-24'),
'amount_untaxed': 750.0,
'amount_total': 765.00,
'amount_tax': 15.0,
'invoice_line_ids': [{
'name': name,
'price_unit': price_unit,
} for name, price_unit in self.get_real_client_invoice_data().lines]
}])
invoice_data = self.get_real_client_invoice_data()
for line in invoice.line_ids.filtered(lambda x: x.name in [data[0] for data in invoice_data.lines]):
withholding_taxes = line.tax_ids.filtered(lambda x: x.l10n_it_withholding_type)
pension_fund_taxes = line.tax_ids.filtered(lambda x: x.l10n_it_pension_fund_type)
vat_taxes = line.tax_ids - withholding_taxes - pension_fund_taxes
self.assertEqual([1, 1, 0], [len(x) for x in (vat_taxes, withholding_taxes, pension_fund_taxes)])
####################################################
# PENSION FUND TAX
####################################################
def test_pension_fund_taxes_export(self):
"""
Invoice
-------------------------------------------------------------
Ordinary accounting service for the year 350.00
Balance deposit for the past year 300.00
Ordinary accounting service for the trimester 50.00
Electronic invoices management 50.00
-------------------------------------------------------------
Total untaxed: 750.00
Pension fund: 4% of Untaxed Amount 30.00
Withholding: 20% of Untaxed Amount -150.00
VAT: 22% of Untaxed Amount + Pension fund 171.60
Document total: Taxed Amount 951.60
Payment amount: Document total - Withholding 801.60
"""
self._assert_export_invoice(self.pension_fund_tax_invoice, 'pension_fund_tax_invoice.xml')
def test_pension_fund_taxes_import(self):
invoice = self._assert_import_invoice('IT00470550013_pfund.xml', [{
'invoice_date': fields.Date.from_string('2022-03-24'),
'amount_untaxed': 750.0,
'amount_total': 795.6,
'amount_tax': 45.6,
'invoice_line_ids': [{
'name': name,
'price_unit': price_unit,
} for name, price_unit in self.get_real_client_invoice_data().lines]
}])
invoice_data = self.get_real_client_invoice_data()
for line in invoice.line_ids.filtered(lambda x: x.name in [data[0] for data in invoice_data.lines]):
withholding_taxes = line.tax_ids.filtered(lambda x: x.l10n_it_withholding_type)
pension_fund_taxes = line.tax_ids.filtered(lambda x: x.l10n_it_pension_fund_type)
vat_taxes = line.tax_ids - withholding_taxes - pension_fund_taxes
self.assertEqual([1, 1, 1], [len(x) for x in (vat_taxes, withholding_taxes, pension_fund_taxes)])
####################################################
# ENASARCO TAX
####################################################
def test_enasarco_tax_export(self):
"""
Invoice
-----------------------------------------------------------------
Ordinary accounting service for the year 350.00
Balance deposit for the past year 300.00
Ordinary accounting service for the trimester 50.00
Electronic invoices management 50.00
-----------------------------------------------------------------
Total untaxed: 750.00
VAT: 22% of Untaxed Amount 165.00
ENASARCO: 8.5% of Untaxed Amount -63.75
Withholding Tax: 23% on 50% of Untaxed Amount -86.25
Document total: Taxed Amount 915.00
Payment amount: Document total - Withholding - Enasarco 765.00
"""
self._assert_export_invoice(self.enasarco_tax_invoice, 'enasarco_tax_invoice.xml')
def test_enasarco_tax_import(self):
invoice = self._assert_import_invoice('IT00470550013_enasa.xml', [{
'invoice_date': fields.Date.from_string('2022-03-24'),
'amount_untaxed': 750.0,
'amount_total': 765.0,
'amount_tax': 15.0,
'invoice_line_ids': [{
'name': name,
'price_unit': price_unit,
} for name, price_unit in self.get_real_client_invoice_data().lines]
}])
invoice_data = self.get_real_client_invoice_data()
for line in invoice.line_ids.filtered(lambda x: x.name in [data[0] for data in invoice_data.lines]):
enasarco_imported_tax = line.tax_ids.filtered(lambda x: x.l10n_it_pension_fund_type == 'TC07')
self.assertEqual(self.enasarco_purchase_tax, enasarco_imported_tax)
self.assertEqual(-8.5, enasarco_imported_tax.amount)
self.assertEqual(self.withholding_purchase_tax_23, line.tax_ids.filtered(lambda x: x.l10n_it_withholding_reason == 'ZO'))
def test_inps_tax_export(self):
"""
Invoice
-----------------------------------------------------------------
Ordinary accounting service for the year 350.00
Balance deposit for the past year 300.00
Ordinary accounting service for the trimester 50.00
Electronic invoices management 50.00
-----------------------------------------------------------------
Total untaxed: 750.00
VAT: 0% of Untaxed Amount 0.00
INPS: 4% of Untaxed Amount 30.00
Document total: Taxed Amount 780.00
Payment amount: Document total 780.00
"""
self._assert_export_invoice(self.inps_tax_invoice, 'inps_tax_invoice.xml')