satdigitalinvoice.sat_functions   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 83
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 10
eloc 63
dl 0
loc 83
rs 10
c 0
b 0
f 0

2 Functions

Rating   Name   Duplication   Size   Complexity  
B sat_retenciones() 0 27 6
A isr_mensual() 0 10 4
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
ISR_MENSUAL_2023 = [  # limite, cuota_fija, porcentaje
8
    (Decimal('375975.62'), Decimal("117912.32"), Decimal("0.3500")),
9
    (Decimal('125325.21'), Decimal("32691.18"), Decimal("0.3400")),
10
    (Decimal('93993.91'), Decimal("22665.17"), Decimal("0.3200")),
11
    (Decimal('49233.01'), Decimal("9236.89"), Decimal("0.3000")),
12
    (Decimal('31236.50'), Decimal("5004.12"), Decimal("0.2352")),
13
    (Decimal('15487.72'), Decimal("1640.18"), Decimal("0.2136")),
14
    (Decimal('12935.83'), Decimal("1182.88"), Decimal("0.1792")),
15
    (Decimal('11128.02'), Decimal("893.63"), Decimal("0.1600")),
16
    (Decimal('6332.06'), Decimal("371.83"), Decimal("0.1088")),
17
    (Decimal('746.05'), Decimal("14.32"), Decimal("0.0640")),
18
    (Decimal("0.00"), Decimal("0.00"), Decimal("0.0192")),
19
]
20
21
ISR_ANUAL_2023 = [  # limite, cuota_fija, porcentaje
22
    (Decimal('4511707.38'), Decimal("1414947.85"), Decimal("0.3500")),
23
    (Decimal('1503902.47'), Decimal("392294.17"), Decimal("0.3400")),
24
    (Decimal('1127926.85'), Decimal("271981.99"), Decimal("0.3200")),
25
    (Decimal('590796.00'), Decimal("110842.74"), Decimal("0.3000")),
26
    (Decimal('374837.89'), Decimal("60049.40"), Decimal("0.2352")),
27
    (Decimal('185852.58'), Decimal("19682.13"), Decimal("0.2136")),
28
    (Decimal('155229.81'), Decimal("14194.54"), Decimal("0.1792")),
29
    (Decimal('133536.08'), Decimal("10723.55"), Decimal("0.1600")),
30
    (Decimal('75984.56'), Decimal("4461.94"), Decimal("0.1088")),
31
    (Decimal('8952.50'), Decimal("171.88"), Decimal("0.0640")),
32
    (Decimal("0.00"), Decimal("0.00"), Decimal("0.0192")),
33
]
34
35
ISR_MENSUAL_RESICO_2023 = [
36
    (Decimal("208333.34"), None, Decimal("0.0250")),
37
    (Decimal("83333.34"), None, Decimal("0.0200")),
38
    (Decimal("50000.01"), None, Decimal("0.0150")),
39
    (Decimal("25000.01"), None, Decimal("0.0110")),
40
    (Decimal("0.00"), None, Decimal("0.0100")),
41
]
42
43
44
def isr_mensual(dp: DatePeriod, ingreso):
45
    if dp.month is None:
46
        isr_table = ISR_ANUAL_2023
47
    else:
48
        isr_table = ISR_MENSUAL_2023
49
50
    for (limite, cuota_fija, porcentaje) in isr_table:
51
        if ingreso >= limite:
52
            return round((ingreso - limite) * porcentaje + cuota_fija)
53
    return Decimal("0.00")
54
55
56
def sat_retenciones(concepto, emisor, receptor):
57
    if 'Retenciones' in concepto['Impuestos']:
58
        return
59
60
    emisor_rfc = RFC(emisor['Rfc'])
61
    receptor_rfc = RFC(receptor['Rfc'])
62
63
    if emisor_rfc.type == RFCType.FISICA and receptor_rfc.type == RFCType.MORAL:
64
        ret_isr = {
65
            'Impuesto': Impuesto.ISR,
66
            'TipoFactor': TipoFactor.TASA,
67
            'TasaOCuota': Decimal('0.100000') if emisor['RegimenFiscal'] != RegimenFiscal.REGIMEN_SIMPLIFICADO_DE_CONFIANZA else Decimal('0.012500')
68
        }
69
70
        if receptor['RegimenFiscal'] == '603':  # Personas morales con fines no lucrativos
71
            concepto['Impuestos']['Retenciones'] = ret_isr  # solo se retiene ISR
72
        else:
73
            traslado = next(i for i in iterate(concepto['Impuestos']['Traslados']) if i['Impuesto'] == Impuesto.IVA)
74
            assert traslado is not None
75
            assert traslado['TipoFactor'] == TipoFactor.TASA
76
77
            concepto['Impuestos']['Retenciones'] = [
78
                ret_isr,
79
                {
80
                    'Impuesto': Impuesto.IVA,
81
                    'TipoFactor': TipoFactor.TASA,
82
                    'TasaOCuota': round(traslado['TasaOCuota'] * 2 / 3, 6)
83
                }
84
            ]
85