Passed
Push — main ( c89de9...8b8d32 )
by Sat CFDI
04:44
created

satcfdi.create.cfd.nomina12   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 500
Duplicated Lines 0 %

Test Coverage

Coverage 79.17%

Importance

Changes 0
Metric Value
eloc 256
dl 0
loc 500
ccs 57
cts 72
cp 0.7917
rs 10
c 0
b 0
f 0
wmc 19

16 Methods

Rating   Name   Duplication   Size   Complexity  
A AccionesOTitulos.__init__() 0 8 1
A Deduccion.__init__() 0 12 1
A SubContratacion.__init__() 0 8 1
A Emisor.__init__() 0 12 1
A Percepciones.__init__() 0 10 1
B Receptor.__init__() 0 42 1
A OtroPago.__init__() 0 16 1
A Incapacidad.__init__() 0 10 1
A Percepcion.__init__() 0 18 1
A Deducciones.__init__() 0 6 1
A CompensacionSaldosAFavor.__init__() 0 10 1
A JubilacionPensionRetiro.__init__() 0 14 1
A HorasExtra.__init__() 0 12 1
A EntidadSNCF.__init__() 0 8 1
A SeparacionIndemnizacion.__init__() 0 14 1
B Nomina.__init__() 0 63 4
1
"""nomina12 http://www.sat.gob.mx/nomina12"""
2 1
from collections.abc import *
3 1
from datetime import date
4 1
from decimal import Decimal
5
6 1
from ...cfdi import CFDI
7 1
from ...utils import ScalarMap
8 1
from ...utils import iterate
9
10
11 1
class Incapacidad(ScalarMap):
12
    """
13
    Nodo requerido para expresar información de las incapacidades.
14
15
    :param dias_incapacidad: Atributo requerido para expresar el número de días enteros que el trabajador se incapacitó en el periodo.
16
    :param tipo_incapacidad: Atributo requerido para expresar la razón de la incapacidad.
17
    :param importe_monetario: Atributo condicional para expresar el monto del importe monetario de la incapacidad.
18
    """
19
20 1
    def __init__(
21
            self,
22
            dias_incapacidad: int,
23
            tipo_incapacidad: str,
24
            importe_monetario: Decimal | int = None,
25
    ):
26
        super().__init__({
27
            'DiasIncapacidad': dias_incapacidad,
28
            'TipoIncapacidad': tipo_incapacidad,
29
            'ImporteMonetario': importe_monetario,
30
        })
31
32
33 1
class CompensacionSaldosAFavor(ScalarMap):
34
    """
35
    Nodo condicional para expresar la información referente a la compensación de saldos a favor de un trabajador.
36
37
    :param saldo_a_favor: Atributo requerido para expresar el saldo a favor determinado por el patrón al trabajador en periodos o ejercicios anteriores.
38
    :param ano: Atributo requerido para expresar el año en que se determinó el saldo a favor del trabajador por el patrón que se incluye en el campo “RemanenteSalFav”.
39
    :param remanente_sal_fav: Atributo requerido para expresar el remanente del saldo a favor del trabajador.
40
    """
41
42 1
    def __init__(
43
            self,
44
            saldo_a_favor: Decimal | int,
45
            ano: int,
46
            remanente_sal_fav: Decimal | int,
47
    ):
48
        super().__init__({
49
            'SaldoAFavor': saldo_a_favor,
50
            'Año': ano,
51
            'RemanenteSalFav': remanente_sal_fav,
52
        })
53
54
55 1
class OtroPago(ScalarMap):
56
    """
57
    Nodo requerido para expresar la información detallada del otro pago.
58
59
    :param tipo_otro_pago: Atributo requerido para expresar la clave agrupadora bajo la cual se clasifica el otro pago.
60
    :param clave: Atributo requerido, representa la clave de otro pago de nómina propia de la contabilidad de cada patrón, puede conformarse desde 3 hasta 15 caracteres.
61
    :param concepto: Atributo requerido para la descripción del concepto de otro pago.
62
    :param importe: Atributo requerido para expresar el importe del concepto de otro pago.
63
    :param subsidio_al_empleo: Nodo condicional para expresar la información referente al subsidio al empleo del trabajador.
64
    :param compensacion_saldos_a_favor: Nodo condicional para expresar la información referente a la compensación de saldos a favor de un trabajador.
65
    """
