X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=bluechips%2Fcontrollers%2Fspend.py;h=4e89b35b55c27ed6c0d79cff74609e991aa3d2ae;hb=94a556a2cc75c26c623e6855039d214ab62e17de;hp=c99d325ba10984b2fd1da0a508cf9479668ca8b3;hpb=da1f93fdb5d86f642018933a5ef51949b28a8125;p=bluechips.git diff --git a/bluechips/controllers/spend.py b/bluechips/controllers/spend.py index c99d325..4e89b35 100644 --- a/bluechips/controllers/spend.py +++ b/bluechips/controllers/spend.py @@ -9,13 +9,14 @@ from decimal import Decimal, InvalidOperation from bluechips.lib.base import * from pylons import request, app_globals as g -from pylons.decorators.rest import dispatch_on from pylons.decorators import validate +from pylons.decorators.secure import authenticate_form from pylons.controllers.util import abort from formencode import validators, Schema from formencode.foreach import ForEach from formencode.variabledecode import NestedVariables +from formencode.schema import SimpleFormValidator from mailer import Message @@ -29,6 +30,12 @@ class ShareSchema(Schema): amount = validators.Number(not_empty=True) +def validate_state(value_dict, state, validator): + if all(s['amount'] == 0 for s in value_dict['shares']): + return {'shares-0.amount': 'Need at least one non-zero share'} +ValidateNotAllZero = SimpleFormValidator(validate_state) + + class ExpenditureSchema(Schema): "Validate an expenditure." allow_extra_fields = False @@ -38,6 +45,7 @@ class ExpenditureSchema(Schema): description = validators.UnicodeString() date = validators.DateConverter() shares = ForEach(ShareSchema) + chained_validators = [ValidateNotAllZero] class SpendController(BaseController): @@ -57,10 +65,9 @@ class SpendController(BaseController): c.values = {} for ii, user_row in enumerate(c.users): user_id, user = user_row + val = 0 if user.resident: val = Decimal(100) / Decimal(num_residents) - else: - val = 0 c.values['shares-%d.amount' % ii] = val else: c.title = 'Edit an Expenditure' @@ -70,18 +77,21 @@ class SpendController(BaseController): c.values = {} for ii, user_row in enumerate(c.users): user_id, user = user_row - try: - share = [s.share for s in c.expenditure.splits - if s.user == user][0] + shares_by_user = dict(((sp.user, sp.share) for sp + in c.expenditure.splits)) + share = shares_by_user.get(user, 0) + if c.expenditure.amount == 0: + percent = 0 + else: percent = (Decimal(100) * Decimal(int(share)) / Decimal(int(c.expenditure.amount))).\ quantize(Decimal("0.001")) - except IndexError: - percent = 0 c.values['shares-%d.amount' % ii] = percent return render('/spend/index.mako') + @redirect_on_get('edit') + @authenticate_form @validate(schema=ExpenditureSchema(), form='edit', variable_decode=True) def update(self, id=None): # Either create a new object, or, if we're editing, get the @@ -99,8 +109,6 @@ class SpendController(BaseController): # Set the fields that were submitted shares = self.form_result.pop('shares') update_sar(e, self.form_result) - if e.id is not None: - e.update_split() users = dict(meta.Session.query(model.User.id, model.User).all()) split_dict = {} @@ -124,3 +132,35 @@ class SpendController(BaseController): g.handle_notification(involved_users, show, body) return h.redirect_to('/') + + def delete(self, id): + c.title = 'Delete an Expenditure' + c.expenditure = meta.Session.query(model.Expenditure).get(id) + if c.expenditure is None: + abort(404) + + return render('/spend/delete.mako') + + @redirect_on_get('delete') + @authenticate_form + def destroy(self, id): + e = meta.Session.query(model.Expenditure).get(id) + if e is None: + abort(404) + + if 'delete' in request.params: + meta.Session.delete(e) + + meta.Session.commit() + show = ("Expenditure of %s paid for by %s deleted." % + (e.amount, e.spender)) + h.flash(show) + + involved_users = set(sp.user for sp in e.splits if sp.share != 0) + involved_users.add(e.spender) + body = render('/emails/expenditure.txt', + extra_vars={'expenditure': e, + 'op': 'deleted'}) + g.handle_notification(involved_users, show, body) + + return h.redirect_to('/')