Odoo18-Base/addons/l10n_dk_oioubl/tests/test_xml_oioubl_dk.py

295 lines
13 KiB
Python
Raw Permalink Normal View History

2025-01-06 10:57:38 +07:00
from freezegun import freeze_time
from odoo import Command, fields
from odoo.addons.l10n_account_edi_ubl_cii_tests.tests.common import TestUBLCommon
from odoo.addons.account.tests.test_account_move_send import TestAccountMoveSendCommon
from odoo.exceptions import UserError
from odoo.tests import tagged
from odoo.tools import file_open
@tagged('post_install_l10n', 'post_install', '-at_install')
class TestUBLDK(TestUBLCommon, TestAccountMoveSendCommon):
@classmethod
@TestUBLCommon.setup_country('dk')
def setUpClass(cls):
super().setUpClass()
cls.company_data['company'].write({
'city': 'Aalborg',
'zip': '9430',
'vat': 'DK12345674',
'phone': '+45 32 12 34 56',
'street': 'Paradisæblevej, 10',
})
cls.env['res.partner.bank'].create({
'acc_type': 'iban',
'partner_id': cls.company_data['company'].partner_id.id,
'acc_number': 'DK5000400440116243',
})
cls.company_data['company'].partner_id.update({
'peppol_endpoint': False,
})
cls.partner_a.write({
'name': 'SUPER DANISH PARTNER',
'city': 'Aalborg',
'zip': '9430',
'vat': 'DK12345674',
'phone': '+45 32 12 35 56',
'street': 'Paradisæblevej, 11',
'country_id': cls.env.ref('base.dk').id,
'invoice_edi_format': 'oioubl_201',
'peppol_endpoint': False,
})
cls.partner_b.write({
'name': 'SUPER BELGIAN PARTNER',
'street': 'Rue du Paradis, 10',
'zip': '6870',
'city': 'Eghezee',
'country_id': cls.env.ref('base.be').id,
'phone': '061928374',
'vat': 'BE0897223670',
'invoice_edi_format': 'oioubl_201',
'peppol_endpoint': False,
})
cls.partner_c = cls.env["res.partner"].create({
'name': 'SUPER FRENCH PARTNER',
'street': 'Rue Fabricy, 16',
'zip': '59000',
'city': 'Lille',
'country_id': cls.env.ref('base.fr').id,
'phone': '+33 1 23 45 67 89',
'vat': 'FR23334175221',
'company_registry': '123 568 941 00056',
'invoice_edi_format': 'oioubl_201',
'peppol_endpoint': False,
})
cls.dk_local_sale_tax_1 = cls.env["account.chart.template"].ref('tax_s1y')
cls.dk_local_sale_tax_2 = cls.env["account.chart.template"].ref('tax_s1')
cls.dk_foreign_sale_tax_1 = cls.env["account.chart.template"].ref('tax_s0')
cls.dk_foreign_sale_tax_2 = cls.env["account.chart.template"].ref('tax_s7')
cls.dk_local_purchase_tax_goods = cls.env["account.chart.template"].ref('tax_k1')
def create_post_and_send_invoice(self, partner=None, move_type='out_invoice'):
if not partner:
partner = self.partner_a
if partner == self.partner_a:
# local dk taxes
tax_1, tax_2 = self.dk_local_sale_tax_1, self.dk_local_sale_tax_2
else:
# dk taxes for foreigners
tax_1, tax_2 = self.dk_foreign_sale_tax_1, self.dk_foreign_sale_tax_2
invoice = self.env["account.move"].create({
'move_type': move_type,
'partner_id': partner.id,
'partner_bank_id': self.env.company.partner_id.bank_ids[:1].id,
'invoice_payment_term_id': self.pay_terms_b.id,
'invoice_date': '2017-01-01',
'date': '2017-01-01',
'narration': 'test narration',
'ref': 'ref_move',
'invoice_line_ids': [
Command.create({
'product_id': self.product_a.id,
'quantity': 1.0,
'price_unit': 500.0,
'tax_ids': [Command.set(tax_1.ids)],
}),
Command.create({
'product_id': self.product_b.id,
'quantity': 1.0,
'price_unit': 1000.0,
'tax_ids': [Command.set(tax_2.ids)],
}),
],
})
invoice.action_post()
wizard = self.env['account.move.send.wizard'] \
.with_context(active_model=invoice._name, active_ids=invoice.ids) \
.create({})
wizard.action_send_and_print()
return invoice
#########
# EXPORT
#########
@freeze_time('2017-01-01')
def test_export_invoice_two_line_partner_dk(self):
invoice = self.create_post_and_send_invoice()
self.assertTrue(invoice.ubl_cii_xml_id)
self._assert_invoice_attachment(invoice.ubl_cii_xml_id, xpaths=None, expected_file_path="from_odoo/oioubl_out_invoice_partner_dk.xml")
@freeze_time('2017-01-01')
def test_export_invoice_two_line_foreign_partner_be(self):
# Set peppol endpoint to have schemeID of 'GLN'
self.company_data['company'].partner_id.peppol_endpoint = '0239843188'
invoice = self.create_post_and_send_invoice(partner=self.partner_b)
self.assertTrue(invoice.ubl_cii_xml_id)
self._assert_invoice_attachment(invoice.ubl_cii_xml_id, xpaths=None, expected_file_path="from_odoo/oioubl_out_invoice_foreign_partner_be.xml")
@freeze_time('2017-01-01')
def test_export_invoice_two_line_foreign_partner_fr(self):
invoice = self.create_post_and_send_invoice(partner=self.partner_c)
self.assertTrue(invoice.ubl_cii_xml_id)
self._assert_invoice_attachment(invoice.ubl_cii_xml_id, xpaths=None, expected_file_path="from_odoo/oioubl_out_invoice_foreign_partner_fr.xml")
@freeze_time('2017-01-01')
def test_export_credit_note_two_line_partner_dk(self):
refund = self.create_post_and_send_invoice(move_type='out_refund')
self.assertTrue(refund.ubl_cii_xml_id)
self._assert_invoice_attachment(refund.ubl_cii_xml_id, xpaths=None, expected_file_path="from_odoo/oioubl_out_refund_partner_dk.xml")
@freeze_time('2017-01-01')
def test_export_credit_note_two_line_partner_fr(self):
refund = self.create_post_and_send_invoice(partner=self.partner_c, move_type='out_refund')
self.assertTrue(refund.ubl_cii_xml_id)
self._assert_invoice_attachment(refund.ubl_cii_xml_id, xpaths=None, expected_file_path="from_odoo/oioubl_out_refund_foreign_partner_fr.xml")
@freeze_time('2017-01-01')
def test_oioubl_export_should_still_be_valid_when_currency_has_more_precision_digit(self):
self.company_data['company'].currency_id.rounding = 0.001
invoice = self.create_post_and_send_invoice()
self.assertTrue(invoice.ubl_cii_xml_id)
self._assert_invoice_attachment(invoice.ubl_cii_xml_id, xpaths=None, expected_file_path="from_odoo/oioubl_out_invoice_partner_dk.xml")
@freeze_time('2017-01-01')
def test_oioubl_export_should_raise_an_error_when_partner_building_number_is_missing(self):
self.partner_a.street = 'Paradisæblevej' # remove the street number from the address
with self.assertRaisesRegex(UserError, "The following partner's street number is missing"):
self.create_post_and_send_invoice()
@freeze_time('2017-01-01')
def test_oioubl_export_should_raise_an_error_when_company_building_number_is_missing(self):
self.env.company.partner_id.street = 'Paradisæblevej'
with self.assertRaisesRegex(UserError, "The following partner's street number is missing"):
self.create_post_and_send_invoice()
@freeze_time('2017-01-01')
def test_export_invoice_company_and_partner_without_country_code_prefix_in_vat(self):
self.company_data['company'].vat = '12345674'
self.company_data['company'].partner_id.peppol_endpoint = False
self.partner_a.vat = 'DK12345674'
self.partner_a.peppol_endpoint = False
invoice = self.create_post_and_send_invoice()
self.assertTrue(invoice.ubl_cii_xml_id)
self._assert_invoice_attachment(invoice.ubl_cii_xml_id, xpaths=None, expected_file_path="from_odoo/oioubl_out_invoice_partner_dk.xml")
@freeze_time('2017-01-01')
def test_export_partner_fr_without_siret_should_raise_an_error(self):
self.partner_c.company_registry = False
self.partner_c.invoice_edi_format = 'oioubl_201' # default format for French partners is facturx
with self.assertRaisesRegex(UserError, "The company registry is required for french partner:"):
self.create_post_and_send_invoice(partner=self.partner_c)
@freeze_time('2017-01-01')
def test_oioubl_export_partner_without_vat_number(self):
""" This test verifies that we can't export an OIOUBL file for a partner
who doesn't have a tax ID. It verifies that we receive a UserError
telling to the user that this field is missing.
"""
self.partner_b.vat = None
self.partner_b.invoice_edi_format = 'oioubl_201' # default format recomputes when vat is changed
with self.assertRaises(UserError) as exception:
self.create_post_and_send_invoice(partner=self.partner_b)
self.assertIn(f"The field '{self.partner_b._fields['vat'].string}' is required", exception.exception.args[0])
#########
# IMPORT
#########
def import_bill_xml_file_in_purchase_journal(self, file_path):
file_path = f"{self.test_module}/tests/test_files/{file_path}"
with file_open(file_path, 'rb') as file:
xml_attachment = self.env['ir.attachment'].create({
'mimetype': 'application/xml',
'name': 'test_invoice.xml',
'raw': file.read(),
})
purchase_journal = self.company_data["default_journal_purchase"]
invoice = purchase_journal._create_document_from_attachment(xml_attachment.id)
return invoice
@freeze_time('2017-01-01')
def test_oioubl_import_exemple_file_1(self):
file_name = 'external/ADVORD_01_01_00_Invoice_v2p1.xml'
bill = self.import_bill_xml_file_in_purchase_journal(file_name)
self.assertRecordValues(bill, ({
'ref': 'A00095678',
'invoice_date': fields.Date.from_string('2006-04-10'),
'amount_total': 6_250.00,
},))
self.assertRecordValues(bill.invoice_line_ids, ({
'name': 'Fine toy',
'quantity': 1,
'price_unit': 5_000.00,
'price_subtotal': 5_000.00,
'price_total': 6_250.00,
'tax_ids': self.dk_local_purchase_tax_goods.ids,
},))
@freeze_time('2017-01-01')
def test_oioubl_import_exemple_file_2(self):
file_name = 'external/ADVORD_02_02_00_Invoice_v2p1.xml'
bill = self.import_bill_xml_file_in_purchase_journal(file_name)
self.assertRecordValues(bill, ({
'ref': 'A00095680',
'invoice_date': fields.Date.from_string('2006-04-10'),
'amount_total': 5_000.00,
},))
self.assertRecordValues(bill.invoice_line_ids, ({
'name': 'Superble',
'quantity': 800,
'price_unit': 5.00,
'price_subtotal': 4_000.00,
'price_total': 5_000.00,
'tax_ids': self.dk_local_purchase_tax_goods.ids,
},))
@freeze_time('2017-01-01')
def test_oioubl_import_exemple_file_3(self):
file_name = 'external/ADVORD_03_03_00_Invoice_v2p1.xml'
bill = self.import_bill_xml_file_in_purchase_journal(file_name)
self.assertRecordValues(bill, ({
'ref': 'A00095678',
'invoice_date': fields.Date.from_string('2006-04-10'),
'amount_total': 6_250.00,
},))
self.assertRecordValues(bill.invoice_line_ids, ({
'name': 'Konsulentrapport',
'quantity': 1,
'price_unit': 5_000.00,
'price_subtotal': 5_000.00,
'price_total': 6_250.00,
'tax_ids': self.dk_local_purchase_tax_goods.ids,
},))
@freeze_time('2017-01-01')
def test_oioubl_import_exemple_file_4(self):
file_name = 'external/BASPRO_01_01_00_Invoice_v2p1.xml'
bill = self.import_bill_xml_file_in_purchase_journal(file_name)
self.assertRecordValues(bill, ({
'ref': 'A00095678',
'invoice_date': fields.Date.from_string('2005-11-20'),
'amount_total': 6_312.50,
},))
self.assertRecordValues(bill.invoice_line_ids, ({
'name': 'Hejsetavle',
'quantity': 1,
'price_unit': 5_000.00,
'price_subtotal': 5_000.00,
'price_total': 6_250.00,
'tax_ids': self.dk_local_purchase_tax_goods.ids,
}, {
'name': 'Beslag',
'quantity': 2,
'price_unit': 25.00,
'price_subtotal': 50.00,
'price_total': 62.50,
'tax_ids': self.dk_local_purchase_tax_goods.ids,
}))