Merge branch 'master' of github.com:ZeusWPI/Haldis

This commit is contained in:
Tom Naessens 2015-08-18 21:19:47 +02:00
commit 48e314335f
10 changed files with 66 additions and 9 deletions

View file

@ -3,6 +3,7 @@ from logging.handlers import TimedRotatingFileHandler
from flask import Flask from flask import Flask
from flask.ext.bootstrap import Bootstrap, StaticCDN from flask.ext.bootstrap import Bootstrap, StaticCDN
from flask.ext.sqlalchemy import SQLAlchemy from flask.ext.sqlalchemy import SQLAlchemy
from flask_debugtoolbar import DebugToolbarExtension
from airbrake import Airbrake, AirbrakeHandler from airbrake import Airbrake, AirbrakeHandler
@ -16,6 +17,8 @@ app.extensions['bootstrap']['cdns']['bootstrap'] = StaticCDN()
db = SQLAlchemy(app) db = SQLAlchemy(app)
toolbar = DebugToolbarExtension(app)
class PrefixFix(object): class PrefixFix(object):
def __init__(self, app, script_name): def __init__(self, app, script_name):

View file

@ -30,6 +30,7 @@ class OrderForm(Form):
class OrderItemForm(Form): class OrderItemForm(Form):
product_id = SelectField('Item', coerce=int) product_id = SelectField('Item', coerce=int)
extra = StringField('Extra')
submit_button = SubmitField('Submit') submit_button = SubmitField('Submit')
def populate(self, location): def populate(self, location):

View file

@ -0,0 +1,26 @@
"""Add extra message
Revision ID: 4e94c0b08ed
Revises: 42709384216
Create Date: 2015-06-24 21:42:41.466973
"""
# revision identifiers, used by Alembic.
revision = '4e94c0b08ed'
down_revision = '42709384216'
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql
def upgrade():
### commands auto generated by Alembic - please adjust! ###
op.add_column('order_item', sa.Column('extra', sa.String(length=254), nullable=True))
### end Alembic commands ###
def downgrade():
### commands auto generated by Alembic - please adjust! ###
op.drop_column('order_item', 'extra')
### end Alembic commands ###

View file

