validar_client()   D
last analyzed

Complexity

Conditions 13

Size

Total Lines 51
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 35
dl 0
loc 51
rs 4.2
c 0
b 0
f 0
cc 13
nop 1

How to fix   Long Method    Complexity   

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:

Complexity

Complex classes like satdigitalinvoice.client_validation.validar_client() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
import logging
2
import re
3
import warnings
4
5
from bs4.builder import XMLParsedAsHTMLWarning
6
from satcfdi.models import RFC, RFCType
7
from satcfdi import csf
8
from satcfdi.pacs.sat import SAT
9
10
sat_service = SAT()
11
logger = logging.getLogger(__name__)
12
warnings.filterwarnings("ignore", category=XMLParsedAsHTMLWarning)
13
14
EMAIL_REGEX = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b'
15
16
17
def validar_client(client):
18
    errors = []
19
20
    rfc = client['Rfc']
21
22
    def error(msg):
23
        errors.append(f"{rfc}: {msg}")
24
25
    try:
26
        rfc = RFC(rfc)
27
28
        for email in client["Email"]:
29
            if not re.fullmatch(EMAIL_REGEX, email):
30
                error(f"Correo '{email}' is invalid")
31
32
        res = csf.retrieve(rfc, id_cif=client["IdCIF"])
33
34
        if rfc.type == RFCType.FISICA:
35
            razon_social = f"{res['Nombre']} {res['Apellido Paterno']} {res['Apellido Materno']}"
36
        elif 'Denominación o Razón Social' in res:
37
            razon_social = res['Denominación o Razón Social']
38
        else:
39
            error(f"Does not have 'Denominación o Razón Social'")
40
41
        if client['RazonSocial'] != razon_social:
0 ignored issues
show
introduced by
The variable razon_social does not seem to be defined for all execution paths.
Loading history...
42
            error(f"RazonSocial '{client['RazonSocial']}' is invalid, expected '{razon_social}'")
43
44
        if client['CodigoPostal'] != res['CP']:
45
            error(f"CodigoPostal '{client['CodigoPostal']}' is invalid, expected '{res['CP']}'")
46
47
        for r in res['Regimenes']:
48
            if r['RegimenFiscal'].code == None:
49
                error(f"RegimenFiscal '{r['RegimenFiscal']}' is invalid")
50
51
        if client['RegimenFiscal'] not in (r['RegimenFiscal'] for r in res['Regimenes']):
0 ignored issues
show
introduced by
The variable r does not seem to be defined in case the for loop on line 47 is not entered. Are you sure this can never be the case?
Loading history...
52
            regimen = ', '.join(r['RegimenFiscal'].code or "" for r in res['Regimenes'])
53
            error(
54
                f"RegimenFiscal '{client['RegimenFiscal']}' is invalid, "
55
                f"expected one of '{regimen}'"
56
            )
57
58
        if res['Situación del contribuyente'] not in ('ACTIVO', 'REACTIVADO'):
59
            error(f"Is not ACTIVO '{res['Situación del contribuyente']}'")
60
61
        taxpayer_status = sat_service.list_69b(rfc)
62
        if taxpayer_status:
63
            error(f"has status '{taxpayer_status}'")
64
    except Exception as ex:
65
        error(ex)
66
67
    return errors
68
69
70
def clientes_generar_txt(filename, clients):
71
    with open(filename, 'w', encoding='utf-8') as f:
72
        for i, (cliente_rfc, cliente_data) in enumerate(clients.items(), start=1):
73
            f.write(f"{i}|{cliente_rfc}|{cliente_data['RazonSocial']}|{cliente_data['CodigoPostal']}\n")
74