feat: Optional link field in bill form.

An optional field has been added to the bill form to add a link to a real bill. A new action button allow user to see this bill. Breaking change with Bill model update for database, a migration is needed.

See issue #429.
This commit is contained in:
Leo Mouyna 2019-09-16 00:33:27 +02:00
parent 33d497aac2
commit 0d7c027617
7 changed files with 46 additions and 4 deletions

View file

@ -1,8 +1,8 @@
from flask_wtf.form import FlaskForm from flask_wtf.form import FlaskForm
from wtforms.fields.core import SelectField, SelectMultipleField from wtforms.fields.core import SelectField, SelectMultipleField
from wtforms.fields.html5 import DateField, DecimalField from wtforms.fields.html5 import DateField, DecimalField, URLField
from wtforms.fields.simple import PasswordField, SubmitField, TextAreaField, StringField from wtforms.fields.simple import PasswordField, SubmitField, TextAreaField, StringField
from wtforms.validators import Email, DataRequired, ValidationError, EqualTo, NumberRange from wtforms.validators import Email, DataRequired, ValidationError, EqualTo, NumberRange, Optional
from flask_babel import lazy_gettext as _ from flask_babel import lazy_gettext as _
from flask import request from flask import request
from werkzeug.security import generate_password_hash from werkzeug.security import generate_password_hash
@ -139,6 +139,7 @@ class BillForm(FlaskForm):
what = StringField(_("What?"), validators=[DataRequired()]) what = StringField(_("What?"), validators=[DataRequired()])
payer = SelectField(_("Payer"), validators=[DataRequired()], coerce=int) payer = SelectField(_("Payer"), validators=[DataRequired()], coerce=int)
amount = CalculatorStringField(_("Amount paid"), validators=[DataRequired()]) amount = CalculatorStringField(_("Amount paid"), validators=[DataRequired()])
document = URLField(_("Document"), validators=[Optional()], description="A link to your bill.")
payed_for = SelectMultipleField(_("For whom?"), payed_for = SelectMultipleField(_("For whom?"),
validators=[DataRequired()], coerce=int) validators=[DataRequired()], coerce=int)
submit = SubmitField(_("Submit")) submit = SubmitField(_("Submit"))
@ -149,6 +150,7 @@ class BillForm(FlaskForm):
bill.amount = self.amount.data bill.amount = self.amount.data
bill.what = self.what.data bill.what = self.what.data
bill.date = self.date.data bill.date = self.date.data
bill.document = self.document.data
bill.owers = [Person.query.get(ower, project) bill.owers = [Person.query.get(ower, project)
for ower in self.payed_for.data] for ower in self.payed_for.data]
@ -159,6 +161,7 @@ class BillForm(FlaskForm):
self.amount.data = bill.amount self.amount.data = bill.amount
self.what.data = bill.what self.what.data = bill.what
self.date.data = bill.date self.date.data = bill.date
self.document.data = bill.document
self.payed_for.data = [int(ower.id) for ower in bill.owers] self.payed_for.data = [int(ower.id) for ower in bill.owers]
def set_default(self): def set_default(self):

View file

@ -0,0 +1,26 @@
"""empty message
Revision ID: df95884d26ae
Revises: a67119aa3ee5
Create Date: 2019-09-15 23:17:29.721176
"""
# revision identifiers, used by Alembic.
revision = 'df95884d26ae'
down_revision = 'a67119aa3ee5'
from alembic import op
import sqlalchemy as sa
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('bill', sa.Column('document', sa.UnicodeText(), nullable=True))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('bill', 'document')
# ### end Alembic commands ###

View file

@ -358,12 +358,13 @@ class Bill(db.Model):
date = db.Column(db.Date, default=datetime.now) date = db.Column(db.Date, default=datetime.now)
creation_date = db.Column(db.Date, default=datetime.now) creation_date = db.Column(db.Date, default=datetime.now)
what = db.Column(db.UnicodeText) what = db.Column(db.UnicodeText)
document = db.Column(db.UnicodeText)
archive = db.Column(db.Integer, db.ForeignKey("archive.id")) archive = db.Column(db.Integer, db.ForeignKey("archive.id"))
@property @property
def _to_serialize(self): def _to_serialize(self):
return { dict = {
"id": self.id, "id": self.id,
"payer_id": self.payer_id, "payer_id": self.payer_id,
"owers": self.owers, "owers": self.owers,
@ -372,6 +373,9 @@ class Bill(db.Model):
"creation_date": self.creation_date, "creation_date": self.creation_date,
"what": self.what, "what": self.what,
} }
if self.document:
dict["document"] = self.document
return dict
def pay_each(self): def pay_each(self):
"""Compute what each share has to pay""" """Compute what each share has to pay"""

View file

@ -290,7 +290,8 @@ footer .footer-left {
} }
.bill-actions > .delete, .bill-actions > .delete,
.bill-actions > .edit { .bill-actions > .edit,
.bill-actions > .see {
font-size: 0px; font-size: 0px;
display: block; display: block;
width: 16px; width: 16px;
@ -308,6 +309,10 @@ footer .footer-left {
background: url("../images/edit.png") no-repeat right; background: url("../images/edit.png") no-repeat right;
} }
.bill-actions > .see {
background: url("../images/see.png") no-repeat right;
}
#bill_table { #bill_table {
margin-top: 30px; margin-top: 30px;
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 B

View file

@ -95,6 +95,7 @@
{{ input(form.what, inline=True) }} {{ input(form.what, inline=True) }}
{{ input(form.payer, inline=True, class="form-control custom-select") }} {{ input(form.payer, inline=True, class="form-control custom-select") }}
{{ input(form.amount, inline=True) }} {{ input(form.amount, inline=True) }}
{{ input(form.document, inline=True) }}
<div class="form-group row"> <div class="form-group row">
<label class="col-3" for="payed_for">{{ _("For whom?") }}</label> <label class="col-3" for="payed_for">{{ _("For whom?") }}</label>

View file

@ -128,6 +128,9 @@
<td class="bill-actions"> <td class="bill-actions">
<a class="edit" href="{{ url_for(".edit_bill", bill_id=bill.id) }}" title="{{ _("edit") }}">{{ _('edit') }}</a> <a class="edit" href="{{ url_for(".edit_bill", bill_id=bill.id) }}" title="{{ _("edit") }}">{{ _('edit') }}</a>
<a class="delete" href="{{ url_for(".delete_bill", bill_id=bill.id) }}" title="{{ _("delete") }}">{{ _('delete') }}</a> <a class="delete" href="{{ url_for(".delete_bill", bill_id=bill.id) }}" title="{{ _("delete") }}">{{ _('delete') }}</a>
{% if bill.document %}
<a class="see" href="{{ bill.document }}" target="_blank" title="{{ _("see") }}">{{ _('see') }} </a>
{% endif %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}