add page to plan a pitstop

This commit is contained in:
Joachim Lusiardi 2017-11-12 15:38:32 +01:00
parent 28990f27fa
commit 9427ed50ad
5 changed files with 124 additions and 41 deletions

View File

@ -190,6 +190,11 @@ class FillingStation(db.Model):
brand = db.Column(db.Text(), nullable=False) brand = db.Column(db.Text(), nullable=False)
lat = db.Column(db.Numeric(2, 5), nullable=False) lat = db.Column(db.Numeric(2, 5), nullable=False)
lng = db.Column(db.Numeric(2, 5), nullable=False) lng = db.Column(db.Numeric(2, 5), nullable=False)
last_update = db.Column(db.DateTime)
diesel = db.Column(db.Numeric(10, 3), default=0)
e5 = db.Column(db.Numeric(10, 3), default=0)
e10 = db.Column(db.Numeric(10, 3), default=0)
open = db.Column(db.Boolean())
def as_dict(self): def as_dict(self):
res = {} res = {}

View File

@ -3,3 +3,4 @@ from .admin import *
from .misc import * from .misc import *
from .pitstop import * from .pitstop import *
from .service import * from .service import *
from .filling_stations import *

View File

@ -6,9 +6,8 @@ from datetime import date
from ..entities import Vehicle, Consumable, Pitstop from ..entities import Vehicle, Consumable, Pitstop
from ..forms import SelectVehicleForm, SelectConsumableForm, CreatePitstopForm, EditPitstopForm, DeletePitStopForm from ..forms import SelectVehicleForm, SelectConsumableForm, CreatePitstopForm, EditPitstopForm, DeletePitStopForm
from ..tools import db_log_update, db_log_delete, db_log_add, get_latest_pitstop_for_vehicle, \ from ..tools import db_log_update, db_log_delete, db_log_add, pitstop_service_key, \
get_latest_pitstop_for_vehicle_and_consumable, compute_lower_limits_for_new_pitstop, pitstop_service_key, \ get_event_line_for_vehicle, update_filling_station_prices
get_event_line_for_vehicle
from .. import app, db from .. import app, db
@ -50,6 +49,27 @@ def select_consumable_for_new_pitstop(vid):
return render_template('selectConsumableForVehicle.html', vehicle=vehicle, form=form) return render_template('selectConsumableForVehicle.html', vehicle=vehicle, form=form)
@app.route('/pitstops/vehicle/<int:vid>/consumable/<int:cid>/plan', methods=['GET', 'POST'])
@login_required
def plan_pit_stop_form(vid, cid):
vehicle = Vehicle.query.get(vid)
if vehicle is None or vehicle not in current_user.vehicles:
return redirect(url_for('select_vehicle_for_new_pitstop'))
consumable = Consumable.query.get(cid)
if consumable not in vehicle.consumables:
return redirect(url_for('select_consumable_for_new_pitstop', vid=vid))
update_filling_station_prices([x.id for x in current_user.favourite_filling_stations])
offers = []
for fs in current_user.favourite_filling_stations:
if fs.open:
offers.append((fs, getattr(fs, consumable.ext_id),))
return render_template('planPitStopForm.html', vehicle=vehicle, consumable=consumable, offers=offers)
@app.route('/pitstops/vehicle/<int:vid>/consumable/<int:cid>/create', methods=['GET', 'POST']) @app.route('/pitstops/vehicle/<int:vid>/consumable/<int:cid>/create', methods=['GET', 'POST'])
@login_required @login_required
def create_pit_stop_form(vid, cid): def create_pit_stop_form(vid, cid):

View File

@ -0,0 +1,50 @@
{% extends "layout.html" %}
{% block body %}
<div class="col-md-2" ></div>
<div class="col-md-8">
<div class="panel panel-default">
<div class="panel-body">
<h3>Plan Pitstop for '{{ vehicle.name }}'</h3>
Price comparision for {{ consumable.name }}:
<div class="table-responsive">
<table id="compare" class="table table-striped table-bordered table-condensed tablesorter">
<thead>
<tr>
<th>Filling Station</th>
<th>Price/{{ consumable.unit }}</th>
</tr>
</thead>
<tbody>
{% for offer in offers %}
<tr>
<td>
<div class="row filling_station_info" style="border: 0px">
<div class="col-md-8">
<div>{{ offer[0].name }}</div>
<div>{{ offer[0].street }} {{ offer[0].houseNumber }}</div>
<div>{{ offer[0].postCode }} {{ offer[0].place }}</div>
</div>
<div class="col-md-4" style="height: 60px;">
<img src="/static/logos/{{ offer[0].brand|lower }}.png">
</div>
</div>
</td>
<td>
{{ offer[1] }} €/{{ consumable.unit }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function() {
$("#compare").tablesorter({sortList: [[1,0]]});
});
</script>
<div class="col-md-2" ></div>
{% endblock %}

View File

