diff --git a/assign_payments.py b/assign_payments.py
new file mode 100644
index 0000000..5e969db
--- /dev/null
+++ b/assign_payments.py
@@ -0,0 +1,106 @@
+# 3. assign manually
+
+from database import Base, engine, SessionLocal
+from time import time
+from models import Payments_CSV, Payments, Members
+import logging, sys
+import datetime
+
+def assign_by_reference(payments: Payments_CSV):
+ for payment in payments:
+ logging.debug(f'payment.pc_reference {payment.pc_reference}')
+ reference = payment.pc_reference.split('-')
+ if len(reference) == 1:
+ reference = payment.pc_reference.split(' ')
+
+ if len(reference) == 4:
+ addPayment(payment, reference[2], reference[0], payment.pc_amount)
+ else:
+ # more than one reference (e.g. 2024-4732-096-2,-097-1,-099-1)
+ referenceList = payment.pc_reference.split(',')
+ number_of_references = completeReference(referenceList=referenceList)
+ amount = payment.pc_amount # assume that the payment is for all references
+
+ for reference in referenceList:
+ referenceItem = reference.split('-')
+ addPayment(payment, referenceItem[2], referenceItem[0], amount/number_of_references*int(referenceItem[3]))
+
+ try:
+ db.commit()
+ except Exception as e:
+ print(e)
+ db.rollback()
+
+def assign_by_name(payments: Payments_CSV):
+ year = 2024
+ removables = ('Dipl.', 'Ing.', 'Mag.')
+ for payment in payments:
+ logging.debug(f'payment.pc_reference {payment.pc_intended}')
+ name = payment.pc_client.split(' ')
+ for removeable in removables:
+ while removeable in name: name.remove(removeable)
+
+ # last part is usually surname
+ member = db.query(Members).filter(Members.member_surname.like(name[len(name)-1]), Members.member_firstname.like(name[0])).all()
+ if len(member) > 1:
+ logging.debug(f'More than one member with same name {payment.pc_client}')
+ elif len(member) == 0:
+ logging.debug(f'No member found with name {payment.pc_client}')
+ else:
+ # update Payments_CSV
+ payment.pc_reference = f'{year}-4732-{member[0].id}-{member[0].member_count}'
+
+ #addPayment(payment, referenceItem[2], referenceItem[0], amount/number_of_references*int(referenceItem[3]))
+
+ try:
+ db.commit()
+ except Exception as e:
+ print(e)
+ db.rollback()
+
+
+def addPayment(payment, member_id, year, amount):
+ newPayment = Payments(payment_date = payment.pc_valuta_date,
+ member_id = member_id,
+ payment_year = datetime.date(int(year),1,1),
+ payment_amount = amount)
+
+ db.add(newPayment)
+ payment.pc_processed = True
+
+def completeReference(referenceList: list) -> int:
+ number_of_references = 0
+ i=0
+ for reference in referenceList:
+ referenceItem = reference.split('-')
+ if referenceItem[0] == '':
+ referenceItem.insert(1, referenceList[0].split('-')[0])
+ referenceItem.insert(2, referenceList[0].split('-')[1])
+ referenceItem.pop(0)
+
+ reference = '-'.join(referenceItem)
+ referenceList[i]=reference
+ i+=1
+
+ number_of_references += int(referenceItem[3])
+
+ return number_of_references
+
+if __name__ == "__main__":
+
+ t = time()
+ logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
+ logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)
+
+ db = SessionLocal()
+ Base.metadata.create_all(bind=engine)
+
+ # 1. create missing reference by name
+ payments = db.query(Payments_CSV).filter(Payments_CSV.pc_intended!='', Payments_CSV.pc_reference=='', Payments_CSV.pc_processed!=True).all()
+ assign_by_name(payments)
+
+ # 2. assign payment by reference
+ payments = db.query(Payments_CSV).filter(Payments_CSV.pc_reference!='', Payments_CSV.pc_processed!=True).all()
+ assign_by_reference(payments)
+
+ logging.debug(f"Time elapsed: " + str(time() - t) + " s.") #0.091s
\ No newline at end of file
diff --git a/convert_payment_export_csv.py b/convert_payment_export_csv.py
new file mode 100644
index 0000000..2e2f2fc
--- /dev/null
+++ b/convert_payment_export_csv.py
@@ -0,0 +1,73 @@
+# Importing libraries
+from numpy import genfromtxt, savetxt
+from time import time
+from datetime import datetime
+import models
+import os, re
+from database import engine, SessionLocal
+from pytz import timezone
+
+def Load_Data(file_name):
+ #data = genfromtxt(file_name, delimiter=';', skip_header=1, converters={0: lambda s: str(s)})
+ #str2date = lambda x: datetime.strptime(x, '%d-%m-%y')
+ data = genfromtxt(file_name, delimiter=';', dtype=None, skip_header=0, encoding='utf-8-sig')
+
+ return data.tolist()
+
+def extract_values(text):
+ # Regular expressions to match the required fields
+ regex_patterns = {
+ 'Auftraggeber': r'Auftraggeber: (.*?) (Verwendungszweck|Zahlungsreferenz|IBAN|BIC)',
+ 'Verwendungszweck': r'Verwendungszweck: (.*?) (Zahlungsreferenz|IBAN|BIC)',
+ 'Zahlungsreferenz': r'Zahlungsreferenz: (.*?) (Verwendungszweck|IBAN|BIC)',
+ 'IBAN': r'IBAN Auftraggeber: (.*?) ',
+ 'BIC': r'BIC Auftraggeber: (.*?)$'
+ }
+
+ # Initialize an empty list to store extracted information
+ extracted_info = []
+
+ # Initialize an empty dictionary to store information from this row
+ row_info = {}
+
+ # Extract information using regular expressions
+ for key, pattern in regex_patterns.items():
+ match = re.search(pattern, text)
+ if match:
+ row_info[key] = match.group(1)
+ else:
+ row_info[key] = None
+
+ # Append the extracted information from this row to the list
+ extracted_info.append(row_info)
+
+ return extracted_info
+
+if __name__ == "__main__":
+ t = time()
+
+ db = SessionLocal()
+ models.Base.metadata.create_all(bind=engine)
+
+ try:
+ home_directory = os.path.expanduser('~')
+ source_csv = os.path.join(home_directory, "OneDrive", "Dokumente", "SUST", "UmsatzListe_AT493443700000113407 (7)_org.csv")
+ target_csv = source_csv.replace(".csv", "_out.csv")
+ data = Load_Data(source_csv)
+
+ tz = timezone('UTC') # Replace with your desired timezone
+ outData = []
+ for i in data:
+ if ('Auftraggeber' in i[1]):
+ # extract key-value pairs Auftraggeber, Verwendungszweck, Zahlungsreferenz, IBAN
+ new_list = extract_values(i[1])
+
+ if len(new_list) > 0:
+ outData.append([i[0], new_list[0].get('Auftraggeber'), new_list[0].get('Zahlungsreferenz'), new_list[0].get('Verwendungszweck'), new_list[0].get('IBAN'), i[2], i[3].replace(',','.'), i[4], i[5]])
+
+ savetxt(target_csv, outData, delimiter=";", encoding='utf-8', header='valuta_date;client;reference;intended;IBAN;entry_date;amount;currency;timestamp', fmt='%s')
+
+ except Exception as e:
+ print (e)
+ finally:
+ print("Time elapsed: " + str(time() - t) + " s.") #0.091s
\ No newline at end of file
diff --git a/create_payment_slip.py b/create_payment_slip.py
index a136837..9dafe40 100644
--- a/create_payment_slip.py
+++ b/create_payment_slip.py
@@ -1,5 +1,4 @@
import models
-import locale
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
diff --git a/epc_qr.png b/epc_qr.png
index a1b7f43..50e49c8 100644
Binary files a/epc_qr.png and b/epc_qr.png differ
diff --git a/helper_scripts.sql b/helper_scripts.sql
index 543c6c3..32a4fd2 100644
--- a/helper_scripts.sql
+++ b/helper_scripts.sql
@@ -22,4 +22,60 @@ values (now(), 78, 186, '2024-01-01'),
(now(), 4, 186, '2024-01-01'),
(now(), 9, 186, '2024-01-01')
-update deliveries set delivery_year = '2024-01-01'
\ No newline at end of file
+insert into deliveries (delivery_date, member_id, delivered_by_id, delivery_year)
+values (now(), 8, 186, '2024-02-21')
+
+select count(*) from deliveries d
+
+update deliveries set delivery_year = '2024-01-01'
+
+create table sust.payments_csv
+(id serial,
+ pc_valuta_date date,
+ pc_client varchar(50),
+ pc_reference varchar(50),
+ pc_intended varchar(50),
+ pc_iban varchar(50),
+ pc_entry_date date,
+ pc_amount money,
+ pc_currency varchar(3),
+ pc_timestamp timestamp)
+
+COPY payments_csv(pc_valuta_date, pc_client, pc_reference, pc_intended, pc_iban, pc_entry_date, pc_amount, pc_currency, pc_timestamp)
+FROM 'C:\Users\zisco\OneDrive\Dokumente\SUST\UmsatzListe_AT493443700000113407_v1.csv'
+DELIMITER ';'
+CSV HEADER;
+
+CREATE UNIQUE INDEX payments_ukey_member_year ON sust.payments USING btree (member_id, payment_year)
+
+select count(*) from payments_csv where pc_processed = true
+
+
+select * from payments_csv pc where id = 168
+
+ALTER TABLE payments_csv ADD PRIMARY KEY (id);
+
+select * from payments p where p.member_id in (132)
+select pc.pc_reference from payments_csv pc where pc_processed =false order by pc_reference asc
+
+select m.member_surname, m.member_firstname, m.member_firstname_spouse from members m
+except
+select mp.member_surname, mp.member_firstname, mp.member_firstname_spouse from members_paid mp
+
+select * from members_paid mp where id = 8
+
+-- already paid?
+select * from members_active m
+join deliveries d on d.member_id = m.id
+where m.id in (select id from members_delivered md
+except
+select id from members_paid mp)
+order by delivery_date asc
+
+insert into deliveries (delivery_date, member_id, delivery_year)
+select now(), ss.id, '2024-01-01' from
+(select id from members_active m
+except
+select member_id from deliveries d) ss
+
+select count(*) from deliveries d
\ No newline at end of file
diff --git a/import_transactions.py b/import_transactions.py
new file mode 100644
index 0000000..e6f2143
--- /dev/null
+++ b/import_transactions.py
@@ -0,0 +1,56 @@
+# Importing libraries
+from numpy import genfromtxt
+from time import time
+from datetime import datetime
+import models
+import os
+from database import engine, SessionLocal
+from pytz import timezone
+
+def Load_Data(file_name):
+ #data = genfromtxt(file_name, delimiter=';', skip_header=1, converters={0: lambda s: str(s)})
+ #str2date = lambda x: datetime.strptime(x, '%d-%m-%y')
+ data = genfromtxt(file_name, delimiter=';', dtype=None, skip_header=1, encoding='utf-8') #
+ return data.tolist()
+
+if __name__ == "__main__":
+ t = time()
+
+ db = SessionLocal()
+ models.Base.metadata.create_all(bind=engine)
+
+ try:
+ home_directory = os.path.expanduser('~')
+ source_csv = os.path.join(home_directory, "OneDrive", "Dokumente", "SUST", "UmsatzListe_AT493443700000113407_v7.csv")
+ data = Load_Data(source_csv)
+
+ tz = timezone('UTC') # Replace with your desired timezone
+ for i in data:
+ dt = datetime.strptime(i[8], '%d.%m.%Y %H:%M:%S:%f')
+ ts_timestamp = tz.localize(dt)
+
+ record = models.Payments_CSV(**{
+ 'pc_valuta_date' : datetime.strptime(i[0], '%d.%m.%Y').date(),
+ 'pc_client' : i[1],
+ 'pc_reference' : i[2],
+ 'pc_intended' : i[3],
+ 'pc_iban' : i[4],
+ 'pc_entry_date' : datetime.strptime(i[5], '%d.%m.%Y').date(),
+ 'pc_amount' : float(i[6]),
+ 'pc_currency' : i[7],
+ 'pc_timestamp' : ts_timestamp
+ })
+ db.add(record) #Add all the records
+
+ try:
+ db.commit() #Attempt to commit all the records
+ except Exception as e:
+ print(e)
+
+ except Exception as e:
+ print (e)
+ db.rollback() #Rollback the changes on error
+ finally:
+ db.close() #Close the connection
+
+ print("Time elapsed: " + str(time() - t) + " s.") #0.091s
\ No newline at end of file
diff --git a/mail_payment_slips.py b/mail_payment_slips.py
index 7108d77..db961bd 100644
--- a/mail_payment_slips.py
+++ b/mail_payment_slips.py
@@ -28,7 +28,8 @@ def send_mail(member: models.Members):
smtp_server = 'mail.gmx.com'
smtp_port = 587
smtp_username = 'zisco@gmx.at'
- smtp_password = '57spunk07'
+ #TODO Secure
+ smtp_password = '57spunk07'
from_email = 'sv.stthomas@gmx.at'
to_email = member.member_email
@@ -70,7 +71,10 @@ models.Base.metadata.create_all(bind=engine)
#members = db.query(models.Members).filter(models.Members.member_email != None, ~models.Members.id.in_([183,51,200,49])).all()
#members = db.query(models.Members).filter(models.Members.member_active == True).all()
#members = db.query(models.Members).filter(models.Members.id.in_([2,3,9,199]), models.Members.member_active == True, models.Members.member_printed == False).all()
-members = db.query(models.Members).filter(models.Members.id.in_([73,142])).all()
+members = db.query(models.Members).filter(models.Members.id.in_([8])).all()
for member in members:
- send_mail(member=member)
\ No newline at end of file
+ if member.member_email:
+ send_mail(member=member)
+ else:
+ logging.debug(f'Member {member.member_surname} has no email associated!')
\ No newline at end of file
diff --git a/map.html b/map.html
index fd31ca7..b941983 100644
--- a/map.html
+++ b/map.html
@@ -25,7 +25,7 @@