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