@ -1,7 +1,10 @@
from sqlalchemy import or_
import requests
import logging import logging
from datetime import date from datetime import date, datetime, timedelta
from .entities import Pitstop from .entities import Pitstop, FillingStation
from . import db, app
class ConsumableStats: class ConsumableStats:
@ -34,7 +37,7 @@ class ConsumableStats:
self.average_amount.append( self.average_amount.append(
StatsEvent( StatsEvent(
current_ps.date, current_ps.date,
round(100 * current_ps.amount/(current_ps.odometer - last_ps.odometer), 2))) round(100 * current_ps.amount / (current_ps.odometer - last_ps.odometer), 2)))
class VehicleStats: class VehicleStats:
@ -104,9 +107,9 @@ def get_latest_pitstop_for_vehicle(vehicle_id):
:param vehicle_id: the id of the vehicle :param vehicle_id: the id of the vehicle
:return: the latest pitstop or None if no pitstop exists :return: the latest pitstop or None if no pitstop exists
""" """
latest_pitstop = Pitstop.query\ latest_pitstop = Pitstop.query \
.filter(Pitstop.vehicle_id == vehicle_id)\ .filter(Pitstop.vehicle_id == vehicle_id) \
.order_by(Pitstop.id.desc())\ .order_by(Pitstop.id.desc()) \
.first() .first()
return latest_pitstop return latest_pitstop
@ -118,10 +121,10 @@ def get_latest_pitstop_for_vehicle_and_consumable(vehicle_id, consumable_id):
:param consumable_id: the id of the consumable :param consumable_id: the id of the consumable
:return: the latest pitstop or None if no pitstop exists :return: the latest pitstop or None if no pitstop exists
""" """
latest_pitstop_consumable = Pitstop.query\ latest_pitstop_consumable = Pitstop.query \
.filter(Pitstop.vehicle_id == vehicle_id)\ .filter(Pitstop.vehicle_id == vehicle_id) \
.filter(Pitstop.consumable_id == consumable_id)\ .filter(Pitstop.consumable_id == consumable_id) \
.order_by(Pitstop.id.desc())\ .order_by(Pitstop.id.desc()) \
.first() .first()
return latest_pitstop_consumable return latest_pitstop_consumable
@ -150,33 +153,6 @@ def compute_lower_limits_for_new_pitstop(latest_pitstop, last_pitstop_consumable
return Pitstop(odometer, amount, date_of_pitstop, costs, consumable_id) return Pitstop(odometer, amount, date_of_pitstop, costs, consumable_id)
# if latest_pitstop is not None:
# if last_pitstop_consumable is not None and last_pitstop_consumable != latest_pitstop:
# if latest_pitstop.id > last_pitstop_consumable.id:
# return Pitstop(latest_pitstop.odometer,
# last_pitstop_consumable.overall_amount,
# latest_pitstop.date,
# last_pitstop_consumable.costs,
# consumable_id)
# else:
# return Pitstop(last_pitstop_consumable.odometer,
# last_pitstop_consumable.overall_amount,
# last_pitstop_consumable.date,
# last_pitstop_consumable.costs,
# consumable_id)
# else:
# # either only one pitstop exists or both are the same
# litres = 0
# costs = 0
# if latest_pitstop.consumable_id == last_pitstop_consumable.consumable_id:
# litres = latest_pitstop.overall_amount
# costs = latest_pitstop.costs
# return Pitstop(latest_pitstop.odometer, litres, latest_pitstop.date, costs, consumable_id)
# else:
# # No existing pitstop at all: insert fake data
# return Pitstop(0, 0, date(1970, 1, 1), 0, None)
def pitstop_service_key(x): def pitstop_service_key(x):
return x.odometer, x.date return x.odometer, x.date
@ -189,3 +165,34 @@ def get_event_line_for_vehicle(vehicle):
data.append(service) data.append(service)
data.sort(key=pitstop_service_key) data.sort(key=pitstop_service_key)
return data return data
def update_filling_station_prices(ids):
max_age = (datetime.now() - timedelta(minutes=15)).strftime('%Y-%m-%d %H:%M')
res = db.session. \
query(FillingStation). \
filter(FillingStation.id.in_(ids)). \
filter(or_(FillingStation.last_update==None, FillingStation.last_update < max_age)).\
all()
if len(res) > 0:
map = {x.id:x for x in res}
query_ids = [x.id for x in res]
api_key = app.config['TANKERKOENIG_API_KEY']
url = 'https://creativecommons.tankerkoenig.de/json/prices.php'
params = {
'apikey': api_key, 'ids': ','.join(query_ids)
}
response = requests.get(url, params=params)
prices = response.json()['prices']
for price in prices:
id = price
station_status = prices[id]
print(id, station_status)
map[id].diesel = station_status['diesel']
map[id].e10 = station_status['e10']
map[id].e5 = station_status['e5']
map[id].open = station_status['status'] == 'open'
map[id].last_update = datetime.now()
db.session.commit()