lexoffice.py added
This commit is contained in:
parent
59ca900a14
commit
6c120b4da7
@ -1,2 +1,3 @@
|
|||||||
Rechnungsnummer;Email;Anrede
|
Rechnungsnummer;Email;Anrede;Betrag
|
||||||
RE255111;fws-rs@vielhuber.eu;Sehr geehrter Herr Vielhuber
|
RE255111;fws-rs@vielhuber.eu;Sehr geehrter Herr Vielhuber ;N/A
|
||||||
|
RE255111;fws-rs@vielhuber.eu;Sehr geehrter Herr Vielhuber;
|
||||||
|
|||||||
|
@ -40,7 +40,13 @@ def render_htmx_or_full(template_partial, template_full):
|
|||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def index():
|
def index():
|
||||||
return render_htmx_or_full('partials/index.html', 'index.html')
|
dashboard_content = render_template('partials/dashboard.html')
|
||||||
|
return render_template('index.html', dashboard_content=dashboard_content)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/dashboard')
|
||||||
|
def dashboard():
|
||||||
|
return render_template('partials/dashboard.html')
|
||||||
|
|
||||||
|
|
||||||
@app.route('/buchhaltung')
|
@app.route('/buchhaltung')
|
||||||
@ -51,38 +57,27 @@ def buchhaltung():
|
|||||||
@app.route('/add-invoice', methods=['POST'])
|
@app.route('/add-invoice', methods=['POST'])
|
||||||
def add_invoice():
|
def add_invoice():
|
||||||
csv_file_path = os.path.join(current_app.root_path, 'data', 'invoices.csv')
|
csv_file_path = os.path.join(current_app.root_path, 'data', 'invoices.csv')
|
||||||
|
|
||||||
# Extract invoice data from form
|
|
||||||
new_invoice = {
|
new_invoice = {
|
||||||
'Rechnungsnummer': request.form['rechnungsnummer'],
|
'Rechnungsnummer': request.form['rechnungsnummer'],
|
||||||
'Email': request.form['email'],
|
'Email': request.form['email'],
|
||||||
'Anrede': request.form['anrede'],
|
'Anrede': request.form['anrede'],
|
||||||
# Initialize 'Betrag' with a placeholder (to be updated)
|
|
||||||
'Betrag': 'N/A'
|
'Betrag': 'N/A'
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Fetch the total gross amount for the new invoice using LexofficeAPI
|
lexoffice_api = LexofficeAPI()
|
||||||
lexoffice_api = LexofficeAPI('your_access_token') # Replace with actual access token
|
|
||||||
total_gross_amount = lexoffice_api.get_invoice_total_gross_amount(new_invoice['Rechnungsnummer'])
|
total_gross_amount = lexoffice_api.get_invoice_total_gross_amount(new_invoice['Rechnungsnummer'])
|
||||||
|
new_invoice['Betrag'] = total_gross_amount if total_gross_amount is not None else 'N/A'
|
||||||
|
|
||||||
# Update 'Betrag' in the new invoice data
|
with open(csv_file_path, 'r+', newline='', encoding='utf-8') as csvfile:
|
||||||
if total_gross_amount is not None:
|
|
||||||
new_invoice['Betrag'] = total_gross_amount
|
|
||||||
|
|
||||||
# Read existing data from CSV
|
|
||||||
with open(csv_file_path, 'r', newline='', encoding='utf-8') as csvfile:
|
|
||||||
reader = csv.DictReader(csvfile, delimiter=';')
|
reader = csv.DictReader(csvfile, delimiter=';')
|
||||||
|
existing_data = list(reader)
|
||||||
fieldnames = reader.fieldnames
|
fieldnames = reader.fieldnames
|
||||||
if 'Betrag' not in fieldnames:
|
if 'Betrag' not in fieldnames:
|
||||||
fieldnames.append('Betrag')
|
fieldnames.append('Betrag')
|
||||||
existing_data = list(reader)
|
existing_data.insert(0, new_invoice)
|
||||||
|
csvfile.seek(0)
|
||||||
# Add the new invoice at the beginning of the data
|
csvfile.truncate()
|
||||||
existing_data.insert(0, new_invoice)
|
|
||||||
|
|
||||||
# Write the updated data back to the CSV file
|
|
||||||
with open(csv_file_path, 'w', newline='', encoding='utf-8') as csvfile:
|
|
||||||
writer = csv.DictWriter(csvfile, fieldnames=fieldnames, delimiter=';')
|
writer = csv.DictWriter(csvfile, fieldnames=fieldnames, delimiter=';')
|
||||||
writer.writeheader()
|
writer.writeheader()
|
||||||
writer.writerows(existing_data)
|
writer.writerows(existing_data)
|
||||||
@ -90,8 +85,8 @@ def add_invoice():
|
|||||||
return redirect(url_for('buchhaltung'))
|
return redirect(url_for('buchhaltung'))
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"Error updating CSV file: {e}")
|
logging.error(f"Error in add_invoice: {e}")
|
||||||
return "An error occurred while adding the invoice", 500
|
return "An error occurred", 500
|
||||||
|
|
||||||
|
|
||||||
# Other imports and routes...
|
# Other imports and routes...
|
||||||
|
|||||||
@ -125,27 +125,56 @@ body {
|
|||||||
padding: 20px;
|
padding: 20px;
|
||||||
width: calc(100% - var(--sidebar-width-collapsed));
|
width: calc(100% - var(--sidebar-width-collapsed));
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-grid {
|
.card-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
background-color: var(--white);
|
background-color: var(--white);
|
||||||
|
border-radius: 8px;
|
||||||
box-shadow: 0 4px 8px var(--box-shadow-color);
|
box-shadow: 0 4px 8px var(--box-shadow-color);
|
||||||
border-radius: 10px;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
transition: all 0.3s ease;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:hover {
|
||||||
|
box-shadow: 0 6px 12px var(--box-shadow-hover-color);
|
||||||
|
transform: translateY(-5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-icon {
|
||||||
|
font-size: 40px;
|
||||||
|
color: var(--primary-color);
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card:hover {
|
.card-title {
|
||||||
transform: translateY(-2px);
|
font-size: 18px;
|
||||||
box-shadow: 0 5px 10px var(--box-shadow-hover-color);
|
font-weight: bold;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-description {
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--dark-grey);
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-container {
|
.card-container {
|
||||||
|
|||||||
@ -62,7 +62,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<nav class="sidebar">
|
<nav class="sidebar">
|
||||||
<div class="menu-item">
|
<div class="menu-item" hx-get="/dashboard" hx-trigger="click" hx-target="#main-content">
|
||||||
<span class="material-icons menu-icon">dashboard</span>
|
<span class="material-icons menu-icon">dashboard</span>
|
||||||
<span class="menu-label">Übersicht</span>
|
<span class="menu-label">Übersicht</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
56
app/templates/partials/dashboard.html
Normal file
56
app/templates/partials/dashboard.html
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<div class="container">
|
||||||
|
<section id="main-content">
|
||||||
|
<h1>Tocknerheld-Dashboard</h1>
|
||||||
|
<p>Bitte wähle einen Menüpunkt, um in den entsprechenden Bereich zu springen.</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Dashboard Cards Section -->
|
||||||
|
<section id="dashboard-cards">
|
||||||
|
<div class="card-grid">
|
||||||
|
<!-- Buchhaltung Card -->
|
||||||
|
<div class="card" hx-get="/buchhaltung" hx-trigger="click" hx-target="#main-content">
|
||||||
|
<span class="material-icons card-icon">account_balance_wallet</span>
|
||||||
|
<div class="card-content">
|
||||||
|
<h3 class="card-title">Buchhaltung</h3>
|
||||||
|
<p class="card-description">Verwalte Deine Buchhaltung und Finanzunterlagen effizient.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Zahlungserinnerungen Card -->
|
||||||
|
<div class="card" hx-get="/zahlungserinnerungen" hx-trigger="click" hx-target="#main-content">
|
||||||
|
<span class="material-icons card-icon">notifications_active</span>
|
||||||
|
<div class="card-content">
|
||||||
|
<h3 class="card-title">Zahlungserinnerungen</h3>
|
||||||
|
<p class="card-description">Behalte alle Zahlungen im Blick und verpasse nie eine Frist.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Flottenmanagement Card -->
|
||||||
|
<div class="card" hx-get="/flottenmanagement" hx-trigger="click" hx-target="#main-content">
|
||||||
|
<span class="material-icons card-icon">directions_car</span>
|
||||||
|
<div class="card-content">
|
||||||
|
<h3 class="card-title">Flottenmanagement</h3>
|
||||||
|
<p class="card-description">Verwalte Deine Fahrzeugflotte einfach und effizient.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Mitarbeiter Card -->
|
||||||
|
<div class="card">
|
||||||
|
<span class="material-icons card-icon">people</span>
|
||||||
|
<div class="card-content">
|
||||||
|
<h3 class="card-title">Mitarbeiter</h3>
|
||||||
|
<p class="card-description">Organisiere und manage Dein Team reibungslos und effektiv.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Einstellungen Card -->
|
||||||
|
<div class="card">
|
||||||
|
<span class="material-icons card-icon">settings</span>
|
||||||
|
<div class="card-content">
|
||||||
|
<h3 class="card-title">Einstellungen</h3>
|
||||||
|
<p class="card-description">Passe die Einstellungen Deiner Web-App nach Deinen Wünschen an.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
20
run.py
20
run.py
@ -1,7 +1,23 @@
|
|||||||
import logging
|
import logging
|
||||||
|
from logging.handlers import RotatingFileHandler
|
||||||
|
import sys
|
||||||
from app import app
|
from app import app
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
logging.basicConfig(filename='app.log', level=logging.DEBUG,
|
def configure_logging():
|
||||||
|
logging.basicConfig(level=logging.DEBUG,
|
||||||
format='%(asctime)s %(levelname)s %(name)s : %(message)s')
|
format='%(asctime)s %(levelname)s %(name)s : %(message)s')
|
||||||
|
|
||||||
|
file_handler = RotatingFileHandler('app.log', maxBytes=10000, backupCount=1)
|
||||||
|
file_handler.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
|
console_handler = logging.StreamHandler(sys.stdout)
|
||||||
|
console_handler.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
logging.getLogger().addHandler(file_handler)
|
||||||
|
logging.getLogger().addHandler(console_handler)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
configure_logging()
|
||||||
app.run(debug=True)
|
app.run(debug=True)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user