diff --git a/modules/account_es_sii/account.py b/modules/account_es_sii/account.py index 5cfa8d6a66..f6e1d6c3c0 100644 --- a/modules/account_es_sii/account.py +++ b/modules/account_es_sii/account.py @@ -486,6 +486,18 @@ class InvoiceSII(ModelSQL, ModelView): ('operation_key', tax.es_sii_operation_key or ''), ('excluded', tax.es_exclude_from_sii), ('product_key', product_type), + ) + + @classmethod + def tax_detail_grouping_key(cls, tax_line): + if not tax_line.tax: + return tuple() + tax = tax_line.tax + if tax.es_reported_with: + tax = tax.es_reported_with + if not tax.es_sii_operation_key: + return tuple() + return ( ('rate', tax.rate * 100), ) @@ -620,18 +632,21 @@ class InvoiceSII(ModelSQL, ModelView): tax_amount = Decimal(0) for tax_key, tax_lines in groupby( tax_lines, key=self.tax_grouping_key): - key = dict(tax_key) - values = self.get_tax_values(key, list(tax_lines)) - if not values: - continue - operation_keys.add(key['operation_key']) - tax_amount += values["Cuota%s" % key['cuota_suffix']] - total_amount += ( - values['BaseImponible'] - + values["Cuota%s" % key['cuota_suffix']]) - if 'CuotaRecargoEquivalencia' in values: - total_amount += values['CuotaRecargoEquivalencia'] - tax_values[tax_key].append(values) + tax_lines = sorted(tax_lines, key=self.tax_detail_grouping_key) + for detail_key, tax_lines in groupby( + tax_lines, key=self.tax_detail_grouping_key): + key = dict(tax_key + detail_key) + values = self.get_tax_values(key, list(tax_lines)) + if not values: + continue + operation_keys.add(key['operation_key']) + tax_amount += values["Cuota%s" % key['cuota_suffix']] + total_amount += ( + values['BaseImponible'] + + values["Cuota%s" % key['cuota_suffix']]) + if 'CuotaRecargoEquivalencia' in values: + total_amount += values['CuotaRecargoEquivalencia'] + tax_values[tax_key].append(values) return self.get_invoice_detail( tax_values, operation_keys, total_amount, tax_amount) diff --git a/modules/account_es_sii/tests/test_module.py b/modules/account_es_sii/tests/test_module.py index 2a56543a8a..cc8268d983 100644 --- a/modules/account_es_sii/tests/test_module.py +++ b/modules/account_es_sii/tests/test_module.py @@ -362,6 +362,58 @@ class AccountEsSiiTestCase(ModuleTestCase): 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') + tax_detail = { + 'DetalleIVA': [{ + 'BaseImponible': Decimal('50.00'), + 'TipoImpositivo': '10.0', + '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"