From fe6f77d97eef5621aefcabcb0692cdd1ec6ec181 Mon Sep 17 00:00:00 2001 From: Evan Broder Date: Fri, 18 Jul 2008 02:59:03 +0000 Subject: [PATCH] Move functions for splitting expenditures into Expenditure model --- bluechips/controllers/spend.py | 3 +- bluechips/lib/split.py | 72 ---------------------------------- bluechips/model/expenditure.py | 64 ++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 74 deletions(-) delete mode 100644 bluechips/lib/split.py diff --git a/bluechips/controllers/spend.py b/bluechips/controllers/spend.py index a775084..a72f65f 100644 --- a/bluechips/controllers/spend.py +++ b/bluechips/controllers/spend.py @@ -6,7 +6,6 @@ import logging from bluechips.lib.base import * from bluechips.widgets import spend -from bluechips.lib.split import * from pylons import request @@ -25,7 +24,7 @@ class SpendController(BaseController): update_sar(e, self.form_result) meta.Session.save(e) - even_split(e) + e.even_split() meta.Session.commit() h.flash('Expenditure recorded.') diff --git a/bluechips/lib/split.py b/bluechips/lib/split.py deleted file mode 100644 index 3d5d88a..0000000 --- a/bluechips/lib/split.py +++ /dev/null @@ -1,72 +0,0 @@ -""" -Functions for handling splitting expenditures between people -""" - -from bluechips import model -from bluechips.model.meta import Session -from bluechips.lib.helpers import round_currency -from decimal import Decimal -import random - -def even_split(e): - """ - Split up an expenditure evenly among the resident users - - e should be a bluechips.model:Expenditure object - """ - - residents = Session.query(model.User).filter(model.User.resident==True) - split_percentage = Decimal(100) / Decimal(residents.count()) - split(e, dict((resident, split_percentage) for resident in residents)) - -def split(e, split_dict): - """ - Split up an expenditure. - - e should be a bluechips.model:Expenditure object. - - split_dict should be a dict mapping from bluechips.model:User - objects to a decimal:Decimal object representing the percentage - that user is responsible for. - - Percentages will be normalized to sum to 100%. - - If the split leaks or gains money due to rounding errors, the - pennies will be randomly distributed to one of the users. - - I mean, come on. You're already living together. Are you really - going to squabble over a few pennies? - """ - - map(Session.delete, Session.query(model.Split).\ - filter_by(expenditure_id=e.id)) - - total = sum(split_dict.itervalues()) - - for user, share in split_dict.iteritems(): - split_dict[user] = share / total - - amounts_dict = dict() - - for user, share in split_dict.iteritems(): - amounts_dict[user] = round_currency(split_dict[user] * e.amount) - - difference = e.amount - sum(amounts_dict.itervalues()) - - if difference > 0: - for i in xrange(difference * 100): - winner = random.choice(amounts_dict.keys()) - amounts_dict[winner] += Decimal('0.01') - elif difference < 0: - for i in xrange(difference * -100): - winner = random.choice(amounts_dict.keys()) - amounts_dict[winner] -= Decimal('0.01') - - for user, share in amounts_dict.iteritems(): - s = model.Split() - s.expenditure = e - s.user = user - s.share = share - Session.save(s) - -__all__ = ['split', 'even_split'] diff --git a/bluechips/model/expenditure.py b/bluechips/model/expenditure.py index c093e75..88d65b3 100644 --- a/bluechips/model/expenditure.py +++ b/bluechips/model/expenditure.py @@ -1,6 +1,70 @@ +from user import User +from split import Split +from bluechips.model import meta +from bluechips.lib.helpers import round_currency +from decimal import Decimal +import random + class Expenditure(object): def __repr__(self): return '' % (self.spender, self.amount) + def even_split(self): + """ + Split up an expenditure evenly among the resident users + """ + + residents = meta.Session.query(User).filter(User.resident==True) + split_percentage = Decimal(100) / Decimal(residents.count()) + self.split(dict((resident, split_percentage) for resident in residents)) + + def split(self, split_dict): + """ + Split up an expenditure. + + split_dict should be a dict mapping from bluechips.model:User + objects to a decimal:Decimal object representing the percentage + that user is responsible for. + + Percentages will be normalized to sum to 100%. + + If the split leaks or gains money due to rounding errors, the + pennies will be randomly distributed to one of the users. + + I mean, come on. You're already living together. Are you really + going to squabble over a few pennies? + """ + + map(meta.Session.delete, meta.Session.query(Split).\ + filter_by(expenditure_id=self.id)) + + total = sum(split_dict.itervalues()) + + for user, share in split_dict.iteritems(): + split_dict[user] = share / total + + amounts_dict = dict() + + for user, share in split_dict.iteritems(): + amounts_dict[user] = round_currency(split_dict[user] * self.amount) + + difference = self.amount - sum(amounts_dict.itervalues()) + + if difference > 0: + for i in xrange(difference * 100): + winner = random.choice(amounts_dict.keys()) + amounts_dict[winner] += Decimal('0.01') + elif difference < 0: + for i in xrange(difference * -100): + winner = random.choice(amounts_dict.keys()) + amounts_dict[winner] -= Decimal('0.01') + + for user, share in amounts_dict.iteritems(): + s = Split() + s.expenditure = self + s.user = user + s.share = share + meta.Session.save(s) + __all__ = ['Expenditure'] -- 2.45.2