Passed
Push — main ( 127c9a...7d6ee6 )
by Sat CFDI
02:12
created

satdigitalinvoice.sat_functions.isr_mensual()   A

Complexity

Conditions 3

Size

Total Lines 18
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 16
dl 0
loc 18
rs 9.6
c 0
b 0
f 0
cc 3
nop 2
1
from decimal import Decimal
2
3
from satcfdi.create.cfd.catalogos import Impuesto, TipoFactor, RegimenFiscal
4
from satcfdi.models import DatePeriod, RFC, RFCType
5
from satcfdi.utils import iterate
6
7
8
def isr_mensual(dp: DatePeriod, ingreso):
9
    table_isr_2023 = [
10
        (Decimal('375975.62'), Decimal("117912.32"), Decimal("0.3500")),
11
        (Decimal('125325.21'), Decimal("32691.18"), Decimal("0.3400")),
12
        (Decimal('93993.91'), Decimal("22665.17"), Decimal("0.3200")),
13
        (Decimal('49233.01'), Decimal("9236.89"), Decimal("0.3000")),
14
        (Decimal('31236.50'), Decimal("5004.12"), Decimal("0.2352")),
15
        (Decimal('15487.72'), Decimal("1640.18"), Decimal("0.2136")),
16
        (Decimal('12935.83'), Decimal("1182.88"), Decimal("0.1792")),
17
        (Decimal('11128.02'), Decimal("893.63"), Decimal("0.1600")),
18
        (Decimal('6332.06'), Decimal("371.83"), Decimal("0.1088")),
19
        (Decimal('746.05'), Decimal("14.32"), Decimal("0.0640")),
20
        (Decimal("0.00"), Decimal("0.00"), Decimal("0.0192")),
21
    ]
22
23
    for (limite, cuota_fija, porcentaje) in table_isr_2023:
24
        if ingreso >= limite:
25
            return round((ingreso - limite) * porcentaje + cuota_fija)
26
27
28
def sat_retenciones(concepto, dp: DatePeriod, emisor, receptor):
29
    if 'Retenciones' in concepto['Impuestos']:
30
        return
31
32
    emisor_rfc = RFC(emisor['Rfc'])
33
    receptor_rfc = RFC(receptor['Rfc'])
34
35
    if emisor_rfc.type == RFCType.FISICA and receptor_rfc.type == RFCType.MORAL:
36
        ret_isr = {
37
            'Impuesto': Impuesto.ISR,
38
            'TipoFactor': TipoFactor.TASA,
39
            'TasaOCuota': Decimal('0.100000') if emisor['RegimenFiscal'] != RegimenFiscal.REGIMEN_SIMPLIFICADO_DE_CONFIANZA else Decimal('0.012500')
40
        }
41
42
        if receptor['RegimenFiscal'] == '603':  # Personas morales con fines no lucrativos
43
            concepto['Impuestos']['Retenciones'] = ret_isr  # solo se retiene ISR
44
        else:
45
            traslado = next(i for i in iterate(concepto['Impuestos']['Traslados']) if i['Impuesto'] == Impuesto.IVA)
46
            assert traslado is not None
47
            assert traslado['TipoFactor'] == TipoFactor.TASA
48
49
            concepto['Impuestos']['Retenciones'] = [
50
                ret_isr,
51
                {
52
                    'Impuesto': Impuesto.IVA,
53
                    'TipoFactor': TipoFactor.TASA,
54
                    'TasaOCuota': round(traslado['TasaOCuota'] * 2 / 3, 6)
55
                }
56
            ]
57