Passed
Push — main ( 97b175...ba1019 )
by Sat CFDI
05:01
created

test_create_cfdi33.test_nomina()   B

Complexity

Conditions 1

Size

Total Lines 97
Code Lines 71

Duplication

Lines 97
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
eloc 71
nop 0
dl 97
loc 97
rs 7.949
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
import os
2
from datetime import datetime, date
3
from decimal import Decimal
4
from unittest import mock
5
6
import pytest
7
8
from satcfdi.cfdi import CFDI
9
from satcfdi.create.cfd import cfdi33, nomina12
10
from satcfdi.pacs.sat import SAT
11
from tests.utils import get_signer, verify_result, _uuid, stamp_v11, SAT_Certificate_Store_Pruebas, XElementPrettyPrinter
12
13
module = 'satcfdi'
14
current_dir = os.path.dirname(__file__)
15
current_filename = os.path.splitext(os.path.basename(__file__))[0]
16
sat = SAT()
17
18
invoices = [
19
    ('xiqb891116qe4', "xiqb891116qe4_ingreso_noobjeto", None, [cfdi33.Impuesto.parse('001|Tasa|0.100000')], '13851.27', False),
20
    # ('xiqb891116qe4', "xiqb891116qe4_ingreso_exento", cfdi33.Traslado.IVA_EXENTO, [cfdi33.Retencion.ISR10], '13851.27', False),
21
    ('xiqb891116qe4', "xiqb891116qe4_ingreso_iva16", cfdi33.Impuesto.parse('002|Tasa|0.160000'), [cfdi33.Impuesto.parse('001|Tasa|0.100000'), cfdi33.Impuesto.parse('002|Tasa|0.106667')], '14672.08', False),
22
    ('h&e951128469', "h&e951128469_ingreso_noobjeto", None, None, '15390.30', False),
23
    # ('h&e951128469', "h&e951128469_ingreso_exento", cfdi33.Traslado.IVA_EXENTO, None, '15390.30', False),
24
    ('h&e951128469', "h&e951128469_ingreso_iva16", cfdi33.Impuesto.parse('002|Tasa|0.160000'), None, '17852.75', False),
25
    # ('h&e951128469', "h&e951128469_ingreso_ieps_exento", cfdi33.Traslado.IEPS_EXENTO, None, '15390.30', False)
26
]
27
28
29
def verify_invoice(invoice, path):
30
    pp = XElementPrettyPrinter()
31
    verify = verify_result(data=pp.pformat(invoice), filename=f"{path}.pretty.py")
32
    assert verify
33
34
    verify = verify_result(data=invoice.xml_bytes(pretty_print=True), filename=f"{path}.xml")
35
    assert verify
36
37
    verify = verify_result(data=invoice.html_str(), filename=f"{path}.html")
38
    assert verify
39
40
41
@pytest.mark.parametrize('rfc, xml_file, traslados, retenciones, total, traslado_incluido', invoices)
42
def test_create_invoice(rfc, xml_file, traslados, retenciones, total, traslado_incluido):
43
    signer = get_signer(rfc)
44
    emisor = cfdi33.Issuer(signer=signer, tax_system="606")
45
46
    invoice = cfdi33.Comprobante(
47
        emisor=emisor,
48
        lugar_expedicion="56820",
49
        fecha=datetime.fromisoformat("2020-01-01T22:40:38"),
50
        receptor=cfdi33.Receptor(
51
            rfc='KIJ0906199R1',
52
            nombre='KIJ, S.A DE C.V.',
53
            uso_cfdi='G03'
54
        ),
55
        metodo_pago='PPD',
56
        serie="A",
57
        folio="123456",
58
        conceptos=[
59
            cfdi33.Concepto(
60
                cuenta_predial='1234567890',
61
                clave_prod_serv='10101702',
62
                cantidad=Decimal('1.00'),
63
                clave_unidad='E48',
64
                descripcion='SERVICIOS DE FACTURACION',
65
                valor_unitario=Decimal('15390.30'),
66
                traslados=traslados,
67
                retenciones=retenciones
68
            )
69
        ]
70
    )
71
    invoice.to_xml(validate=True)
