1 | import sys |
---|
2 | import os |
---|
3 | import csv |
---|
4 | import subprocess |
---|
5 | import vouchers.models |
---|
6 | import finance_core.models |
---|
7 | from django.db import connection |
---|
8 | from finance_core.models import BudgetArea |
---|
9 | from finance_core.models import coerce_full_email |
---|
10 | from finance_core.models import Transaction |
---|
11 | from finance_core.models import get_layer_by_name, layer_num |
---|
12 | from decimal import * |
---|
13 | |
---|
14 | columns = ['comm_name','priority','expense_type','start_date','end_date','project','item_name','desc','people','count','costitem','subtotal','per_person','email_list'] |
---|
15 | line_format = "%(priority)-4.4s %(expense_type)-10.10s %(subtotal)10.10s %(project)-16.16s %(item_name)-20.20s %(desc)-20.20s %(people)6.6s %(count)5.5s %(costitem)10.10s" |
---|
16 | |
---|
17 | def build_committees(infile=sys.stdin): |
---|
18 | committees = {} |
---|
19 | reader = csv.reader(infile) |
---|
20 | for comm in reader: |
---|
21 | email_list,chair_list,name,prefer_chair,area,account = comm |
---|
22 | if prefer_chair=='yes': prefer_chair = True |
---|
23 | else: prefer_chair = False |
---|
24 | committees[email_list] = { 'email_list': email_list, 'chair_list': chair_list, 'name': name, 'prefer_chair':prefer_chair, 'area':area, 'account':account} |
---|
25 | return committees |
---|
26 | |
---|
27 | def do_populate_area_structure(): |
---|
28 | nodes = [ |
---|
29 | [ ('Accounts', 'Root',) ], |
---|
30 | [ ('Assets', 'Assets', ) ], |
---|
31 | [ ('Budget', "This period's intended operating budget", ) ], |
---|
32 | [ |
---|
33 | ('Holding', "Holding account for the budgets between income and transferring to committee / line item accounts", ), |
---|
34 | ('Core', "Core budget areas", ), |
---|
35 | ('Committees', "Committees and auxiliary budget areas", ), |
---|
36 | ], |
---|
37 | ] |
---|
38 | parent = None |
---|
39 | for zdepth, accounts in enumerate(nodes): |
---|
40 | depth=zdepth+1 |
---|
41 | for name, comment in accounts: |
---|
42 | if(len(BudgetArea.objects.filter(name=name, depth=depth)) == 0): |
---|
43 | # Create the new node |
---|
44 | if parent: |
---|
45 | parent.add_child(name=name, comment=comment, |
---|
46 | always=True, use_owner=True,) |
---|
47 | else: |
---|
48 | BudgetArea.add_root(name=name, comment=comment, |
---|
49 | always=True, use_owner=True, |
---|
50 | owner='ua-treasurer@mit.edu', |
---|
51 | interested='ua-treasurer@mit.edu', ) |
---|
52 | # This is sorta evil, in that it abuses the fact that Python |
---|
53 | # won't put name out of scope |
---|
54 | parent = BudgetArea.objects.get(name=name, depth=depth) |
---|
55 | return (depth, ) |
---|
56 | |
---|
57 | def do_populate_committees(committees): |
---|
58 | (depth,) = do_populate_area_structure() |
---|
59 | core = BudgetArea.objects.get(name='Core', depth=depth) |
---|
60 | comms = BudgetArea.objects.get(name='Committees', depth=depth) |
---|
61 | parents = { |
---|
62 | 'Core':core, |
---|
63 | 'Committees':comms, |
---|
64 | } |
---|
65 | for comm in committees.values(): |
---|
66 | parent = parents[comm['area']] |
---|
67 | if len(parent.get_children().filter(name=comm['name'])) > 0: |
---|
68 | pass |
---|
69 | else: |
---|
70 | parent.add_child( |
---|
71 | name=comm['name'], |
---|
72 | owner=coerce_full_email(comm['chair_list']), |
---|
73 | interested=coerce_full_email(comm['email_list']), |
---|
74 | use_owner=comm['prefer_chair'], |
---|
75 | always=True, |
---|
76 | ) |
---|
77 | return (depth+1, ) |
---|
78 | |
---|
79 | budget_layer = layer_num(get_layer_by_name('budget')) |
---|
80 | def do_process_rows(committees, budget, term, depth): |
---|
81 | reader = csv.reader(budget) |
---|
82 | |
---|
83 | header = reader.next() |
---|
84 | line_dict = {} |
---|
85 | for key, elem in zip(columns, header,): |
---|
86 | line_dict[key]=elem |
---|
87 | |
---|
88 | budget_source = BudgetArea.get_by_path( |
---|
89 | ['Accounts','Assets','Budget','Holding'] |
---|
90 | ) |
---|
91 | |
---|
92 | for line in reader: |
---|
93 | comm_name,priority,expense_type,start_date,end_date,project,item_name,desc,people,count,costitem,subtotal,perperson,email_list=line |
---|
94 | line_dict = {} |
---|
95 | for key, elem in zip(columns, line,): |
---|
96 | line_dict[key]=elem |
---|
97 | if(email_list != "" and comm_name[-4:] != " Sum"): |
---|
98 | email_list = coerce_full_email(email_list.lower()) |
---|
99 | comm = BudgetArea.objects.get(depth=depth, interested=email_list,) |
---|
100 | projects = comm.get_children().filter(name=project) |
---|
101 | if(len(projects)==0): |
---|
102 | parent_project = comm.add_child( |
---|
103 | name=project, |
---|
104 | always=False, |
---|
105 | ) |
---|
106 | else: parent_project = projects[0] |
---|
107 | parent_project.mark_used(term) |
---|
108 | line_items = parent_project.get_children().filter(name=item_name) |
---|
109 | if(len(line_items)==0): |
---|
110 | line_item_obj = parent_project.add_child( |
---|
111 | name=item_name, |
---|
112 | always=False, |
---|
113 | ) |
---|
114 | else: line_item_obj = line_items[0] |
---|
115 | line_item_obj.mark_used(term) |
---|
116 | amount = Decimal(subtotal.replace('$', '').replace(',', '')) |
---|
117 | finance_core.models.make_transfer( |
---|
118 | item_name, amount, budget_layer, |
---|
119 | term, budget_source, line_item_obj, desc=desc) |
---|
120 | |
---|
121 | |
---|
122 | def main(committees_file, budget_file, term_name, ): |
---|
123 | term = vouchers.models.BudgetTerm.objects.get(name=term_name) |
---|
124 | committees = build_committees(committees_file,) |
---|
125 | (depth, ) = do_populate_committees(committees) |
---|
126 | do_process_rows(committees, budget_file, term, depth) |
---|
127 | |
---|
128 | |
---|
129 | def spring_2010(): |
---|
130 | committee_file = open('/mit/ua/officers/treasurer/resources/software/committees.csv') |
---|
131 | budget_file = open('/mit/ua/officers/treasurer/budgeting/FY10/private/spring-working.csv') |
---|
132 | term_name = 'Spring 2010' |
---|
133 | main(committee_file, budget_file, term_name, ) |
---|
134 | print connection.queries |
---|
135 | |
---|
136 | |
---|
137 | if __name__== '__main__': |
---|
138 | #print "Syntax: %s committee_file format_file budget_file budget_term [override_address]" % (sys.argv[0], ) |
---|
139 | spring_2010() |
---|