Skip to content

Commit 1f49dcd

Browse files
authored
Merge pull request #169 from gisce/imp_retenciones_irpf
Añadir envió de facturas con Retenciones de IRPF
2 parents 0dfc420 + 0f70f5e commit 1f49dcd

File tree

3 files changed

+261
-1
lines changed

3 files changed

+261
-1
lines changed

sii/resource.py

+17-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ def get_iva_values(invoice, in_invoice, is_export=False, is_import=False):
4343
'iva_no_exento': False,
4444
'detalle_iva_exento': {'BaseImponible': 0},
4545
'importe_no_sujeto': 0,
46-
'inversion_sujeto_pasivo': []
46+
'inversion_sujeto_pasivo': [],
47+
'factura_retencion': False
4748
}
4849

4950
# iva_values es un diccionario que agrupa los valores del IVA por el tipo
@@ -67,6 +68,10 @@ def get_iva_values(invoice, in_invoice, is_export=False, is_import=False):
6768
invoice_total = sign * invoice.amount_total
6869

6970
for inv_tax in invoice.tax_line:
71+
if ' IRPF ' in inv_tax.name.upper():
72+
invoice_total -= (inv_tax.tax_amount)
73+
vals['factura_retencion'] = True
74+
continue
7075
if 'iva' in inv_tax.name.lower():
7176
base_iva = inv_tax.base
7277
base_imponible = sign * base_iva
@@ -150,6 +155,15 @@ def get_iva_values(invoice, in_invoice, is_export=False, is_import=False):
150155

151156
return vals
152157

158+
def get_total_factura_retencion(invoice):
159+
total_retencion = Decimal('0.0')
160+
sign = get_invoice_sign(invoice)
161+
for inv_tax in invoice.tax_line:
162+
if 'iva' in inv_tax.name.lower():
163+
total_retencion += inv_tax.base
164+
total_retencion += sign * inv_tax.tax_amount
165+
return total_retencion
166+
153167

154168
def get_partner_info(fiscal_partner, in_invoice, nombre_razon=False):
155169
vat_type = fiscal_partner.sii_get_vat_type()
@@ -564,6 +578,8 @@ def get_factura_recibida(invoice, rect_sust_opc1=False, rect_sust_opc2=False):
564578
# Fecha registro contable: Fecha del envío.
565579
fecha_reg_contable = date.today().strftime('%Y-%m-%d')
566580
cuota_deducible = 0 # Cuota deducible: Etiqueta con 0
581+
if iva_values.get('factura_retencion'):
582+
importe_total = get_total_factura_retencion(invoice)
567583

568584
rectificativa = rect_sust_opc1 or rect_sust_opc2
569585
fiscal_partner = FiscalPartner(invoice)

spec/serialization_spec.py

+118
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,65 @@ def group_by_tax_rate(iva_values, in_invoice):
480480

481481
expect(detalle_inmueble['SituacionInmueble']).to(equal('4'))
482482

483+
with context('en los detalles del IVA con IRPF'):
484+
with before.all:
485+
self.out_invoice_irpf = self.data_gen.get_out_invoice_with_irfp()
486+
487+
self.out_invoice_obj = SII(self.out_invoice_irpf).generate_object()
488+
self.factura_emitida = (
489+
self.out_invoice_obj['SuministroLRFacturasEmitidas']['RegistroLRFacturasEmitidas']
490+
)
491+
self.detalle_iva_irpf_list = get_iva_values(self.out_invoice_irpf, in_invoice=False)
492+
self.detalle_iva_desglose_irpf = (
493+
self.factura_emitida['FacturaExpedida']['TipoDesglose']
494+
['DesgloseFactura']['Sujeta']['NoExenta']['DesgloseIVA']
495+
['DetalleIVA'][0]
496+
)
497+
498+
with context('debe contener'):
499+
with it('solo la parte del IVA'):
500+
tax_line_iva = None
501+
for x in self.out_invoice_irpf.tax_line:
502+
if 'IVA' in x.name.upper():
503+
tax_line_iva = x
504+
expect(
505+
self.detalle_iva_desglose_irpf['BaseImponible']
506+
).to(equal(
507+
tax_line_iva.base
508+
))
509+
expect(
510+
Decimal('2400')
511+
).to(
512+
equal(
513+
self.detalle_iva_desglose_irpf['BaseImponible']
514+
)
515+
)
516+
expect(
517+
Decimal('504')
518+
).to(
519+
equal(
520+
self.detalle_iva_desglose_irpf['CuotaRepercutida']
521+
522+
)
523+
)
524+
expect(
525+
self.detalle_iva_desglose_irpf['CuotaRepercutida']
526+
).to(equal(
527+
tax_line_iva.tax_amount
528+
))
529+
expect(
530+
Decimal('21.0')
531+
).to(
532+
equal(
533+
self.detalle_iva_desglose_irpf['TipoImpositivo']
534+
)
535+
)
536+
expect(
537+
self.detalle_iva_desglose_irpf['TipoImpositivo']
538+
).to(equal(
539+
tax_line_iva.tax_id.amount * 100
540+
))
541+
483542
with description('en los datos de una factura recibida'):
484543
with before.all:
485544
self.in_invoice = self.data_gen.get_in_invoice()
@@ -668,6 +727,65 @@ def group_by_tax_rate(iva_values, in_invoice):
668727
)
669728
)
670729

