From afc93531809913660c3e08b661bc3b1e4b3ddd2d Mon Sep 17 00:00:00 2001
From: Leo Mouyna
Date: Sat, 28 Sep 2019 14:16:42 +0200
Subject: [PATCH] feat: Optional field 'external link' 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.
---
ihatemoney/forms.py | 8 ++++--
.../migrations/versions/6c6fb2b7f229_.py | 26 ++++++++++++++++++
ihatemoney/models.py | 2 ++
ihatemoney/static/css/main.css | 19 +++++++------
ihatemoney/static/images/see.png | Bin 0 -> 448 bytes
ihatemoney/templates/forms.html | 3 +-
ihatemoney/templates/list_bills.html | 3 ++
7 files changed, 50 insertions(+), 11 deletions(-)
create mode 100644 ihatemoney/migrations/versions/6c6fb2b7f229_.py
create mode 100644 ihatemoney/static/images/see.png
diff --git a/ihatemoney/forms.py b/ihatemoney/forms.py
index cce36e39..a4c80c16 100644
--- a/ihatemoney/forms.py
+++ b/ihatemoney/forms.py
@@ -1,8 +1,8 @@
from flask_wtf.form import FlaskForm
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.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 import request
from werkzeug.security import generate_password_hash
@@ -146,6 +146,8 @@ class BillForm(FlaskForm):
what = StringField(_("What?"), validators=[DataRequired()])
payer = SelectField(_("Payer"), validators=[DataRequired()], coerce=int)
amount = CalculatorStringField(_("Amount paid"), validators=[DataRequired()])
+ external_link = URLField(_("External link"), validators=[Optional(
+ )], description="A link to an external document, related to this bill")
payed_for = SelectMultipleField(_("For whom?"),
validators=[DataRequired()], coerce=int)
submit = SubmitField(_("Submit"))
@@ -155,6 +157,7 @@ class BillForm(FlaskForm):
bill.payer_id = self.payer.data
bill.amount = self.amount.data
bill.what = self.what.data
+ bill.external_link = self.external_link.data
bill.date = self.date.data
bill.owers = [Person.query.get(ower, project)
for ower in self.payed_for.data]
@@ -165,6 +168,7 @@ class BillForm(FlaskForm):
self.payer.data = bill.payer_id
self.amount.data = bill.amount
self.what.data = bill.what
+ self.external_link.data = bill.external_link
self.date.data = bill.date
self.payed_for.data = [int(ower.id) for ower in bill.owers]
diff --git a/ihatemoney/migrations/versions/6c6fb2b7f229_.py b/ihatemoney/migrations/versions/6c6fb2b7f229_.py
new file mode 100644
index 00000000..0336f6c4
--- /dev/null
+++ b/ihatemoney/migrations/versions/6c6fb2b7f229_.py
@@ -0,0 +1,26 @@
+"""empty message
+
+Revision ID: 6c6fb2b7f229
+Revises: a67119aa3ee5
+Create Date: 2019-09-28 13:38:09.550747
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '6c6fb2b7f229'
+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('external_link', sa.UnicodeText(), nullable=True))
+ # ### end Alembic commands ###
+
+
+def downgrade():
+ # ### commands auto generated by Alembic - please adjust! ###
+ op.drop_column('bill', 'external_link')
+ # ### end Alembic commands ###
diff --git a/ihatemoney/models.py b/ihatemoney/models.py
index 325cf579..48e16a79 100644
--- a/ihatemoney/models.py
+++ b/ihatemoney/models.py
@@ -327,6 +327,7 @@ class Bill(db.Model):
date = db.Column(db.Date, default=datetime.now)
creation_date = db.Column(db.Date, default=datetime.now)
what = db.Column(db.UnicodeText)
+ external_link = db.Column(db.UnicodeText)
archive = db.Column(db.Integer, db.ForeignKey("archive.id"))
@@ -340,6 +341,7 @@ class Bill(db.Model):
"date": self.date,
"creation_date": self.creation_date,
"what": self.what,
+ "external_link": self.external_link,
}
def pay_each(self):
diff --git a/ihatemoney/static/css/main.css b/ihatemoney/static/css/main.css
index acc95a1a..52bd77b2 100644
--- a/ihatemoney/static/css/main.css
+++ b/ihatemoney/static/css/main.css
@@ -32,7 +32,7 @@ body {
@media (min-width: 992px) {
.projects-item {
- margin-left: auto!important;
+ margin-left: auto !important;
}
}
@@ -108,7 +108,6 @@ body {
.identifier {
margin-bottom: 0;
}
-
}
#add-member-form {
@@ -132,7 +131,7 @@ body {
/* Home */
.home-container {
- background: linear-gradient(150deg, #abe128 0%, #43CA61 100%);
+ background: linear-gradient(150deg, #abe128 0%, #43ca61 100%);
}
.home {
padding-top: 1em;
@@ -146,7 +145,7 @@ body {
min-width: 25em;
border: 0;
border-radius: 0;
- box-shadow: 0px 0px 10px rgba(83, 88, 93, .40);
+ box-shadow: 0px 0px 10px rgba(83, 88, 93, 0.4);
margin-right: 25px;
margin-bottom: 20px;
margin-left: 25px;
@@ -159,7 +158,6 @@ body {
.empty-bill {
margin-top: 5rem !important;
-
}
.empty-bill .card {
border: 0;
@@ -240,7 +238,7 @@ footer .footer-right a {
@-moz-document url-prefix() {
/** Firefox style fix **/
footer .footer-right a {
- padding-top: 2px
+ padding-top: 2px;
}
}
footer .footer-right a:hover {
@@ -290,7 +288,8 @@ footer .footer-left {
}
.bill-actions > .delete,
-.bill-actions > .edit {
+.bill-actions > .edit,
+.bill-actions > .see {
font-size: 0px;
display: block;
width: 16px;
@@ -308,6 +307,10 @@ footer .footer-left {
background: url("../images/edit.png") no-repeat right;
}
+.bill-actions > .see {
+ background: url("../images/see.png") no-repeat right;
+}
+
#bill_table {
margin-top: 30px;
}
@@ -483,4 +486,4 @@ footer .icon svg {
}
.icon.icon-white {
fill: white;
-}
\ No newline at end of file
+}
diff --git a/ihatemoney/static/images/see.png b/ihatemoney/static/images/see.png
new file mode 100644
index 0000000000000000000000000000000000000000..741e8292c3033c7ee858304bb6b5ed6d7a628ac9
GIT binary patch
literal 448
zcmV;x0YCnUP)`2@oNb#?U|PEO7aAoC#*-~Idd?-yofWP6W
z6*q3&m;yEc=u|dEMa2a`#X;Y{f3Nxf|NnU){p0cD$46CERC0jwlc9F}2a3A_X+xkz
zEkFy_J$UdSfl*ISZz~fMlj*y6@BAJ;dUQflQ*#E;&j;?@xw8Vu?qp|YFN3-A*RNkQ
zuU)&AAuB6uAuKGs>EFM9rx|s1b+-a-Hw6ZeAJ9aw0YFVDK=mMh${~9bW`MlByoI2k
zAjAM}Zf>v_fB_c-^c&aS2j{RFroH8r&yE-o%uAbtg6
z6C^`W0ug9X#m$>Hr(i^*h=_=cxVU&VF#fSdBQR{1yn6Mj6&RJ6(TEKA`1m-1UIQm2
qpp!v<2PdRYpFZJFNaTQlHvj+@g|p^li1V-j0000{{ field.description }}
+ {{ field.description }}
{% endif %}
@@ -95,6 +95,7 @@
{{ input(form.what, inline=True) }}
{{ input(form.payer, inline=True, class="form-control custom-select") }}
{{ input(form.amount, inline=True) }}
+ {{ input(form.external_link, inline=True) }}