source: remit/vouchers/models.py @ dc17b01

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

WIP WIP WIP: Start of doc upload

  • Property mode set to 100644
File size: 7.7 KB
Line 
1from django.db import models
2import settings
3import finance_core
4from finance_core.models import BudgetArea, BudgetTerm
5
6import datetime
7
8APPROVAL_STATE_PENDING = 0
9APPROVAL_STATE_APPROVED = 1
10APPROVAL_STATE_REJECTED = -1
11APPROVAL_STATES = (
12    (APPROVAL_STATE_PENDING,  'Pending'),
13    (APPROVAL_STATE_APPROVED, 'Approved'),
14    (APPROVAL_STATE_REJECTED, 'Rejected'),
15)
16
17class ReimbursementRequest(models.Model):
18    submitter = models.CharField(max_length=10) # MIT username of submitter
19    check_to_first_name = models.CharField(max_length=50, verbose_name="check recipient's first name")
20    check_to_last_name = models.CharField(max_length=50, verbose_name="check recipient's last name")
21    check_to_email = models.EmailField(verbose_name="email address for check pickup")
22    check_to_addr = models.TextField(blank=True, verbose_name="address for check mailing", help_text="For most requests, this should be blank for pickup in SAO (W20-549)")
23    amount = models.DecimalField(max_digits=7, decimal_places=2, help_text='Do not include "$"')
24    budget_area = models.ForeignKey(BudgetArea, related_name='as_budget_area')
25    budget_term = models.ForeignKey(BudgetTerm)
26    expense_area = models.ForeignKey(BudgetArea, related_name='as_expense_area') # ~GL
27    request_time = models.DateTimeField(default=datetime.datetime.now)
28    approval_time = models.DateTimeField(blank=True, null=True,)
29    approval_status = models.IntegerField(default=0, choices=APPROVAL_STATES)
30    printing_time = models.DateTimeField(blank=True, null=True,)
31    name = models.CharField(max_length=50, verbose_name='short description', )
32    description = models.TextField(blank=True, verbose_name='long description', )
33    documentation = models.ForeignKey('Documentation', null=True, )
34
35    class Meta:
36        permissions = (
37            ('can_list', 'Can list requests',),
38            ('can_approve', 'Can approve requests',),
39            ('can_email', 'Can send mail about requests',),
40        )
41
42    def __unicode__(self, ):
43        return "%s: %s %s (%s) (by %s) for $%s" % (
44            self.name,
45            self.check_to_first_name,
46            self.check_to_last_name,
47            self.check_to_email,
48            self.submitter,
49            self.amount,
50        )
51
52    def convert(self, signatory, signatory_email=settings.SIGNATORY_EMAIL):
53        voucher = Voucher()
54        voucher.group_name = settings.GROUP_NAME
55        voucher.account = self.budget_area.get_account_number()
56        voucher.signatory = signatory
57        voucher.signatory_email = signatory_email
58        voucher.first_name = self.check_to_first_name
59        voucher.last_name = self.check_to_last_name
60        voucher.email_address = self.check_to_email
61        voucher.mailing_address = self.check_to_addr
62        voucher.amount = self.amount
63        voucher.description = self.label() + ': ' + self.name
64        voucher.gl = self.expense_area.get_account_number()
65        voucher.save()
66        finance_core.models.make_transfer(
67            self.name,
68            self.amount,
69            finance_core.models.LAYER_EXPENDITURE,
70            self.budget_term,
71            self.budget_area,
72            self.expense_area,
73            self.description,
74        )
75        self.approval_status = 1
76        self.approval_time = datetime.datetime.now()
77        self.save()
78
79    def label(self, ):
80        return settings.GROUP_ABBR + unicode(self.pk) + 'RR'
81
82class Voucher(models.Model):
83    group_name = models.CharField(max_length=10)
84    account = models.IntegerField()
85    signatory = models.CharField(max_length=50)
86    signatory_email = models.EmailField()
87    first_name = models.CharField(max_length=20)
88    last_name = models.CharField(max_length=20)
89    email_address = models.EmailField(max_length=50)
90    mailing_address = models.TextField()
91    amount = models.DecimalField(max_digits=7, decimal_places=2,)
92    description = models.TextField()
93    gl = models.IntegerField()
94    processed = models.BooleanField()
95    documentation = models.ForeignKey('Documentation', null=True, )
96
97    def mailing_addr_lines(self):
98        import re
99        if self.mailing_address:
100            lst = re.split(re.compile('[\n\r]*'), self.mailing_address)
101            lst = filter(lambda elem: len(elem)>0, lst)
102        else:
103            lst = []
104        lst = lst + ['']*(3-len(lst))
105        return lst
106
107    def __unicode__(self, ):
108        return "%s: %s %s (%s) for $%s" % (
109            self.description,
110            self.first_name,
111            self.last_name,
112            self.email_address,
113            self.amount,
114        )
115
116    class Meta:
117        permissions = (
118            ('generate_vouchers', 'Can generate vouchers',),
119        )
120
121
122class Documentation(models.Model):
123    backing_file = models.FileField(upload_to='documentation', verbose_name='File', help_text='PDF files only', )
124    label = models.CharField(max_length=50, )
125    submitter = models.CharField(max_length=10) # MIT username of submitter
126    upload_time = models.DateTimeField(default=datetime.datetime.now)
127
128
129class StockEmail:
130    def __init__(self, name, label, recipients, template, subject_template, context, ):
131        """
132        Initialize a stock email object.
133       
134        Each argument is required.
135       
136        name:       Short name. Letters, numbers, and hyphens only.
137        label:      User-readable label. Briefly describe what the email says
138        recipients: Who receives the email. List of "recipient" (check recipient), "area" (area owner), "admins" (site admins)
139        template:   Django template filename with the actual text
140        subject_template: Django template string with the subject
141        context:    Type of context the email needs. Must be 'request' currently.
142        """
143
144        self.name       = name
145        self.label      = label
146        self.recipients = recipients
147        self.template   = template
148        self.subject_template = subject_template
149        self.context    = context
150
151    def send_email_request(self, request,):
152        """
153        Send an email that requires context "request".
154        """
155
156        assert self.context == 'request'
157
158        # Generate text
159        from django.template import Context, Template
160        from django.template.loader import get_template
161        ctx = Context({
162            'prefix': settings.EMAIL_SUBJECT_PREFIX,
163            'request': request,
164            'sender': settings.USER_EMAIL_SIGNATURE,
165        })
166        tmpl = get_template(self.template)
167        body = tmpl.render(ctx)
168        subject_tmpl = Template(self.subject_template)
169        subject = subject_tmpl.render(ctx)
170
171        # Generate recipients
172        recipients = []
173        for rt in self.recipients:
174            if rt == 'recipient':
175                recipients.append(request.check_to_email)
176            elif rt == 'area':
177                recipients.append(request.budget_area.owner_address())
178            elif rt == 'admins':
179                pass # you don't *actually* have a choice...
180        for name, addr in settings.ADMINS:
181            recipients.append(addr)
182
183        # Send mail!
184        from django.core.mail import send_mail
185        send_mail(
186            subject,
187            body,
188            settings.SERVER_EMAIL,
189            recipients,
190        )
191
192stock_emails = {
193    'nodoc': StockEmail(
194        name='nodoc',
195        label='No documentation',
196        recipients=['recipient', 'area',],
197        template='vouchers/emails/no_docs_user.txt',
198        subject_template='{{prefix}}Missing documentation for reimbursement',
199        context = 'request',
200    ),
201    'voucher-sao': StockEmail(
202        name='voucher-sao',
203        label='Voucher submitted to SAO',
204        recipients=['recipient', ],
205        template='vouchers/emails/voucher_sao_user.txt',
206        subject_template='{{prefix}}Reimbursement sent to SAO for processing',
207        context = 'request',
208    ),
209}
Note: See TracBrowser for help on using the repository browser.