]> asedeno.scripts.mit.edu Git - bluechips.git/blob - bluechips/controllers/spend.py
749d73039a4c34550d5baaadf607315f098b65b8
[bluechips.git] / bluechips / controllers / spend.py
1 """
2 Handle expenditures
3 """
4
5 import logging
6
7 from decimal import Decimal, InvalidOperation
8
9 from bluechips.lib.base import *
10
11 from pylons import request
12 from pylons.decorators.rest import dispatch_on
13 from pylons.decorators import validate
14
15 from formencode import validators, Schema
16 from formencode.foreach import ForEach
17 from formencode.variabledecode import NestedVariables
18
19 log = logging.getLogger(__name__)
20
21
22 class ShareSchema(Schema):
23     "Validate individual user shares."
24     allow_extra_fields = False
25     user_id = validators.Int(not_empty=True)
26     amount = validators.Number(not_empty=True)
27
28
29 class ExpenditureSchema(Schema):
30     "Validate an expenditure."
31     allow_extra_fields = False
32     pre_validators = [NestedVariables()]
33     spender_id = validators.Int(not_empty=True)
34     amount = model.types.CurrencyValidator(not_empty=True)
35     description = validators.UnicodeString()
36     date = validators.DateConverter()
37     shares = ForEach(ShareSchema)
38     
39
40 class SpendController(BaseController):
41     def index(self):
42         return self.edit()
43     
44     def edit(self, id=None):
45         c.users = meta.Session.query(model.User.id, model.User)
46         if id is None:
47             c.title = 'Add a New Expenditure'
48             c.expenditure = model.Expenditure()
49             c.expenditure.spender_id = request.environ['user'].id
50
51             num_residents = meta.Session.query(model.User).\
52                     filter_by(resident=True).count()
53             # Pre-populate split percentages for an even split.
54             c.values = {}
55             for ii, user_row in enumerate(c.users):
56                 user_id, user = user_row
57                 if user.resident:
58                     val = Decimal(100) / Decimal(num_residents)
59                 else:
60                     val = 0
61                 c.values['shares-%d.amount' % ii] = val
62         else:
63             c.title = 'Edit an Expenditure'
64             c.expenditure = meta.Session.query(model.Expenditure).get(id)
65         return render('/spend/index.mako')
66
67     @validate(schema=ExpenditureSchema(), form='edit', variable_decode=True)
68     def update(self, id=None):
69         # Either create a new object, or, if we're editing, get the
70         # old one
71         if id is None:
72             e = model.Expenditure()
73             meta.Session.add(e)
74         else:
75             e = meta.Session.query(model.Expenditure).get(id)
76         
77         # Set the fields that were submitted
78         shares = self.form_result.pop('shares')
79         update_sar(e, self.form_result)
80         if e.id is not None:
81             e.update_split()
82
83         users = dict(meta.Session.query(model.User.id, model.User).all())
84         split_dict = {}
85         for share_params in shares:
86             user = users[share_params['user_id']]
87             split_dict[user] = Decimal(share_params['amount'])
88         e.split(split_dict)
89         
90         meta.Session.commit()
91         
92         if id is None:
93             h.flash("Expenditure created.")
94         else:
95             h.flash('Expenditure updated.')
96        
97         return h.redirect_to('/')