With unregistered user (fixes #1 )

This commit is contained in:
Feliciaan De Palmenaer 2015-03-28 20:38:15 +01:00
parent 511bdebea5
commit bf1b6b92ab
9 changed files with 147 additions and 84 deletions

View file

@ -1,7 +1,8 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta
from flask import session
from flask.ext.login import current_user from flask.ext.login import current_user
from flask_wtf import Form from flask_wtf import Form
from wtforms import SelectField, DateTimeField, validators, SubmitField, HiddenField from wtforms import SelectField, DateTimeField, validators, SubmitField, StringField
from models import User, Location from models import User, Location
from utils import euro from utils import euro
@ -33,3 +34,24 @@ class OrderItemForm(Form):
def populate(self, location): def populate(self, location):
self.product_id.choices = [(i.id, (i.name + ": " + euro(i.price))) for i in location.products] self.product_id.choices = [(i.id, (i.name + ": " + euro(i.price))) for i in location.products]
class AnonOrderItemForm(OrderItemForm):
name = StringField('Name', validators=[validators.required()])
def populate(self, location):
OrderItemForm.populate(self, location)
if self.name.data is None:
self.name.data = session.get('anon_name', None)
def validate(self):
rv = OrderForm.validate(self)
if not rv:
return False
# check if we have a user with this name
user = User.query.filter_by(username=self.name.data).first()
if user is not None:
self.name.errors.append('Name already in use')
return False
return True

View file

@ -80,6 +80,7 @@ class Order(db.Model):
location_id = db.Column(db.Integer, db.ForeignKey('location.id')) location_id = db.Column(db.Integer, db.ForeignKey('location.id'))
starttime = db.Column(db.DateTime) starttime = db.Column(db.DateTime)
stoptime = db.Column(db.DateTime) stoptime = db.Column(db.DateTime)
public = db.Column(db.Boolean, default=True)
items = db.relationship('OrderItem', backref='order', lazy='dynamic') items = db.relationship('OrderItem', backref='order', lazy='dynamic')
def configure(self, courrier, location, starttime, stoptime): def configure(self, courrier, location, starttime, stoptime):
@ -94,13 +95,13 @@ class Order(db.Model):
def group_by_user(self): def group_by_user(self):
group = defaultdict(list) group = defaultdict(list)
for item in self.items: for item in self.items:
group[item.user_id] += [item.product] group[item.get_name()] += [item.product]
return group return group
def group_by_user_pay(self): def group_by_user_pay(self):
group = defaultdict(int) group = defaultdict(int)
for item in self.items: for item in self.items:
group[item.user] += item.product.price group[item.get_name()] += item.product.price
return group return group
class OrderItem(db.Model): class OrderItem(db.Model):
@ -108,20 +109,26 @@ class OrderItem(db.Model):
user_id = db.Column(db.Integer, db.ForeignKey('user.id')) user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
order_id = db.Column(db.Integer, db.ForeignKey('order.id')) order_id = db.Column(db.Integer, db.ForeignKey('order.id'))
product_id = db.Column(db.Integer, db.ForeignKey('product.id')) product_id = db.Column(db.Integer, db.ForeignKey('product.id'))
name = db.Column(db.String(120))
def configure(self, user, order, product): def configure(self, user, order, product):
self.user = user self.user = user
self.order = order self.order = order
self.product = product self.product = product
def __repr__(self): def get_name(self):
return 'OrderItem' if self.user_id is not None and self.user_id > 0:
return self.user.username
return self.name
def can_delete(self, order_id, user_id): def __repr__(self):
if self.user_id != user_id: return 'Order %d: %s wants %s' % (self.order_id, self.get_name(), self.product.name)
return False
def can_delete(self, order_id, user_id, name):
if int(self.order_id) != int(order_id): if int(self.order_id) != int(order_id):
return False return False
if self.order.stoptime and self.order.stoptime < datetime.now(): if self.order.stoptime and self.order.stoptime < datetime.now():
return False return False
return True if self.user_id == user_id or self.name == name:
return True
return False

View file

@ -5,4 +5,14 @@
<h2>Welcome to FoodBot</h2> <h2>Welcome to FoodBot</h2>
<h3>This is the home page for FoodBot</h3> <h3>This is the home page for FoodBot</h3>
</div> </div>
<div class="row">
<div class="col-md-4">
<h3>Open orders:</h3>
<ul>
{% for order in orders %}
<li><a href="{{ url_for('order_bp.order', id=order.id) }}">{{ order.location.name }}-{{ order.stoptime }}</a></li>
{% endfor %}
</ul>
</div>
</div>
{% endblock %} {% endblock %}

View file

@ -1,14 +0,0 @@
{% extends "home.html" %}
{% block container %}
{{ super() }}
<div class="row">
<div class="col-md-4">
<h3>Open orders:</h3>
<ul>
{% for order in orders %}
<li><a href="{{ url_for('order_bp.order', id=order.id) }}">{{ order.location.name }}-{{ order.stoptime }}</a></li>
{% endfor %}
</ul>
</div>
</div>
{% endblock %}

View file

@ -10,7 +10,7 @@
<a class="btn btn-danger" href="{{ url_for('.close_order', id=order.id) }}">Close</a><br/> <a class="btn btn-danger" href="{{ url_for('.close_order', id=order.id) }}">Close</a><br/>
{%- endif %}</h3> {%- endif %}</h3>
Courrier: {{ order.courrier.username }} Courrier: {{ order.courrier.username }}
{% if order.courrier == None %} {% if order.courrier == None and not current_user.is_anonymous() %}
<a href="{{ url_for('.volunteer', id=order.id) }}" class="btn btn-primary">Volunteer</a> <a href="{{ url_for('.volunteer', id=order.id) }}" class="btn btn-primary">Volunteer</a>
{% endif %} {% endif %}
<br/> <br/>
@ -20,12 +20,12 @@
Total price: {{ total_price|euro }} Total price: {{ total_price|euro }}
<h3>Orders</h3> <h3>Orders</h3>
{% for item in order.items %} {% for item in order.items %}
{{ item.user.username }} - {{ item.product.name }} - {{ item.product.price|euro }} {{ item.get_name() }} - {{ item.product.name }} - {{ item.product.price|euro }}
{% if item.can_delete(order.id, current_user.id) -%}<a href="{{ url_for('.delete_item', order_id=order.id, item_id=item.id) }}"><span class="glyphicon glyphicon-remove"></span></a>{%- endif %}<br/> {% if item.can_delete(order.id, current_user.id, session.get('anon_name', '')) -%}<a href="{{ url_for('.delete_item', order_id=order.id, item_id=item.id) }}"><span class="glyphicon glyphicon-remove"></span></a>{%- endif %}<br/>
{% endfor %} {% endfor %}
<h3>Debts</h3> <h3>Debts</h3>
{% for key, value in total_payments.items() %} {% for key, value in total_payments.items() %}
{{ key.username }} - {{ value|euro }}<br/> {{ key }} - {{ value|euro }}<br/>
{% endfor %} {% endfor %}
</div> </div>
<div class="col-md-push-1 col-md-4"> <div class="col-md-push-1 col-md-4">

View file

@ -12,9 +12,11 @@
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
{% if not current_user.is_anonymous() %}
<div class="col-md-push-1 col-md-6"> <div class="col-md-push-1 col-md-6">
{{ wtf.quick_form(form, action=url_for('.order_create'), button_map={'submit_button': 'primary'}, form_type='horizontal') }} {{ wtf.quick_form(form, action=url_for('.order_create'), button_map={'submit_button': 'primary'}, form_type='horizontal') }}
</div> </div>
{% endif %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View file

@ -1,6 +1,8 @@
from flask import render_template from flask import render_template
from app import app from app import app
from login import login_manager
__author__ = 'feliciaan' __author__ = 'feliciaan'
@app.template_filter('euro') @app.template_filter('euro')
@ -15,3 +17,21 @@ def handle404(e):
@app.errorhandler(401) @app.errorhandler(401)
def handle401(e): def handle401(e):
return render_template('errors/401.html'), 401 return render_template('errors/401.html'), 401
class AnonymouseUser:
def is_active(self):
return False
def is_authenticated(self):
return False
def is_anonymous(self):
return True
def is_admin(self):
return False
def get_id(self):
return None
login_manager.anonymous_user = AnonymouseUser

View file

@ -12,10 +12,7 @@ import views.order
@app.route('/') @app.route('/')
def home(): def home():
if not current_user.is_anonymous(): return render_template('home.html', orders=views.order.get_orders())
orders = Order.query.filter((Order.stoptime > datetime.now()) | (Order.stoptime == None)).all()
return render_template('home_loggedin.html', orders=orders)
return render_template('home.html')
@app.route('/about/') @app.route('/about/')

View file

@ -1,22 +1,22 @@
__author__ = 'feliciaan' __author__ = 'feliciaan'
from flask import url_for, render_template, abort, redirect, Blueprint, flash from flask import url_for, render_template, abort, redirect, Blueprint, flash, session
from flask.ext.login import current_user, login_required from flask.ext.login import current_user, login_required
import random import random
from datetime import datetime from datetime import datetime
from app import app, db from app import app, db
from models import Order, OrderItem from models import Order, OrderItem
from forms import OrderItemForm, OrderForm from forms import OrderItemForm, OrderForm, AnonOrderItemForm
order_bp = Blueprint('order_bp', 'order') order_bp = Blueprint('order_bp', 'order')
@order_bp.route('/') @order_bp.route('/')
@login_required
def orders(): def orders():
orders = Order.query.filter((Order.stoptime > datetime.now()) | (Order.stoptime == None)).all() orderForm = None
orderForm = OrderForm() if not current_user.is_anonymous():
orderForm.populate() orderForm = OrderForm()
return render_template('orders.html', orders=orders, form=orderForm) orderForm.populate()
return render_template('orders.html', orders=get_orders(), form=orderForm)
@order_bp.route('/create', methods=['GET', 'POST']) @order_bp.route('/create', methods=['GET', 'POST'])
@ -35,41 +35,52 @@ def order_create():
@order_bp.route('/<id>') @order_bp.route('/<id>')
@login_required
def order(id): def order(id):
order = Order.query.filter(Order.id == id).first() order = Order.query.filter(Order.id == id).first()
if order is not None: if order is None:
abort(404)
form = None
if not current_user.is_anonymous():
form = OrderItemForm() form = OrderItemForm()
form.populate(order.location) else:
total_price = sum([o.product.price for o in order.items]) form = AnonOrderItemForm()
total_payments = order.group_by_user_pay() form.populate(order.location)
return render_template('order.html', order=order, form=form, total_price=total_price, total_payments=total_payments) total_price = sum([o.product.price for o in order.items])
return abort(404) total_payments = order.group_by_user_pay()
return render_template('order.html', order=order, form=form, total_price=total_price, total_payments=total_payments)
@order_bp.route('/<id>/create', methods=['GET', 'POST']) @order_bp.route('/<id>/create', methods=['GET', 'POST'])
@login_required
def order_item_create(id): def order_item_create(id):
order = Order.query.filter(Order.id == id).first() order = Order.query.filter(Order.id == id).first()
if order is not None: if order is None:
abort(404)
form = None
if not current_user.is_anonymous():
form = OrderItemForm() form = OrderItemForm()
form.populate(order.location) else:
if form.validate_on_submit(): form = AnonOrderItemForm()
item = OrderItem() form.populate(order.location)
form.populate_obj(item) if form.validate_on_submit():
item.order_id = id item = OrderItem()
form.populate_obj(item)
item.order_id = id
if not current_user.is_anonymous():
item.user_id = current_user.id item.user_id = current_user.id
db.session.add(item) else:
db.session.commit() session['anon_name'] = item.name
return redirect(url_for('.order', id=id)) db.session.add(item)
return render_template('order_form.html', form=form, url=url_for(".order_item_create", id=id)) db.session.commit()
return abort(404) return redirect(url_for('.order', id=id))
return render_template('order_form.html', form=form, url=url_for(".order_item_create", id=id))
@order_bp.route('/<order_id>/<item_id>/delete') @order_bp.route('/<order_id>/<item_id>/delete')
@login_required
def delete_item(order_id, item_id): def delete_item(order_id, item_id):
item = OrderItem.query.filter(OrderItem.id == item_id).first() item = OrderItem.query.filter(OrderItem.id == item_id).first()
if item.can_delete(order_id, current_user.id): id = None
if not current_user.is_anonymous():
id = current_user.id
if item.can_delete(order_id, id, session.get('anon_name', '')):
db.session.delete(item) db.session.delete(item)
db.session.commit() db.session.commit()
return redirect(url_for('.order', id=order_id)) return redirect(url_for('.order', id=order_id))
@ -80,33 +91,32 @@ def delete_item(order_id, item_id):
@login_required @login_required
def volunteer(id): def volunteer(id):
order = Order.query.filter(Order.id == id).first() order = Order.query.filter(Order.id == id).first()
if order is not None: if order is None:
print(order.courrier_id) abort(404)
if order.courrier_id == 0: if order.courrier_id is None or order.courrier_id == 0:
order.courrier_id = current_user.id order.courrier_id = current_user.id
db.session.commit() db.session.commit()
flash("Thank you for volunteering!") flash("Thank you for volunteering!")
else: else:
flash("Volunteering not possible!") flash("Volunteering not possible!")
return redirect(url_for('.order', id=id)) return redirect(url_for('.order', id=id))
abort(404)
@order_bp.route('/<id>/close') @order_bp.route('/<id>/close')
@login_required @login_required
def close_order(id): def close_order(id):
order = Order.query.filter(Order.id == id).first() order = Order.query.filter(Order.id == id).first()
if order is not None: if order is None:
if (current_user.id == order.courrier_id or current_user.is_admin()) \ abort(401)
and order.stoptime is None or (order.stoptime > datetime.now()): if (current_user.id == order.courrier_id or current_user.is_admin()) \
order.stoptime = datetime.now() and order.stoptime is None or (order.stoptime > datetime.now()):
if order.courrier_id == 0 or order.courrier_id is None: order.stoptime = datetime.now()
courrier = select_user(order.items) if order.courrier_id == 0 or order.courrier_id is None:
if courrier is not None: courrier = select_user(order.items)
order.courrier_id = courrier.id if courrier is not None:
db.session.commit() order.courrier_id = courrier.id
return redirect(url_for('.order', id=id)) db.session.commit()
abort(401) return redirect(url_for('.order', id=id))
app.register_blueprint(order_bp, url_prefix='/order') app.register_blueprint(order_bp, url_prefix='/order')
@ -120,7 +130,16 @@ def select_user(items):
while user is None: while user is None:
item = random.choice(items) item = random.choice(items)
user = item.user user = item.user
if random.randint(user.bias, 100) < 80: if user:
user = None if random.randint(user.bias, 100) < 80:
user = None
return user return user
def get_orders():
orders = []
if not current_user.is_anonymous():
orders = Order.query.filter((Order.stoptime > datetime.now()) | (Order.stoptime == None)).all()
else:
orders = Order.query.filter(((Order.stoptime > datetime.now()) | (Order.stoptime == None) & (Order.public == True))).all()
return orders