66
67 1
    def __init__(
68
            self,
69
            tipo_otro_pago: str,
70
            clave: str,
71
            concepto: str,
72
            importe: Decimal | int,
73
            subsidio_al_empleo: Decimal | int = None,
74
            compensacion_saldos_a_favor: CompensacionSaldosAFavor | dict = None,
75
    ):
76
        super().__init__({
77
            'TipoOtroPago': tipo_otro_pago,
78
            'Clave': clave,
79
            'Concepto': concepto,
80
            'Importe': importe,
81
            'SubsidioAlEmpleo': subsidio_al_empleo,
82
            'CompensacionSaldosAFavor': compensacion_saldos_a_favor,
83
        })
84
85
86 1
class Deduccion(ScalarMap):
87
    """
88
    Nodo requerido para expresar la información detallada de una deducción.
89
90
    :param tipo_deduccion: Atributo requerido para registrar la clave agrupadora que clasifica la deducción.
91
    :param clave: Atributo requerido para la clave de deducción de nómina propia de la contabilidad de cada patrón, puede conformarse desde 3 hasta 15 caracteres.
92
    :param concepto: Atributo requerido para la descripción del concepto de deducción.
93
    :param importe: Atributo requerido para registrar el importe del concepto de deducción.
94
    """
95
96 1
    def __init__(
97
            self,
98
            tipo_deduccion: str,
99
            clave: str,
100
            concepto: str,
101
            importe: Decimal | int,
102
    ):
103
        super().__init__({
104
            'TipoDeduccion': tipo_deduccion,
105
            'Clave': clave,
106
            'Concepto': concepto,
107
            'Importe': importe,
108
        })
109
110
111 1
class Deducciones(ScalarMap):
112
    """
113
    Nodo opcional para expresar las deducciones aplicables.
114
115
    :param deduccion: Nodo requerido para expresar la información detallada de una deducción.
116
    """
117
118 1
    def __init__(
119
            self,
120
            deduccion: Deduccion | Sequence[Deduccion | dict],
121
    ):
122
        super().__init__({
123
            'Deduccion': deduccion,
124
        })
125
126
127 1
class SeparacionIndemnizacion(ScalarMap):
128
    """
129
    Nodo condicional para expresar la información detallada de otros pagos por separación.
130
131
    :param total_pagado: Atributo requerido que indica el monto total del pago.
132
    :param num_anos_servicio: Atributo requerido para expresar el número de años de servicio del trabajador. Se redondea al entero superior si la cifra contiene años y meses y hay más de 6 meses.
133
    :param ultimo_sueldo_mens_ord: Atributo requerido que indica el último sueldo mensual ordinario.
134
    :param ingreso_acumulable: Atributo requerido para expresar los ingresos acumulables.
135
    :param ingreso_no_acumulable: Atributo requerido que indica los ingresos no acumulables.
136
    """
137
138 1
    def __init__(
139
            self,
140
            total_pagado: Decimal | int,
141
            num_anos_servicio: int,
142
            ultimo_sueldo_mens_ord: Decimal | int,
143
            ingreso_acumulable: Decimal | int,
144
            ingreso_no_acumulable: Decimal | int,
145
    ):
146
        super().__init__({
147
            'TotalPagado': total_pagado,
148
            'NumAñosServicio': num_anos_servicio,
149
            'UltimoSueldoMensOrd': ultimo_sueldo_mens_ord,
150
            'IngresoAcumulable': ingreso_acumulable,
151
            'IngresoNoAcumulable': ingreso_no_acumulable,
152
        })
153
154
155 1
class JubilacionPensionRetiro(ScalarMap):
156
    """
157
    Nodo condicional para expresar la información detallada de pagos por jubilación, pensiones o haberes de retiro.
158
159
    :param ingreso_acumulable: Atributo requerido para expresar los ingresos acumulables.
160
    :param ingreso_no_acumulable: Atributo requerido para expresar los ingresos no acumulables.
161
    :param total_una_exhibicion: Atributo condicional que indica el monto total del pago cuando se realiza en una sola exhibición.
162
    :param total_parcialidad: Atributo condicional para expresar los ingresos totales por pago cuando se hace en parcialidades.
163
    :param monto_diario: Atributo condicional para expresar el monto diario percibido por jubilación, pensiones o haberes de retiro cuando se realiza en parcialidades.
164
    """
