Passed
Push — main ( 9e4efb...b47580 )
by Sat CFDI
01:45
created

satdigitalinvoice.utils.to_date_period()   A

Complexity

Conditions 5

Size

Total Lines 11
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 10
dl 0
loc 11
rs 9.3333
c 0
b 0
f 0
cc 5
nop 1
1
import os
2
import random
3
import shutil
4
from datetime import datetime
5
from uuid import UUID
6
7
from satcfdi import Signer, DatePeriod
8
9
10
def to_date_period(periodo):
11
    if not periodo:
12
        return DatePeriod(year=None)
13
14
    fmt, period = try_parsing_date(periodo)
15
    if fmt == '%Y':
16
        return DatePeriod(period.year)
17
    if fmt == '%Y-%m':
18
        return DatePeriod(period.year, period.month)
19
    if fmt == '%Y-%m-%d':
20
        return DatePeriod(period.year, period.month, period.day)
21
22
23
def try_parsing_date(text):
24
    for fmt in ('%Y', '%Y-%m', '%Y-%m-%d'):
25
        try:
26
            return fmt, datetime.strptime(text, fmt)
27
        except ValueError:
28
            pass
29
    return None, None
30
31
32
def to_uuid(s):
33
    try:
34
        return UUID(s)
35
    except ValueError:
36
        return None
37
38
39
def to_int(s):
40
    try:
41
        return int(s)
42
    except ValueError:
43
        return None
44
45
46
def random_string():
47
    chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
48
    return "".join(random.choice(chars) for _ in range(32))
49
50
51
def convert_ans1_date(ans1_date):
52
    return datetime.strptime(ans1_date.decode('utf-8'), '%Y%m%d%H%M%SZ')
53
54
55
def cert_info(signer: Signer):
56
    if signer:
57
        return {
58
            "NoCertificado": signer.certificate_number,
59
            # "Tipo": str(signer.type),
60
            #
61
            # "organizationName": signer.certificate.get_subject().O,
62
            # "x500UniqueIdentifier": signer.certificate.get_subject().x500UniqueIdentifier,
63
            # "serialNumber": signer.certificate.get_subject().serialNumber,
64
            # "organizationUnitName": signer.certificate.get_subject().OU,
65
            # "emailAddress": signer.certificate.get_subject().emailAddress,
66
            #
67
            "Expira": convert_ans1_date(signer.certificate.get_notAfter()),
68
            "Creado": convert_ans1_date(signer.certificate.get_notBefore()),
69
        }
70
71
72
def find_best_match(cases, dp: DatePeriod) -> (datetime, object):
73
    fk, fv = (None, None)
74
    for k, v in cases.items():
75
        k = datetime.strptime(k, '%Y-%m')
76
        if k <= dp:
77
            if fk is None or k > fk:
78
                fk, fv = k, v
79
    return fk, fv
80
81
82
def clear_directory(directory):
83
    shutil.rmtree(directory, ignore_errors=True)
84
    os.makedirs(directory, exist_ok=True)
85
86
87
# calculate the number of months between two dates
88
def months_between(d1, d2):
89
    return (d1.year - d2.year) * 12 + d1.month - d2.month
90
91
92
def add_month(dp: DatePeriod, months):
93
    year, month = divmod(dp.year * 12 + dp.month + months - 1, 12)
94
    month += 1
95
    return DatePeriod(year, month)
96
97
98
def load_certificate(data):
99
    if 'data' in data:
100
        return Signer.load_pkcs12(
101
            **data,
102
        )
103
    else:
104
        return Signer.load(
105
            **data,
106
        )
107
108
109
def first_duplicate(seq):
110
    seen = set()
111
    for x in seq:
112
        if x in seen:
113
            return x
114
        seen.add(x)
115
    return None
116
117
118
def parse_rango(rango):
119
    if rango == "":
120
        return 1, None
121
    if rango.isdigit():
122
        return int(rango), int(rango)
123
    if "-" in rango:
124
        start, end = rango.split("-")
125
        return int(start), int(end)
126