Passed
Push — main ( 26371d...01722e )
by Sat CFDI
01:42
created

validar_client()   C

Complexity

Conditions 10

Size

Total Lines 39
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 27
dl 0
loc 39
rs 5.9999
c 0
b 0
f 0
cc 10
nop 1

How to fix   Complexity   

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
# noinspection PyUnresolvedReferences
6
from bs4.builder import XMLParsedAsHTMLWarning
7
from satcfdi import csf, RFC, RFCType
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
    rfc = client['Rfc']
19
20
    def error(msg):
21
        print(f"{rfc}: {msg}")
22
23
    try:
24
        rfc = RFC(rfc)
25
26
        for email in client["Email"]:
27
            if not re.fullmatch(EMAIL_REGEX, email):
28
                error(f"Correo '{email}' is invalid")
29
30
        res = csf.retrieve(rfc, id_cif=client["IdCIF"])
31
32
        if rfc.type == RFCType.FISICA:
33
            razon_social = f"{res['Nombre']} {res['Apellido Paterno']} {res['Apellido Materno']}"
34
        else:
35
            razon_social = res['Denominación o Razón Social']
36
        if client['RazonSocial'] != razon_social:
37
            error(f"RazonSocial '{client['RazonSocial']}' is invalid, expected '{razon_social}'")
38
39
        if client['CodigoPostal'] != res['CP']:
40
            error(f"CodigoPostal '{client['CodigoPostal']}' is invalid, expected '{res['CP']}'")
41
42
        if client['RegimenFiscal'] not in (r['RegimenFiscal'] for r in res['Regimenes']):
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable r does not seem to be defined.
Loading history...
43
            error(
44
                f"RegimenFiscal '{client['RegimenFiscal']}' is invalid, "
45
                f"expected '{(r['RegimenFiscal'].code for r in res['Regimenes'])}'"
46
            )
47
48
        if res['Situación del contribuyente'] not in ('ACTIVO', 'REACTIVADO'):
49
            error(f"Is not ACTIVO '{res['Situación del contribuyente']}'")
50
51
        taxpayer_status = sat_service.list_69b(rfc)
52
        if taxpayer_status:
53
            error(f"has status '{taxpayer_status}'")
54
    except ValueError as ex:
55
        error(ex)
56
57
58
def clientes_generar_txt(filename, clients):
59
    with open(filename, 'w', encoding='utf-8') as f:
60
        for i, (cliente_rfc, cliente_data) in enumerate(clients.items(), start=1):
61
            f.write(f"{i}|{cliente_rfc}|{cliente_data['RazonSocial']}|{cliente_data['CodigoPostal']}\n")
62