730+
with context('en los detalles del IVA con IRPF'):
731+
with before.all:
732+
self.in_invoice_irpf = self.data_gen.get_in_invoice_with_irfp()
733+
734+
self.in_invoice_obj = SII(self.in_invoice_irpf).generate_object()
735+
self.factura_recibida = (
736+
self.in_invoice_obj['SuministroLRFacturasRecibidas']
737+
['RegistroLRFacturasRecibidas']
738+
)
739+
self.detalle_iva_irpf_list = get_iva_values(self.in_invoice_irpf, in_invoice=True)
740+
self.detalle_iva_desglose_irpf = (
741+
self.factura_recibida['FacturaRecibida']['DesgloseFactura']
742+
['DesgloseIVA']['DetalleIVA'][0]
743+
)
744+
745+
with context('debe contener'):
746+
with it('solo la parte del IVA'):
747+
tax_line_iva = None
748+
for x in self.in_invoice_irpf.tax_line:
749+
if 'IVA' in x.name.upper():
750+
tax_line_iva = x
751+
expect(
752+
self.detalle_iva_desglose_irpf['BaseImponible']
753+
).to(equal(
754+
tax_line_iva.base
755+
))
756+
expect(
757+
Decimal('2400')
758+
).to(
759+
equal(
760+
self.detalle_iva_desglose_irpf['BaseImponible']
761+
)
762+
)
763+
expect(
764+
Decimal('504')
765+
).to(
766+
equal(
767+
self.detalle_iva_desglose_irpf['CuotaSoportada']
768+
769+
)
770+
)
771+
expect(
772+
self.detalle_iva_desglose_irpf['CuotaSoportada']
773+
).to(equal(
774+
tax_line_iva.tax_amount
775+
))
776+
expect(
777+
Decimal('21.0')
778+
).to(
779+
equal(
780+
self.detalle_iva_desglose_irpf['TipoImpositivo']
781+
)
782+
)
783+
expect(
784+
self.detalle_iva_desglose_irpf['TipoImpositivo']
785+
).to(equal(
786+
tax_line_iva.tax_id.amount * 100
787+
))
788+
671789
with context('si es una importación'):
672790
with before.all:
673791
# Clave Régimen Especial importación: '13'

spec/testing_data.py

