-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpayment_info.py
117 lines (94 loc) · 3.36 KB
/
payment_info.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import datetime
from dataclasses import dataclass
import pandas as pd
from unidecode import unidecode
from config import CONFIG
from payment_data import NeededColumns
IBAN_ACC_NUMBER = CONFIG['payment']['iban']
SS_PREFIX = CONFIG['payment']['ss_prefix']
DUE_DATE = datetime.date.today() + datetime.timedelta(days=6)
PAYMENT_MESSAGE = CONFIG['payment']['message_template']
@dataclass
class Troop:
name: str
text_code: str
num_code: str
leader_name: str
leader_email: str
@property
def specific_symbol(self):
return f"{SS_PREFIX}{self.num_code}"
@classmethod
def from_string(cls, coma_separated_fields: str):
args = [v.strip() for v in coma_separated_fields.split(',')]
return cls(*args)
troops = [Troop.from_string(v) for k, v in CONFIG['troops'].items()]
TROOPS = {troop.name: troop for troop in troops}
@dataclass
class PaymentInfo:
_name: str
troop: Troop
variable_symbol: str
_due_date: datetime.date
amount_czk: str
iban_account_number: str
_amount_due: str
_amount_paid: str
def __post_init__(self):
assert len(self._name) > 5
assert len(self.variable_symbol) > 2
assert int(self.amount_czk) > 0
@property
def name(self):
return unidecode(self._name)
@property
def specific_symbol(self):
return self.troop.specific_symbol
@property
def payment_message(self):
# Unidecode to get rid of accents
msg = unidecode(PAYMENT_MESSAGE.format(troop_code=self.troop.text_code, name=self.name))
# trim to 60 characters
msg = msg[:61]
assert len(msg) <= 60
return msg
@property
def human_account_number(self):
"""Parses IBAN format into human form.
CZkk bbbb ssss sscc cccc cccc
Where:
b = National bank code
s = Account number prefix
c = Account number
See https://en.wikipedia.org/wiki/International_Bank_Account_Number"""
country = self.iban_account_number[:2]
checksum = self.iban_account_number[2:4]
bank = self.iban_account_number[4:8]
prefix = self.iban_account_number[8:14]
account_number = self.iban_account_number[14:24]
assert f"{country}{checksum}{bank}{prefix}{account_number}" == self.iban_account_number
return f"{prefix}-{account_number}/{bank}"
@property
def qr_code_due_date(self):
return self._due_date.strftime("%Y%m%d")
@property
def human_due_date(self):
return self._due_date.strftime("%d. %m. %Y")
@property
def number_of_sts_phones(self):
if CONFIG.has_section('sts'):
return str(int(int(self._amount_due)/int(CONFIG.get('sts', 'STS_payment_per_number'))))
else:
raise ValueError("Number of STS phones should only be checked with STS settings")
@classmethod
def from_df_row(cls, row: pd.Series, needed_cols: NeededColumns):
troop = TROOPS[row.loc[needed_cols.troop]]
amount_czk = row.loc[needed_cols.amount_due] - row.loc[needed_cols.amount_paid]
return cls(row.loc[needed_cols.name],
troop,
row.loc[needed_cols.reg_num],
DUE_DATE,
amount_czk,
IBAN_ACC_NUMBER,
row.loc[needed_cols.amount_due],
row.loc[needed_cols.amount_paid])