Reorganize project structure

This commit is contained in:
Markus Zimmerberger
2024-11-19 09:22:39 +01:00
parent 48d06341ef
commit 7d76e217f1
13 changed files with 142 additions and 68 deletions
+27
View File
@@ -0,0 +1,27 @@
from decimal import Decimal
import gocardless_pro
import os
token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzA2OTY4NjI1LCJqdGkiOiJkMDUzN2I5MmIzMTg0M2RmYjE4NTdlMDg1NDUyYWRkZSIsInV1aWQiOiI4MjA4MDMxNy1mZTVlLTRjNDMtODlkZi0xOWViMzdhNWJlZDAiLCJhbGxvd2VkX2NpZHJzIjpbIjAuMC4wLjAvMCIsIjo6LzAiXX0.qr1Y3A9NEzJFqYmm6cPuZqxYqVJliL4CHy8ajRh_nis'
#os.environ['ACCESS_TOKEN']
client = gocardless_pro.Client(access_token=token, environment='live')
# Create a new customer. We automatically add idempotency keys to requests to create
# resources, stopping duplicates accidentally getting created if something goes wrong
# with the API (e.g. networking problems) - see https://developer.gocardless.com/api
# -reference/#making-requests-idempotency-keys for details
customer = client.customers.create(params={'email': 'markus.zimmerberger@zisco.at'})
# Fetch a payment by its ID
payment = client.payments.get("PA123")
# Loop through a page of payments, printing each payment's amount
for payment in client.payments.list().records:
decimal_amount = Decimal.Decimal(payment.amount) / 100
print('Payment for £{0}'.format(decimal_amount))
# Create a mandate PDF in a specific language
client.mandate_pdfs.create(
params={'links': {'mandate': 'MD00001234XYZ'}},
headers={'Accept-Language': 'fr'}
)
+13
View File
@@ -0,0 +1,13 @@
{'maintainer': 'Markus Zimmerberger',
'pca_params': {'n_components': 224},
'umap_params': {'metrics': ['euclidean', 'l1', 'manhattan'],
'min_dist': [0.01, 0.1, 0.5],
'spread': 1.0},
'visualize_params': {'median_threshold': 6},
'spreadsheet_name': 'Zeiterfassung alle Projekte',
'worksheet_name': 'November 2024',
'week': [45,46],
'name': 'Markus Zimmerberger',
'username': 'ZIM9003',
'ansprechpartner_username': 'GRM0003',
'ansprechpartner_name': 'Marlene Griesser'}
+50
View File
@@ -0,0 +1,50 @@
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from reportlab.lib.utils import ImageReader
from reportlab.lib import colors
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle
import gspread
import csv
import locale
import datetime
import yaml
with open("config.yaml", encoding='utf8') as f:
cfg = yaml.load(f, Loader=yaml.FullLoader)
locale.setlocale(locale.LC_ALL, 'de_DE')
gc = gspread.service_account()
sh = gc.open('Zeiterfassung alle Projekte')
worksheet = sh.worksheet(cfg['worksheet_name'])
invoice_nr = 'R000543'
# read the whole sheet
list_of_dicts = worksheet.get_all_records(numericise_ignore=['all'])
doc = SimpleDocTemplate(f"{invoice_nr}.pdf", pagesize=A4)
# container for the 'Flowable' objects
elements = []
data= [['00', '01', '02', '03', '04'],
['10', '11', '12', '13', '14'],
['20', '21', '22', '23', '24'],
['30', '31', '32', '33', '34']]
t = Table(data)
t.setStyle(TableStyle([('BACKGROUND',(1,1),(-2,-2),colors.green),
('TEXTCOLOR',(0,0),(1,-1),colors.red)]))
elements.append(t)
# write the document to disk
doc.build(elements)
""" for key in ["wgwr3", "wgwr_service", "dkarb", "bauwb"]:
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}" """
+15
View File
@@ -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()
+92
View File
@@ -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)
+88
View File
@@ -0,0 +1,88 @@
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import mm, inch
from reportlab.pdfgen import canvas
from reportlab.platypus import Image, Paragraph, Table
########################################################################
class InvoiceMaker(object):
""""""
#----------------------------------------------------------------------
def __init__(self, pdf_file, org, seconds):
self.c = canvas.Canvas(pdf_file, pagesize=A4)
self.styles = getSampleStyleSheet()
self.width, self.height = A4
self.organization = org
self.seconds = seconds
#----------------------------------------------------------------------
def create_document(self):
""""""
voffset = 65
# create return address
address = """<font size="9">
Markus Zimmerberger<br/>
zisco it consulting e.U.<br/>
4732 St. Thomas 80, Austria</font>
"""
p = Paragraph(address, self.styles["Normal"])
# add a logo and size it
logo = Image("zisco it consulting logo 2023.png")
logo.drawHeight = 2*inch
logo.drawWidth = 2*inch
## logo.wrapOn(self.c, self.width, self.height)
## logo.drawOn(self.c, *self.coord(140, 60, mm))
##
data = [[p, logo]]
table = Table(data, colWidths=4*inch)
table.setStyle([("VALIGN", (0,0), (0,0), "TOP")])
table.wrapOn(self.c, self.width, self.height)
table.drawOn(self.c, *self.coord(18, 60, mm))
# insert body of letter
ptext = "Dear Sir or Madam:"
self.createParagraph(ptext, 20, voffset+35)
ptext = """
The document you are holding is a set of requirements for your next mission, should you
choose to accept it. In any event, this document will self-destruct <b>%s</b> seconds after you
read it. Yes, <b>%s</b> can tell when you're done...usually.
""" % (self.seconds, self.organization)
p = Paragraph(ptext, self.styles["Normal"])
p.wrapOn(self.c, self.width-70, self.height)
p.drawOn(self.c, *self.coord(20, voffset+48, mm))
#----------------------------------------------------------------------
def coord(self, x, y, unit=1):
"""
# http://stackoverflow.com/questions/4726011/wrap-text-in-a-table-reportlab
Helper class to help position flowables in Canvas objects
"""
x, y = x * unit, self.height - y * unit
return x, y
#----------------------------------------------------------------------
def createParagraph(self, ptext, x, y, style=None):
""""""
if not style:
style = self.styles["Normal"]
p = Paragraph(ptext, style=style)
p.wrapOn(self.c, self.width, self.height)
p.drawOn(self.c, *self.coord(x, y, mm))
#----------------------------------------------------------------------
def savePDF(self):
""""""
self.c.save()
#----------------------------------------------------------------------
if __name__ == "__main__":
doc = InvoiceMaker("example.pdf", "The MVP", 10)
doc.create_document()
doc.savePDF()
+14
View File
@@ -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
+9
View File
@@ -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)
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB