source: remit/vouchers/views.py @ e601d3b

client
Last change on this file since e601d3b was e601d3b, checked in by Alex Dehnert <adehnert@…>, 15 years ago

Slightly clearer request review page

  • Property mode set to 100644
File size: 8.3 KB
RevLine 
[269db50]1import vouchers.models
[6b8d891]2from vouchers.models import ReimbursementRequest
[3e79308]3from finance_core.models import BudgetTerm, BudgetArea
[269db50]4
[6b8d891]5from django.contrib.auth.decorators import user_passes_test
6from django.shortcuts import render_to_response, get_object_or_404
[fedcbcf]7from django.template import RequestContext
[6b8d891]8from django.http import Http404, HttpResponseRedirect
[587bb95]9import django.forms
[70ce03a]10from django.forms import Form
[6b8d891]11from django.forms import ModelForm
12from django.forms import ModelChoiceField
13from django.core.urlresolvers import reverse
[269db50]14
[587bb95]15import settings
16
[6b8d891]17class RequestForm(ModelForm):
18    class Meta:
19        model = ReimbursementRequest
20        fields = (
21            'name',
22            'description',
23            'amount',
24            'budget_area',
[f6c7295]25            'expense_area',
[248b30b]26            'check_to_first_name',
27            'check_to_last_name',
[6b8d891]28            'check_to_email',
29            'check_to_addr',
30        )
31
[70ce03a]32class CommitteesField(ModelChoiceField):
33    def __init__(self, *args, **kargs):
34        base_area = BudgetArea.get_by_path(['Accounts', 'Assets', 'Budget', ])
35        self.strip_levels = base_area.depth
36        areas = (base_area.get_descendants()
37            .filter(depth__lte=base_area.depth+2)
38            .exclude(name='Holding')
39        )
40        ModelChoiceField.__init__(self, queryset=areas,
41            help_text='Select the appropriate committe or other budget area',
42            *args, **kargs)
43
44    def label_from_instance(self, obj,):
45        return obj.indented_name(strip_levels=self.strip_levels)
46
47class SelectRequestBasicsForm(Form):
[17193ee]48    area = CommitteesField()
[70ce03a]49    term = ModelChoiceField(queryset = BudgetTerm.objects.all())
50
51@user_passes_test(lambda u: u.is_authenticated())
52def select_request_basics(http_request, ):
53    if http_request.method == 'POST': # If the form has been submitted...
54        form = SelectRequestBasicsForm(http_request.POST) # A form bound to the POST data
55        if form.is_valid(): # All validation rules pass
56            term = form.cleaned_data['term'].slug
57            area = form.cleaned_data['area'].id
58            return HttpResponseRedirect(reverse(submit_request, args=[term, area],)) # Redirect after POST
59    else:
60        form = SelectRequestBasicsForm() # An unbound form
61
62    context = {
63        'form':form,
[3a0c51b]64        'pagename':'request_reimbursement',
[70ce03a]65    }
[fedcbcf]66    return render_to_response('vouchers/select.html', context, context_instance=RequestContext(http_request), )
[70ce03a]67
68class CommitteeBudgetAreasField(ModelChoiceField):
[6b8d891]69    def __init__(self, base_area, *args, **kargs):
70        self.strip_levels = base_area.depth
71        areas = base_area.get_descendants()
72        ModelChoiceField.__init__(self, queryset=areas,
73            help_text='In general, this should be a fully indented budget area, not one with children',
74            *args, **kargs)
75
76    def label_from_instance(self, obj,):
77        return obj.indented_name(strip_levels=self.strip_levels)
78
[f6c7295]79class ExpenseAreasField(ModelChoiceField):
80    def __init__(self, *args, **kargs):
81        base_area = vouchers.models.BudgetArea.get_by_path(['Accounts', 'Expenses'])
82        self.strip_levels = base_area.depth
83        areas = base_area.get_descendants()
84        ModelChoiceField.__init__(self, queryset=areas,
85            help_text='In general, this should be a fully indented budget area, not one with children',
86            *args, **kargs)
87
88    def label_from_instance(self, obj,):
89        return obj.indented_name(strip_levels=self.strip_levels)
90
[6b8d891]91@user_passes_test(lambda u: u.is_authenticated())
92def submit_request(http_request, term, committee):
93    term_obj = get_object_or_404(BudgetTerm, slug=term)
94    comm_obj = get_object_or_404(BudgetArea, pk=committee)
95
96    new_request = ReimbursementRequest()
97    new_request.submitter = http_request.user.username
98    new_request.budget_term = term_obj
99
[e2f2aa9]100    # Prefill from certs
101    initial = {}
102    try:
103        name = http_request.META['SSL_CLIENT_S_DN_CN']
104        names = name.split(' ')
105        initial['check_to_first_name'] = names[0]
106        initial['check_to_last_name'] = names[-1]
107    except KeyError:
108        pass
109    try:
110        initial['check_to_email'] = http_request.META['SSL_CLIENT_S_DN_Email']
111    except KeyError:
112        pass
113
[6b8d891]114    if http_request.method == 'POST': # If the form has been submitted...
115        form = RequestForm(http_request.POST, instance=new_request) # A form bound to the POST data
[70ce03a]116        form.fields['budget_area'] = CommitteeBudgetAreasField(comm_obj)
[f6c7295]117        form.fields['expense_area'] = ExpenseAreasField()
[6b8d891]118        if form.is_valid(): # All validation rules pass
119            form.save()
[856aac8]120            return HttpResponseRedirect(reverse(review_request, args=[new_request.pk],) + '?new=true') # Redirect after POST
[6b8d891]121    else:
[e2f2aa9]122        form = RequestForm(instance=new_request, initial=initial, ) # An unbound form
[70ce03a]123        form.fields['budget_area'] = CommitteeBudgetAreasField(comm_obj)
[f6c7295]124        form.fields['expense_area'] = ExpenseAreasField()
[269db50]125
126    context = {
127        'term':term_obj,
128        'comm':comm_obj,
[6b8d891]129        'form':form,
[3a0c51b]130        'pagename':'request_reimbursement',
[269db50]131    }
[fedcbcf]132    return render_to_response('vouchers/submit.html', context, context_instance=RequestContext(http_request), )
[6b8d891]133
[587bb95]134class VoucherizeForm(Form):
[e601d3b]135    name = django.forms.CharField(max_length=100, help_text='Signatory name for voucher',)
136    email = django.forms.EmailField(max_length=100, help_text='Signatory email for voucher')
[587bb95]137
138
[6b8d891]139@user_passes_test(lambda u: u.is_authenticated())
140def review_request(http_request, object_id):
141    request_obj = get_object_or_404(ReimbursementRequest, pk=object_id)
[856aac8]142    new = False
143    if 'new' in http_request.REQUEST:
144        if http_request.REQUEST['new'].upper() == 'TRUE':
145            new = True
146        else:
147            new = False
[587bb95]148
[3e79308]149    show_approve = (http_request.user.has_perm('vouchers.can_approve')
150        and request_obj.approval_status == vouchers.models.APPROVAL_STATE_PENDING)
151    if show_approve:
[587bb95]152        # Voucherize form
153        # Prefill from certs / config
154        initial = {}
155        try:
156            name = http_request.META['SSL_CLIENT_S_DN_CN']
157            initial['name'] = name
158        except KeyError:
159            pass
160        if settings.SIGNATORY_EMAIL:
161            initial['email'] = settings.SIGNATORY_EMAIL
162        else:
163            try:
164                initial['email'] = http_request.META['SSL_CLIENT_S_DN_Email']
165            except KeyError:
166                pass
167
168        approve_message = ''
169        if http_request.method == 'POST' and 'approve' in http_request.REQUEST:
170            approve_form = VoucherizeForm(http_request.POST)
171            if approve_form.is_valid():
172                voucher = request_obj.convert(
173                    approve_form.cleaned_data['name'],
174                    signatory_email=approve_form.cleaned_data['email'],)
175                approve_message = 'Created new voucher from request'
176        else:
177            approve_form = VoucherizeForm(initial=initial)
178
179    # Display the content
[6b8d891]180    if not (http_request.user.has_perm('vouchers.view_requests')
181        or http_request.user.username == request_obj.submitter):
182        # I'd probably use a 403, but that requires like writing
183        # a new template and stuff
184        # So I'm going to call this "don't leak information"
185        # and let it be
186        raise Http404
187    context = {
188        'rr':request_obj,
[3a0c51b]189        'pagename':'request_reimbursement',
[856aac8]190        'new': new,
[6b8d891]191    }
[3e79308]192    if show_approve:
[587bb95]193        context['approve_form'] = approve_form
194        context['approve_message'] = approve_message
[fedcbcf]195    return render_to_response('vouchers/ReimbursementRequest_review.html', context, context_instance=RequestContext(http_request), )
[6b8d891]196
[dcaa9c0]197def generate_vouchers(http_request, *args):
198    unprocessed = True
199    if 'unprocessed' in http_request.REQUEST:
200        if http_request.REQUEST['unprocessed'].upper() == 'TRUE':
201            unprocessed = True
202        else:
203            unprocessed = False
204    mark = True
205    if 'mark' in http_request.REQUEST:
206        if http_request.REQUEST['mark'].upper() == 'TRUE':
207            mark = True
208        else:
209            mark = False
210
211    lst = vouchers.models.Voucher.objects.all()
212    if unprocessed:
213        lst = lst.filter(processed=False)
214
215    context = {'vouchers': lst }
216    response = render_to_response('vouchers/vouchers.tex', context, context_instance=RequestContext(http_request), )
217
218    if mark:
219        for voucher in lst:
220            voucher.processed = True
221            voucher.save()
222
223    return response
Note: See TracBrowser for help on using the repository browser.