165
166 1
    def __init__(
167
            self,
168
            ingreso_acumulable: Decimal | int,
169
            ingreso_no_acumulable: Decimal | int,
170
            total_una_exhibicion: Decimal | int = None,
171
            total_parcialidad: Decimal | int = None,
172
            monto_diario: Decimal | int = None,
173
    ):
174
        super().__init__({
175
            'IngresoAcumulable': ingreso_acumulable,
176
            'IngresoNoAcumulable': ingreso_no_acumulable,
177
            'TotalUnaExhibicion': total_una_exhibicion,
178
            'TotalParcialidad': total_parcialidad,
179
            'MontoDiario': monto_diario,
180
        })
181
182
183 1
class HorasExtra(ScalarMap):
184
    """
185
    Nodo condicional para expresar las horas extra aplicables.
186
187
    :param dias: Atributo requerido para expresar el número de días en que el trabajador realizó horas extra en el periodo.
188
    :param tipo_horas: Atributo requerido para expresar el tipo de pago de las horas extra.
189
    :param horas_extra: Atributo requerido para expresar el número de horas extra trabajadas en el periodo.
190
    :param importe_pagado: Atributo requerido para expresar el importe pagado por las horas extra.
191
    """
192
193 1
    def __init__(
194
            self,
195
            dias: int,
196
            tipo_horas: str,
197
            horas_extra: int,
198
            importe_pagado: Decimal | int,
199
    ):
200
        super().__init__({
201
            'Dias': dias,
202
            'TipoHoras': tipo_horas,
203
            'HorasExtra': horas_extra,
204
            'ImportePagado': importe_pagado,
205
        })
206
207
208 1
class AccionesOTitulos(ScalarMap):
209
    """
210
    Nodo condicional para expresar ingresos por acciones o títulos valor que representan bienes. Se vuelve requerido cuando existan ingresos por sueldos derivados de adquisición de acciones o títulos (Art. 94, fracción VII LISR).
211
212
    :param valor_mercado: Atributo requerido para expresar el valor de mercado de las Acciones o Títulos valor al ejercer la opción.
213
    :param precio_al_otorgarse: Atributo requerido para expresar el precio establecido al otorgarse la opción de ingresos en acciones o títulos valor.
214
    """
215
216 1
    def __init__(
217
            self,
218
            valor_mercado: Decimal | int,
219
            precio_al_otorgarse: Decimal | int,
220
    ):
221
        super().__init__({
222
            'ValorMercado': valor_mercado,
223
            'PrecioAlOtorgarse': precio_al_otorgarse,
224
        })
225
226
227 1
class Percepcion(ScalarMap):
228
    """
229
    Nodo requerido para expresar la información detallada de una percepción
230
231
    :param tipo_percepcion: Atributo requerido para expresar la Clave agrupadora bajo la cual se clasifica la percepción.
232
    :param clave: Atributo requerido para expresar la clave de percepción de nómina propia de la contabilidad de cada patrón, puede conformarse desde 3 hasta 15 caracteres.
233
    :param concepto: Atributo requerido para la descripción del concepto de percepción
234
    :param importe_gravado: Atributo requerido, representa el importe gravado de un concepto de percepción.
235
    :param importe_exento: Atributo requerido, representa el importe exento de un concepto de percepción.
236
    :param acciones_o_titulos: Nodo condicional para expresar ingresos por acciones o títulos valor que representan bienes. Se vuelve requerido cuando existan ingresos por sueldos derivados de adquisición de acciones o títulos (Art. 94, fracción VII LISR).
237
    :param horas_extra: Nodo condicional para expresar las horas extra aplicables.
238
    """
239
240 1
    def __init__(
241
            self,
242
            tipo_percepcion: str,
243
            clave: str,
244
            concepto: str,
245
            importe_gravado: Decimal | int,
246
            importe_exento: Decimal | int,
247
            acciones_o_titulos: AccionesOTitulos | dict = None,
248
            horas_extra: HorasExtra | Sequence[HorasExtra | dict] = None,
249
    ):
250
        super().__init__({
251
            'TipoPercepcion': tipo_percepcion,
252
            'Clave': clave,
253
            'Concepto': concepto,
254
            'ImporteGravado': importe_gravado,
255
            'ImporteExento': importe_exento,
256
            'AccionesOTitulos': acciones_o_titulos,
257
            'HorasExtra': horas_extra,
258
        })
