Passed
Push — main ( d75fb3...cc42ac )
by Sat CFDI
01:40
created

validar_client()   D

Complexity

Conditions 13

Size

Total Lines 42
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 31
dl 0
loc 42
rs 4.2
c 0
b 0
f 0
cc 13
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
        if not rfc.is_valid():
26
            raise ValueError("RFC Not Valid Regex")
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.MORAL:
35
            if client['RazonSocial'] != res['Denominación o Razón Social']:
36
                error(f"RazonSocial '{client['RazonSocial']}' is invalid, expected '{res['Denominación o Razón Social']}'")
37
        elif rfc.type == RFCType.FISICA:
38
            razon_social = f"{res['Nombre']} {res['Apellido Paterno']} {res['Apellido Materno']}"
39
            if client['RazonSocial'] != razon_social:
40
                error(f"RazonSocial '{client['RazonSocial']}' is invalid, expected '{razon_social}'")
41
42
        if client['CodigoPostal'] != res['CP']:
43
            error(f"CodigoPostal '{client['CodigoPostal']}' is invalid, expected '{res['CP']}'")
44
45
        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...
46
            error(
47
                f"RegimenFiscal '{client['RegimenFiscal']}' is invalid, "
48
                f"expected '{(r['RegimenFiscal'].code for r in res['Regimenes'])}'"
49
            )
50
51
        if res['Situación del contribuyente'] not in ['ACTIVO', 'REACTIVADO']:
52
            error(f"Is not ACTIVO '{res['Situación del contribuyente']}'")
53
54
        taxpayer_status = sat_service.list_69b(rfc)
55
        if taxpayer_status:
56
            error(f"has status '{taxpayer_status}'")
57
    except ValueError as ex:
58
        error(ex)
59
60
61
def clientes_generar_txt(filename, clients):
62
    with open(filename, 'w', encoding='utf-8') as f:
63
        for i, (cliente_rfc, cliente_data) in enumerate(clients.items(), start=1):
64
            f.write(f"{i}|{cliente_rfc}|{cliente_data['RazonSocial']}|{cliente_data['CodigoPostal']}")
65
            f.write("\n")
66