284 lines
15 KiB
Python
284 lines
15 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
from odoo.addons.account_reports.tests.account_sales_report_common import AccountSalesReportCommon
|
|
from odoo.tests import tagged
|
|
from odoo.tools.misc import NON_BREAKING_SPACE
|
|
from freezegun import freeze_time
|
|
|
|
|
|
@tagged('post_install_l10n', 'post_install', '-at_install')
|
|
class BelgiumSalesReportTest(AccountSalesReportCommon):
|
|
|
|
@classmethod
|
|
@AccountSalesReportCommon.setup_country('be')
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
cls.partner_b.update({
|
|
'country_id': cls.env.ref('base.de').id,
|
|
"vat": "DE123456788",
|
|
})
|
|
cls.company.update({
|
|
'vat': 'BE0477472701',
|
|
})
|
|
cls.report = cls.env.ref('l10n_be_reports.belgian_ec_sales_report')
|
|
|
|
cls.l_tax = cls.env['account.tax'].search([('name', '=', '0% EU M'), ('company_id', '=', cls.env.company.id)], limit=1)
|
|
cls.t_tax = cls.env['account.tax'].search([('name', '=', '0% EU T'), ('company_id', '=', cls.env.company.id)], limit=1)
|
|
cls.s_tax = cls.env['account.tax'].search([('name', '=', '0% EU S'), ('company_id', '=', cls.env.company.id)], limit=1)
|
|
|
|
@freeze_time('2019-12-31')
|
|
def test_ec_sales_report(self):
|
|
self._create_invoices([
|
|
(self.partner_a, self.l_tax, 300),
|
|
(self.partner_a, self.l_tax, 300),
|
|
(self.partner_a, self.t_tax, 500),
|
|
(self.partner_b, self.t_tax, 500),
|
|
(self.partner_a, self.s_tax, 700),
|
|
(self.partner_b, self.s_tax, 700),
|
|
])
|
|
|
|
options = self.report.get_options({'date': {'mode': 'range', 'filter': 'this_month'}})
|
|
lines = self.report._get_lines(options)
|
|
self.assertLinesValues(
|
|
lines,
|
|
# pylint: disable=C0326
|
|
# Partner country code, VAT Number, Tax Amount
|
|
[ 0, 1, 2, 3, 4],
|
|
[
|
|
(self.partner_a.name, self.partner_a.vat[:2], self.partner_a.vat[2:], 'L (46L)', f'600.00{NON_BREAKING_SPACE}€'),
|
|
(self.partner_a.name, self.partner_a.vat[:2], self.partner_a.vat[2:], 'T (46T)', f'500.00{NON_BREAKING_SPACE}€'),
|
|
(self.partner_a.name, self.partner_a.vat[:2], self.partner_a.vat[2:], 'S (44)', f'700.00{NON_BREAKING_SPACE}€'),
|
|
(self.partner_b.name, self.partner_b.vat[:2], self.partner_b.vat[2:], 'T (46T)', f'500.00{NON_BREAKING_SPACE}€'),
|
|
(self.partner_b.name, self.partner_b.vat[:2], self.partner_b.vat[2:], 'S (44)', f'700.00{NON_BREAKING_SPACE}€'),
|
|
('Total', '', '', '', f'3,000.00{NON_BREAKING_SPACE}€'),
|
|
],
|
|
options,
|
|
)
|
|
|
|
expected_xml = '''
|
|
<ns2:IntraConsignment xmlns="http://www.minfin.fgov.be/InputCommon" xmlns:ns2="http://www.minfin.fgov.be/IntraConsignment" IntraListingsNbr="1">
|
|
<ns2:IntraListing SequenceNumber="1" ClientsNbr="5" DeclarantReference="___ignore___" AmountSum="3000.00">
|
|
<ns2:Declarant>
|
|
<VATNumber>0477472701</VATNumber>
|
|
<Name>company_1_data</Name>
|
|
<Street></Street>
|
|
<PostCode></PostCode>
|
|
<City></City>
|
|
<CountryCode>BE</CountryCode>
|
|
<EmailAddress>jsmith@mail.com</EmailAddress>
|
|
<Phone>+32475123456</Phone>
|
|
</ns2:Declarant>
|
|
<ns2:Period>
|
|
<ns2:Month>12</ns2:Month>
|
|
<ns2:Year>2019</ns2:Year>
|
|
</ns2:Period>
|
|
<ns2:IntraClient SequenceNumber="1">
|
|
<ns2:CompanyVATNumber issuedBy="FR">23334175221</ns2:CompanyVATNumber>
|
|
<ns2:Code>L</ns2:Code>
|
|
<ns2:Amount>600.00</ns2:Amount>
|
|
</ns2:IntraClient>
|
|
<ns2:IntraClient SequenceNumber="2">
|
|
<ns2:CompanyVATNumber issuedBy="FR">23334175221</ns2:CompanyVATNumber>
|
|
<ns2:Code>T</ns2:Code>
|
|
<ns2:Amount>500.00</ns2:Amount>
|
|
</ns2:IntraClient>
|
|
<ns2:IntraClient SequenceNumber="3">
|
|
<ns2:CompanyVATNumber issuedBy="FR">23334175221</ns2:CompanyVATNumber>
|
|
<ns2:Code>S</ns2:Code>
|
|
<ns2:Amount>700.00</ns2:Amount>
|
|
</ns2:IntraClient>
|
|
<ns2:IntraClient SequenceNumber="4">
|
|
<ns2:CompanyVATNumber issuedBy="DE">123456788</ns2:CompanyVATNumber>
|
|
<ns2:Code>T</ns2:Code>
|
|
<ns2:Amount>500.00</ns2:Amount>
|
|
</ns2:IntraClient>
|
|
<ns2:IntraClient SequenceNumber="5">
|
|
<ns2:CompanyVATNumber issuedBy="DE">123456788</ns2:CompanyVATNumber>
|
|
<ns2:Code>S</ns2:Code>
|
|
<ns2:Amount>700.00</ns2:Amount>
|
|
</ns2:IntraClient>
|
|
</ns2:IntraListing>
|
|
</ns2:IntraConsignment>
|
|
'''
|
|
self.assertXmlTreeEqual(
|
|
self.get_xml_tree_from_string(self.env[self.report.custom_handler_model_name].export_to_xml_sales_report(options)['file_content']),
|
|
self.get_xml_tree_from_string(expected_xml)
|
|
)
|
|
|
|
@freeze_time('2019-12-31')
|
|
def test_be_ec_sales_report_refund(self):
|
|
l_tax = self.env['account.tax'].search([('name', '=', '0% EU M'), ('company_id', '=', self.env.company.id)], limit=1)
|
|
t_tax = self.env['account.tax'].search([('name', '=', '0% EU T'), ('company_id', '=', self.env.company.id)], limit=1)
|
|
s_tax = self.env['account.tax'].search([('name', '=', '0% EU S'), ('company_id', '=', self.env.company.id)], limit=1)
|
|
|
|
self._create_invoices([(self.partner_a, l_tax, 100), (self.partner_a, t_tax, 90), (self.partner_a, s_tax, 80)])
|
|
self._create_invoices([(self.partner_a, l_tax, 42), (self.partner_a, t_tax, 42), (self.partner_a, s_tax, 42)], is_refund=True)
|
|
|
|
options = self.report.get_options({'date': {'mode': 'range', 'filter': 'this_month'}})
|
|
lines = self.report._get_lines(options)
|
|
self.assertLinesValues(
|
|
lines,
|
|
# pylint: disable=C0326
|
|
# Partner country code, VAT Number, Tax Amount
|
|
[ 0, 1, 2, 3, 4],
|
|
[
|
|
(self.partner_a.name, self.partner_a.vat[:2], self.partner_a.vat[2:], 'L (46L)', 58.0),
|
|
(self.partner_a.name, self.partner_a.vat[:2], self.partner_a.vat[2:], 'T (46T)', 48.0),
|
|
(self.partner_a.name, self.partner_a.vat[:2], self.partner_a.vat[2:], 'S (44)', 38.0),
|
|
('Total', '', '', '', 144.0),
|
|
],
|
|
options,
|
|
)
|
|
|
|
@freeze_time('2019-12-31')
|
|
def test_ec_sales_report_month_only(self):
|
|
options = self.report.get_options({'date': {'date_to': '2025-06-30', 'mode': 'range', 'filter': 'custom_return_period'}})
|
|
xml_string = self.env[self.report.custom_handler_model_name].export_to_xml_sales_report(options)['file_content']
|
|
xml_tree = self.get_xml_tree_from_string(xml_string)
|
|
|
|
namespaces = {'ns2': 'http://www.minfin.fgov.be/IntraConsignment'}
|
|
month_node = xml_tree.find('.//ns2:Period/ns2:Month', namespaces)
|
|
self.assertIsNotNone(month_node, "The <ns2:Month> element was not found in the <ns2:Period> section.")
|
|
self.assertEqual(month_node.text, '6', "The <ns2:Month> element does not have the expected value.")
|
|
|
|
@freeze_time('2019-12-31')
|
|
def test_ec_sales_report_without_country_code(self):
|
|
self.company.vat = '0477472701'
|
|
|
|
l_tax = self.env['account.chart.template'].ref('attn_VAT-OUT-00-EU-L')
|
|
self._create_invoices([
|
|
(self.partner_a, l_tax, 300),
|
|
])
|
|
options = self.report.get_options({'date': {'mode': 'range', 'filter': 'this_month'}})
|
|
expected_xml = '''
|
|
<ns2:IntraConsignment xmlns="http://www.minfin.fgov.be/InputCommon" xmlns:ns2="http://www.minfin.fgov.be/IntraConsignment" IntraListingsNbr="1">
|
|
<ns2:IntraListing SequenceNumber="1" ClientsNbr="1" DeclarantReference="___ignore___" AmountSum="300.00">
|
|
<ns2:Declarant>
|
|
<VATNumber>0477472701</VATNumber>
|
|
<Name>company_1_data</Name>
|
|
<Street></Street>
|
|
<PostCode></PostCode>
|
|
<City></City>
|
|
<CountryCode>BE</CountryCode>
|
|
<EmailAddress>jsmith@mail.com</EmailAddress>
|
|
<Phone>+32475123456</Phone>
|
|
</ns2:Declarant>
|
|
<ns2:Period>
|
|
<ns2:Month>12</ns2:Month>
|
|
<ns2:Year>2019</ns2:Year>
|
|
</ns2:Period>
|
|
<ns2:IntraClient SequenceNumber="1">
|
|
<ns2:CompanyVATNumber issuedBy="FR">23334175221</ns2:CompanyVATNumber>
|
|
<ns2:Code>L</ns2:Code>
|
|
<ns2:Amount>300.00</ns2:Amount>
|
|
</ns2:IntraClient>
|
|
</ns2:IntraListing>
|
|
</ns2:IntraConsignment>
|
|
'''
|
|
self.assertXmlTreeEqual(
|
|
self.get_xml_tree_from_string(self.env[self.report.custom_handler_model_name].export_to_xml_sales_report(options)['file_content']),
|
|
self.get_xml_tree_from_string(expected_xml)
|
|
)
|
|
|
|
@freeze_time('2019-12-31')
|
|
def test_be_ec_sales_report_northern_ireland_customer(self):
|
|
""" Ensure services sales are excluded from the EC Sales List report if the
|
|
sale is to a Northern Ireland Customer
|
|
"""
|
|
xi_partner = self.env['res.partner'].create([{
|
|
'country_id': self.env.ref('base.uk').id,
|
|
'name': 'XI Partner',
|
|
'vat': 'XI123456782',
|
|
}])
|
|
|
|
self._create_invoices([(xi_partner, self.l_tax, 100), (xi_partner, self.s_tax, 80)])
|
|
|
|
options = self.report.get_options({'date': {'mode': 'range', 'filter': 'this_month'}})
|
|
lines = self.report._get_lines(options)
|
|
self.assertLinesValues(
|
|
lines,
|
|
# Partner country code, VAT Number, Tax Amount
|
|
[ 0, 1, 2, 3, 4],
|
|
[
|
|
(xi_partner.name, xi_partner.vat[:2], xi_partner.vat[2:], 'L (46L)', 100.0),
|
|
('Total', '', '', '', 100.0),
|
|
],
|
|
options,
|
|
)
|
|
|
|
@freeze_time('2019-12-31')
|
|
def test_ec_sales_report_same_vat_partners(self):
|
|
self.partner.country_id = self.partner_a.country_id
|
|
self.partner.vat = 'FR23334175221'
|
|
self.partner_a.vat = self.partner_b.vat
|
|
|
|
l_tax = self.env['account.tax'].search([('name', '=', '0% EU M'), ('company_id', '=', self.env.company.id)], limit=1)
|
|
self._create_invoices([(self.partner_a, l_tax, 100), (self.partner_b, l_tax, 10), (self.partner, l_tax, 1)])
|
|
|
|
options = self.report.get_options({'date': {'mode': 'range', 'filter': 'this_month'}})
|
|
expected_xml = '''
|
|
<ns2:IntraConsignment xmlns="http://www.minfin.fgov.be/InputCommon" xmlns:ns2="http://www.minfin.fgov.be/IntraConsignment" IntraListingsNbr="1">
|
|
<ns2:IntraListing SequenceNumber="1" ClientsNbr="2" DeclarantReference="___ignore___" AmountSum="111.00">
|
|
<ns2:Declarant>
|
|
<VATNumber>0477472701</VATNumber>
|
|
<Name>company_1_data</Name>
|
|
<Street></Street>
|
|
<PostCode></PostCode>
|
|
<City></City>
|
|
<CountryCode>BE</CountryCode>
|
|
<EmailAddress>jsmith@mail.com</EmailAddress>
|
|
<Phone>+32475123456</Phone>
|
|
</ns2:Declarant>
|
|
<ns2:Period>
|
|
<ns2:Month>12</ns2:Month>
|
|
<ns2:Year>2019</ns2:Year>
|
|
</ns2:Period>
|
|
<ns2:IntraClient SequenceNumber="1">
|
|
<ns2:CompanyVATNumber issuedBy="DE">123456788</ns2:CompanyVATNumber>
|
|
<ns2:Code>L</ns2:Code>
|
|
<ns2:Amount>110.00</ns2:Amount>
|
|
</ns2:IntraClient>
|
|
<ns2:IntraClient SequenceNumber="2">
|
|
<ns2:CompanyVATNumber issuedBy="FR">23334175221</ns2:CompanyVATNumber>
|
|
<ns2:Code>L</ns2:Code>
|
|
<ns2:Amount>1.00</ns2:Amount>
|
|
</ns2:IntraClient>
|
|
</ns2:IntraListing>
|
|
</ns2:IntraConsignment>
|
|
|
|
'''
|
|
self.assertXmlTreeEqual(
|
|
self.get_xml_tree_from_string(self.env[self.report.custom_handler_model_name].export_to_xml_sales_report(options)['file_content']),
|
|
self.get_xml_tree_from_string(expected_xml)
|
|
)
|
|
|
|
@freeze_time('2019-12-31')
|
|
def test_be_ec_sales_report_foreign_vat(self):
|
|
"""Test the attachments uses the foreign VAT instead of the company VAT when a foreign company generates the Belgian report."""
|
|
|
|
lu_country = self.env.ref('base.lu')
|
|
be_country = self.env.ref('base.be')
|
|
|
|
self.company.write({
|
|
'country_id': lu_country.id,
|
|
'account_fiscal_country_id': lu_country.id,
|
|
'vat': 'LU12345613',
|
|
})
|
|
fpos = self.env['account.fiscal.position'].create({
|
|
'name': 'Belgian Operations',
|
|
'company_id': self.company.id,
|
|
'country_id': be_country.id,
|
|
'foreign_vat': 'BE0477472701',
|
|
})
|
|
self.partner_a.property_account_position_id = fpos
|
|
self._create_invoices([(self.partner_a, self.l_tax, 300)])
|
|
|
|
options = self.report.get_options({'date': {'mode': 'range', 'filter': 'this_month'}})
|
|
xml_string = self.env[self.report.custom_handler_model_name].export_to_xml_sales_report(options)['file_content']
|
|
|
|
xml_tree = self.get_xml_tree_from_string(xml_string)
|
|
namespaces = {'ns2': 'http://www.minfin.fgov.be/IntraConsignment'}
|
|
listing_node = xml_tree.find('.//ns2:IntraListing', namespaces)
|
|
declarant_ref = listing_node.get('DeclarantReference')
|
|
self.assertIn('0477472701', declarant_ref)
|