259
260
261 1
class Percepciones(ScalarMap):
262
    """
263
    Nodo condicional para expresar las percepciones aplicables.
264
265
    :param jubilacion_pension_retiro: Nodo condicional para expresar la información detallada de pagos por jubilación, pensiones o haberes de retiro.
266
    :param separacion_indemnizacion: Nodo condicional para expresar la información detallada de otros pagos por separación.
267
    """
268
269 1
    def __init__(
270
            self,
271
            percepcion: Percepcion | Sequence[Percepcion | dict],
272
            jubilacion_pension_retiro: JubilacionPensionRetiro | dict = None,
273
            separacion_indemnizacion: SeparacionIndemnizacion | dict = None,
274
    ):
275
        super().__init__({
276
            'Percepcion': percepcion,
277
            'JubilacionPensionRetiro': jubilacion_pension_retiro,
278
            'SeparacionIndemnizacion': separacion_indemnizacion,
279
        })
280
281
282 1
class EntidadSNCF(ScalarMap):
283
    """
284
    Nodo condicional para que las entidades adheridas al Sistema Nacional de Coordinación Fiscal realicen la identificación del origen de los recursos utilizados en el pago de nómina del personal que presta o desempeña un servicio personal subordinado en las dependencias de la entidad federativa, del municipio o demarcación territorial de la Ciudad de México, así como en sus respectivos organismos autónomos y entidades paraestatales y paramunicipales
285
286
    :param origen_recurso: Atributo requerido para identificar el origen del recurso utilizado para el pago de nómina del personal que presta o desempeña un servicio personal subordinado o asimilado a salarios en las dependencias.
287
    :param monto_recurso_propio: Atributo condicional para expresar el monto del recurso pagado con cargo a sus participaciones u otros ingresos locales (importe bruto de los ingresos propios, es decir total de gravados y exentos), cuando el origen es mixto.
288
    """
289
290 1
    def __init__(
291
            self,
292
            origen_recurso: str,
293
            monto_recurso_propio: Decimal | int = None,
294
    ):
295
        super().__init__({
296
            'OrigenRecurso': origen_recurso,
297
            'MontoRecursoPropio': monto_recurso_propio,
298
        })
299
300
301 1
class Emisor(ScalarMap):
302
    """
303
    Nodo condicional para expresar la información del contribuyente emisor del comprobante de nómina.
304
305
    :param curp: Atributo condicional para expresar la CURP del emisor del comprobante de nómina cuando es una persona física.
306
    :param registro_patronal: Atributo condicional para expresar el registro patronal, clave de ramo - pagaduría o la que le asigne la institución de seguridad social al patrón, a 20 posiciones máximo. Se debe ingresar cuando se cuente con él, o se esté obligado conforme a otras disposiciones distintas a las fiscales.
307
    :param rfc_patron_origen: Atributo opcional para expresar el RFC de la persona que fungió como patrón cuando el pago al trabajador se realice a través de un tercero como vehículo o herramienta de pago.
308
    :param entidad_sncf: Nodo condicional para que las entidades adheridas al Sistema Nacional de Coordinación Fiscal realicen la identificación del origen de los recursos utilizados en el pago de nómina del personal que presta o desempeña un servicio personal subordinado en las dependencias de la entidad federativa, del municipio o demarcación territorial de la Ciudad de México, así como en sus respectivos organismos autónomos y entidades paraestatales y paramunicipales
309
    """
310
311 1
    def __init__(
312
            self,
313
            curp: str = None,
314
            registro_patronal: str = None,
315
            rfc_patron_origen: str = None,
316
            entidad_sncf: EntidadSNCF | dict = None,
317
    ):
318
        super().__init__({
319
            'Curp': curp,
320
            'RegistroPatronal': registro_patronal,
321
            'RfcPatronOrigen': rfc_patron_origen,
322
            'EntidadSNCF': entidad_sncf,
323
        })
324
325
326 1
class SubContratacion(ScalarMap):
327
    """
328
    Nodo condicional para expresar la lista de las personas que los subcontrataron.
329
330
    :param rfc_labora: Atributo requerido para expresar el RFC de la persona que subcontrata.
331
    :param porcentaje_tiempo: Atributo requerido para expresar el porcentaje del tiempo que prestó sus servicios con el RFC que lo subcontrata.
332
    """
333
334 1
    def __init__(
335
            self,
336
            rfc_labora: str,
337
            porcentaje_tiempo: Decimal | int,
338
    ):
