rollerverbrauch/app/routes/pitstop.py

232 lines
7.3 KiB
Python
Raw Normal View History

2016-11-01 18:01:52 +01:00
from flask import url_for, redirect, render_template, flash
from flask_security import login_required
from flask_security.core import current_user
from sqlalchemy.exc import IntegrityError
from datetime import date
2021-06-17 18:28:19 +02:00
import types
2016-11-01 18:01:52 +01:00
from ..entities import Vehicle, Consumable, Pitstop
2021-06-20 08:43:46 +02:00
from ..forms import (
SelectVehicleForm,
SelectConsumableForm,
CreatePitstopForm,
EditPitstopForm,
DeletePitStopForm,
)
from ..tools import (
db_log_update,
db_log_delete,
db_log_add,
pitstop_service_key,
get_event_line_for_vehicle,
RegularCostInstance,
calculate_regular_cost_instances,
get_users_active_vehicle,
)
2016-11-01 18:01:52 +01:00
from .. import app, db
2021-06-20 08:43:46 +02:00
@app.route("/pitstops/vehicle/select", methods=["GET", "POST"])
2016-11-01 18:01:52 +01:00
@login_required
def select_vehicle_for_new_pitstop():
2021-06-20 08:43:46 +02:00
active_vehicles = get_users_active_vehicle(current_user)
if len(active_vehicles) == 1:
return redirect(
url_for(
"select_consumable_for_new_pitstop", vid=active_vehicles[0].id
)
)
2016-11-01 18:01:52 +01:00
form = SelectVehicleForm()
2021-06-20 08:43:46 +02:00
form.vehicle.choices = [
(g.id, g.name) for g in active_vehicles
]
2016-11-01 18:01:52 +01:00
if form.validate_on_submit():
2021-06-20 08:43:46 +02:00
return redirect(
url_for("select_consumable_for_new_pitstop", vid=form.vehicle.data)
)
2016-11-01 18:01:52 +01:00
2021-06-20 08:43:46 +02:00
return render_template("selectVehicle.html", form=form)
2016-11-01 18:01:52 +01:00
2021-06-20 08:43:46 +02:00
@app.route("/pitstops/vehicle/<int:vid>/consumable/select", methods=["GET", "POST"])
2016-11-01 18:01:52 +01:00
@login_required
def select_consumable_for_new_pitstop(vid):
vehicle = Vehicle.query.get(vid)
if vehicle is None or vehicle not in current_user.vehicles:
2021-06-20 08:43:46 +02:00
return redirect(url_for("select_vehicle_for_new_pitstop"))
2016-11-01 18:01:52 +01:00
if len(vehicle.consumables) == 0:
2021-06-20 08:43:46 +02:00
flash("Please choose at least one consumable!", "warning")
return redirect(url_for("edit_vehicle", vid=vid))
2016-11-01 18:01:52 +01:00
if len(vehicle.consumables) == 1:
2021-06-20 08:43:46 +02:00
return redirect(
url_for("create_pit_stop_form", vid=vid, cid=vehicle.consumables[0].id)
)
2016-11-01 18:01:52 +01:00
form = SelectConsumableForm()
form.consumable.choices = [(g.id, g.name) for g in vehicle.consumables]
if form.validate_on_submit():
2021-06-20 08:43:46 +02:00
return redirect(
url_for("create_pit_stop_form", vid=vid, cid=form.consumable.data)
)
2016-11-01 18:01:52 +01:00
2021-06-20 08:43:46 +02:00
return render_template(
"selectConsumableForVehicle.html", vehicle=vehicle, form=form
)
2016-11-01 18:01:52 +01:00
2021-06-20 08:43:46 +02:00
@app.route(
"/pitstops/vehicle/<int:vid>/consumable/<int:cid>/create", methods=["GET", "POST"]
)
2016-11-01 18:01:52 +01:00
@login_required
def create_pit_stop_form(vid, cid):
vehicle = Vehicle.query.get(vid)
if vehicle is None or vehicle not in current_user.vehicles:
2021-06-20 08:43:46 +02:00
return redirect(url_for("select_vehicle_for_new_pitstop"))
2016-11-01 18:01:52 +01:00
consumable = Consumable.query.get(cid)
if consumable not in vehicle.consumables:
2021-06-20 08:43:46 +02:00
return redirect(url_for("select_consumable_for_new_pitstop", vid=vid))
2016-11-01 18:01:52 +01:00
form = CreatePitstopForm()
2016-11-06 13:22:54 +01:00
data = get_event_line_for_vehicle(vehicle)
if len(data) > 0:
form.set_pitstops(data)
2021-06-20 08:43:46 +02:00
form.same_odometer_allowed = (type(data[-1]) != Pitstop) or (
data[-1].consumable.id != cid
)
2016-11-06 13:22:54 +01:00
else:
form.set_pitstops([])
2016-11-06 13:22:54 +01:00
form.same_odometer_allowed = True
2016-11-01 18:01:52 +01:00
# set the label of the litres field to make the user comfortable
form.set_consumable(consumable)
# preinitialize the defaults with potentially existing values from a try before
form.preinit_with_data()
#
# Validate should accept same odometer on different consumables
#
if form.validate_on_submit():
2021-06-20 08:43:46 +02:00
new_stop = Pitstop(
form.odometer.data, form.litres.data, form.date.data, form.costs.data, cid
)
2016-11-01 18:01:52 +01:00
db.session.add(new_stop)
vehicle.pitstops.append(new_stop)
try:
db.session.commit()
db_log_add(new_stop)
except IntegrityError:
db.session.rollback()
2021-06-20 08:43:46 +02:00
form.odometer.errors.append(
"Pitstop already present for %s at odometer %s km!"
% (consumable.name, form.odometer.data)
)
return render_template(
"createPitStopForm.html",
form=form,
vehicle=vehicle,
messages=form.get_hint_messages(),
)
return redirect(url_for("get_pit_stops", _anchor="v" + str(vehicle.id)))
2016-11-01 18:01:52 +01:00
form.process()
2021-06-20 08:43:46 +02:00
return render_template(
"createPitStopForm.html",
form=form,
vehicle=vehicle,
messages=form.get_hint_messages(),
)
2016-11-01 18:01:52 +01:00
2021-06-20 08:43:46 +02:00
@app.route("/pitstops/delete/<int:pid>", methods=["GET", "POST"])
2016-11-01 18:01:52 +01:00
@login_required
def delete_pit_stop_form(pid):
pitstop = Pitstop.query.filter(Pitstop.id == pid).first()
if pitstop is None:
2021-06-20 08:43:46 +02:00
return redirect(url_for("get_pit_stops"))
2016-11-01 18:01:52 +01:00
vehicle = Vehicle.query.filter(Vehicle.id == pitstop.vehicle_id).first()
if vehicle not in current_user.vehicles:
2021-06-20 08:43:46 +02:00
return redirect(url_for("get_pit_stops"))
2016-11-01 18:01:52 +01:00
form = DeletePitStopForm()
if form.validate_on_submit():
db.session.delete(pitstop)
db.session.commit()
db_log_delete(pitstop)
2021-06-20 08:43:46 +02:00
return redirect(url_for("get_pit_stops", _anchor="v" + str(vehicle.id)))
2016-11-01 18:01:52 +01:00
2021-06-20 08:43:46 +02:00
return render_template("deletePitstopForm.html", form=form, pitstop=pitstop)
2016-11-01 18:01:52 +01:00
2021-06-20 08:43:46 +02:00
@app.route("/pitstops/edit/<int:pid>", methods=["GET", "POST"])
2016-11-01 18:01:52 +01:00
@login_required
def edit_pit_stop_form(pid):
edit_pitstop = Pitstop.query.get(pid)
if edit_pitstop is None:
2021-06-20 08:43:46 +02:00
return redirect(url_for("get_pit_stops"))
2016-11-01 18:01:52 +01:00
vehicle = Vehicle.query.filter(Vehicle.id == edit_pitstop.vehicle_id).first()
if vehicle not in current_user.vehicles:
2021-06-20 08:43:46 +02:00
return redirect(url_for("get_pit_stops"))
2016-11-01 18:01:52 +01:00
form = EditPitstopForm()
data = get_event_line_for_vehicle(vehicle)
data = [x for x in data if x != edit_pitstop]
form.set_pitstops(data)
if not form.is_submitted():
form.odometer.default = edit_pitstop.odometer
form.litres.default = edit_pitstop.amount
form.date.default = edit_pitstop.date
form.costs.default = edit_pitstop.costs
2016-11-01 18:01:52 +01:00
if form.validate_on_submit():
edit_pitstop.costs = form.costs.data
edit_pitstop.date = form.date.data
edit_pitstop.amount = form.litres.data
edit_pitstop.odometer = form.odometer.data
db.session.commit()
db_log_update(edit_pitstop)
2021-06-20 08:43:46 +02:00
return redirect(url_for("get_pit_stops", _anchor="v" + str(vehicle.id)))
2016-11-01 18:01:52 +01:00
form.preinit_with_data()
2016-11-01 18:01:52 +01:00
form.process()
2021-06-20 08:43:46 +02:00
return render_template(
"editPitStopForm.html",
form=form,
vehicle=vehicle,
messages=form.get_hint_messages(),
)
2016-11-01 18:01:52 +01:00
2021-06-20 08:43:46 +02:00
@app.route("/pitstops", methods=["GET"])
2016-11-01 18:01:52 +01:00
@login_required
def get_pit_stops():
2021-06-20 08:43:46 +02:00
user = {"vehicles": []}
2016-11-01 18:01:52 +01:00
for vehicle in current_user.vehicles:
data = []
for pitstop in vehicle.pitstops:
data.append(pitstop)
for service in vehicle.services:
data.append(service)
2021-06-17 18:28:19 +02:00
for regular_instance in calculate_regular_cost_instances(vehicle):
data.append(regular_instance)
2016-11-01 19:48:24 +01:00
data.sort(key=pitstop_service_key)
2016-11-01 18:01:52 +01:00
v = {
2021-06-20 08:43:46 +02:00
"id": vehicle.id,
"name": vehicle.name,
"data": data,
2021-06-17 18:28:19 +02:00
"regulars": vehicle.regulars,
2016-11-01 18:01:52 +01:00
}
2021-06-20 08:43:46 +02:00
user["vehicles"].append(v)
2024-05-25 17:26:09 +02:00
user["vehicles"].sort(key=lambda v: (v["data"][-1].date, v["data"][-1].odometer or 0 ), reverse=true)
2016-11-01 18:01:52 +01:00
2021-06-20 08:43:46 +02:00
return render_template("pitstops.html", user=user)