satcfdi.create.cfd.cfdi33   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 254
Duplicated Lines 41.34 %

Test Coverage

Coverage 94.87%

Importance

Changes 0
Metric Value
eloc 134
dl 105
loc 254
ccs 37
cts 39
cp 0.9487
rs 10
c 0
b 0
f 0
wmc 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A Receptor.__init__() 0 14 1
A Emisor.__init__() 0 10 1
A Parte.__init__() 20 20 1
A CfdiRelacionados.__init__() 0 8 1
A Impuestos.__init__() 8 8 1
A Traslado.__init__() 14 14 1
A Retencion.__init__() 14 14 1
A Concepto.__init__() 0 30 1

1 Function

Rating   Name   Duplication   Size   Complexity  
A _find_impuesto() 2 5 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
"""cfdi http://www.sat.gob.mx/cfd/3"""
2 1
from collections.abc import *
3 1
from decimal import Decimal
4
5 1
from satcfdi.create.cfd.catalogos import Impuesto as CatImpuesto
6 1
from . import cfdi40, pago10
7 1
from ...cfdi import CFDI
8 1
from ...utils import ScalarMap
9
10
11 1
class CfdiRelacionados(ScalarMap):
12
    """
13
    Nodo opcional para precisar la información de los comprobantes relacionados.
14
15
    :param tipo_relacion: Atributo requerido para indicar la clave de la relación que existe entre éste que se esta generando y el o los CFDI previos.
16
    :param cfdi_relacionado: Nodo requerido para precisar la información de los comprobantes relacionados.
17
    """
18
19 1
    def __init__(
20
            self,
21
            tipo_relacion: str,
22
            cfdi_relacionado: str | Sequence[str],
23
    ):
24
        super().__init__({
25
            'TipoRelacion': tipo_relacion,
26
            'CfdiRelacionado': cfdi_relacionado,
27
        })
28
29
30 1 View Code Duplication
class Parte(ScalarMap):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
31
    """
32
    Nodo opcional para expresar las partes o componentes que integran la totalidad del concepto expresado en el comprobante fiscal digital por Internet.
33
34
    :param clave_prod_serv: Atributo requerido para expresar la clave del producto o del servicio amparado por la presente parte. Es requerido y deben utilizar las claves del catálogo de productos y servicios, cuando los conceptos que registren por sus actividades correspondan con dichos conceptos.
35
    :param cantidad: Atributo requerido para precisar la cantidad de bienes o servicios del tipo particular definido por la presente parte.
36
    :param descripcion: Atributo requerido para precisar la descripción del bien o servicio cubierto por la presente parte.
37
    :param no_identificacion: Atributo opcional para expresar el número de serie, número de parte del bien o identificador del producto o del servicio amparado por la presente parte. Opcionalmente se puede utilizar claves del estándar GTIN.
38
    :param unidad: Atributo opcional para precisar la unidad de medida propia de la operación del emisor, aplicable para la cantidad expresada en la parte. La unidad debe corresponder con la descripción de la parte.
39
    :param valor_unitario: Atributo opcional para precisar el valor o precio unitario del bien o servicio cubierto por la presente parte. No se permiten valores negativos.
40
    :param importe: Atributo opcional para precisar el importe total de los bienes o servicios de la presente parte. Debe ser equivalente al resultado de multiplicar la cantidad por el valor unitario expresado en la parte. No se permiten valores negativos.
41
    :param informacion_aduanera: Nodo opcional para introducir la información aduanera aplicable cuando se trate de ventas de primera mano de mercancías importadas o se trate de operaciones de comercio exterior con bienes o servicios.
42
    """
43
44 1
    def __init__(
45
            self,
46
            clave_prod_serv: str,
47
            cantidad: Decimal | int,
48
            descripcion: str,
49
            no_identificacion: str = None,
50
            unidad: str = None,
51
            valor_unitario: Decimal | int = None,
52
            importe: Decimal | int = None,
53
            informacion_aduanera: str | Sequence[str] = None,
54
    ):
55
        super().__init__({
56
            'ClaveProdServ': clave_prod_serv,
57
            'Cantidad': cantidad,
58
            'Descripcion': descripcion,
59
            'NoIdentificacion': no_identificacion,
60
            'Unidad': unidad,
61
            'ValorUnitario': valor_unitario,
62
            'Importe': importe,
63
            'InformacionAduanera': informacion_aduanera,
64
        })
65
66
67 1
def _find_impuesto(impuesto):
68 1
    try:
69 1
        return CatImpuesto[impuesto]
70 1
    except KeyError:
71 1
        return impuesto
