167 lines
8.6 KiB
Python
167 lines
8.6 KiB
Python
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
from odoo.addons.account.tests.common import skip_unless_external
|
|
from odoo.addons.l10n_ar_edi.tests.common import TestArEdiCommon
|
|
from odoo.exceptions import UserError
|
|
from odoo.tests import tagged
|
|
|
|
|
|
@tagged('post_install', 'post_install_l10n', '-at_install', *TestArEdiCommon.extra_tags)
|
|
class TestArEdiWsfe(TestArEdiCommon):
|
|
|
|
@classmethod
|
|
@TestArEdiCommon.setup_afip_ws('wsfe')
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
cls.subfolder = "wsfe/normal"
|
|
cls.partner = cls.res_partner_adhoc
|
|
cls.journal = cls._create_journal('wsfe')
|
|
cls._create_test_invoices_like_demo()
|
|
|
|
@skip_unless_external
|
|
def test_ar_edi_wsfe_external_flow(self):
|
|
self._test_ar_edi_common_external()
|
|
|
|
def test_ar_edi_wsfe_flow_suite(self):
|
|
for test_name, move_type, document_code, concept in (
|
|
('test_wsfe_invoice_a_product', 'invoice', 'a', 'product'),
|
|
('test_wsfe_invoice_a_service', 'invoice', 'a', 'service'),
|
|
('test_wsfe_invoice_a_product_service', 'invoice', 'a', 'product_service'),
|
|
('test_wsfe_invoice_b_product', 'invoice', 'b', 'product'),
|
|
('test_wsfe_invoice_b_service', 'invoice', 'b', 'service'),
|
|
('test_wsfe_invoice_b_product_service', 'invoice', 'b', 'product_service'),
|
|
('test_wsfe_credit_note_a_product', 'credit_note', 'a', 'product'),
|
|
('test_wsfe_credit_note_a_service', 'credit_note', 'a', 'service'),
|
|
('test_wsfe_credit_note_a_product_service', 'credit_note', 'a', 'product_service'),
|
|
('test_wsfe_credit_note_b_product', 'credit_note', 'b', 'product'),
|
|
('test_wsfe_credit_note_b_service', 'credit_note', 'b', 'service'),
|
|
('test_wsfe_credit_note_b_product_service', 'credit_note', 'b', 'product_service'),
|
|
):
|
|
with self.subTest(test_name=test_name), self.cr.savepoint() as sp:
|
|
self._test_ar_edi_flow(test_name, move_type, document_code, concept)
|
|
sp.close() # Rollback to ensure all subtests start in the same situation
|
|
|
|
def test_ar_edi_wsfe_corner_cases(self):
|
|
for demo_invoice_key in (
|
|
'test_invoice_1', # Mono partner of type Service and VAT 21
|
|
'test_invoice_2', # Exento partner with multiple VAT types 21, 27 and 10,5
|
|
'test_invoice_3', # RI partner with VAT 0 and 21
|
|
'test_invoice_4', # RI partner with VAT exempt and 21
|
|
'test_invoice_5', # RI partner with all type of taxes
|
|
'test_invoice_8', # Consumidor Final
|
|
|
|
# RI partner with many lines in order to prove rounding error (with 4 decimals of precision):
|
|
'test_invoice_11', # -> rounding of 4 decimals on the currency and 2 decimals for the product
|
|
'test_invoice_12', # -> standard
|
|
'test_invoice_13', # -> standard, but change 260.59 for 260.60
|
|
'test_invoice_17', # -> 100%% of discount
|
|
'test_invoice_18', # -> 100%% of discount with different VAT aliquots
|
|
):
|
|
with self.subTest(demo_invoice_key=demo_invoice_key):
|
|
self._post(self.demo_invoices[demo_invoice_key])
|
|
|
|
def test_ar_edi_wsfe_multicurrency(self):
|
|
""" RI in USD and VAT 21 """
|
|
self._prepare_multicurrency_values()
|
|
self._post(self.demo_invoices['test_invoice_10'])
|
|
|
|
def test_ar_edi_wsfe_iibb_sales_ars(self):
|
|
iibb_tax = self._search_tax('percepcion_iibb_ba')
|
|
iibb_tax.active = True
|
|
|
|
product_27 = self.service_iva_27
|
|
product_no_gravado = self.product_no_gravado
|
|
product_exento = self.product_iva_exento
|
|
|
|
invoice = self._create_invoice_ar(
|
|
invoice_line_ids=[
|
|
self._prepare_invoice_line(price_unit=100.0, product_id=product_27, quantity=8),
|
|
self._prepare_invoice_line(price_unit=750.0, product_id=product_no_gravado, quantity=1),
|
|
self._prepare_invoice_line(price_unit=40.0, product_id=product_exento, quantity=20),
|
|
],
|
|
)
|
|
|
|
# Add perceptions taxes
|
|
invoice.invoice_line_ids.filtered(lambda x: x.product_id == product_27).tax_ids = [(4, iibb_tax.id)]
|
|
invoice.invoice_line_ids.filtered(lambda x: x.product_id == product_exento).tax_ids = [(4, iibb_tax.id)]
|
|
|
|
self.assertIn(iibb_tax.name, invoice.invoice_line_ids.mapped('tax_ids').mapped('name'))
|
|
self._validate_and_review(invoice, "test_wsfe_iibb_sales_ars")
|
|
|
|
def test_ar_edi_wsfe_iibb_sales_usd(self):
|
|
iibb_tax = self._search_tax('percepcion_iibb_ba')
|
|
iibb_tax.active = True
|
|
|
|
self._prepare_multicurrency_values()
|
|
invoice = self._create_invoice_ar(currency_id=self.env.ref('base.USD'))
|
|
invoice.invoice_line_ids.filtered(lambda x: x.tax_ids).tax_ids = [(4, iibb_tax.id)]
|
|
self.assertIn(iibb_tax.name, invoice.invoice_line_ids.mapped('tax_ids').mapped('name'))
|
|
self._validate_and_review(invoice, "test_wsfe_iibb_sales_usd")
|
|
|
|
def test_ar_edi_wsfe_vendor_bill_verify(self):
|
|
# Create a customer invoice in "Responsable Inscripto" Company to "Monotributista" Company
|
|
invoice = self._create_invoice_ar(partner_id=self.company_mono.partner_id)
|
|
self._validate_and_review(invoice, "test_wsfe_verify_invoice")
|
|
|
|
# Login in "Monotributista" Company
|
|
self.env.user.write({'company_id': self.company_mono.id})
|
|
if 'external' in self.test_tags:
|
|
self.company_mono.write({'l10n_ar_afip_ws_crt_id': self.ar_certificate_2})
|
|
self._create_afip_connections(self.company_mono, 'wscdc')
|
|
|
|
# Create a vendor bill with the same values of "Responsable Inscripto"
|
|
bill = self._create_invoice_ar(
|
|
invoice_line_ids=[self._prepare_invoice_line(price_unit=invoice.amount_total, product_id=self.product_iva_21)],
|
|
l10n_latam_document_number=invoice.l10n_latam_document_number,
|
|
move_type='in_invoice',
|
|
)
|
|
|
|
# Set CAE type and number to be able to verify in ARCA
|
|
bill.l10n_ar_afip_auth_mode = 'CAE'
|
|
bill.l10n_ar_afip_auth_code = invoice.l10n_ar_afip_auth_code
|
|
|
|
# Verify manually vendor bill in ARCA from "Responsable Inscripto" in "Monotributista" Company
|
|
self.assertFalse(bill.l10n_ar_afip_verification_result)
|
|
if 'external' in self.test_tags:
|
|
with self._handler_afip_internal_error():
|
|
bill.l10n_ar_verify_on_afip()
|
|
|
|
self.assertTrue(bill.l10n_ar_afip_verification_result)
|
|
# Need to use a real CUIT to be able to verify vendor bills in ARCA, that is why we receive Rejected
|
|
self.assertEqual(bill.l10n_ar_afip_verification_result, 'R', bill.message_ids[0].body)
|
|
else:
|
|
verify_request_data = bill._l10n_ar_edi_get_request_data_verify()
|
|
self.assert_json(verify_request_data, 'test_wsfe_verify_bill', 'wsfe/bill')
|
|
|
|
def test_ar_edi_wsfe_payment_foreign_currency(self):
|
|
""" Payment in Foreign Currency """
|
|
self._test_payment_foreign_currency()
|
|
|
|
def test_ar_edi_wsfe_rounding_complex(self):
|
|
custom_invoice_line_ids = [
|
|
self._prepare_invoice_line(price_unit=100.545, tax_ids=self.tax_21, discount=25.0),
|
|
self._prepare_invoice_line(price_unit=100.545, tax_ids=self.tax_21, discount=25.0),
|
|
self._prepare_invoice_line(price_unit=100.545, tax_ids=self.tax_21, discount=25.0),
|
|
self._prepare_invoice_line(price_unit=100.545, tax_ids=self.tax_21, discount=25.0),
|
|
]
|
|
|
|
with self.subTest('invoice_a'), self.cr.savepoint() as sp:
|
|
self.env.company.tax_calculation_rounding_method = 'round_globally'
|
|
invoice_a = self._create_invoice_ar(invoice_line_ids=custom_invoice_line_ids)
|
|
self._validate_and_review(invoice_a, "test_wsfe_round_01")
|
|
sp.close()
|
|
|
|
with self.subTest('invoice_b'):
|
|
self.env.company.tax_calculation_rounding_method = 'round_per_line'
|
|
invoice_b = self._create_invoice_ar(invoice_line_ids=custom_invoice_line_ids)
|
|
self._validate_and_review(invoice_b, "test_wsfe_round_02")
|
|
|
|
def test_ar_edi_final_consumer_doc_type(self):
|
|
self.partner_cf.write({
|
|
'country_id': self.env.ref('base.ar').id,
|
|
'vat': 'A12345678',
|
|
})
|
|
invoice = self._create_invoice_ar(partner_id=self.partner_cf)
|
|
|
|
with self.assertRaisesRegex(UserError, 'For Argentinean contacts with AFIP Responsibility Type "Consumidor Final", the identification type must be DNI or CUIL/CUIT.'):
|
|
self._validate_and_review(invoice, "")
|