339
        super().__init__({
340
            'RfcLabora': rfc_labora,
341
            'PorcentajeTiempo': porcentaje_tiempo,
342
        })
343
344
345 1
class Receptor(ScalarMap):
346
    """
347
    Nodo requerido para precisar la información del contribuyente receptor del comprobante de nómina.
348
349
    :param curp: Atributo requerido para expresar la CURP del receptor del comprobante de nómina.
350
    :param tipo_contrato: Atributo requerido para expresar el tipo de contrato que tiene el trabajador.
351
    :param tipo_regimen: Atributo requerido para la expresión de la clave del régimen por el cual se tiene contratado al trabajador.
352
    :param num_empleado: Atributo requerido para expresar el número de empleado de 1 a 15 posiciones.
353
    :param periodicidad_pago: Atributo requerido para la forma en que se establece el pago del salario.
354
    :param clave_ent_fed: Atributo requerido para expresar la clave de la entidad federativa en donde el receptor del recibo prestó el servicio.
355
    :param num_seguridad_social: Atributo condicional para expresar el número de seguridad social del trabajador. Se debe ingresar cuando se cuente con él, o se esté obligado conforme a otras disposiciones distintas a las fiscales.
356
    :param fecha_inicio_rel_laboral: Atributo condicional para expresar la fecha de inicio de la relación laboral entre el empleador y el empleado. Se expresa en la forma AAAA-MM-DD, de acuerdo con la especificación ISO 8601. Se debe ingresar cuando se cuente con él, o se esté obligado conforme a otras disposiciones distintas a las fiscales.
357
    :param antiguedad: Atributo condicional para expresar el número de semanas o el periodo de años, meses y días que el empleado ha mantenido relación laboral con el empleador. Se debe ingresar cuando se cuente con él, o se esté obligado conforme a otras disposiciones distintas a las fiscales.
358
    :param sindicalizado: Atributo opcional para indicar si el trabajador está asociado a un sindicato. Si se omite se asume que no está asociado a algún sindicato.
359
    :param tipo_jornada: Atributo condicional para expresar el tipo de jornada que cubre el trabajador. Se debe ingresar cuando se esté obligado conforme a otras disposiciones distintas a las fiscales.
360
    :param departamento: Atributo opcional para la expresión del departamento o área a la que pertenece el trabajador.
361
    :param puesto: Atributo opcional para la expresión del puesto asignado al empleado o actividad que realiza.
362
    :param riesgo_puesto: Atributo opcional para expresar la clave conforme a la Clase en que deben inscribirse los patrones, de acuerdo con las actividades que desempeñan sus trabajadores, según lo previsto en el artículo 196 del Reglamento en Materia de Afiliación Clasificación de Empresas, Recaudación y Fiscalización, o conforme con la normatividad del Instituto de Seguridad Social del trabajador.  Se debe ingresar cuando se cuente con él, o se esté obligado conforme a otras disposiciones distintas a las fiscales.
363
    :param banco: Atributo condicional para la expresión de la clave del Banco conforme al catálogo, donde se realiza el depósito de nómina.
364
    :param cuenta_bancaria: Atributo condicional para la expresión de la cuenta bancaria a 11 posiciones o número de teléfono celular a 10 posiciones o número de tarjeta de crédito, débito o servicios a 15 ó 16 posiciones o la CLABE a 18 posiciones o número de monedero electrónico, donde se realiza el depósito de nómina.
365
    :param salario_base_cot_apor: Atributo opcional para expresar la retribución otorgada al trabajador, que se integra por los pagos hechos en efectivo por cuota diaria, gratificaciones, percepciones, alimentación, habitación, primas, comisiones, prestaciones en especie y cualquiera otra cantidad o prestación que se entregue al trabajador por su trabajo, sin considerar los conceptos que se excluyen de conformidad con el Artículo 27 de la Ley del Seguro Social, o la integración de los pagos conforme la normatividad del Instituto de Seguridad Social del trabajador. (Se emplea para pagar las cuotas y aportaciones de Seguridad Social). Se debe ingresar cuando se esté obligado conforme a otras disposiciones distintas a las fiscales.
366
    :param salario_diario_integrado: Atributo opcional para expresar el salario que se integra con los pagos hechos en efectivo por cuota diaria, gratificaciones, percepciones, habitación, primas, comisiones, prestaciones en especie y cualquier otra cantidad o prestación que se entregue al trabajador por su trabajo, de conformidad con el Art. 84 de la Ley Federal del Trabajo. (Se utiliza para el cálculo de las indemnizaciones). Se debe ingresar cuando se esté obligado conforme a otras disposiciones distintas a las fiscales.
367
    :param sub_contratacion: Nodo condicional para expresar la lista de las personas que los subcontrataron.
368
    """
