# -*- coding: utf-8 -* from odoo import Command from odoo.tests import tagged from .common import TestPeEdiCommon, mocked_l10n_pe_edi_post_invoice_web_service from unittest.mock import patch from freezegun import freeze_time @tagged('post_install_l10n', 'post_install', '-at_install') class TestEdiXmls(TestPeEdiCommon): def test_price_amount_rounding(self): with freeze_time(self.frozen_today), \ patch('odoo.addons.l10n_pe_edi.models.account_edi_format.AccountEdiFormat._l10n_pe_edi_post_invoice_web_service', new=mocked_l10n_pe_edi_post_invoice_web_service): move = self._create_invoice(invoice_line_ids=[(0, 0, { 'product_id': self.product.id, 'product_uom_id': self.env.ref('uom.product_uom_kgm').id, 'price_unit': 83.6, # We will compute 250.8 / 3, which results in 83.60000000000001. It must be rounded. 'quantity': 3, 'tax_ids': [(6, 0, self.tax_18.ids)], })]) move.action_post() generated_files = self._process_documents_web_services(move, {'pe_ubl_2_1'}) self.assertTrue(generated_files) zip_edi_str = generated_files[0] edi_xml = self.edi_format._l10n_pe_edi_unzip_edi_document(zip_edi_str) etree = self.get_xml_tree_from_string(edi_xml) price_amount = etree.find('.//{*}InvoiceLine/{*}Price/{*}PriceAmount') self.assertEqual(price_amount.text, '83.6') def test_invoice_simple_case(self): with freeze_time(self.frozen_today), \ patch('odoo.addons.l10n_pe_edi.models.account_edi_format.AccountEdiFormat._l10n_pe_edi_post_invoice_web_service', new=mocked_l10n_pe_edi_post_invoice_web_service): move = self._create_invoice() move.action_post() generated_files = self._process_documents_web_services(move, {'pe_ubl_2_1'}) self.assertTrue(generated_files) zip_edi_str = generated_files[0] edi_xml = self.edi_format._l10n_pe_edi_unzip_edi_document(zip_edi_str) current_etree = self.get_xml_tree_from_string(edi_xml) expected_etree = self.get_xml_tree_from_string(self.expected_invoice_xml_values) self.assertXmlTreeEqual(current_etree, expected_etree) def test_refund_simple_case(self): with freeze_time(self.frozen_today), \ patch('odoo.addons.l10n_pe_edi.models.account_edi_format.AccountEdiFormat._l10n_pe_edi_post_invoice_web_service', new=mocked_l10n_pe_edi_post_invoice_web_service): move = self._create_refund() (move.reversed_entry_id + move).action_post() generated_files = self._process_documents_web_services(move, {'pe_ubl_2_1'}) self.assertTrue(generated_files) zip_edi_str = generated_files[0] edi_xml = self.edi_format._l10n_pe_edi_unzip_edi_document(zip_edi_str) current_etree = self.get_xml_tree_from_string(edi_xml) expected_etree = self.get_xml_tree_from_string(self.expected_refund_xml_values) self.assertXmlTreeEqual(current_etree, expected_etree) def test_debit_note_simple_case(self): with freeze_time(self.frozen_today), \ patch('odoo.addons.l10n_pe_edi.models.account_edi_format.AccountEdiFormat._l10n_pe_edi_post_invoice_web_service', new=mocked_l10n_pe_edi_post_invoice_web_service): move = self._create_debit_note() (move.debit_origin_id + move).action_post() generated_files = self._process_documents_web_services(move, {'pe_ubl_2_1'}) self.assertTrue(generated_files) zip_edi_str = generated_files[0] edi_xml = self.edi_format._l10n_pe_edi_unzip_edi_document(zip_edi_str) current_etree = self.get_xml_tree_from_string(edi_xml) expected_etree = self.get_xml_tree_from_string(self.expected_debit_note_xml_values) self.assertXmlTreeEqual(current_etree, expected_etree) def test_invoice_payment_term_detraction_case(self): """ Invoice in USD with detractions and multiple payment term lines""" self.product.l10n_pe_withhold_percentage = 10 self.product.l10n_pe_withhold_code = '001' with freeze_time(self.frozen_today), \ patch('odoo.addons.l10n_pe_edi.models.account_edi_format.AccountEdiFormat._l10n_pe_edi_post_invoice_web_service', new=mocked_l10n_pe_edi_post_invoice_web_service): update_vals_dict = {"l10n_pe_edi_operation_type": "1001", "invoice_payment_term_id": self.env.ref("account.account_payment_term_advance_60days").id} invoice = self._create_invoice(**update_vals_dict).with_context(edi_test_mode=True) invoice.action_post() generated_files = self._process_documents_web_services(invoice, {'pe_ubl_2_1'}) self.assertTrue(generated_files) zip_edi_str = generated_files[0] edi_xml = self.edi_format._l10n_pe_edi_unzip_edi_document(zip_edi_str) current_etree = self.get_xml_tree_from_string(edi_xml) expected_etree = self.get_xml_tree_from_string(self.expected_invoice_xml_values) expected_etree = self.with_applied_xpath( expected_etree, ''' 1001 Leyenda: Operacion sujeta a detraccion 2017-03-02 Detraccion 999 CUENTAPRUEBA Detraccion 001 10.0 472.00 FormaPago Credito 8496.00 FormaPago Cuota001 1888.00 2017-01-01 FormaPago Cuota002 6608.00 2017-03-02 ''') self.assertXmlTreeEqual(current_etree, expected_etree) def test_invoice_detraction_with_decimal(self): """ Invoice in PEN with detraction containing decimal digits""" self.product.l10n_pe_withhold_percentage = 10 self.product.l10n_pe_withhold_code = '019' with freeze_time(self.frozen_today), \ patch('odoo.addons.l10n_pe_edi.models.account_edi_format.AccountEdiFormat._l10n_pe_edi_post_invoice_web_service', new=mocked_l10n_pe_edi_post_invoice_web_service): vals = { 'name': 'F FFI-%s1' % self.time_name, 'move_type': 'out_invoice', 'partner_id': self.partner_a.id, 'invoice_date': '2017-01-01', 'date': '2017-01-01', 'invoice_payment_term_id': self.env.ref("account.account_payment_term_end_following_month").id, 'l10n_latam_document_type_id': self.env.ref('l10n_pe.document_type01').id, 'l10n_pe_edi_operation_type': '1001', 'invoice_line_ids': [Command.create({ 'product_id': self.product.id, 'price_unit': 990.0, 'quantity': 1, 'tax_ids': [Command.set(self.tax_18.ids)], })], } invoice = self.env['account.move'].create(vals).with_context(edi_test_mode=True) invoice.action_post() generated_files = self._process_documents_web_services(invoice, {'pe_ubl_2_1'}) self.assertTrue(generated_files) zip_edi_str = generated_files[0] edi_xml = self.edi_format._l10n_pe_edi_unzip_edi_document(zip_edi_str) current_etree = self.get_xml_tree_from_string(edi_xml) expected_invoice_xml_values = ''' 2.1 2.0 ___ignore___ 2017-01-01 2017-02-28 01 MIL CIENTO SESENTA Y OCHO Y 20/100 SOLES Leyenda: Operacion sujeta a detraccion PEN ___ignore___ IDSignKG 20557912879 COMPANY_1_DATA #SignVX 20557912879 20557912879 company_1_data PE Peru company_1_data 20557912879 PE Peru VAT company_1_data 20557912879 0000 PE Peru ___ignore___ company_1_data 6 20462509236 partner_a PE Peru partner_a 20462509236 PE Peru VAT partner_a 20462509236 PE Peru ___ignore___ partner_a
PE Peru
Detraccion 999 CUENTAPRUEBA Detraccion 019 10.0 117.00 FormaPago Credito 1051.20 FormaPago Cuota001 1051.20 2017-02-28 178.20 990.00 178.20 1000 IGV VAT 990.00 990.00 1168.20 0.00 1168.20 1 1.0 990.00 1168.20 01 178.20 990.00 178.20 18.0 10 1000 IGV VAT product_pe product_pe 01010101 990.0
''' expected_etree = self.get_xml_tree_from_string(expected_invoice_xml_values) self.assertXmlTreeEqual(current_etree, expected_etree) def test_invoice_detraction_with_decimal_foreign_currency(self): """ Invoice in USD with detraction containing decimal digits""" self.product.l10n_pe_withhold_percentage = 10 self.product.l10n_pe_withhold_code = '019' with freeze_time(self.frozen_today), \ patch('odoo.addons.l10n_pe_edi.models.account_edi_format.AccountEdiFormat._l10n_pe_edi_post_invoice_web_service', new=mocked_l10n_pe_edi_post_invoice_web_service): vals = { 'name': 'F FFI-%s1' % self.time_name, 'move_type': 'out_invoice', 'partner_id': self.partner_a.id, 'invoice_date': '2017-01-01', 'date': '2017-01-01', 'currency_id': self.currency_data['currency'].id, 'invoice_payment_term_id': self.env.ref("account.account_payment_term_end_following_month").id, 'l10n_latam_document_type_id': self.env.ref('l10n_pe.document_type01').id, 'l10n_pe_edi_operation_type': '1001', 'invoice_line_ids': [Command.create({ 'product_id': self.product.id, 'price_unit': 990.0, 'quantity': 1, 'tax_ids': [Command.set(self.tax_18.ids)], })], } invoice = self.env['account.move'].create(vals).with_context(edi_test_mode=True) invoice.action_post() generated_files = self._process_documents_web_services(invoice, {'pe_ubl_2_1'}) self.assertTrue(generated_files) zip_edi_str = generated_files[0] edi_xml = self.edi_format._l10n_pe_edi_unzip_edi_document(zip_edi_str) current_etree = self.get_xml_tree_from_string(edi_xml) expected_invoice_xml_values = ''' 2.1 2.0 ___ignore___ 2017-01-01 2017-02-28 01 MIL CIENTO SESENTA Y OCHO Y 20/100 GOLD Leyenda: Operacion sujeta a detraccion USD ___ignore___ IDSignKG 20557912879 COMPANY_1_DATA #SignVX 20557912879 20557912879 company_1_data PE Peru company_1_data 20557912879 PE Peru VAT company_1_data 20557912879 0000 PE Peru ___ignore___ company_1_data 6 20462509236 partner_a PE Peru partner_a 20462509236 PE Peru VAT partner_a 20462509236 PE Peru ___ignore___ partner_a
PE Peru
Detraccion 999 CUENTAPRUEBA Detraccion 019 10.0 58.00 FormaPago Credito 1051.38 FormaPago Cuota001 1051.38 2017-02-28 178.20 990.00 178.20 1000 IGV VAT 990.00 990.00 1168.20 0.00 1168.20 1 1.0 990.00 1168.20 01 178.20 990.00 178.20 18.0 10 1000 IGV VAT product_pe product_pe 01010101 990.0
''' expected_etree = self.get_xml_tree_from_string(expected_invoice_xml_values) self.assertXmlTreeEqual(current_etree, expected_etree)