Reorganize project structure
This commit is contained in:
@@ -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'}
|
||||
)
|
||||
@@ -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'}
|
||||
@@ -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}" """
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
@@ -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
@@ -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
|
||||
@@ -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)
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 9.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
Reference in New Issue
Block a user