72
73
74 1 View Code Duplication
class Traslado(ScalarMap):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
75
    """
76
    Nodo requerido para la información detallada de un traslado de impuesto específico.
77
78
    :param base: Atributo requerido para señalar la suma de los atributos Base de los conceptos del impuesto trasladado. No se permiten valores negativos.
79
    :param impuesto: Atributo requerido para señalar la clave del tipo de impuesto retencion.
80
    :param tipo_factor: Atributo requerido para señalar la clave del tipo de factor que se aplica a la base del impuesto.
81
    :param tasa_o_cuota: Atributo condicional para señalar el valor de la tasa o cuota del impuesto que se traslada por los conceptos amparados en el comprobante.
82
    :param importe: Atributo condicional para señalar la suma del importe del impuesto trasladado, agrupado por impuesto, TipoFactor y TasaOCuota. No se permiten valores negativos.
83
    """
84
85 1
    def __init__(
86
            self,
87
            impuesto: str,
88
            tipo_factor: str,
89
            tasa_o_cuota: Decimal | int = None,
90
            importe: Decimal | int = None,
91
            base: Decimal | int = None,
92
    ):
93 1
        super().__init__({
94
            'Base': base,
95
            'Impuesto': _find_impuesto(impuesto),
96
            'TipoFactor': tipo_factor,
97
            'TasaOCuota': tasa_o_cuota,
98
            'Importe': importe,
99
        })
100
101
102 1 View Code Duplication
class Retencion(ScalarMap):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
103
    """
104
    Nodo requerido para la información detallada de un traslado de impuesto específico.
105
106
    :param base: Atributo requerido para señalar la suma de los atributos Base de los conceptos del impuesto trasladado. No se permiten valores negativos.
107
    :param impuesto: Atributo requerido para señalar la clave del tipo de impuesto retencion.
108
    :param tipo_factor: Atributo requerido para señalar la clave del tipo de factor que se aplica a la base del impuesto.
109
    :param tasa_o_cuota: Atributo condicional para señalar el valor de la tasa o cuota del impuesto que se traslada por los conceptos amparados en el comprobante.
110
    :param importe: Atributo condicional para señalar la suma del importe del impuesto trasladado, agrupado por impuesto, TipoFactor y TasaOCuota. No se permiten valores negativos.
111
    """
112
113 1
    def __init__(
114
            self,
115
            impuesto: str,
116
            tipo_factor: str,
117
            tasa_o_cuota: Decimal | int = None,
118
            importe: Decimal | int = None,
119
            base: Decimal | int = None,
120
    ):
121 1
        super().__init__({
122
            'Base': base,
123
            'Impuesto': _find_impuesto(impuesto),
124
            'TipoFactor': tipo_factor,
125
            'TasaOCuota': tasa_o_cuota,
126
            'Importe': importe,
127
        })
128
129
130 1 View Code Duplication
class Impuestos(ScalarMap):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
131
    """
132
    Nodo condicional para expresar el resumen de los impuestos aplicables.
133
134
    :param retenciones: Nodo condicional para capturar los impuestos retenidos aplicables. Es requerido cuando en los conceptos se registre algún impuesto retenido.
135
    :param traslados: Nodo condicional para capturar los impuestos trasladados aplicables. Es requerido cuando en los conceptos se registre un impuesto trasladado.
136
    """
137
138 1
    def __init__(
139
            self,
140
            retenciones: Retencion | dict | str | Sequence[Retencion | dict | str] = None,
141
            traslados: Traslado | dict | str | Sequence[Traslado | dict | str] = None,
142
    ):
143 1
        super().__init__({
144
            'Retenciones': retenciones,
145
            'Traslados': traslados,
146
        })
147
148
149 1
class Concepto(ScalarMap):
150
    """
151
    Nodo requerido para registrar la información detallada de un bien o servicio amparado en el comprobante.
152
153
    :param clave_prod_serv: Atributo requerido para expresar la clave del producto o del servicio amparado por el presente concepto. Es requerido y deben utilizar las claves del catálogo de productos y servicios, cuando los conceptos que registren por sus actividades correspondan con dichos conceptos.
154
    :param cantidad: Atributo requerido para precisar la cantidad de bienes o servicios del tipo particular definido por el presente concepto.
155
    :param clave_unidad: Atributo requerido para precisar la clave de unidad de medida estandarizada aplicable para la cantidad expresada en el concepto. La unidad debe corresponder con la descripción del concepto.
156
    :param descripcion: Atributo requerido para precisar la descripción del bien o servicio cubierto por el presente concepto.
157
    :param valor_unitario: Atributo requerido para precisar el valor o precio unitario del bien o servicio cubierto por el presente concepto.
158
    :param no_identificacion: Atributo opcional para expresar el número de parte, identificador del producto o del servicio, la clave de producto o servicio, SKU o equivalente, propia de la operación del emisor, amparado por el presente concepto. Opcionalmente se puede utilizar claves del estándar GTIN.
159
    :param unidad: Atributo opcional para precisar la unidad de medida propia de la operación del emisor, aplicable para la cantidad expresada en el concepto. La unidad debe corresponder con la descripción del concepto.
160
    :param descuento: Atributo opcional para representar el importe de los descuentos aplicables al concepto. No se permiten valores negativos.
161
    :param informacion_aduanera: Nodo opcional para introducir la información aduanera aplicable cuando se trate de ventas de primera mano de mercancías importadas o se trate de operaciones de comercio exterior con bienes o servicios.
162
    :param cuenta_predial: Nodo opcional para asentar el número de cuenta predial con el que fue registrado el inmueble, en el sistema catastral de la entidad federativa de que trate, o bien para incorporar los datos de identificación del certificado de participación inmobiliaria no amortizable.
163
    :param complemento_concepto: Nodo opcional donde se incluyen los nodos complementarios de extensión al concepto definidos por el SAT, de acuerdo con las disposiciones particulares para un sector o actividad específica.
164
    :param parte: Nodo opcional para expresar las partes o componentes que integran la totalidad del concepto expresado en el comprobante fiscal digital por Internet.
165
    """
