1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/ihatemoney_ynh.git synced 2024-09-03 19:26:15 +02:00

Add members weight in models and budget backend refs #94

This commit is contained in:
Jocelyn Delande 2015-08-20 10:33:43 +02:00
parent 7891967215
commit 2b071a1a3b
4 changed files with 64 additions and 3 deletions

View file

@ -152,6 +152,7 @@ class BillForm(Form):
class MemberForm(Form): class MemberForm(Form):
name = TextField(_("Name"), validators=[Required()]) name = TextField(_("Name"), validators=[Required()])
weight = CommaDecimalField(_("Weight"), default=1)
submit = SubmitField(_("Add")) submit = SubmitField(_("Add"))
def __init__(self, project, *args, **kwargs): def __init__(self, project, *args, **kwargs):
@ -170,6 +171,7 @@ class MemberForm(Form):
# if the user is already bound to the project, just reactivate him # if the user is already bound to the project, just reactivate him
person.name = self.name.data person.name = self.name.data
person.project = project person.project = project
person.weight = self.weight.data
return person return person

View file

@ -0,0 +1,26 @@
"""Add Person.weight column
Revision ID: 26d6a218c329
Revises: b9a10d5d63ce
Create Date: 2016-06-15 09:22:04.069447
"""
# revision identifiers, used by Alembic.
revision = '26d6a218c329'
down_revision = 'b9a10d5d63ce'
from alembic import op
import sqlalchemy as sa
def upgrade():
### commands auto generated by Alembic - please adjust! ###
op.add_column('person', sa.Column('weight', sa.Float(), nullable=True))
### end Alembic commands ###
def downgrade():
### commands auto generated by Alembic - please adjust! ###
op.drop_column('person', 'weight')
### end Alembic commands ###

View file

@ -40,8 +40,9 @@ class Project(db.Model):
bills = Bill.query.filter(Bill.owers.contains(person)) bills = Bill.query.filter(Bill.owers.contains(person))
for bill in bills.all(): for bill in bills.all():
if person != bill.payer: if person != bill.payer:
should_pay[person] += bill.pay_each() share = bill.pay_each() * person.weight
should_receive[bill.payer] += bill.pay_each() should_pay[person] += share
should_receive[bill.payer] += share
for person in self.members: for person in self.members:
balance = should_receive[person] - should_pay[person] balance = should_receive[person] - should_pay[person]
@ -159,6 +160,7 @@ class Person(db.Model):
bills = db.relationship("Bill", backref="payer") bills = db.relationship("Bill", backref="payer")
name = db.Column(db.UnicodeText) name = db.Column(db.UnicodeText)
weight = db.Column(db.Float, default=1)
activated = db.Column(db.Boolean, default=True) activated = db.Column(db.Boolean, default=True)
def has_bills(self): def has_bills(self):
@ -219,7 +221,8 @@ class Bill(db.Model):
def pay_each(self): def pay_each(self):
"""Compute what each person has to pay""" """Compute what each person has to pay"""
if self.owers: if self.owers:
return self.amount / len(self.owers) # FIXME: SQL might dot that more efficiently
return self.amount / sum(i.weight for i in self.owers)
else: else:
return 0 return 0

View file

@ -416,6 +416,36 @@ class BudgetTestCase(TestCase):
bill = models.Bill.query.filter(models.Bill.date == '2011-08-01')[0] bill = models.Bill.query.filter(models.Bill.date == '2011-08-01')[0]
self.assertEqual(bill.amount, 25.02) self.assertEqual(bill.amount, 25.02)
def test_weighted_balance(self):
self.post_project("raclette")
# add two persons
self.app.post("/raclette/members/add", data={'name': 'alexis'})
self.app.post("/raclette/members/add", data={'name': 'freddy familly', 'weight': 4})
members_ids = [m.id for m in
models.Project.query.get("raclette").members]
# test balance
self.app.post("/raclette/add", data={
'date': '2011-08-10',
'what': u'fromage à raclette',
'payer': members_ids[0],
'payed_for': members_ids,
'amount': '10',
})
self.app.post("/raclette/add", data={
'date': '2011-08-10',
'what': u'pommes de terre',
'payer': members_ids[1],
'payed_for': members_ids,
'amount': '10',
})
balance = models.Project.query.get("raclette").balance
self.assertEqual(set(balance.values()), set([6, -6]))
def test_rounding(self): def test_rounding(self):
self.post_project("raclette") self.post_project("raclette")