+126
Original file line numberDiff line numberDiff line change
@@ -1028,3 +1028,129 @@ def get_out_invoice_rescision(self):
10281028
sii_out_clave_regimen_especial=self.sii_out_clave_regimen_especial,
10291029
)
10301030
return invoice
1031+
1032+
def get_out_invoice_with_irfp(self):
1033+
journal = Journal(
1034+
name=u'Factura de Energía Recibida'
1035+
)
1036+
1037+
tax_iva_irpf_19 = Tax(
1038+
name='Retenciones IRPF 19%',
1039+
amount=-0.19, type='percent'
1040+
)
1041+
tax_iva_soportado_21 = Tax(
1042+
name='21% IVA repercutido',
1043+
amount=0.21, type='percent'
1044+
)
1045+
invoice_line = [
1046+
InvoiceLine(
1047+
price_subtotal=2400.0,
1048+
invoice_line_tax_id=[tax_iva_irpf_19, tax_iva_soportado_21])
1049+
]
1050+
base_iva_irfp = sum(
1051+
[line.price_subtotal
1052+
for line in invoice_line]
1053+
)
1054+
invoice_tax_iva_isp_soportado_21 = InvoiceTax(
1055+
name=tax_iva_soportado_21.name, base=base_iva_irfp,
1056+
tax_amount=504.0,
1057+
tax_id=tax_iva_soportado_21
1058+
)
1059+
tax_iva_irpf_19 = InvoiceTax(
1060+
name=tax_iva_irpf_19.name, base=base_iva_irfp,
1061+
tax_amount=-456.0,
1062+
tax_id=tax_iva_irpf_19
1063+
)
1064+
tax_line_inversion_sujeto_pasivo = [
1065+
tax_iva_irpf_19, invoice_tax_iva_isp_soportado_21
1066+
]
1067+
tax_lines = tax_line_inversion_sujeto_pasivo
1068+
invoice_lines = invoice_line
1069+
1070+
invoice = Invoice(
1071+
invoice_type='out_invoice',
1072+
journal_id=journal,
1073+
rectificative_type='N',
1074+
rectifying_id=False,
1075+
number='FEmit{}'.format(self.invoice_number),
1076+
partner_id=self.partner_invoice,
1077+
fiscal_name=self.fiscal_name,
1078+
fiscal_vat=self.fiscal_vat,
1079+
address_contact_id=self.address_contact_id,
1080+
company_id=self.company,
1081+
amount_total=self.amount_total,
1082+
amount_untaxed=self.amount_untaxed,
1083+
amount_tax=self.amount_tax,
1084+
period_id=self.period,
1085+
date_invoice=self.date_invoice,
1086+
tax_line=tax_lines,
1087+
invoice_line=invoice_lines,
1088+
sii_registered=self.sii_registered,
1089+
fiscal_position=self.fiscal_position,
1090+
sii_description=self.sii_description,
1091+
sii_out_clave_regimen_especial=self.sii_out_clave_regimen_especial,
1092+
)
1093+
return invoice
1094+
1095+
def get_in_invoice_with_irfp(self):
1096+
journal = Journal(
1097+
name=u'Factura de Energía Emitida'
1098+
)
1099+
1100+
tax_iva_irpf_19 = Tax(
1101+
name='Retenciones IRPF 19%',
1102+
amount=-0.19, type='percent'
1103+
)
1104+
tax_iva_soportado_21 = Tax(
1105+
name='21% IVA Soportado (operaciones corrientes)',
1106+
amount=0.21, type='percent'
1107+
)
1108+
invoice_line = [
1109+
InvoiceLine(
1110+
price_subtotal=2400.0,
1111+
invoice_line_tax_id=[tax_iva_irpf_19, tax_iva_soportado_21])
1112+
]
1113+
base_iva_irfp = sum(
1114+
[line.price_subtotal
1115+
for line in invoice_line]
1116+
)
1117+
invoice_tax_iva_isp_soportado_21 = InvoiceTax(
1118+
name=tax_iva_soportado_21.name, base=base_iva_irfp,
1119+
tax_amount=504.0,
1120+
tax_id=tax_iva_soportado_21
1121+
)
1122+
tax_iva_irpf_19 = InvoiceTax(
1123+
name=tax_iva_irpf_19.name, base=base_iva_irfp,
1124+
tax_amount=-456.0,
1125+
tax_id=tax_iva_irpf_19
1126+
)
1127+
tax_line_inversion_sujeto_pasivo = [
1128+
tax_iva_irpf_19, invoice_tax_iva_isp_soportado_21
1129+
]
1130+
tax_lines = tax_line_inversion_sujeto_pasivo
1131+
invoice_lines = invoice_line
1132+
1133+
invoice = Invoice(
1134+
invoice_type='in_invoice',
1135+
journal_id=journal,
1136+
rectificative_type='N',
1137+
rectifying_id=False,
1138+
number='FRecib{}'.format(self.invoice_number),
1139+
origin='FRecibOrigen{}'.format(self.invoice_number),
1140+
partner_id=self.partner_invoice,
1141+
address_contact_id=self.address_contact_id,
1142+
company_id=self.company,
1143+
amount_total=self.amount_total,
1144+
amount_untaxed=self.amount_untaxed,
1145+
amount_tax=self.amount_tax,
1146+
period_id=self.period,
1147+
origin_date_invoice=self.origin_date_invoice,
1148+
date_invoice=self.date_invoice,
1149+
tax_line=tax_lines,
1150+
invoice_line=invoice_lines,
1151+
sii_registered=self.sii_registered,
1152+
fiscal_position=self.fiscal_position,
1153+
sii_description=self.sii_description,
1154+
sii_in_clave_regimen_especial=self.sii_in_clave_regimen_especial,
1155+
)
1156+
return invoice

0 commit comments

Comments
 (0)