369
370 1
    def __init__(
371
            self,
372
            curp: str,
373
            tipo_contrato: str,
374
            tipo_regimen: str,
375
            num_empleado: str,
376
            periodicidad_pago: str,
377
            clave_ent_fed: str,
378
            num_seguridad_social: str = None,
379
            fecha_inicio_rel_laboral: date = None,
380
            antiguedad: str = None,
381
            sindicalizado: str = None,
382
            tipo_jornada: str = None,
383
            departamento: str = None,
384
            puesto: str = None,
385
            riesgo_puesto: str = None,
386
            banco: str = None,
387
            cuenta_bancaria: int | str = None,
388
            salario_base_cot_apor: Decimal | int = None,
389
            salario_diario_integrado: Decimal | int = None,
390
            sub_contratacion: SubContratacion | Sequence[SubContratacion | dict] = None,
391
    ):
392
        super().__init__({
393
            'Curp': curp,
394
            'TipoContrato': tipo_contrato,
395
            'TipoRegimen': tipo_regimen,
396
            'NumEmpleado': num_empleado,
397
            'PeriodicidadPago': periodicidad_pago,
398
            'ClaveEntFed': clave_ent_fed,
399
            'NumSeguridadSocial': num_seguridad_social,
400
            'FechaInicioRelLaboral': fecha_inicio_rel_laboral,
401
            'Antigüedad': antiguedad,
402
            'Sindicalizado': sindicalizado,
403
            'TipoJornada': tipo_jornada,
404
            'Departamento': departamento,
405
            'Puesto': puesto,
406
            'RiesgoPuesto': riesgo_puesto,
407
            'Banco': banco,
408
            'CuentaBancaria': cuenta_bancaria,
409
            'SalarioBaseCotApor': salario_base_cot_apor,
410
            'SalarioDiarioIntegrado': salario_diario_integrado,
411
            'SubContratacion': sub_contratacion,
412
        })
413
414
415
# Main #
416 1
class Nomina(CFDI):
417
    """
418
    Complemento para incorporar al Comprobante Fiscal Digital por Internet (CFDI) la información que ampara conceptos de ingresos por salarios, la prestación de un servicio personal subordinado o conceptos asimilados a salarios (Nómina).
419
420
    :param tipo_nomina: Atributo requerido para indicar el tipo de nómina, puede ser O= Nómina ordinaria o E= Nómina extraordinaria.
421
    :param fecha_pago: Atributo requerido para la expresión de la fecha efectiva de erogación del gasto. Se expresa en la forma AAAA-MM-DD, de acuerdo con la especificación ISO 8601.
422
    :param fecha_inicial_pago: Atributo requerido para la expresión de la fecha inicial del período de pago. Se expresa en la forma AAAA-MM-DD, de acuerdo con la especificación ISO 8601.
423
    :param fecha_final_pago: Atributo requerido para la expresión de la fecha final del período de pago. Se expresa en la forma AAAA-MM-DD, de acuerdo con la especificación ISO 8601.
424
    :param num_dias_pagados: Atributo requerido para la expresión del número o la fracción de días pagados.
425
    :param receptor: Nodo requerido para precisar la información del contribuyente receptor del comprobante de nómina.
426
    :param emisor: Nodo condicional para expresar la información del contribuyente emisor del comprobante de nómina.
427
    :param percepciones: Nodo condicional para expresar las percepciones aplicables.
428
    :param deducciones: Nodo opcional para expresar las deducciones aplicables.
429
    :param otros_pagos: Nodo condicional para expresar otros pagos aplicables.
430
    :param incapacidades: Nodo condicional para expresar información de las incapacidades.
431
    :return: objeto CFDI
432
    """
433
434 1
    tag = '{http://www.sat.gob.mx/nomina12}Nomina'
435 1
    version = '1.2'
436
437 1
    def __init__(
438
            self,
439
            tipo_nomina: str,
440
            fecha_pago: date,
441
            fecha_inicial_pago: date,
442
            fecha_final_pago: date,
443
            num_dias_pagados: Decimal,
444
            receptor: Receptor | dict,
445
            emisor: Emisor | dict = None,
446
            percepciones: Percepciones | dict = None,
447
            deducciones: Deducciones | dict = None,
448
            otros_pagos: OtroPago | Sequence[OtroPago | dict] = None,
449
            incapacidades: Incapacidad | Sequence[Incapacidad | dict] = None,
450
    ):