@ -102,12 +102,18 @@ class Order(db.Model):
user["paid"] = user.get("paid", True) and item.paid user["paid"] = user.get("paid", True) and item.paid
user["products"] = user.get("products", []) + [item.product] user["products"] = user.get("products", []) + [item.product]
group[item.get_name()] = user group[item.get_name()] = user
return group return group
def group_by_product(self): def group_by_product(self):
group = defaultdict(int) group = dict()
for item in self.items: for item in self.items:
group[item.product.name] += 1 product = group.get(item.product.name, dict())
product['count'] = product.get("count", 0) + 1
if item.extra:
product["extras"] = product.get("extras", []) + [item.extra]
group[item.product.name] = product
return group return group
def can_close(self, user_id): def can_close(self, user_id):
@ -126,8 +132,10 @@ class OrderItem(db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
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'), nullable=False) order_id = db.Column(db.Integer, db.ForeignKey('order.id'), nullable=False)
product_id = db.Column(db.Integer, db.ForeignKey('product.id')) product_id = db.Column(db.Integer, db.ForeignKey('product.id'),
paid = db.Column(db.Boolean, default=False) nullable=False)
paid = db.Column(db.Boolean, default=False, nullable=False)
extra = db.Column(db.String(254), nullable=True)
name = db.Column(db.String(120)) name = db.Column(db.String(120))
def configure(self, user, order, product): def configure(self, user, order, product):

View file

@ -18,3 +18,7 @@ body {
.full-width { .full-width {
width: 100%; width: 100%;
} }
.product .extras {
padding-left: 20px;
}

View file

@ -27,7 +27,7 @@
{%- endif %} {%- endif %}
</div> </div>
<div class="col-sm-5 col-sm-push-2"> <div class="col-sm-5 col-sm-push-2">
{% if orders|count > 0 -%} {% if recently_closed|count > 0 -%}
<h3>Recently closed orders:</h3> <h3>Recently closed orders:</h3>
{% for order in recently_closed %} {% for order in recently_closed %}
{{ util.render_order(order) }} {{ util.render_order(order) }}

View file

@ -38,6 +38,11 @@
{{ form.product_id(class='form-control select') }} {{ form.product_id(class='form-control select') }}
{{ util.render_form_field_errors(form.product_id) }} {{ util.render_form_field_errors(form.product_id) }}
</div> </div>
<div class="form-group {{ 'has-errors' if form.product_id.errors }}">
{{ form.extra.label(class='control-label') }}<br>
{{ form.extra(class='form-control', placeholder='Fill in extras, when applicable') }}
{{ util.render_form_field_errors(form.extra) }}
</div>
{% if current_user.is_anonymous() %} {% if current_user.is_anonymous() %}
<div class="form-group{{ ' has-error' if form.name.errors }}{{ ' required' if form.name.flags.required }}"> <div class="form-group{{ ' has-error' if form.name.errors }}{{ ' required' if form.name.flags.required }}">
{{ form.name.label(class='control-label') }} {{ form.name.label(class='control-label') }}
@ -63,7 +68,7 @@
{% for item in order.items -%} {% for item in order.items -%}
<tr> <tr>
<td>{{ item.get_name() }}</td> <td>{{ item.get_name() }}</td>
<td>{{ item.product.name }}</td> <td><span title="{{ item.extra if item.extra }}">{{ item.product.name }}{{ "*" if item.extra }}</span></td>
<td>{{ item.product.price|euro }}</td> <td>{{ item.product.price|euro }}</td>
{% if courier_or_admin %}<td>{% if not item.paid %} <a class="btn btn-xs btn-primary" href="{{ url_for('.item_paid', order_id=order.id, item_id=item.id) }}">Pay</a> {% else %} <span class="glyphicon glyphicon-chevron-down"></span> {% endif %}</td>{% endif %} {% if courier_or_admin %}<td>{% if not item.paid %} <a class="btn btn-xs btn-primary" href="{{ url_for('.item_paid', order_id=order.id, item_id=item.id) }}">Pay</a> {% else %} <span class="glyphicon glyphicon-chevron-down"></span> {% endif %}</td>{% endif %}
<td>{% 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/></td> <td>{% 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/></td>
@ -75,7 +80,16 @@
<div class="col-md-push-2 col-md-4 darker" id="items-ordered"> <div class="col-md-push-2 col-md-4 darker" id="items-ordered">
<h3>Ordered products:</h3> <h3>Ordered products:</h3>
{% for key, value in order.group_by_product().items() -%} {% for key, value in order.group_by_product().items() -%}
{{ key }} - {{ value }}<br/> <div class="product">
{{ key }}: {{ value["count"] }}
{% if value["extras"] -%}
<div class="extras">
{% for extra in value["extras"] -%}
<div>{{ extra }}</div>
{% endfor %}
</div>
{%- endif %}
</div>
{%- endfor %} {%- endfor %}
</div> </div>
</div> </div>

View file

@ -35,7 +35,7 @@
{{ util.render_form_field_errors(form.starttime) }} {{ util.render_form_field_errors(form.starttime) }}
</div> </div>
{% endif %} {% endif %}
<div class="form-group{{ ' has-error' if form.stoptime.errors }}{{ ' required' if form.stoptime.flags.required }}{{ ' hidden' if not current_user.is_admin() }}"> <div class="form-group{{ ' has-error' if form.stoptime.errors }}{{ ' required' if form.stoptime.flags.required }}">
{{ form.stoptime.label(class='control-label') }} {{ form.stoptime.label(class='control-label') }}
<div class='input-group date' class='datetimepicker'> <div class='input-group date' class='datetimepicker'>
{{ form.stoptime(class='form-control datetimepicker') }} {{ form.stoptime(class='form-control datetimepicker') }}

View file

@ -50,7 +50,7 @@
{{ util.render_form_field_errors(form.starttime) }} {{ util.render_form_field_errors(form.starttime) }}
</div> </div>
{% endif %} {% endif %}
<div class="form-group{{ ' has-error' if form.stoptime.errors }}{{ ' required' if form.stoptime.flags.required }}{{ ' hidden' if not current_user.is_admin() }}"> <div class="form-group{{ ' has-error' if form.stoptime.errors }}{{ ' required' if form.stoptime.flags.required }}">
{{ form.stoptime.label(class='control-label') }} {{ form.stoptime.label(class='control-label') }}
<div class='input-group date' class='datetimepicker'> <div class='input-group date' class='datetimepicker'>
{{ form.stoptime(class='form-control datetimepicker') }} {{ form.stoptime(class='form-control datetimepicker') }}

View file

@ -1,6 +1,7 @@
Flask==0.10.1 Flask==0.10.1
Flask-Admin==1.1.0 Flask-Admin==1.1.0
Flask-Bootstrap==3.3.4.1 Flask-Bootstrap==3.3.4.1
Flask-DebugToolbar==0.10.0
Flask-Login==0.2.11 Flask-Login==0.2.11
Flask-Migrate==1.4.0 Flask-Migrate==1.4.0
Flask-OAuthlib==0.9.1 Flask-OAuthlib==0.9.1