Files
enterprise-addons/l10n_ar_reports/tests/test_reports.py
T

545 lines
27 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
from freezegun import freeze_time
from odoo import fields
from odoo.addons.l10n_ar.tests.common import TestArCommon
from odoo.addons.account_reports.tests.common import TestAccountReportsCommon
from odoo.tests import Form, tagged
from odoo.tools import file_open
from odoo.fields import Command
import logging
_logger = logging.getLogger(__name__)
@tagged('post_install_l10n', 'post_install', '-at_install')
class TestArReports(TestArCommon, TestAccountReportsCommon):
def _create_test_credit_notes_like_demo(self):
""" Create in the unit tests the same credit notes created in demo data """
credit_notes = {
"demo_refund_invoice_3": {
# "ref": "demo_refund_invoice_3: Create draft refund for invoice 3",
"reason": "Mercadería defectuosa",
"is_refund": True,
"move_ids": self.demo_invoices['test_invoice_3'],
"date": '2021-03-01',
},
"demo_refund_invoice_4": {
# "ref": "demo_refund_invoice_4: Create draft refund for invoice 4",
"reason": "Venta cancelada",
"is_refund": False,
"move_ids": self.demo_invoices['test_invoice_4'],
"date": '2021-03-01',
},
"demo_refund_invoice_16": {
# "ref": "demo_refund_invoice_16: Create cancel refund for expo invoice 16 (las nc/nd expo invoice no requiere parametro permiso existennte, por eso agregamos este ejemplo)",
"reason": "Venta cancelada",
"is_refund": False,
"move_ids": self.demo_invoices['test_invoice_16'],
"date": '2021-03-01',
},
"demo_refund_bill_1": {
"reason": "demo_sup_refund_invoice_5: liquido producto bill refund (credit note)",
"is_refund": False,
"move_ids": self.demo_bills['test_vendor_bill_8'],
"date": '2021-03-27',
"l10n_latam_document_number": "00011-00000012",
"l10n_latam_document_type_id": self.document_type['liq_pro_doc'].id,
}
}
refund_wizard = self.env['account.move.reversal']
for key, values in credit_notes.items():
origin_move = values.get("move_ids")
is_refund = values.pop("is_refund")
values.update({
'date': fields.Date.from_string(values.get('date')),
'journal_id': origin_move.journal_id.id,
})
move_reversal = refund_wizard.with_context(
active_model="account.move",
active_ids=origin_move.ids).create(values)
reversal = move_reversal.refund_moves() if is_refund else move_reversal.modify_moves()
reverse_move = self.env['account.move'].browse(reversal['res_id'])
self.demo_credit_notes[key] = reverse_move
def _create_test_vendor_bill_invoice_demo(self):
""" Create in the unit tests the same vendor bills created in demo data """
payment_term_id = self.env.ref("account.account_payment_term_end_following_month")
purchase_journal = self.env["account.journal"].search([('type', '=', 'purchase'), ('company_id', '=', self.env.company.id)])
vendor_bills = {
"test_vendor_bill_1": {
"ref": "demo_sup_invoice_1: Invoice from Gritti support service, auto fiscal position set VAT Not Applicable",
"l10n_latam_document_number": "0001-00000008",
"partner_id": self.res_partner_gritti_mono,
"invoice_payment_term_id": payment_term_id,
"move_type": "in_invoice",
"invoice_date": '2021-03-01',
"company_id": self.env.company,
"invoice_line_ids": [
{'product_id': self.service_iva_21, 'price_unit': 642.0, 'quantity': 1},
{'product_id': self.product_iva_105, 'price_unit': 642.0, 'quantity': 5},
{'product_id': self.service_iva_27, 'price_unit': 250.0, 'quantity': 1},
{'product_id': self.product_no_gravado, 'price_unit': 50.0, 'quantity': 10},
{'product_id': self.product_iva_cero, 'price_unit': 200.0, 'quantity': 1},
{'product_id': self.product_iva_exento, 'price_unit': 100.0, 'quantity': 1},
],
}, "test_vendor_bill_2": {
"ref": "demo_sup_invoice_2: Invoice from Foreign with vat 21, 27 and 10,5",
"l10n_latam_document_number": "0002-00000123",
"partner_id": self.res_partner_barcelona_food,
"invoice_payment_term_id": payment_term_id,
"move_type": "in_invoice",
"invoice_date": '2021-03-01',
"company_id": self.env.company,
"invoice_line_ids": [
{'product_id': self.product_iva_105, 'price_unit': 642.0, 'quantity': 5},
{'product_id': self.service_iva_27, 'price_unit': 250.0, 'quantity': 1},
{'product_id': self.product_iva_105_perc, 'price_unit': 3245.0, 'quantity': 2},
],
}, "test_vendor_bill_3": {
"ref": "demo_sup_invoice_3: Invoice from Foreign with vat zero and 21",
"l10n_latam_document_number": "0003-00000312",
"partner_id": self.res_partner_barcelona_food,
"invoice_payment_term_id": payment_term_id,
"move_type": "in_invoice",
"invoice_date": '2021-03-01',
"company_id": self.env.company,
"invoice_line_ids": [
{'product_id': self.product_iva_105, 'price_unit': 642.0, 'quantity': 5},
{'product_id': self.product_iva_cero, 'price_unit': 200.0, 'quantity': 1},
],
}, "test_vendor_bill_4": {
"ref": "demo_sup_invoice_4: Invoice to Foreign with vat exempt and 21",
"l10n_latam_document_number": "0001-00000200",
"partner_id": self.res_partner_barcelona_food,
"invoice_payment_term_id": payment_term_id,
"move_type": "in_invoice",
"invoice_date": '2021-03-15',
"company_id": self.env.company,
"invoice_line_ids": [
{'product_id': self.product_iva_105, 'price_unit': 642.0, 'quantity': 5},
{'product_id': self.product_iva_exento, 'price_unit': 100.0, 'quantity': 1},
],
}, "test_vendor_bill_5": {
"ref": "demo_sup_invoice_5: Invoice to Foreign with all type of taxes",
"l10n_latam_document_number": "0001-00000222",
"partner_id": self.res_partner_barcelona_food,
"invoice_payment_term_id": payment_term_id,
"move_type": "in_invoice",
"invoice_date": '2021-03-18',
"company_id": self.env.company,
"invoice_line_ids": [
{'product_id': self.product_iva_105, 'price_unit': 642.0, 'quantity': 5},
{'product_id': self.service_iva_27, 'price_unit': 250.0, 'quantity': 1},
{'product_id': self.product_iva_105_perc, 'price_unit': 3245.0, 'quantity': 2},
{'product_id': self.product_no_gravado, 'price_unit': 50.0, 'quantity': 10},
{'product_id': self.product_iva_cero, 'price_unit': 200.0, 'quantity': 1},
{'product_id': self.product_iva_exento, 'price_unit': 100.0, 'quantity': 1},
],
}, "test_vendor_bill_6": {
"ref": "demo_sup_invoice_6: Service Import to Odoo, fiscal position changes tax not correspond",
"l10n_latam_document_number": "0001-00000333",
"partner_id": self.res_partner_barcelona_food,
"invoice_payment_term_id": payment_term_id,
"move_type": "in_invoice",
"invoice_date": '2021-03-26',
"company_id": self.env.company,
"invoice_line_ids": [
{'product_id': self.service_iva_21, 'price_unit': 1642.0, 'quantity': 1},
],
}, "test_vendor_bill_7": {
"ref": "demo_sup_invoice_7: Similar to last one but with line that have tax not correspond with negative amount",
"l10n_latam_document_number": "0001-00000334",
"partner_id": self.res_partner_barcelona_food,
"invoice_payment_term_id": payment_term_id,
"move_type": "in_invoice",
"invoice_date": '2021-03-27',
"company_id": self.env.company,
"invoice_line_ids": [
{'product_id': self.service_iva_21, 'price_unit': 1642.0, 'quantity': 1},
{'product_id': self.product_no_gravado, 'price_unit': -50.0, 'quantity': 10},
],
}, "test_vendor_bill_8": {
"ref": "demo_sup_invoice_8: Invoice to ADHOC with multiple taxes and perceptions",
"l10n_latam_document_number": "0001-00000335",
"partner_id": self.res_partner_adhoc,
"invoice_payment_term_id": payment_term_id,
"move_type": "in_invoice",
"invoice_date": '2021-03-01',
"company_id": self.env.company,
"invoice_line_ids": [
{'product_id': self.product_iva_105, 'price_unit': 642.0, 'quantity': 5},
{'product_id': self.service_iva_27, 'price_unit': 250.0, 'quantity': 1},
{'product_id': self.product_iva_105_perc, 'price_unit': 3245.0, 'quantity': 2},
],
}, "demo_despacho_1": {
"ref": "demo_despacho_1: Import Cleareance ",
"l10n_latam_document_number": "16052IC04000605L",
"partner_id": self.partner_afip,
"invoice_payment_term_id": payment_term_id,
"move_type": "in_invoice",
"invoice_date": '2021-03-13',
"company_id": self.env.company,
# as we create lines separatelly we need to set journal, if not, misc journal is selected
"journal_id": purchase_journal,
"invoice_line_ids": [
{'product_id': self.service_wo_tax, "name": "[ARCA_DESPACHO] Despacho de importación", 'price_unit': 5064.98, 'quantity': 1,
"tax_ids": [(6, 0, self.tax_21_purchase.ids)]},
{'product_id': self.service_wo_tax, "name": "[ARCA_TASA_EST] Tasa Estadística", 'price_unit': 152.08, 'quantity': 1,
"tax_ids": [(6, 0, self.tax_21_purchase.ids)]},
{'product_id': self.service_iva_no_gravado, "name": "[ARCA_ARANCEL] Arancel", 'price_unit': 10.0, 'quantity': 1,
"tax_ids": [(6, 0, self.tax_no_gravado_purchase.ids)]},
],
},
"test_vendor_bill_9": {
"ref": " demo_liquido_producto_1: Vendor bill liquido producto (document type 186)",
"l10n_latam_document_type_id": self.document_type['liq_pro_doc'],
"l10n_latam_document_number": "00077-00000077",
"partner_id": self.res_partner_adhoc,
"invoice_payment_term_id": payment_term_id,
"move_type": "in_invoice",
"invoice_date": '2021-03-25',
"company_id": self.env.company,
# as we create lines separatelly we need to set journal, if not, misc journal is selected
"journal_id": purchase_journal,
"invoice_line_ids": [
{'product_id': self.service_wo_tax, "name": "[ARCA_DESPACHO] Despacho de importación", 'price_unit': 5064.98, 'quantity': 1,
"tax_ids": [(6, 0, self.tax_21_purchase.ids)]},
{'product_id': self.service_wo_tax, "name": "[ARCA_TASA_EST] Tasa Estadística", 'price_unit': 152.08, 'quantity': 1,
"tax_ids": [(6, 0, self.tax_21_purchase.ids)]},
{'product_id': self.service_iva_no_gravado, "name": "[ARCA_ARANCEL] Arancel", 'price_unit': 10.0, 'quantity': 1,
"tax_ids": [(6, 0, self.tax_no_gravado_purchase.ids)]},
],
}
}
for key, values in vendor_bills.items():
with Form(self.env['account.move'].with_context(default_move_type=values['move_type'])) as invoice_form:
invoice_form.ref = values['ref']
invoice_form.partner_id = values['partner_id']
invoice_form.invoice_payment_term_id = values['invoice_payment_term_id']
invoice_form.invoice_date = values['invoice_date']
if values.get('l10n_latam_document_type_id'):
invoice_form.l10n_latam_document_type_id = values['l10n_latam_document_type_id']
invoice_form.l10n_latam_document_number = values['l10n_latam_document_number']
if values.get('invoice_incoterm_id'):
invoice_form.invoice_incoterm_id = values['invoice_incoterm_id']
for line in values['invoice_line_ids']:
with invoice_form.invoice_line_ids.new() as line_form:
line_form.product_id = line.get('product_id')
line_form.price_unit = line.get('price_unit')
line_form.quantity = line.get('quantity')
# TODO: check this lines, should not be necessary to add
line_form.name = 'xxxx'
line_form.account_id = self.company_data['default_account_revenue']
invoice = invoice_form.save()
self.demo_bills[key] = invoice
def _vat_book_report_create_test_data(self):
purchase_journal = self.env["account.journal"].search([('type', '=', 'purchase'), ('company_id', '=', self.env.company.id)])
ar_partner = self.env['res.partner'].create({
'name': 'BEST PARTNER',
'vat': '30714295698',
'l10n_latam_identification_type_id': self.env.ref('l10n_ar.it_cuit').id
})
test_tax_group = self.env['account.tax.group'].create({
'name': "test tax group",
'l10n_ar_vat_afip_code': '5',
})
test_tax_21 = self.env['account.tax'].create({
'name': "test tax",
'amount_type': 'percent',
'amount': 21,
'tax_group_id': test_tax_group.id,
})
test_product = self.env['product.product'].create({
'name': "Test Product",
'lst_price': 100.0,
'standard_price': 10.0,
'property_account_income_id': self.company_data["default_account_revenue"].id,
'property_account_expense_id': self.company_data["default_account_expense"].id,
})
invoices = self.env['account.move'].create([
{
'move_type': 'in_invoice',
'partner_id': ar_partner.id,
'invoice_date': '2022-03-01',
"journal_id": purchase_journal.id,
"l10n_latam_document_number": "0001-00000001000",
'invoice_line_ids': [(0, 0, {
'product_id': test_product.id,
'price_unit': 1000.0,
'tax_ids': [(6, 0, [test_tax_21.id])],
})],
},
{
'move_type': 'in_invoice',
'partner_id': ar_partner.id,
'invoice_date': '2022-03-10',
"journal_id": purchase_journal.id,
"l10n_latam_document_number": "0001-00000002000",
'invoice_line_ids': [(0, 0, {
'product_id': test_product.id,
'price_unit': 500.0,
'tax_ids': [(6, 0, [test_tax_21.id])],
})],
},
{
'move_type': 'in_invoice',
'partner_id': ar_partner.id,
'invoice_date': '2022-03-31',
"journal_id": purchase_journal.id,
"l10n_latam_document_number": "0001-00000003000",
'invoice_line_ids': [(0, 0, {
'product_id': test_product.id,
'price_unit': 800.0,
'tax_ids': [(6, 0, [test_tax_21.id])],
})],
},
])
invoices.action_post()
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.journal = cls._create_journal('preprinted', data={'l10n_ar_afip_pos_number': 37928})
cls.maxDiff = None
cls.report = cls.env.ref('l10n_ar_reports.l10n_ar_vat_book_report')
# Login to (AR) Responsable Inscripto company
context = dict(cls.env.context, allowed_company_ids=[cls.company_ri.id])
cls.env = cls.env(context=context)
cls.env.user.write({'company_ids': [(4, cls.company_ri.id)]})
# ==== Document Types ====
cls.document_type.update({
'liq_pro_doc': cls.env.ref('l10n_ar.dc_liq_cd_sp_a'),
})
# ==== Create VAT BOOK demo data ====
cls._create_test_invoices_like_demo(use_current_date=False)
for inv in cls.demo_invoices.values():
inv.action_post()
cls._create_test_vendor_bill_invoice_demo(cls)
for inv in cls.demo_bills.values():
inv.action_post()
# demo_credit_notes are automatically posted thanks to the refund type
cls._create_test_credit_notes_like_demo(cls)
cls.options = cls._generate_options(cls.report, fields.Date.from_string('2021-03-01'), fields.Date.from_string('2021-03-31'))
cls._vat_book_report_create_test_data(cls)
def _test_txt_file(self, filename, journal_type):
filetype = 1 if 'IVA' in filename else 0
out_txt = self.env['l10n_ar.tax.report.handler']._vat_book_get_txt_files(self.options, journal_type)[filetype].decode('ISO-8859-1')
res_file = file_open('l10n_ar_reports/tests/' + filename, 'rb').read().decode('ISO-8859-1')
self.assertEqual(out_txt, res_file)
def test_01_sale_vat_book_vouchers(self):
self.options['ar_vat_book_tax_types_available']['sale']['selected'] = True
self.options['ar_vat_book_tax_types_available']['purchase']['selected'] = False
self.options['txt_type'] = 'sale'
self._test_txt_file('Ventas.txt', 'sale')
def test_02_sale_vat_book_aliquots(self):
self.options['ar_vat_book_tax_types_available']['sale']['selected'] = True
self.options['ar_vat_book_tax_types_available']['purchase']['selected'] = False
self.options['txt_type'] = 'sale'
self._test_txt_file('IVA_Ventas.txt', 'sale')
def test_03_purchase_vat_book_purchases_voucher(self):
self.options['ar_vat_book_tax_types_available']['purchase']['selected'] = True
self.options['ar_vat_book_tax_types_available']['sale']['selected'] = False
self.options['txt_type'] = 'purchases'
self._test_txt_file('Compras.txt', 'purchase')
def test_04_purchase_vat_book_purchases_aliquots(self):
self.options['ar_vat_book_tax_types_available']['purchase']['selected'] = True
self.options['ar_vat_book_tax_types_available']['sale']['selected'] = False
self.options['txt_type'] = 'purchases'
self._test_txt_file('IVA_Compras.txt', 'purchase')
def test_05_purchase_vat_book_goods_import_voucher(self):
self.options['ar_vat_book_tax_types_available']['purchase']['selected'] = True
self.options['ar_vat_book_tax_types_available']['sale']['selected'] = False
self.options['txt_type'] = 'goods_import'
self._test_txt_file('Importaciones_de_Bienes.txt', 'purchase')
def test_06_purchase_vat_book_goods_import_aliquots(self):
self.options['ar_vat_book_tax_types_available']['purchase']['selected'] = True
self.options['ar_vat_book_tax_types_available']['sale']['selected'] = False
self.options['txt_type'] = 'goods_import'
self._test_txt_file('IVA_Importaciones_de_Bienes.txt', 'purchase')
@freeze_time("2021-04-19")
def test_07_sale_vat_book_vouchers_with_branch(self):
parent_company = self.env.company
branch_A, branch_B = self.env['res.company'].create([
{
'name': "Branch_A",
'parent_id': self.company.id,
}, {
'name': "Branch_B",
'parent_id': self.company.id,
'vat': '/'
}
])
# Load CoA
self.cr.precommit.run()
invoice_B = self.env['account.move'].with_company(company=branch_B).create([
{
"ref": "test_invoice_007: Invoice to gritti support service, vat 21",
"company_id": branch_B.id,
"partner_id": self.res_partner_adhoc.id,
"move_type": "out_invoice",
"invoice_date": "2021-03-22",
"invoice_line_ids": [
Command.create({'product_id': self.service_iva_21.id})
]
},
])
invoice_A = self.env['account.move'].with_company(company=branch_A).create([
{
"ref": "test_invoice_007: Invoice to gritti support service, vat 21",
"company_id": branch_A.id,
"partner_id": self.res_partner_gritti_mono.id,
"move_type": "out_invoice",
"invoice_date": "2021-03-22",
"invoice_line_ids": [
Command.create({'product_id': self.service_iva_21.id})
]
}
])
invoice_B.action_post()
invoice_A.action_post()
options = self._generate_options(
self.report.with_context({"allowed_company_ids": (parent_company | branch_A | branch_B).ids})
.with_company(company=branch_A),
fields.Date.from_string('2021-03-22'),
fields.Date.from_string('2021-05-31'))
options['ar_vat_book_tax_types_available']['sale']['selected'] = True
options['ar_vat_book_tax_types_available']['purchase']['selected'] = False
options['txt_type'] = 'sale'
out_txt = self.env['l10n_ar.tax.report.handler']\
.with_context({"allowed_company_ids": (parent_company | branch_A | branch_B).ids})\
.with_company(company=branch_A)\
._vat_book_get_txt_files(options, 'sale')[0].decode('ISO-8859-1')
res_file = file_open('l10n_ar_reports/tests/Ventas_branch.txt', 'rb').read().decode('ISO-8859-1')
self.assertEqual(out_txt, res_file)
def test_vat_book_report(self):
options = self._generate_options(self.report, date_from=fields.Date.from_string('2022-03-01'), date_to=fields.Date.from_string('2022-03-31'))
lines = self.report._get_lines(options)
self.assertLinesValues(
# pylint: disable=C0326
lines,
# Move Name Partner Name VAT Taxed VAT 21% Total
[ 0, 2, 4, 5, 8, 15],
[
('DI 0001-00000001000', 'BEST PARTNER', '30714295698', -1000, -210, -1210),
('DI 0001-00000002000', 'BEST PARTNER', '30714295698', -500, -105, -605),
('DI 0001-00000003000', 'BEST PARTNER', '30714295698', -800, -168, -968),
],
options,
)
def test_vat_book_report_price_tax_included_plus_IIBB_taxes(self):
purchase_journal = self.env["account.journal"].search([('type', '=', 'purchase'), ('company_id', '=', self.env.company.id)])
self.tax_21.price_include = True
self.tax_21.include_base_amount = True
iibb_group = self.env['account.tax.group'].create({
'name': "IIBB Group",
'l10n_ar_tribute_afip_code': '07',
})
iibb_tax_1 = self.env['account.tax'].create({
'name': "IIBB Córdoba",
'amount_type': 'percent',
'amount': 1,
'tax_group_id': iibb_group.id,
})
iibb_tax_2 = self.env['account.tax'].create({
'name': "IIBB Buenos Aires",
'amount_type': 'percent',
'amount': 1,
'tax_group_id': iibb_group.id,
})
test_product = self.env['product.product'].create({
'name': "Test Product",
'lst_price': 100.0,
'standard_price': 10.0,
'property_account_income_id': self.company_data["default_account_revenue"].id,
'property_account_expense_id': self.company_data["default_account_expense"].id,
})
invoices = self.env['account.move'].create([
{
'move_type': 'in_invoice',
'partner_id': self.res_partner_adhoc.id,
'invoice_date': '2025-05-30',
"journal_id": purchase_journal.id,
"l10n_latam_document_number": "0001-00000001",
'invoice_line_ids': [
Command.create({
'product_id': test_product.id,
'price_unit': 1210.0,
'tax_ids': [Command.set([self.tax_21.id, iibb_tax_1.id, iibb_tax_2.id])],
})],
},
])
invoices.action_post()
options = self._generate_options(self.report, date_from=fields.Date.from_string('2025-05-29'), date_to=fields.Date.from_string('2025-05-31'))
lines = self.report._get_lines(options)
self.assertLinesValues(
# pylint: disable=C0326
lines,
# Move Name Partner Name VAT Taxed VAT 21% Others Total
[ 0, 2, 4, 5, 8, 11, 15],
[
('FA-A 00001-00000001', 'ADHOC SA', '30714295698', -1000, -210, -24.20, -1234.20),
],
options,
)
def test_foreign_provider_vat_book_export(self):
""" Test that Proveedor del Exterior (code 8) partners with ForeignID
use the country-level VAT, just like Cliente del Exterior (code 9).
"""
foreign_partner = self.env['res.partner'].create({
'name': 'foreign partner',
'is_company': True,
'country_id': self.env.ref('base.ie').id,
'l10n_latam_identification_type_id': self.env.ref('l10n_latam_base.it_fid').id,
'vat': 'IE1234567T',
'l10n_ar_afip_responsibility_type_id': self.env.ref('l10n_ar.res_EXT_Prov').id,
})
invoice = self.env['account.move'].create({
'move_type': 'out_invoice',
'partner_id': foreign_partner.id,
'invoice_date': '2021-03-15',
'invoice_line_ids': [
Command.create({
'product_id': self.product_iva_exento.id,
'price_unit': 100.0,
'quantity': 1,
}),
],
})
invoice.action_post()
self.options['ar_vat_book_tax_type_selected'] = 'sale'
self.options['txt_type'] = 'sale'
out = self.env['l10n_ar.tax.report.handler']._vat_book_get_txt_files(self.options, 'sale')
self.assertTrue(out)