72
    assert invoice["Total"] == Decimal(total)
73
74
    verify_invoice(invoice, f"{xml_file}")
75
76
    # Stamping
77
    with mock.patch('uuid.uuid4', _uuid), \
78
            mock.patch(f'{module}.Certificate.rfc_pac', "SAT970701NN3"):
79
        stamp_v11(invoice, signer=signer, date=datetime(year=2020, month=1, day=11))
80
81
    verify_invoice(invoice, f"{xml_file}_stamped")
82
83
    def from_no_certificado(_, no_certificado):
84
        return signer
85
86
    # Verify Signature
87
    with mock.patch(f'{module}.transform.SAT_Certificate_Store', SAT_Certificate_Store_Pruebas), \
88
            mock.patch(f'{module}.pacs.sat.SAT.recover_certificate', from_no_certificado), \
89
            mock.patch(f'{module}.Certificate.rfc_pac', "SAT970701NN3"):
90
        ver = sat.validate(invoice)
91
        assert ver
92
93
94
@pytest.mark.parametrize('rfc, xml_file, traslados, retenciones, total, traslado_incluido', invoices)
95
def test_create_pago(rfc, xml_file, traslados, retenciones, total, traslado_incluido):
96
    signer = get_signer(rfc)
97
    emisor = cfdi33.Issuer(signer=signer, tax_system="606")
98
99
    ingreso_invoice = CFDI.from_file(os.path.join(current_dir, f"{current_filename}/{xml_file}_stamped.xml"))
100
101
    invoice = cfdi33.Comprobante.pago_comprobantes(
102
        emisor=emisor,
103
        lugar_expedicion="56820",
104
        fecha=datetime.fromisoformat("2020-01-01T22:40:38"),
105
        comprobantes=[ingreso_invoice],
106
        fecha_pago=datetime.fromisoformat("2020-01-02T22:40:38"),
107
        forma_pago="03",
108
        serie="A",
109
        folio="123456",
110
    )
111
112
    assert invoice['Complemento']['Pago'][0]['Monto'] == Decimal(total)
113
114
    verify_invoice(invoice, f"pago_{xml_file}")
115
116
117
@pytest.mark.parametrize('rfc, xml_file, traslados, retenciones, total, traslado_incluido', invoices)
118
def test_create_pago_parcial(rfc, xml_file, traslados, retenciones, total, traslado_incluido):
119
    signer = get_signer(rfc)
120
    emisor = cfdi33.Issuer(signer=signer, tax_system="606")
121
122
    ingreso_invoice = CFDI.from_file(os.path.join(current_dir, f"{current_filename}/{xml_file}_stamped.xml"))
123
124
    invoice = cfdi33.Comprobante.pago_comprobante(
125
        emisor=emisor,
126
        lugar_expedicion="56820",
127
        fecha=datetime.fromisoformat("2020-01-01T22:40:38"),
128
        comprobante=ingreso_invoice,
129
        num_parcialidad=2,
130
        imp_saldo_ant=Decimal("5000.43"),
131
        imp_pagado=Decimal("3245.12"),
132
        fecha_pago=datetime.fromisoformat("2020-01-02T22:40:38"),
133
        forma_pago="03",
134
        serie="A",
135
        folio="123456",
136
    )
137
138
    assert invoice['Complemento']['Pago'][0]['Monto'] == Decimal("3245.12")
139
140
    verify_invoice(invoice, f"pago_p_{xml_file}")
141
142
143
@pytest.mark.parametrize('rfc, xml_file, traslados, retenciones, total, traslado_incluido', invoices)
144
def test_create_pago_multiple(rfc, xml_file, traslados, retenciones, total, traslado_incluido):
145
    signer = get_signer(rfc)
146
    emisor = cfdi33.Issuer(signer=signer, tax_system="606")
147
148
    ingreso_invoice = CFDI.from_file(os.path.join(current_dir, f"{current_filename}/{xml_file}_stamped.xml"))
