1
0
forked from Mapan/odoo17e
odoo17e-kedaikipas58/addons/l10n_uy_edi/tests/common.py
2024-12-10 09:04:09 +07:00

212 lines
9.1 KiB
Python

import logging
import requests
from freezegun import freeze_time
from unittest.mock import patch
from unittest import mock
from odoo.tests.common import tagged
from odoo.tools import misc
from odoo import Command
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
_logger = logging.getLogger(__name__)
@tagged("-at_install", "post_install", "post_install_l10n")
class TestUyEdi(AccountTestInvoicingCommon):
@classmethod
def setUpClass(cls, chart_template_ref="uy"):
super().setUpClass(chart_template_ref=chart_template_ref)
cls.frozen_today = "2024-06-15T10:00:00"
cls.company_data["company"].write({
"name": "(UY) Uruguay Company (Unit Tests)",
"vat": "215521750017",
"state_id": cls.env.ref("base.state_uy_10").id,
"street": "Calle Falsa 254",
"city": "Montevideo",
"zip": "2000",
"phone": "+1 555 123 8069",
"email": "info@example.com",
"website": "www.example.com",
})
cls.company_uy = cls.company_data["company"]
cls.partner_local_tk = cls.env["res.partner"].create({
"name": "IEB Internacional",
"l10n_latam_identification_type_id": cls.env.ref("l10n_uy.it_dni").id,
"vat": "218435730016",
"street": "Bach 0",
"city": "Aeroparque",
"state_id": cls.env.ref("base.state_uy_02").id,
"country_id": cls.env.ref("base.uy").id,
"email": "rut@example.com",
})
cls.partner_local = cls.env["res.partner"].create({
"name": "IEB Internacional",
"l10n_latam_identification_type_id": cls.env.ref("l10n_uy.it_rut").id,
"vat": "218435730016",
"street": "Bach 0",
"city": "Aeroparque",
"state_id": cls.env.ref("base.state_uy_02").id,
"country_id": cls.env.ref("base.uy").id,
"email": "rut@example.com",
})
cls.foreign_partner = cls.env["res.partner"].create({
"name": "Foreign Inc",
"l10n_latam_identification_type_id": cls.env.ref("l10n_latam_base.it_vat").id,
"is_company": True,
"vat": "17-2038053",
"zip": "95380",
"street": "7841 Red Road",
"city": "San Francisco",
"state_id": cls.env.ref("base.state_us_5").id,
"country_id": cls.env.ref("base.us").id,
"email": "foreing@example.com",
"phone": "(123)-456-7890",
"website": "http://www.foreign-inc.com",
})
cls.tax_22 = cls.env.ref("account.%s_vat1" % cls.company_uy.id)
cls.tax_10 = cls.env.ref("account.%s_vat2" % cls.company_uy.id)
cls.tax_0 = cls.env.ref("account.%s_vat3" % cls.company_uy.id)
# Products
cls.service_vat_22 = cls.env["product.product"].create({
"name": "Virtual Home Staging (VAT 22)",
"list_price": 38.25,
"standard_price": 45.5,
"type": "service",
"default_code": "VAT 22",
"taxes_id": [(6, 0, cls.tax_22.ids)],
})
cls.service_vat_10 = cls.env["product.product"].create({
"name": "Service (VAT 10)",
"list_price": 38.25,
"standard_price": 45.5,
"type": "service",
"default_code": "VAT 10",
"taxes_id": [(6, 0, cls.tax_10.ids)],
})
cls.product_vat_22 = cls.env["product.product"].create({
"name": "Customizable Desk (VAT 10)",
"list_price": 38.25,
"standard_price": 45.5,
"type": "consu",
"default_code": "product UY",
"taxes_id": [(6, 0, cls.tax_22.ids)],
})
# Rates
cls.env["res.currency.rate"].create({
"name": "2024-05-08",
"currency_id": cls.env.ref("base.USD").id,
"rate": 0.02602066,
"company_id": cls.company_uy.id,
})
cls.env["res.currency.rate"].create({
"name": "2024-05-08",
"currency_id": cls.env.ref("base.UYI").id,
"rate": 0.1665806,
"company_id": cls.company_uy.id,
})
cls.utils_path = "odoo.addons.l10n_uy_edi.models.l10n_uy_edi_document.L10nUyEdiDocument"
@classmethod
def _create_move(cls, **kwargs):
with freeze_time(cls.frozen_today, tz_offset=3):
invoice = cls.env['account.move'].create({
'partner_id': cls.partner_local_tk.id,
'move_type': 'out_invoice',
'journal_id': cls.company_data['default_journal_sale'].id,
'invoice_line_ids': [
Command.create({
'product_id': cls.service_vat_22.id,
'quantity': 1.0,
'price_unit': 100.0,
}),
],
**kwargs,
})
invoice.invoice_date = invoice.date
return invoice
def _create_credit_note(self, invoice):
with freeze_time(self.frozen_today, tz_offset=3):
refund_wizard = self.env["account.move.reversal"].with_context({
"active_ids": [invoice.id], "active_model": "account.move"}).create({
"reason": "Mercadería defectuosa",
"journal_id": invoice.journal_id.id,
})
res = refund_wizard.refund_moves()
return self.env["account.move"].browse(res["res_id"])
def _create_debit_note(self, invoice):
with freeze_time(self.frozen_today, tz_offset=3):
debit_note_wizard = self.env["account.debit.note"]\
.with_context({"active_ids": [invoice.id], "active_model": "account.move", "default_copy_lines": True})\
.create({"reason": "Mercadería defectuosa"})
res = debit_note_wizard.create_debit()
debit_note = self.env["account.move"].browse(res["res_id"])
return debit_note
def _mocked_response(self, response_file, exception=None):
""" Read the xml response file, change it to dictionary and return the result """
if response_file == "NO_RESPONSE" or not response_file:
mock_response = None
else:
xml_content = misc.file_open("l10n_uy_edi/tests/responses/" + response_file + ".xml", mode="rb").read()
mock_response = mock.Mock(spec=requests.Response)
mock_response.status_code = 200
mock_response.headers = ""
mock_response.content = xml_content
errors = [exception] if exception else []
return self.env["l10n_uy_edi.document"]._process_response(mock_response, errors)
def _mock_send_and_print(self, invoice, expected_xml_file, get_pdf=None, exception=None):
inbox_patch = dict(
target=f"{self.utils_path}._ucfe_inbox",
return_value=self._mocked_response(expected_xml_file, exception=exception),
)
query_patch = dict(
target=f"{self.utils_path}._ucfe_query",
return_value=self._mocked_response(expected_xml_file + "_pdf" if get_pdf else False),
)
with patch(**inbox_patch), patch(**query_patch):
self._send_and_print(invoice)
def _mock_update_dgi_state(self, invoice, expected_xml_file):
with patch(f"{self.utils_path}._ucfe_inbox", return_value=self._mocked_response(expected_xml_file + "_status")):
invoice.l10n_uy_edi_action_update_dgi_state()
def _mock_check_credentials(self, company, expected_xml_file):
with patch(f"{self.utils_path}._ucfe_inbox", return_value=self._mocked_response(expected_xml_file)):
error_msg = self.env["l10n_uy_edi.document"]._validate_credentials(company)
return error_msg
def _send_and_print(self, invoice):
self.env["account.move.send"] \
.with_context(active_model=invoice._name, active_ids=invoice.ids) \
.create({}) \
.action_send_and_print()
def _check_cfe(self, invoice, expected_prefix, expected_xml_file):
self.assertEqual(invoice.name, "%s DE%07d" % (expected_prefix, invoice.id), "Not valid name")
self.assertEqual(invoice.l10n_uy_edi_cfe_state, "accepted", "CFE not accepted in demo mode not possible (it is always accepted)")
expected_xml = self.get_xml_tree_from_string(misc.file_open("l10n_uy_edi/tests/expected_cfes/" + expected_xml_file + ".xml").read())
result_xml = self.get_xml_tree_from_attachment(invoice.l10n_uy_edi_document_id.attachment_id)
# For Debit/Credit Notes we need to change the original expected document to add the proper tag.
ref_number = False
if invoice.reversed_entry_id:
ref_number = invoice.l10n_uy_edi_document_id._get_doc_parts(invoice.reversed_entry_id)[1]
if invoice.debit_origin_id:
ref_number = invoice.l10n_uy_edi_document_id._get_doc_parts(invoice.debit_origin_id)[1]
if ref_number:
namespace = {"cfe": "http://cfe.dgi.gub.uy"}
expected_xml.find(".//cfe:Referencia/cfe:Referencia/cfe:NroCFERef", namespace).text = ref_number
self.assertXmlTreeEqual(expected_xml, result_xml)