Accordion-Logik und Panel-Index korrigiert, kombinierte Plus/Minus-Funktion, Tests aktualisiert
This commit is contained in:
82
app.py
82
app.py
@@ -41,6 +41,7 @@ def index():
|
|||||||
f.write(f"{dt.now().isoformat()} PAGEVIEW\n")
|
f.write(f"{dt.now().isoformat()} PAGEVIEW\n")
|
||||||
tage = werktage = wochentag = datumsrechnung = werktagsrechnung = kw_berechnen = kw_datum = wochen_monate = None
|
tage = werktage = wochentag = datumsrechnung = werktagsrechnung = kw_berechnen = kw_datum = wochen_monate = None
|
||||||
active_idx = 0
|
active_idx = 0
|
||||||
|
plusminus_result = None
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
action = request.form.get('action')
|
action = request.form.get('action')
|
||||||
# Funktions-Logging
|
# Funktions-Logging
|
||||||
@@ -64,48 +65,15 @@ def index():
|
|||||||
except Exception:
|
except Exception:
|
||||||
tage = 'Ungültige Eingabe'
|
tage = 'Ungültige Eingabe'
|
||||||
elif action == 'wochentag':
|
elif action == 'wochentag':
|
||||||
active_idx = 2
|
active_idx = 1
|
||||||
datum = request.form.get('datum3')
|
datum = request.form.get('datum3')
|
||||||
try:
|
try:
|
||||||
d = datetime.strptime(datum, '%Y-%m-%d')
|
d = datetime.strptime(datum, '%Y-%m-%d')
|
||||||
wochentag = WOCHENTAGE[d.weekday()]
|
wochentag = WOCHENTAGE[d.weekday()]
|
||||||
except Exception:
|
except Exception:
|
||||||
wochentag = 'Ungültige Eingabe'
|
wochentag = 'Ungültige Eingabe'
|
||||||
elif action == 'datumsrechnung':
|
|
||||||
active_idx = 3
|
|
||||||
datum = request.form.get('datum4')
|
|
||||||
tage_input = request.form.get('tage4')
|
|
||||||
richtung = request.form.get('richtung4')
|
|
||||||
try:
|
|
||||||
d = datetime.strptime(datum, '%Y-%m-%d')
|
|
||||||
tage_int = int(tage_input)
|
|
||||||
if richtung == 'add':
|
|
||||||
result = d + timedelta(days=tage_int)
|
|
||||||
else:
|
|
||||||
result = d - timedelta(days=tage_int)
|
|
||||||
datumsrechnung = result.strftime('%d.%m.%Y')
|
|
||||||
except Exception:
|
|
||||||
datumsrechnung = 'Ungültige Eingabe'
|
|
||||||
elif action == 'werktagsrechnung':
|
|
||||||
active_idx = 4
|
|
||||||
datum = request.form.get('datum5')
|
|
||||||
tage_input = request.form.get('tage5')
|
|
||||||
richtung = request.form.get('richtung5')
|
|
||||||
try:
|
|
||||||
d = datetime.strptime(datum, '%Y-%m-%d').date()
|
|
||||||
tage_int = int(tage_input)
|
|
||||||
if richtung == 'add':
|
|
||||||
result = np.busday_offset(d, tage_int, roll='forward')
|
|
||||||
else:
|
|
||||||
result = np.busday_offset(d, -tage_int, roll='backward')
|
|
||||||
werktagsrechnung = np.datetime_as_string(result, unit='D')
|
|
||||||
# Formatierung auf deutsch
|
|
||||||
dt = datetime.strptime(werktagsrechnung, '%Y-%m-%d')
|
|
||||||
werktagsrechnung = dt.strftime('%d.%m.%Y')
|
|
||||||
except Exception:
|
|
||||||
werktagsrechnung = 'Ungültige Eingabe'
|
|
||||||
elif action == 'kw_berechnen':
|
elif action == 'kw_berechnen':
|
||||||
active_idx = 5
|
active_idx = 2
|
||||||
datum = request.form.get('datum6')
|
datum = request.form.get('datum6')
|
||||||
try:
|
try:
|
||||||
d = datetime.strptime(datum, '%Y-%m-%d')
|
d = datetime.strptime(datum, '%Y-%m-%d')
|
||||||
@@ -114,7 +82,7 @@ def index():
|
|||||||
except Exception:
|
except Exception:
|
||||||
kw_berechnen = 'Ungültige Eingabe'
|
kw_berechnen = 'Ungültige Eingabe'
|
||||||
elif action == 'kw_datum':
|
elif action == 'kw_datum':
|
||||||
active_idx = 6
|
active_idx = 3
|
||||||
jahr = request.form.get('jahr7')
|
jahr = request.form.get('jahr7')
|
||||||
kw = request.form.get('kw7')
|
kw = request.form.get('kw7')
|
||||||
try:
|
try:
|
||||||
@@ -126,24 +94,42 @@ def index():
|
|||||||
kw_datum = f"{start.strftime('%d.%m.%Y')} bis {end.strftime('%d.%m.%Y')}"
|
kw_datum = f"{start.strftime('%d.%m.%Y')} bis {end.strftime('%d.%m.%Y')}"
|
||||||
except Exception:
|
except Exception:
|
||||||
kw_datum = 'Ungültige Eingabe'
|
kw_datum = 'Ungültige Eingabe'
|
||||||
elif action == 'wochen_monate':
|
elif action == 'plusminus':
|
||||||
datum = request.form.get('datum8')
|
active_idx = 4
|
||||||
anzahl = request.form.get('anzahl8')
|
datum = request.form.get('datum_pm')
|
||||||
einheit = request.form.get('einheit8')
|
anzahl = request.form.get('anzahl_pm')
|
||||||
richtung = request.form.get('richtung8')
|
einheit = request.form.get('einheit_pm')
|
||||||
|
richtung = request.form.get('richtung_pm')
|
||||||
|
is_werktage = request.form.get('werktage_pm') in ('on', 'true', '1', True)
|
||||||
try:
|
try:
|
||||||
d = datetime.strptime(datum, '%Y-%m-%d')
|
d = datetime.strptime(datum, '%Y-%m-%d')
|
||||||
anzahl_int = int(anzahl)
|
anzahl_int = int(anzahl)
|
||||||
if richtung == 'sub':
|
if richtung == 'sub':
|
||||||
anzahl_int = -anzahl_int
|
anzahl_int = -anzahl_int
|
||||||
if einheit == 'wochen':
|
if einheit == 'tage':
|
||||||
result = d + timedelta(weeks=anzahl_int)
|
if is_werktage:
|
||||||
else:
|
# Werktage: numpy busday_offset
|
||||||
result = d + relativedelta(months=anzahl_int)
|
result = np.busday_offset(d.date(), anzahl_int, roll='forward')
|
||||||
wochen_monate = result.strftime('%d.%m.%Y')
|
result_dt = datetime.strptime(str(result), '%Y-%m-%d')
|
||||||
|
plusminus_result = f"Datum {d.strftime('%d.%m.%Y')} {'plus' if anzahl_int>=0 else 'minus'} {abs(anzahl_int)} Werktage: {result_dt.strftime('%d.%m.%Y')}"
|
||||||
|
else:
|
||||||
|
result = d + timedelta(days=anzahl_int)
|
||||||
|
plusminus_result = f"Datum {d.strftime('%d.%m.%Y')} {'plus' if anzahl_int>=0 else 'minus'} {abs(anzahl_int)} Tage: {result.strftime('%d.%m.%Y')}"
|
||||||
|
elif einheit == 'wochen':
|
||||||
|
if is_werktage:
|
||||||
|
plusminus_result = 'Nicht unterstützt: Werktage + Wochen.'
|
||||||
|
else:
|
||||||
|
result = d + timedelta(weeks=anzahl_int)
|
||||||
|
plusminus_result = f"Datum {d.strftime('%d.%m.%Y')} {'plus' if anzahl_int>=0 else 'minus'} {abs(anzahl_int)} Wochen: {result.strftime('%d.%m.%Y')}"
|
||||||
|
elif einheit == 'monate':
|
||||||
|
if is_werktage:
|
||||||
|
plusminus_result = 'Nicht unterstützt: Werktage + Monate.'
|
||||||
|
else:
|
||||||
|
result = d + relativedelta(months=anzahl_int)
|
||||||
|
plusminus_result = f"Datum {d.strftime('%d.%m.%Y')} {'plus' if anzahl_int>=0 else 'minus'} {abs(anzahl_int)} Monate: {result.strftime('%d.%m.%Y')}"
|
||||||
except Exception:
|
except Exception:
|
||||||
wochen_monate = 'Ungültige Eingabe'
|
plusminus_result = 'Ungültige Eingabe'
|
||||||
return render_template('index.html', tage=tage, werktage=werktage, wochentag=wochentag, datumsrechnung=datumsrechnung, werktagsrechnung=werktagsrechnung, kw_berechnen=kw_berechnen, kw_datum=kw_datum, active_idx=active_idx, wochen_monate=wochen_monate)
|
return render_template('index.html', tage=tage, werktage=werktage, wochentag=wochentag, plusminus_result=plusminus_result, kw_berechnen=kw_berechnen, kw_datum=kw_datum, active_idx=active_idx)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/stats', methods=['GET', 'POST'])
|
@app.route('/stats', methods=['GET', 'POST'])
|
||||||
|
@@ -92,7 +92,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="accordion-item">
|
<div class="accordion-item">
|
||||||
<button type="button" class="accordion-header header-wochentag" onclick="openAccordion(2)">
|
<button type="button" class="accordion-header header-wochentag" onclick="openAccordion(1)">
|
||||||
<span style="vertical-align:middle;display:inline-block;width:1.5em;">
|
<span style="vertical-align:middle;display:inline-block;width:1.5em;">
|
||||||
<!-- Kalender mit W -->
|
<!-- Kalender mit W -->
|
||||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="3" y="5" width="18" height="16" rx="4" fill="#fff" stroke="#2563eb" stroke-width="2"/><rect x="3" y="5" width="18" height="4" rx="2" fill="#2563eb"/><rect x="6" y="2" width="2" height="4" rx="1" fill="#2563eb"/><rect x="16" y="2" width="2" height="4" rx="1" fill="#2563eb"/><text x="12" y="17" text-anchor="middle" font-size="12" font-family="Segoe UI, Arial, sans-serif" fill="#2563eb" font-weight="bold">W</text></svg>
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="3" y="5" width="18" height="16" rx="4" fill="#fff" stroke="#2563eb" stroke-width="2"/><rect x="3" y="5" width="18" height="4" rx="2" fill="#2563eb"/><rect x="6" y="2" width="2" height="4" rx="1" fill="#2563eb"/><rect x="16" y="2" width="2" height="4" rx="1" fill="#2563eb"/><text x="12" y="17" text-anchor="middle" font-size="12" font-family="Segoe UI, Arial, sans-serif" fill="#2563eb" font-weight="bold">W</text></svg>
|
||||||
@@ -115,101 +115,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="accordion-item">
|
<div class="accordion-item">
|
||||||
<button type="button" class="accordion-header header-plusminus-tage" onclick="openAccordion(3)">
|
<button type="button" class="accordion-header header-kw-datum" onclick="openAccordion(2)">
|
||||||
<span style="vertical-align:middle;display:inline-block;width:1.5em;">
|
|
||||||
<!-- Kalender mit ± -->
|
|
||||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="3" y="5" width="18" height="16" rx="4" fill="#fff" stroke="#2563eb" stroke-width="2"/><rect x="3" y="5" width="18" height="4" rx="2" fill="#2563eb"/><rect x="6" y="2" width="2" height="4" rx="1" fill="#2563eb"/><rect x="16" y="2" width="2" height="4" rx="1" fill="#2563eb"/><text x="12" y="17" text-anchor="middle" font-size="16" font-family="Segoe UI, Arial, sans-serif" fill="#2563eb" font-weight="bold">±</text></svg>
|
|
||||||
</span>
|
|
||||||
Datum plus/minus X Tage
|
|
||||||
</button>
|
|
||||||
<div class="accordion-content">
|
|
||||||
<form method="post">
|
|
||||||
<label>Datum:<br>
|
|
||||||
<span class="date-row">
|
|
||||||
<input type="date" name="datum4" id="datum4">
|
|
||||||
<button type="button" class="today-btn" onclick="setToday('datum4')">Heute</button>
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
<label>Anzahl Tage:<br>
|
|
||||||
<input type="number" name="tage4" id="tage4" style="width: 6em;">
|
|
||||||
</label>
|
|
||||||
<span class="date-calc-row">
|
|
||||||
<label><input type="radio" name="richtung4" value="add" checked> addieren</label>
|
|
||||||
<label><input type="radio" name="richtung4" value="sub"> subtrahieren</label>
|
|
||||||
</span>
|
|
||||||
<button name="action" value="datumsrechnung" type="submit">Berechnen</button>
|
|
||||||
</form>
|
|
||||||
{% if datumsrechnung is not none %}
|
|
||||||
<div class="result">Datum <b>{{ format_date(request.form.get('datum4', '')) }}</b> {{ 'plus' if request.form.get('richtung4') == 'add' else 'minus' }} <b>{{ request.form.get('tage4', '') }}</b> Tage: {{ datumsrechnung }}</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="accordion-item">
|
|
||||||
<button type="button" class="accordion-header header-plusminus-werktage" onclick="openAccordion(4)">
|
|
||||||
<span style="vertical-align:middle;display:inline-block;width:1.5em;">
|
|
||||||
<!-- Kalender mit ± und Mo-Fr -->
|
|
||||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="3" y="5" width="18" height="16" rx="4" fill="#fff" stroke="#2563eb" stroke-width="2"/><rect x="3" y="5" width="18" height="4" rx="2" fill="#2563eb"/><rect x="6" y="2" width="2" height="4" rx="1" fill="#2563eb"/><rect x="16" y="2" width="2" height="4" rx="1" fill="#2563eb"/><text x="12" y="14" text-anchor="middle" font-size="10" font-family="Segoe UI, Arial, sans-serif" fill="#2563eb" font-weight="bold">±</text><text x="12" y="20" text-anchor="middle" font-size="7" font-family="Segoe UI, Arial, sans-serif" fill="#2563eb" font-weight="bold">Mo-Fr</text></svg>
|
|
||||||
</span>
|
|
||||||
Datum plus/minus X Werktage
|
|
||||||
</button>
|
|
||||||
<div class="accordion-content">
|
|
||||||
<form method="post">
|
|
||||||
<label>Datum:<br>
|
|
||||||
<span class="date-row">
|
|
||||||
<input type="date" name="datum5" id="datum5">
|
|
||||||
<button type="button" class="today-btn" onclick="setToday('datum5')">Heute</button>
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
<label>Anzahl Werktage:<br>
|
|
||||||
<input type="number" name="tage5" id="tage5" style="width: 6em;">
|
|
||||||
</label>
|
|
||||||
<span class="date-calc-row">
|
|
||||||
<label><input type="radio" name="richtung5" value="add" checked> addieren</label>
|
|
||||||
<label><input type="radio" name="richtung5" value="sub"> subtrahieren</label>
|
|
||||||
</span>
|
|
||||||
<button name="action" value="werktagsrechnung" type="submit">Berechnen</button>
|
|
||||||
</form>
|
|
||||||
{% if werktagsrechnung is not none %}
|
|
||||||
<div class="result">Datum <b>{{ format_date(request.form.get('datum5', '')) }}</b> {{ 'plus' if request.form.get('richtung5') == 'add' else 'minus' }} <b>{{ request.form.get('tage5', '') }}</b> Werktage: {{ werktagsrechnung }}</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="accordion-item">
|
|
||||||
<button type="button" class="accordion-header header-plusminus-wochenmonate" onclick="openAccordion(5)">
|
|
||||||
<span style="vertical-align:middle;display:inline-block;width:1.5em;">
|
|
||||||
<!-- Kalender mit ± und W/M -->
|
|
||||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="3" y="5" width="18" height="16" rx="4" fill="#fff" stroke="#2563eb" stroke-width="2"/><rect x="3" y="5" width="18" height="4" rx="2" fill="#2563eb"/><rect x="6" y="2" width="2" height="4" rx="1" fill="#2563eb"/><rect x="16" y="2" width="2" height="4" rx="1" fill="#2563eb"/><text x="12" y="14" text-anchor="middle" font-size="10" font-family="Segoe UI, Arial, sans-serif" fill="#2563eb" font-weight="bold">±</text><text x="12" y="20" text-anchor="middle" font-size="7" font-family="Segoe UI, Arial, sans-serif" fill="#2563eb" font-weight="bold">W/M</text></svg>
|
|
||||||
</span>
|
|
||||||
Datum plus/minus X Wochen/Monate
|
|
||||||
</button>
|
|
||||||
<div class="accordion-content">
|
|
||||||
<form method="post">
|
|
||||||
<label>Datum:<br>
|
|
||||||
<span class="date-row">
|
|
||||||
<input type="date" name="datum8" id="datum8">
|
|
||||||
<button type="button" class="today-btn" onclick="setToday('datum8')">Heute</button>
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
<label>Anzahl:<br>
|
|
||||||
<input type="number" name="anzahl8" id="anzahl8" style="width: 6em;">
|
|
||||||
</label>
|
|
||||||
<span class="date-calc-row">
|
|
||||||
<label><input type="radio" name="einheit8" value="wochen" checked> Wochen</label>
|
|
||||||
<label><input type="radio" name="einheit8" value="monate"> Monate</label>
|
|
||||||
</span>
|
|
||||||
<span class="date-calc-row">
|
|
||||||
<label><input type="radio" name="richtung8" value="add" checked> addieren</label>
|
|
||||||
<label><input type="radio" name="richtung8" value="sub"> subtrahieren</label>
|
|
||||||
</span>
|
|
||||||
<button name="action" value="wochen_monate" type="submit">Berechnen</button>
|
|
||||||
</form>
|
|
||||||
{% if wochen_monate is not none %}
|
|
||||||
<div class="result">Datum <b>{{ format_date(request.form.get('datum8', '')) }}</b> {{ 'plus' if request.form.get('richtung8') == 'add' else 'minus' }} <b>{{ request.form.get('anzahl8', '') }}</b> {{ 'Wochen' if request.form.get('einheit8') == 'wochen' else 'Monate' }}: {{ wochen_monate }}</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="accordion-item">
|
|
||||||
<button type="button" class="accordion-header header-kw-datum" onclick="openAccordion(7)">
|
|
||||||
<span style="vertical-align:middle;display:inline-block;width:1.5em;">
|
<span style="vertical-align:middle;display:inline-block;width:1.5em;">
|
||||||
<!-- Kalender mit # -->
|
<!-- Kalender mit # -->
|
||||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="3" y="5" width="18" height="16" rx="4" fill="#fff" stroke="#2563eb" stroke-width="2"/><rect x="3" y="5" width="18" height="4" rx="2" fill="#2563eb"/><rect x="6" y="2" width="2" height="4" rx="1" fill="#2563eb"/><rect x="16" y="2" width="2" height="4" rx="1" fill="#2563eb"/><text x="12" y="17" text-anchor="middle" font-size="13" font-family="Segoe UI, Arial, sans-serif" fill="#2563eb" font-weight="bold">#</text></svg>
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="3" y="5" width="18" height="16" rx="4" fill="#fff" stroke="#2563eb" stroke-width="2"/><rect x="3" y="5" width="18" height="4" rx="2" fill="#2563eb"/><rect x="6" y="2" width="2" height="4" rx="1" fill="#2563eb"/><rect x="16" y="2" width="2" height="4" rx="1" fill="#2563eb"/><text x="12" y="17" text-anchor="middle" font-size="13" font-family="Segoe UI, Arial, sans-serif" fill="#2563eb" font-weight="bold">#</text></svg>
|
||||||
@@ -232,7 +138,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="accordion-item">
|
<div class="accordion-item">
|
||||||
<button type="button" class="accordion-header header-kw" onclick="openAccordion(6)">
|
<button type="button" class="accordion-header header-kw" onclick="openAccordion(3)">
|
||||||
<span style="vertical-align:middle;display:inline-block;width:1.5em;">
|
<span style="vertical-align:middle;display:inline-block;width:1.5em;">
|
||||||
<!-- Kalender mit Pfeil nach außen -->
|
<!-- Kalender mit Pfeil nach außen -->
|
||||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="3" y="5" width="18" height="16" rx="4" fill="#fff" stroke="#2563eb" stroke-width="2"/><rect x="3" y="5" width="18" height="4" rx="2" fill="#2563eb"/><rect x="6" y="2" width="2" height="4" rx="1" fill="#2563eb"/><rect x="16" y="2" width="2" height="4" rx="1" fill="#2563eb"/><path d="M7 17l5-5 5 5" stroke="#2563eb" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><text x="12" y="12" text-anchor="middle" font-size="8" font-family="Segoe UI, Arial, sans-serif" fill="#2563eb" font-weight="bold">KW</text></svg>
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="3" y="5" width="18" height="16" rx="4" fill="#fff" stroke="#2563eb" stroke-width="2"/><rect x="3" y="5" width="18" height="4" rx="2" fill="#2563eb"/><rect x="6" y="2" width="2" height="4" rx="1" fill="#2563eb"/><rect x="16" y="2" width="2" height="4" rx="1" fill="#2563eb"/><path d="M7 17l5-5 5 5" stroke="#2563eb" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><text x="12" y="12" text-anchor="middle" font-size="8" font-family="Segoe UI, Arial, sans-serif" fill="#2563eb" font-weight="bold">KW</text></svg>
|
||||||
@@ -254,6 +160,46 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="accordion-item">
|
||||||
|
<button type="button" class="accordion-header header-plusminus" onclick="openAccordion(4)">
|
||||||
|
<span style="vertical-align:middle;display:inline-block;width:1.5em;">
|
||||||
|
<!-- Kalender mit ± -->
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="3" y="5" width="18" height="16" rx="4" fill="#fff" stroke="#2563eb" stroke-width="2"/><rect x="3" y="5" width="18" height="4" rx="2" fill="#2563eb"/><rect x="6" y="2" width="2" height="4" rx="1" fill="#2563eb"/><rect x="16" y="2" width="2" height="4" rx="1" fill="#2563eb"/><text x="12" y="17" text-anchor="middle" font-size="16" font-family="Segoe UI, Arial, sans-serif" fill="#2563eb" font-weight="bold">±</text></svg>
|
||||||
|
</span>
|
||||||
|
Datum plus/minus X Tage/Wochen/Monate
|
||||||
|
</button>
|
||||||
|
<div class="accordion-content">
|
||||||
|
<form method="post">
|
||||||
|
<label>Datum:<br>
|
||||||
|
<span class="date-row">
|
||||||
|
<input type="date" name="datum_pm" id="datum_pm">
|
||||||
|
<button type="button" class="today-btn" onclick="setToday('datum_pm')">Heute</button>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<label>Anzahl:<br>
|
||||||
|
<input type="number" name="anzahl_pm" id="anzahl_pm" style="width: 6em;">
|
||||||
|
</label>
|
||||||
|
<span class="date-calc-row">
|
||||||
|
<label><input type="radio" name="richtung_pm" value="add" checked> addieren</label>
|
||||||
|
<label><input type="radio" name="richtung_pm" value="sub"> subtrahieren</label>
|
||||||
|
</span>
|
||||||
|
<span class="date-calc-row">
|
||||||
|
<label>Einheit:
|
||||||
|
<select name="einheit_pm" id="einheit_pm">
|
||||||
|
<option value="tage">Tage</option>
|
||||||
|
<option value="wochen">Wochen</option>
|
||||||
|
<option value="monate">Monate</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<label style="margin-left:1em;"><input type="checkbox" name="werktage_pm" id="werktage_pm"> Nur Werktage</label>
|
||||||
|
</span>
|
||||||
|
<button name="action" value="plusminus" type="submit">Berechnen</button>
|
||||||
|
</form>
|
||||||
|
{% if plusminus_result is not none %}
|
||||||
|
<div class="result">{{ plusminus_result }}</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer style="text-align:center; margin-top:2em; color:#64748b; font-size:0.98em; padding-bottom:1.5em;">
|
<footer style="text-align:center; margin-top:2em; color:#64748b; font-size:0.98em; padding-bottom:1.5em;">
|
||||||
|
102
test_app.py
102
test_app.py
@@ -13,15 +13,105 @@ def test_homepage(client):
|
|||||||
assert resp.status_code == 200
|
assert resp.status_code == 200
|
||||||
assert b'Elpatrons Datumsrechner' in resp.data
|
assert b'Elpatrons Datumsrechner' in resp.data
|
||||||
|
|
||||||
def test_tage_berechnung(client):
|
def test_plusminus_tage(client):
|
||||||
resp = client.post('/', data={
|
resp = client.post('/', data={
|
||||||
'action': 'tage_werktage',
|
'action': 'plusminus',
|
||||||
'start1': '2024-01-01',
|
'datum_pm': '2024-01-10',
|
||||||
'end1': '2024-01-10'
|
'anzahl_pm': '5',
|
||||||
|
'einheit_pm': 'tage',
|
||||||
|
'richtung_pm': 'add'
|
||||||
})
|
})
|
||||||
assert resp.status_code == 200
|
assert resp.status_code == 200
|
||||||
assert b'Anzahl der Tage' in resp.data
|
assert b'plus 5 Tage' in resp.data
|
||||||
assert b'9' in resp.data
|
assert b'15.01.2024' in resp.data
|
||||||
|
# Subtraktion
|
||||||
|
resp = client.post('/', data={
|
||||||
|
'action': 'plusminus',
|
||||||
|
'datum_pm': '2024-01-10',
|
||||||
|
'anzahl_pm': '5',
|
||||||
|
'einheit_pm': 'tage',
|
||||||
|
'richtung_pm': 'sub'
|
||||||
|
})
|
||||||
|
assert b'minus 5 Tage' in resp.data
|
||||||
|
assert b'05.01.2024' in resp.data
|
||||||
|
|
||||||
|
def test_plusminus_werktage(client):
|
||||||
|
from numpy import busday_offset
|
||||||
|
from datetime import datetime
|
||||||
|
start = '2024-01-10'
|
||||||
|
anzahl = 5
|
||||||
|
# Addition
|
||||||
|
result = busday_offset(datetime.strptime(start, '%Y-%m-%d').date(), anzahl, roll='forward')
|
||||||
|
result_str = datetime.strptime(str(result), '%Y-%m-%d').strftime('%d.%m.%Y')
|
||||||
|
resp = client.post('/', data={
|
||||||
|
'action': 'plusminus',
|
||||||
|
'datum_pm': start,
|
||||||
|
'anzahl_pm': str(anzahl),
|
||||||
|
'einheit_pm': 'tage',
|
||||||
|
'richtung_pm': 'add',
|
||||||
|
'werktage_pm': 'on'
|
||||||
|
})
|
||||||
|
assert resp.status_code == 200
|
||||||
|
assert b'plus 5 Werktage' in resp.data
|
||||||
|
assert result_str.encode() in resp.data
|
||||||
|
# Subtraktion
|
||||||
|
result = busday_offset(datetime.strptime(start, '%Y-%m-%d').date(), -anzahl, roll='forward')
|
||||||
|
result_str = datetime.strptime(str(result), '%Y-%m-%d').strftime('%d.%m.%Y')
|
||||||
|
resp = client.post('/', data={
|
||||||
|
'action': 'plusminus',
|
||||||
|
'datum_pm': start,
|
||||||
|
'anzahl_pm': str(anzahl),
|
||||||
|
'einheit_pm': 'tage',
|
||||||
|
'richtung_pm': 'sub',
|
||||||
|
'werktage_pm': 'on'
|
||||||
|
})
|
||||||
|
assert b'minus 5 Werktage' in resp.data
|
||||||
|
assert result_str.encode() in resp.data
|
||||||
|
|
||||||
|
def test_plusminus_wochen_monate(client):
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
from dateutil.relativedelta import relativedelta
|
||||||
|
start = '2024-01-10'
|
||||||
|
# Wochen addieren
|
||||||
|
resp = client.post('/', data={
|
||||||
|
'action': 'plusminus',
|
||||||
|
'datum_pm': start,
|
||||||
|
'anzahl_pm': '2',
|
||||||
|
'einheit_pm': 'wochen',
|
||||||
|
'richtung_pm': 'add'
|
||||||
|
})
|
||||||
|
assert b'plus 2 Wochen' in resp.data
|
||||||
|
assert b'24.01.2024' in resp.data
|
||||||
|
# Wochen subtrahieren
|
||||||
|
resp = client.post('/', data={
|
||||||
|
'action': 'plusminus',
|
||||||
|
'datum_pm': start,
|
||||||
|
'anzahl_pm': '2',
|
||||||
|
'einheit_pm': 'wochen',
|
||||||
|
'richtung_pm': 'sub'
|
||||||
|
})
|
||||||
|
assert b'minus 2 Wochen' in resp.data
|
||||||
|
assert b'27.12.2023' in resp.data
|
||||||
|
# Monate addieren
|
||||||
|
resp = client.post('/', data={
|
||||||
|
'action': 'plusminus',
|
||||||
|
'datum_pm': start,
|
||||||
|
'anzahl_pm': '2',
|
||||||
|
'einheit_pm': 'monate',
|
||||||
|
'richtung_pm': 'add'
|
||||||
|
})
|
||||||
|
assert b'plus 2 Monate' in resp.data
|
||||||
|
assert b'10.03.2024' in resp.data
|
||||||
|
# Monate subtrahieren
|
||||||
|
resp = client.post('/', data={
|
||||||
|
'action': 'plusminus',
|
||||||
|
'datum_pm': start,
|
||||||
|
'anzahl_pm': '2',
|
||||||
|
'einheit_pm': 'monate',
|
||||||
|
'richtung_pm': 'sub'
|
||||||
|
})
|
||||||
|
assert b'minus 2 Monate' in resp.data
|
||||||
|
assert b'10.11.2023' in resp.data
|
||||||
|
|
||||||
def test_xss_protection(client):
|
def test_xss_protection(client):
|
||||||
# Versuche ein Skript einzuschleusen
|
# Versuche ein Skript einzuschleusen
|
||||||
|
Reference in New Issue
Block a user