149
150
    invoice = cfdi33.Comprobante.pago_comprobantes(
151
        emisor=emisor,
152
        lugar_expedicion="56820",
153
        fecha=datetime.fromisoformat("2020-01-01T22:40:38"),
154
        comprobantes=[ingreso_invoice, ingreso_invoice],
155
        fecha_pago=datetime.fromisoformat("2020-01-02T22:40:38"),
156
        forma_pago="03",
157
        serie="A",
158
        folio="123456",
159
    )
160
161
    assert invoice['Complemento']['Pago'][0]['Monto'] == Decimal(total) * 2
162
163
    verify_invoice(invoice, f"mpago_{xml_file}")
164
165
166
def test_nomina():
167
    xml_file = "invoice_nomina"
168
169
    signer = get_signer('xiqb891116qe4')
170
    emisor = cfdi33.Issuer(signer=signer, tax_system="606")
171
172
    invoice = cfdi33.Comprobante.nomina(
173
        emisor=emisor,
174
        receptor=cfdi33.Receptor(
175
            rfc='KIJ0906199R1',
176
            nombre='KIJ, S.A DE C.V.',
177
            uso_cfdi='G03',
178
        ),
179
        lugar_expedicion="56820",
180
        complemento_nomina=nomina12.Nomina(
181
            emisor={
182
                'RegistroPatronal': 'Z1234567890'
183
            },
184
            receptor={
185
                'Curp': 'XIQB891116MCHZRL72',
186
                'NumSeguridadSocial': '987654321',
187
                'FechaInicioRelLaboral': date(2020, 1, 1),
188
                'Antigüedad': 'P96W',
189
                'TipoContrato': '01',
190
                'Sindicalizado': 'No',
191
                'TipoJornada': '01',
192
                'TipoRegimen': '02',
193
                'NumEmpleado': '12345678',
194
                'Departamento': 'Departamento del Trabajo',
195
                'Puesto': 'Trabajador',
196
                'RiesgoPuesto': '2',
197
                'PeriodicidadPago': '04',
198
                'CuentaBancaria': '0001000200030004',
199
                'SalarioDiarioIntegrado': Decimal('100.01'),
200
                'ClaveEntFed': 'MOR'
201
            },
202
            percepciones={
203
                'Percepcion': [
204
                    {
205
                        'TipoPercepcion': '001',
206
                        'Clave': '001',
207
                        'Concepto': 'SUELDO',
208
                        'ImporteGravado': Decimal('1200'),
209
                        'ImporteExento': Decimal('400')
210
                    }
211
                ]
212
            },
213
            deducciones={
214
                'Deduccion': [
215
                    {
216
                        'TipoDeduccion': '002',
217
                        'Clave': '300',
218
                        'Concepto': 'ISR A CARGO',
219
                        'Importe': Decimal('1234.73')
220
                    },
221
                    {
222
                        'TipoDeduccion': '004',
223
                        'Clave': '204',
224
                        'Concepto': 'FONDO DE AHORRO EMPLEADOS',
225
                        'Importe': Decimal('521.10')
226
                    },
227
                ]
228
            },
229
            otros_pagos=[
230
                {
231
                    'TipoOtroPago': '999',
232
                    'Clave': '046',
233
                    'Concepto': 'REEMBOLSO DE GASTOS',
234
                    'Importe': Decimal('456')
235
                },
236
                {
237
                    'SubsidioAlEmpleo': Decimal('0'),
238
                    'TipoOtroPago': '002',
239
                    'Clave': '002',
240
                    'Concepto': 'SUBSIDIO EMPLEO',
241
                    'Importe': Decimal('0')
242
                }
243
            ],
244
            incapacidades=[
245
                {
246
                    "DiasIncapacidad": 2,
247
                    'TipoIncapacidad': '02',
248
                    'ImporteMonetario': Decimal(1000),
249
                }
250
            ],
251
            tipo_nomina='O',
252
            fecha_pago=date(2020, 1, 30),
253
            fecha_final_pago=date(2020, 1, 31),
254
            fecha_inicial_pago=date(2020, 1, 16),
255
            num_dias_pagados=Decimal('16.000')
256
        ),
257
        serie="A",
258
        folio="123456",
259
        fecha=datetime.fromisoformat("2020-09-29T22:40:38")
260
    )
261
262
    verify_invoice(invoice, f"{xml_file}")
263