# 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