451
        # total_percepciones: Atributo condicional para representar la suma de las percepciones.
452 1
        total_percepciones = None
453 1
        if percepciones:
454
            # TotalGravado: Atributo requerido para expresar el total de percepciones gravadas que se relacionan en el comprobante.
455 1
            percepciones['TotalGravado'] = sum(p['ImporteGravado'] for p in iterate(percepciones['Percepcion']))
456
            # TotalExento: Atributo requerido para expresar el total de percepciones exentas que se relacionan en el comprobante.
457 1
            percepciones['TotalExento'] = sum(p['ImporteExento'] for p in iterate(percepciones['Percepcion']))
458
            # TotalSueldos: Atributo condicional para expresar el total de percepciones brutas (gravadas y exentas) por sueldos y salarios y conceptos asimilados a salarios.
459 1
            percepciones['TotalSueldos'] = percepciones['TotalGravado'] + percepciones['TotalExento']
460
461
            # TotalSeparacionIndemnizacion: Atributo condicional para expresar el importe exento y gravado de las claves tipo percepción 022 Prima por Antigüedad, 023 Pagos por separación y 025 Indemnizaciones.
462 1
            deducciones['TotalSeparacionIndemnizacion'] = sum(
463
                p['ImporteGravado'] + p['ImporteExento'] for p in iterate(percepciones['Percepcion']) if p['TipoPercepcion'] in ['022', '023', '025'])
464
            # TotalJubilacionPensionRetiro: Atributo condicional para expresar el importe exento y gravado de las claves tipo percepción 039 Jubilaciones, pensiones o haberes de retiro en una exhibición y 044 Jubilaciones, pensiones o haberes de retiro en parcialidades.
465 1
            deducciones['TotalJubilacionPensionRetiro'] = sum(p['ImporteGravado'] + p['ImporteExento'] for p in iterate(percepciones['Percepcion']) if p['TipoPercepcion'] in ['039', '044'])
466
467 1
            total_percepciones = percepciones['TotalSueldos']
468
469
        # total_deducciones: Atributo condicional para representar la suma de las deducciones aplicables.
470 1
        total_deducciones = None
471 1
        if deducciones:
472
            # TotalOtrasDeducciones: Atributo condicional para expresar el total de deducciones que se relacionan en el comprobante, donde la clave de tipo de deducción sea distinta a la 002 correspondiente a ISR.
473 1
            deducciones['TotalOtrasDeducciones'] = sum(p['Importe'] for p in iterate(deducciones['Deduccion']) if p['TipoDeduccion'] != '002')
474
            # TotalImpuestosRetenidos: Atributo condicional para expresar el total de los impuestos federales retenidos, es decir, donde la clave de tipo de deducción sea 002 correspondiente a ISR.
475 1
            deducciones['TotalImpuestosRetenidos'] = sum(p['Importe'] for p in iterate(deducciones['Deduccion']) if p['TipoDeduccion'] == '002')
476
477 1
            total_deducciones = deducciones['TotalImpuestosRetenidos'] + deducciones['TotalOtrasDeducciones']
478
479
        # total_otros_pagos: Atributo condicional para representar la suma de otros pagos.
480 1
        total_otros_pagos = None
481 1
        if otros_pagos:
482 1
            total_otros_pagos = sum(p["Importe"] for p in iterate(otros_pagos))
483
484 1
        super().__init__({
485
            'Version': self.version,
486
            'TipoNomina': tipo_nomina,
487
            'FechaPago': fecha_pago,
488
            'FechaInicialPago': fecha_inicial_pago,
489
            'FechaFinalPago': fecha_final_pago,
490
            'NumDiasPagados': num_dias_pagados,
491
            'Receptor': receptor,
492
            'TotalPercepciones': total_percepciones,
493
            'TotalDeducciones': total_deducciones,
494
            'TotalOtrosPagos': total_otros_pagos,
495
            'Emisor': emisor,
496
            'Percepciones': percepciones,
497
            'Deducciones': deducciones,
498
            'OtrosPagos': otros_pagos,
499
            'Incapacidades': incapacidades,
500
        })
501