From 7d76e217f1ee1c7b17f8af045bf8193f7189526a Mon Sep 17 00:00:00 2001 From: Markus Zimmerberger Date: Tue, 19 Nov 2024 09:22:39 +0100 Subject: [PATCH] Reorganize project structure --- GoCardless.py => app/GoCardless.py | 0 config.yaml => app/config.yaml | 4 +- create invoice.py => app/create invoice.py | 0 app/database.py | 15 +++ app/export timesheets.py | 92 ++++++++++++++++++ letterMaker.py => app/letterMaker.py | 4 +- app/main.py | 14 +++ app/models.py | 9 ++ snakehead.jpg => app/snakehead.jpg | Bin .../zisco it consulting logo 2023.png | Bin export timesheets.py | 64 ------------ flyway.conf | 4 + sql/V1__init.sql | 4 + 13 files changed, 142 insertions(+), 68 deletions(-) rename GoCardless.py => app/GoCardless.py (100%) rename config.yaml => app/config.yaml (89%) rename create invoice.py => app/create invoice.py (100%) create mode 100644 app/database.py create mode 100644 app/export timesheets.py rename letterMaker.py => app/letterMaker.py (98%) create mode 100644 app/main.py create mode 100644 app/models.py rename snakehead.jpg => app/snakehead.jpg (100%) rename zisco it consulting logo 2023.png => app/zisco it consulting logo 2023.png (100%) delete mode 100644 export timesheets.py create mode 100644 flyway.conf create mode 100644 sql/V1__init.sql diff --git a/GoCardless.py b/app/GoCardless.py similarity index 100% rename from GoCardless.py rename to app/GoCardless.py diff --git a/config.yaml b/app/config.yaml similarity index 89% rename from config.yaml rename to app/config.yaml index 5248c74..9986dd5 100644 --- a/config.yaml +++ b/app/config.yaml @@ -5,8 +5,8 @@ 'spread': 1.0}, 'visualize_params': {'median_threshold': 6}, 'spreadsheet_name': 'Zeiterfassung alle Projekte', - 'worksheet_name': 'Juni 2024', - 'week': [23], + 'worksheet_name': 'November 2024', + 'week': [45,46], 'name': 'Markus Zimmerberger', 'username': 'ZIM9003', 'ansprechpartner_username': 'GRM0003', diff --git a/create invoice.py b/app/create invoice.py similarity index 100% rename from create invoice.py rename to app/create invoice.py diff --git a/app/database.py b/app/database.py new file mode 100644 index 0000000..8338920 --- /dev/null +++ b/app/database.py @@ -0,0 +1,15 @@ +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker, declarative_base + +DATABASE_URL = 'postgresql://zisco:ELcowUwryNy0PUf3Jr7z@192.168.1.202:5432/zisco' + +engine = create_engine(DATABASE_URL) +SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) +Base = declarative_base() + +def get_db(): + db = SessionLocal() + try: + yield db + finally: + db.close() \ No newline at end of file diff --git a/app/export timesheets.py b/app/export timesheets.py new file mode 100644 index 0000000..dd60e2a --- /dev/null +++ b/app/export timesheets.py @@ -0,0 +1,92 @@ +from dataclasses import dataclass +import gspread +import csv +import locale +import datetime +import yaml +import os + +#TODO: Upload automatically! + +@dataclass +class Export: # all necessary fields for ELSAP-importfiles + sum_col: str + desc_col: str + week: str + bestellnummer: str + bestellposition: str + leistungszeilennummer: str + kurztext: str + leistungszeilentext: str + username: str + name: str + kontierung: str + ansprechpartner_username: str + ansprechpartner_name: str + +def export_timesheet(csvexport_filename, ex: Export): + with open(f"{csvexport_filename}.csv", 'w') as file: + writer = csv.writer(file, delimiter=';', lineterminator="\n") + + writer.writerow(["Bestellnummer","Bestellpositionsnr","Leistungszeilennummer","Kurztext","Leistungszeilentext","Username","Name","Arbeitstag","Stunden","Beschreibung","Kontierung","Ansprechpartner Username","Ansprechpartner","Status"]) + # iterate + for time_entry in list_of_dicts: + if time_entry.get(ex.sum_col) and time_entry.get(ex.desc_col) and time_entry.get("week"): + if (int(time_entry.get("week")) in week) or week is None: + #if week == int(time_entry.get("week")) or week is None: + date_str_de_de = time_entry.get("date") + datetime_object = datetime.datetime.strptime(date_str_de_de, '%a., %d. %B %Y') + if ex.kontierung == '': + sub_kontierung = time_entry.get("pos_service").split("-")[1] + writer.writerow([ex.bestellnummer,ex.bestellposition,ex.leistungszeilennummer,ex.kurztext,ex.leistungszeilentext,ex.username,ex.name,datetime_object.strftime('%d.%m.%Y'),time_entry.get(ex.sum_col),time_entry.get(ex.desc_col),sub_kontierung,ex.ansprechpartner_username,ex.ansprechpartner_name,"OFFEN"]) + else: + writer.writerow([ex.bestellnummer,ex.bestellposition,ex.leistungszeilennummer,ex.kurztext,ex.leistungszeilentext,ex.username,ex.name,datetime_object.strftime('%d.%m.%Y'),time_entry.get(ex.sum_col),time_entry.get(ex.desc_col),ex.kontierung,ex.ansprechpartner_username,ex.ansprechpartner_name,"OFFEN"]) + + # Check if the file size is small (indicating only the header) + file_path = f"{csvexport_filename}.csv" + + # Use os.path.getsize to get the file size + if os.path.getsize(file_path) <= 190: # Adjust this size threshold based on your expected header size + os.remove(file_path) + print(f"File {file_path} was deleted because it only contained the header.") + else: + print(f"File {file_path} contains data and was not deleted.") + +locale.setlocale(locale.LC_ALL, 'de_DE') + +with open("./app/config.yaml", encoding='utf8') as f: + cfg = yaml.load(f, Loader=yaml.FullLoader) + +gc = gspread.service_account() +sh = gc.open(cfg['spreadsheet_name']) +worksheet = sh.worksheet(cfg['worksheet_name']) +week = cfg['week'] # 10, 11, 12 or None + +username = cfg['username'] +name = cfg['name'] +ansprechpartner_username = cfg['ansprechpartner_username'] +ansprechpartner_name = cfg['ansprechpartner_name'] + +# read the whole sheet +list_of_dicts = worksheet.get_all_records(numericise_ignore=['all']) + +for key in ["wgwr3", "wgwr_service", "dkarb", "bauwb", "service"]: + elsap_id = list_of_dicts[2].get(f"sum_{key}") + if elsap_id != "": + csvexport_filename = f"{datetime.date.today().strftime('%Y_%m')}_01_{elsap_id}_{username}" + + ex1 = Export(sum_col=f"sum_{key}", + desc_col=f"desc_{key}", + week=week, + bestellnummer=elsap_id.split('_')[0], + bestellposition=elsap_id.split('_')[1], + leistungszeilennummer=elsap_id.split('_')[2], + kurztext=list_of_dicts[1].get(f"sum_{key}"), + leistungszeilentext=list_of_dicts[3].get(f"sum_{key}"), + username=username, + name=name, + kontierung=list_of_dicts[4].get(f"sum_{key}"), + ansprechpartner_username=ansprechpartner_username, + ansprechpartner_name=ansprechpartner_name) + + export_timesheet(csvexport_filename=csvexport_filename, ex=ex1) \ No newline at end of file diff --git a/letterMaker.py b/app/letterMaker.py similarity index 98% rename from letterMaker.py rename to app/letterMaker.py index 7178658..70dfec4 100644 --- a/letterMaker.py +++ b/app/letterMaker.py @@ -19,7 +19,7 @@ class InvoiceMaker(object): #---------------------------------------------------------------------- - def createDocument(self): + def create_document(self): """""" voffset = 65 @@ -84,5 +84,5 @@ class InvoiceMaker(object): #---------------------------------------------------------------------- if __name__ == "__main__": doc = InvoiceMaker("example.pdf", "The MVP", 10) - doc.createDocument() + doc.create_document() doc.savePDF() \ No newline at end of file diff --git a/app/main.py b/app/main.py new file mode 100644 index 0000000..aff0bc3 --- /dev/null +++ b/app/main.py @@ -0,0 +1,14 @@ +from fastapi import FastAPI, Depends +from sqlalchemy.orm import Session +from . import models, database + +app = FastAPI() + +@app.on_event("startup") +def startup(): + models.Base.metadata.create_all(bind=database.engine) + +@app.get("/users/") +def read_users(db: Session = Depends(database.get_db)): + users = db.query(models.User).all() + return users \ No newline at end of file diff --git a/app/models.py b/app/models.py new file mode 100644 index 0000000..38c3734 --- /dev/null +++ b/app/models.py @@ -0,0 +1,9 @@ +from sqlalchemy import Column, Integer, String +from .database import Base + +class User(Base): + __tablename__ = 'time_recordings' + + id = Column(Integer, primary_key=True, index=True) + project_id = Column(String(255), index=True) + #email = Column(String(255), unique=True, index=True) \ No newline at end of file diff --git a/snakehead.jpg b/app/snakehead.jpg similarity index 100% rename from snakehead.jpg rename to app/snakehead.jpg diff --git a/zisco it consulting logo 2023.png b/app/zisco it consulting logo 2023.png similarity index 100% rename from zisco it consulting logo 2023.png rename to app/zisco it consulting logo 2023.png diff --git a/export timesheets.py b/export timesheets.py deleted file mode 100644 index a8e4ab9..0000000 --- a/export timesheets.py +++ /dev/null @@ -1,64 +0,0 @@ -import gspread -import csv -import locale -import datetime -import yaml - -#TODO: Upload automatically! - -def export_timesheet(Csvexport_filename,Sum_col,Desc_col,Week,Bestellnummer,Bestellposition,Leistungszeilennummer,Kurztext,Leistungszeilentext,Username,Name,Kontierung,Ansprechpartner_username,Ansprechpartner_name): - with open(f"{Csvexport_filename}.csv", 'w') as file: - writer = csv.writer(file, delimiter=';', lineterminator="\n") - - writer.writerow(["Bestellnummer","Bestellpositionsnr","Leistungszeilennummer","Kurztext","Leistungszeilentext","Username","Name","Arbeitstag","Stunden","Beschreibung","Kontierung","Ansprechpartner Username","Ansprechpartner","Status"]) - # iterate - for time_entry in list_of_dicts: - if time_entry.get(Sum_col) and time_entry.get(Desc_col) and time_entry.get("week"): - if (int(time_entry.get("week")) in week) or week is None: - #if week == int(time_entry.get("week")) or week is None: - date_str_de_DE = time_entry.get("date") - datetime_object = datetime.datetime.strptime(date_str_de_DE, '%a., %d. %B %Y') - if Kontierung == '': - SubKontierung = time_entry.get("pos_service").split("-")[1] - writer.writerow([Bestellnummer,Bestellposition,Leistungszeilennummer,Kurztext,Leistungszeilentext,Username,Name,datetime_object.strftime('%d.%m.%Y'),time_entry.get(Sum_col),time_entry.get(Desc_col),SubKontierung,Ansprechpartner_username,Ansprechpartner_name,"OFFEN"]) - else: - writer.writerow([Bestellnummer,Bestellposition,Leistungszeilennummer,Kurztext,Leistungszeilentext,Username,Name,datetime_object.strftime('%d.%m.%Y'),time_entry.get(Sum_col),time_entry.get(Desc_col),Kontierung,Ansprechpartner_username,Ansprechpartner_name,"OFFEN"]) - -locale.setlocale(locale.LC_ALL, 'de_DE') - -with open("config.yaml", encoding='utf8') as f: - cfg = yaml.load(f, Loader=yaml.FullLoader) - -gc = gspread.service_account() -sh = gc.open(cfg['spreadsheet_name']) -worksheet = sh.worksheet(cfg['worksheet_name']) -week = cfg['week'] # 10, 11, 12 or None - -username = cfg['username'] -name = cfg['name'] -ansprechpartner_username = cfg['ansprechpartner_username'] -ansprechpartner_name = cfg['ansprechpartner_name'] - -# read the whole sheet -list_of_dicts = worksheet.get_all_records(numericise_ignore=['all']) - -for key in ["wgwr3", "wgwr_service", "dkarb", "bauwb", "service"]: - elsap_id = list_of_dicts[2].get(f"sum_{key}") - if elsap_id != "": - # elsap_id = worksheet.acell('H3').value #'2061818_00030_0000000020' - csvexport_filename = f"{datetime.date.today().strftime('%Y_%m')}_01_{elsap_id}_{username}" - - export_timesheet(Csvexport_filename=csvexport_filename, - Sum_col=f"sum_{key}", - Desc_col=f"desc_{key}", - Week=week, - Bestellnummer=elsap_id.split('_')[0], - Bestellposition=elsap_id.split('_')[1], - Leistungszeilennummer=elsap_id.split('_')[2], - Kurztext=list_of_dicts[1].get(f"sum_{key}"), - Leistungszeilentext=list_of_dicts[3].get(f"sum_{key}"), - Username=username, - Name=name, - Kontierung=list_of_dicts[4].get(f"sum_{key}"), - Ansprechpartner_username=ansprechpartner_username, - Ansprechpartner_name=ansprechpartner_name) \ No newline at end of file diff --git a/flyway.conf b/flyway.conf new file mode 100644 index 0000000..27218a3 --- /dev/null +++ b/flyway.conf @@ -0,0 +1,4 @@ +flyway.url=jdbc:postgresql://postgresql.home:5432/zisco +flyway.user=zisco +flyway.password=ELcowUwryNy0PUf3Jr7z +flyway.locations=filesystem:./sql \ No newline at end of file diff --git a/sql/V1__init.sql b/sql/V1__init.sql new file mode 100644 index 0000000..2067abd --- /dev/null +++ b/sql/V1__init.sql @@ -0,0 +1,4 @@ +CREATE TABLE zisco.time_recordings ( + id INT AUTO_INCREMENT PRIMARY KEY, + project_id INT +); \ No newline at end of file