Files
tradon/modules/account_es_sii/tests/test_module.py
2026-03-14 09:42:12 +00:00

586 lines
23 KiB
Python

# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import datetime
from decimal import Decimal
from trytond.modules.account.tests import create_chart, get_fiscalyear
from trytond.modules.account_invoice.tests import set_invoice_sequences
from trytond.modules.company.tests import create_company, set_company
from trytond.modules.currency.tests import add_currency_rate, create_currency
from trytond.pool import Pool
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
today = datetime.date.today()
def create_party(name, identifier_type, identifier_code):
pool = Pool()
Party = pool.get('party.party')
party, = Party.create([{
'name': name,
'addresses': [('create', [{}])],
'identifiers':
[('create', [{
'type': identifier_type,
'code': identifier_code,
}])]}])
return party
def create_invoice(type_, company, party, taxes, currency=None, quantity=1):
pool = Pool()
Account = pool.get('account.account')
Journal = pool.get('account.journal')
Invoice = pool.get('account.invoice')
InvoiceSII = pool.get('account.invoice.sii')
if type_ == 'out':
kind = 'revenue'
invoice_account = party.account_receivable_used
else:
kind = 'expense'
invoice_account = party.account_payable_used
journal, = Journal.search([
('type', '=', kind),
], limit=1)
line_account, = Account.search([
('company', '=', company.id),
('type.%s' % kind, '=', True),
], limit=1)
if currency is None:
currency = company.currency
invoice, = Invoice.create([{
'type': type_,
'company': company.id,
'currency': currency.id,
'party': party.id,
'invoice_address': party.addresses[0].id,
'journal': journal.id,
'account': invoice_account.id,
'invoice_date': today,
'lines': [
('create', [{
'company': company.id,
'currency': currency.id,
'account': line_account.id,
'quantity': quantity,
'unit_price': Decimal('50'),
'taxes': [('add', [t.id for t in taxes])],
}]),
],
}])
Invoice.post([invoice])
sii_invoices = InvoiceSII.search([('invoice', '=', invoice.id)])
if sii_invoices:
sii_invoice, = sii_invoices
return sii_invoice
return sii_invoices
class AccountEsSiiTestCase(ModuleTestCase):
"Test Account Es Sii module"
module = 'account_es_sii'
@with_transaction()
def test_party_identifier_sii_values(self):
"Test party identifier sii values"
for type_, code, value in [
('eu_vat', 'ES00000000T', {'NIF': '00000000T'}),
('es_vat', '00000000T', {'NIF': '00000000T'}),
('eu_vat', 'BE0897290877', {
'IDOtro': {
'ID': 'BE0897290877',
'IDType': '02',
'CodigoPais': 'BE',
},
}),
('eu_vat', 'EL094259216', {
'IDOtro': {
'ID': 'GR094259216',
'IDType': '02',
'CodigoPais': 'GR',
}
}),
('ad_vat', 'L709604E', {
'IDOtro': {
'ID': 'ADL709604E',
'IDType': '06',
'CodigoPais': 'AD',
}
}),
]:
party = create_party('Customer', type_, code)
self.assertDictEqual(party.tax_identifier.es_sii_values(), value)
@with_transaction()
def test_fiscalyear_sii_send_invoices(self):
"Test Fiscalyear SII send invoices"
pool = Pool()
FiscalYear = pool.get('account.fiscalyear')
company = create_company()
with set_company(company):
create_chart(company, chart='account_es.pgc_0_pyme')
fiscalyear = set_invoice_sequences(get_fiscalyear(company))
fiscalyear.save()
FiscalYear.create_period([fiscalyear])
self.assertFalse(fiscalyear.es_sii_send_invoices)
fiscalyear.es_sii_send_invoices = True
fiscalyear.save()
self.assertTrue(fiscalyear.es_sii_send_invoices)
period = fiscalyear.periods[0]
period.es_sii_send_invoices = False
period.save()
fiscalyear = FiscalYear(fiscalyear.id)
self.assertIsNone(fiscalyear.es_sii_send_invoices)
@with_transaction()
def test_customer_invoice_sii_payload(self):
"Test Customer Invoice SII Payload"
pool = Pool()
FiscalYear = pool.get('account.fiscalyear')
Tax = pool.get('account.tax')
company = create_company()
with set_company(company):
create_chart(company, chart='account_es.pgc_0_pyme')
fiscalyear = set_invoice_sequences(get_fiscalyear(company))
fiscalyear.save()
FiscalYear.create_period([fiscalyear])
fiscalyear.es_sii_send_invoices = True
fiscalyear.save()
fiscalyear.es_sii_send_invoices = True
party = create_party('Customer', 'eu_vat', 'ES00000000T')
tax, = Tax.search([
('company', '=', company.id),
('name', '=', 'IVA 21% (bienes)'),
('group.kind', '=', 'sale'),
])
sii_invoice = create_invoice('out', company, party, [tax])
payload = sii_invoice.get_payload()
self.assertListEqual(
list(payload.keys()),
['PeriodoLiquidacion', 'IDFactura', 'FacturaExpedida'])
self.assertEqual(
payload['FacturaExpedida']['TipoFactura'], 'F1')
self.assertEqual(
payload['FacturaExpedida']['ImporteTotal'], '60.50')
invoice_detail = {
'DesgloseFactura': {
'Sujeta': [{
'NoExenta': {
'TipoNoExenta': 'S1',
'DesgloseIVA': {
'DetalleIVA': [{
'BaseImponible': Decimal('50.00'),
'TipoImpositivo': '21.00',
'CuotaRepercutida': (
Decimal('10.50')),
}],
},
},
}]
},
}
self.assertDictEqual(
payload['FacturaExpedida']['TipoDesglose'], invoice_detail)
@with_transaction()
def test_customer_invoice_excempt_sii_payload(self):
"Test Customer Invoice Excempt SII Payload"
pool = Pool()
FiscalYear = pool.get('account.fiscalyear')
Tax = pool.get('account.tax')
company = create_company()
with set_company(company):
create_chart(company, chart='account_es.pgc_0_pyme')
fiscalyear = set_invoice_sequences(get_fiscalyear(company))
fiscalyear.save()
FiscalYear.create_period([fiscalyear])
fiscalyear.es_sii_send_invoices = True
fiscalyear.save()
party = create_party('Customer', 'es_vat', '00000000T')
tax, = Tax.search([
('company', '=', company.id),
('name', '=', 'IVA Exento (bienes)'),
('group.kind', '=', 'sale'),
])
sii_invoice = create_invoice('out', company, party, [tax])
payload = sii_invoice.get_payload()
invoice_detail = {
'DesgloseFactura': {
'Sujeta': [{
'Exenta': {
'DetalleExenta': {
'CausaExencion': 'E1',
'BaseImponible': Decimal('50.00'),
},
},
}],
},
}
self.assertDictEqual(
payload['FacturaExpedida']['TipoDesglose'], invoice_detail)
@with_transaction()
def test_customer_surcharge_tax_invoice_sii_payload(self):
"Test Customer Surcharge Tax Invoice SII Payload"
pool = Pool()
FiscalYear = pool.get('account.fiscalyear')
Tax = pool.get('account.tax')
company = create_company()
with set_company(company):
create_chart(company, chart='account_es.pgc_0_pyme')
fiscalyear = set_invoice_sequences(get_fiscalyear(company))
fiscalyear.save()
FiscalYear.create_period([fiscalyear])
fiscalyear.es_sii_send_invoices = True
fiscalyear.save()
party = create_party('Customer', 'eu_vat', 'ES00000000T')
tax, = Tax.search([
('company', '=', company.id),
('name', '=', 'Recargo Equivalencia 1.4%'),
('group.kind', '=', 'sale'),
])
sii_invoice = create_invoice(
'out', company, party, [tax.es_reported_with, tax])
payload = sii_invoice.get_payload()
self.assertEqual(
payload['FacturaExpedida']['ImporteTotal'], '55.70')
tax_detail = {
'DetalleIVA': [{
'BaseImponible': Decimal('50.00'),
'TipoImpositivo': '10.00',
'CuotaRepercutida': (
Decimal('5.00')),
'TipoRecargoEquivalencia': '1.4',
'CuotaRecargoEquivalencia': (
Decimal('0.70')),
},
],
}
self.assertDictEqual(
payload['FacturaExpedida']['TipoDesglose']['DesgloseFactura'][
'Sujeta'][0]['NoExenta']['DesgloseIVA'], tax_detail)
@with_transaction()
def test_customer_intracomunitary_invoice_sii_payload(self):
"Test Customer Intracomunitary Invoice Excempt SII Payload"
pool = Pool()
FiscalYear = pool.get('account.fiscalyear')
Tax = pool.get('account.tax')
company = create_company()
with set_company(company):
create_chart(company, chart='account_es.pgc_0_pyme')
fiscalyear = set_invoice_sequences(get_fiscalyear(company))
fiscalyear.save()
FiscalYear.create_period([fiscalyear])
fiscalyear.es_sii_send_invoices = True
fiscalyear.save()
party = create_party('Customer', 'eu_vat', 'BE0897290877')
tax, = Tax.search([
('company', '=', company.id),
('name', '=', 'IVA Intracomunitario (bienes)'),
('group.kind', '=', 'sale'),
])
sii_invoice = create_invoice('out', company, party, [tax])
payload = sii_invoice.get_payload()
invoice_detail = {
'Entrega': {
'Sujeta': [{
'Exenta': {
'DetalleExenta': {
'CausaExencion': 'E5',
'BaseImponible': Decimal('50.00'),
},
},
}],
},
}
self.assertDictEqual(
payload['FacturaExpedida']['TipoDesglose'][
'DesgloseTipoOperacion'], invoice_detail)
@with_transaction()
def test_customer_invoice_alternate_currency_sii_payload(self):
"Test Customer Invoice Alternate Currency SII Payload"
pool = Pool()
FiscalYear = pool.get('account.fiscalyear')
Tax = pool.get('account.tax')
company = create_company()
with set_company(company):
create_chart(company, chart='account_es.pgc_0_pyme')
fiscalyear = set_invoice_sequences(get_fiscalyear(company))
fiscalyear.save()
FiscalYear.create_period([fiscalyear])
fiscalyear.es_sii_send_invoices = True
fiscalyear.save()
currency = create_currency('gbp')
add_currency_rate(currency, 2, fiscalyear.start_date)
party = create_party('Customer', 'eu_vat', 'ES00000000T')
tax, = Tax.search([
('company', '=', company.id),
('name', '=', 'IVA 21% (bienes)'),
('group.kind', '=', 'sale'),
])
sii_invoice = create_invoice(
'out', company, party, [tax], currency=currency)
payload = sii_invoice.get_payload()
self.assertEqual(
payload['FacturaExpedida']['ImporteTotal'], '30.25')
tax_detail = {
'DetalleIVA': [{
'BaseImponible': Decimal('25.00'),
'TipoImpositivo': '21.00',
'CuotaRepercutida': (
Decimal('5.25')),
},
],
}
self.assertDictEqual(
payload['FacturaExpedida']['TipoDesglose']['DesgloseFactura'][
'Sujeta'][0]['NoExenta']['DesgloseIVA'], tax_detail)
@with_transaction()
def test_customer_invoice_multiple_taxes_sii_payload(self):
"Test Customer Invoice Multiple Taxes SII Payload"
pool = Pool()
FiscalYear = pool.get('account.fiscalyear')
Tax = pool.get('account.tax')
company = create_company()
with set_company(company):
create_chart(company, chart='account_es.pgc_0_pyme')
fiscalyear = set_invoice_sequences(get_fiscalyear(company))
fiscalyear.save()
FiscalYear.create_period([fiscalyear])
fiscalyear.es_sii_send_invoices = True
fiscalyear.save()
fiscalyear.es_sii_send_invoices = True
party = create_party('Customer', 'eu_vat', 'ES00000000T')
normal_tax, = Tax.search([
('company', '=', company.id),
('name', '=', 'IVA 21% (bienes)'),
('group.kind', '=', 'sale'),
])
reduced_tax, = Tax.search([
('company', '=', company.id),
('name', '=', 'IVA 10% (bienes)'),
('group.kind', '=', 'sale'),
])
taxes = [normal_tax, reduced_tax]
sii_invoice = create_invoice('out', company, party, taxes)
payload = sii_invoice.get_payload()
self.assertListEqual(
list(payload.keys()),
['PeriodoLiquidacion', 'IDFactura', 'FacturaExpedida'])
self.assertEqual(
payload['FacturaExpedida']['TipoFactura'], 'F1')
self.assertEqual(
payload['FacturaExpedida']['ImporteTotal'], '65.50')
tax_detail = {
'DetalleIVA': [{
'BaseImponible': Decimal('50.00'),
'TipoImpositivo': '10.00',
'CuotaRepercutida': Decimal('5.00'),
}, {
'BaseImponible': Decimal('50.00'),
'TipoImpositivo': '21.00',
'CuotaRepercutida': Decimal('10.50'),
}],
}
self.assertDictEqual(
payload['FacturaExpedida']['TipoDesglose']['DesgloseFactura'][
'Sujeta'][0]['NoExenta']['DesgloseIVA'], tax_detail)
@with_transaction()
def test_customer_credit_note_sii_payload(self):
"Test Customer Credit Note SII Payload"
pool = Pool()
FiscalYear = pool.get('account.fiscalyear')
Tax = pool.get('account.tax')
company = create_company()
with set_company(company):
create_chart(company, chart='account_es.pgc_0_pyme')
fiscalyear = set_invoice_sequences(get_fiscalyear(company))
fiscalyear.save()
FiscalYear.create_period([fiscalyear])
fiscalyear.es_sii_send_invoices = True
fiscalyear.save()
party = create_party('Customer', 'eu_vat', 'ES00000000T')
tax, = Tax.search([
('company', '=', company.id),
('name', '=', 'IVA 21% (bienes)'),
('group.kind', '=', 'sale'),
])
sii_invoice = create_invoice(
'out', company, party, [tax], quantity=-1)
payload = sii_invoice.get_payload()
self.assertEqual(
payload['FacturaExpedida']['ImporteTotal'], '-60.50')
self.assertEqual(
payload['FacturaExpedida']['TipoFactura'], 'R1')
self.assertEqual(
payload['FacturaExpedida']['TipoRectificativa'], 'I')
tax_detail = {
'DetalleIVA': [{
'BaseImponible': Decimal('-50.00'),
'TipoImpositivo': '21.00',
'CuotaRepercutida': (
Decimal('-10.50')),
},
],
}
self.assertDictEqual(
payload['FacturaExpedida']['TipoDesglose']['DesgloseFactura'][
'Sujeta'][0]['NoExenta']['DesgloseIVA'], tax_detail)
@with_transaction()
def test_supplier_invoice_sii_payload(self):
"Test Supplier Invoice SII Payload"
pool = Pool()
FiscalYear = pool.get('account.fiscalyear')
Tax = pool.get('account.tax')
company = create_company()
with set_company(company):
create_chart(company, chart='account_es.pgc_0_pyme')
fiscalyear = set_invoice_sequences(get_fiscalyear(company))
fiscalyear.save()
FiscalYear.create_period([fiscalyear])
fiscalyear.es_sii_send_invoices = True
fiscalyear.save()
party = create_party('Supplier', 'eu_vat', 'ES00000000T')
tax, = Tax.search([
('company', '=', company.id),
('name', '=', 'IVA 10% (bienes)'),
('group.kind', '=', 'purchase'),
])
sii_invoice = create_invoice('in', company, party, [tax])
payload = sii_invoice.get_payload()
self.assertListEqual(
list(payload.keys()),
['PeriodoLiquidacion', 'IDFactura', 'FacturaRecibida'])
self.assertEqual(
payload['FacturaRecibida']['TipoFactura'], 'F1')
self.assertEqual(
payload['FacturaRecibida'][
'ClaveRegimenEspecialOTrascendencia'], '01')
self.assertEqual(
payload['FacturaRecibida']['ImporteTotal'], '55.00')
self.assertEqual(
payload['FacturaRecibida']['CuotaDeducible'], '5.00')
invoice_detail = {
'DesgloseIVA': {
'DetalleIVA': [{
'BaseImponible': Decimal('50.00'),
'TipoImpositivo': '10.00',
'CuotaSoportada': Decimal('5.00')}]}}
self.assertDictEqual(
payload['FacturaRecibida']['DesgloseFactura'], invoice_detail)
@with_transaction()
def test_supplier_intracomunitary_invoice_sii_payload(self):
"Test Supplier Intracomunitary Invoice SII Payload"
pool = Pool()
FiscalYear = pool.get('account.fiscalyear')
Tax = pool.get('account.tax')
company = create_company()
with set_company(company):
create_chart(company, chart='account_es.pgc_0_pyme')
fiscalyear = set_invoice_sequences(get_fiscalyear(company))
fiscalyear.save()
FiscalYear.create_period([fiscalyear])
fiscalyear.es_sii_send_invoices = True
fiscalyear.save()
party = create_party('Supplier', 'eu_vat', 'BE0897290877')
tax, = Tax.search([
('company', '=', company.id),
('name', '=', 'IVA Intracomunitario 21% (bienes)'),
('group.kind', '=', 'purchase'),
])
sii_invoice = create_invoice('in', company, party, [tax])
payload = sii_invoice.get_payload()
self.assertListEqual(
list(payload.keys()),
['PeriodoLiquidacion', 'IDFactura', 'FacturaRecibida'])
self.assertEqual(
payload['FacturaRecibida']['TipoFactura'], 'F1')
self.assertEqual(
payload['FacturaRecibida'][
'ClaveRegimenEspecialOTrascendencia'], '09')
self.assertEqual(
payload['FacturaRecibida']['ImporteTotal'], '60.50')
self.assertEqual(
payload['FacturaRecibida']['CuotaDeducible'], '10.50')
invoice_detail = {
'DesgloseIVA': {
'DetalleIVA': [{
'BaseImponible': Decimal('50.00'),
'TipoImpositivo': '21.00',
'CuotaSoportada': Decimal('10.50')}]}}
self.assertDictEqual(
payload['FacturaRecibida']['DesgloseFactura'], invoice_detail)
@with_transaction()
def test_taxes_excluded_from_sii_taxes(self):
"Test Taxes excluded from SII"
pool = Pool()
FiscalYear = pool.get('account.fiscalyear')
Tax = pool.get('account.tax')
company = create_company()
with set_company(company):
create_chart(company, chart='account_es.pgc_0_pyme')
fiscalyear = set_invoice_sequences(get_fiscalyear(company))
fiscalyear.save()
FiscalYear.create_period([fiscalyear])
fiscalyear.es_sii_send_invoices = True
fiscalyear.save()
party = create_party('Supplier', 'eu_vat', 'BE0897290877')
tax, = Tax.search([
('company', '=', company.id),
('name', '=', 'IVA Importaciones (bienes)'),
('group.kind', '=', 'purchase'),
])
self.assertTrue(tax.es_exclude_from_sii)
sii_invoice = create_invoice('in', company, party, [tax])
self.assertEqual(sii_invoice, [])
del ModuleTestCase