166
167 1
    def __init__(
168
            self,
169
            clave_prod_serv: str,
170
            cantidad: Decimal | int,
171
            clave_unidad: str,
172
            descripcion: str,
173
            valor_unitario: Decimal | int,
174
            no_identificacion: str = None,
175
            unidad: str = None,
176
            descuento: Decimal | int = None,
177
            impuestos: Impuestos | dict = None,
178
            informacion_aduanera: str | Sequence[str] = None,
179
            cuenta_predial: str = None,
180
            complemento_concepto: Sequence[CFDI] = None,
181
            parte: Sequence[Parte | dict] = None
182
    ):
183 1
        super().__init__({
184
            'ClaveProdServ': clave_prod_serv,
185
            'Cantidad': cantidad,
186
            'ClaveUnidad': clave_unidad,
187
            'Descripcion': descripcion,
188
            'ValorUnitario': valor_unitario,
189
            'NoIdentificacion': no_identificacion,
190
            'Unidad': unidad,
191
            'Descuento': descuento,
192
            'Impuestos': impuestos,
193
            'InformacionAduanera': informacion_aduanera,
194
            'CuentaPredial': cuenta_predial,
195
            'ComplementoConcepto': complemento_concepto,
196
            'Parte': parte
197
        })
198
199
200 1
class Receptor(ScalarMap):
201
    """
202
    Nodo requerido para precisar la información del contribuyente receptor del comprobante.
203
204
    :param rfc: Atributo requerido para precisar la Clave del Registro Federal de Contribuyentes correspondiente al contribuyente receptor del comprobante.
205
    :param uso_cfdi: Atributo requerido para expresar la clave del uso que dará a esta factura el receptor del CFDI.
206
    :param nombre: Atributo opcional para precisar el nombre, denominación o razón social del contribuyente receptor del comprobante.
207
    :param residencia_fiscal: Atributo condicional para registrar la clave del país de residencia para efectos fiscales del receptor del comprobante, cuando se trate de un extranjero, y que es conforme con la especificación ISO 3166-1 alpha-3. Es requerido cuando se incluya el complemento de comercio exterior o se registre el atributo NumRegIdTrib.
208
    :param num_reg_id_trib: Atributo condicional para expresar el número de registro de identidad fiscal del receptor cuando sea residente en el extranjero. Es requerido cuando se incluya el complemento de comercio exterior.
209
    """
210
211 1
    def __init__(
212
            self,
213
            rfc: str,
214
            uso_cfdi: str,
215
            nombre: str = None,
216
            residencia_fiscal: str = None,
217
            num_reg_id_trib: str = None,
218
    ):
219 1
        super().__init__({
220
            'Rfc': rfc,
221
            'UsoCFDI': uso_cfdi,
222
            'Nombre': nombre,
223
            'ResidenciaFiscal': residencia_fiscal,
224
            'NumRegIdTrib': num_reg_id_trib,
225
        })
226
227
228 1
class Emisor(ScalarMap):
229
    """
230
    Nodo requerido para expresar la información del contribuyente emisor del comprobante.
231
232
    :param rfc: Atributo requerido para registrar la Clave del Registro Federal de Contribuyentes correspondiente al contribuyente emisor del comprobante.
233
    :param regimen_fiscal: Atributo requerido para incorporar la clave del régimen del contribuyente emisor al que aplicará el efecto fiscal de este comprobante.
234
    :param nombre: Atributo opcional para registrar el nombre, denominación o razón social del contribuyente emisor del comprobante.
235
    """
236
237 1
    def __init__(
238
            self,
239
            rfc: str,
240
            regimen_fiscal: str,
241
            nombre: str = None,
242
    ):
243 1
        super().__init__({
244
            'Rfc': rfc,
245
            'RegimenFiscal': regimen_fiscal,
246
            'Nombre': nombre,
247
        })
248
249
250 1
class Comprobante(cfdi40.Comprobante):
251 1
    tag = '{http://www.sat.gob.mx/cfd/3}Comprobante'
252 1
    version = '3.3'
253
    complemento_pago = pago10.Pagos
254