Index: remit/remit_templates/vouchers/ReimbursementRequest_review.html
===================================================================
--- remit/remit_templates/vouchers/ReimbursementRequest_review.html	(revision e8550be3fa19b22cb087aaba216fdad79c43a025)
+++ remit/remit_templates/vouchers/ReimbursementRequest_review.html	(revision dc17b01800a1d88a58be1b8eaefdadb800ab747c)
@@ -55,4 +55,8 @@
 </tr>
 <tr>
+    <th>Documentation</th>
+    <td>{{rr.documentation}}</td>
+</tr>
+<tr>
     <th>Request Time</th>
     <td>{{rr.request_time}}</td>
@@ -67,4 +71,17 @@
 </tr>
 </table>
+
+{% if doc_form %}
+<h3>(Optional) Upload Documentation</h3>
+
+<p>If you ordered online, you may wish to upload documentation instead of providing a physical copy.</p>
+
+<form enctype="multipart/form-data" method="post" action="">
+<table class='pretty-table'>
+{{ doc_form.as_table }}
+<tr><th colspan='2'><input type='submit' value='Upload Documentation' /></th></tr>
+</table>
+</form>
+{% endif %}
 
 {% if new %}
Index: remit/vouchers/migrations/0002_documentation_support.py
===================================================================
--- remit/vouchers/migrations/0002_documentation_support.py	(revision dc17b01800a1d88a58be1b8eaefdadb800ab747c)
+++ remit/vouchers/migrations/0002_documentation_support.py	(revision dc17b01800a1d88a58be1b8eaefdadb800ab747c)
@@ -0,0 +1,104 @@
+
+from south.db import db
+from django.db import models
+from vouchers.models import *
+
+class Migration:
+    
+    def forwards(self, orm):
+        
+        # Adding model 'Documentation'
+        db.create_table('vouchers_documentation', (
+            ('id', orm['vouchers.documentation:id']),
+            ('backing_file', orm['vouchers.documentation:backing_file']),
+            ('label', orm['vouchers.documentation:label']),
+        ))
+        db.send_create_signal('vouchers', ['Documentation'])
+        
+        # Adding field 'Voucher.documentation'
+        db.add_column('vouchers_voucher', 'documentation', orm['vouchers.voucher:documentation'])
+        
+        # Adding field 'ReimbursementRequest.documentation'
+        db.add_column('vouchers_reimbursementrequest', 'documentation', orm['vouchers.reimbursementrequest:documentation'])
+        
+    
+    
+    def backwards(self, orm):
+        
+        # Deleting model 'Documentation'
+        db.delete_table('vouchers_documentation')
+        
+        # Deleting field 'Voucher.documentation'
+        db.delete_column('vouchers_voucher', 'documentation_id')
+        
+        # Deleting field 'ReimbursementRequest.documentation'
+        db.delete_column('vouchers_reimbursementrequest', 'documentation_id')
+        
+    
+    
+    models = {
+        'finance_core.budgetarea': {
+            'account_number': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'always': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+            'budget_term': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['finance_core.BudgetTerm']"}),
+            'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'depth': ('django.db.models.fields.PositiveIntegerField', [], {}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'interested': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+            'numchild': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+            'owner': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'path': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'use_owner': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'})
+        },
+        'finance_core.budgetterm': {
+            'end_date': ('django.db.models.fields.DateField', [], {}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '20', 'db_index': 'True'}),
+            'start_date': ('django.db.models.fields.DateField', [], {}),
+            'submit_deadline': ('django.db.models.fields.DateField', [], {})
+        },
+        'vouchers.documentation': {
+            'backing_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'label': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        'vouchers.reimbursementrequest': {
+            'amount': ('django.db.models.fields.DecimalField', [], {'max_digits': '7', 'decimal_places': '2'}),
+            'approval_status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'approval_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'budget_area': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'as_budget_area'", 'to': "orm['finance_core.BudgetArea']"}),
+            'budget_term': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['finance_core.BudgetTerm']"}),
+            'check_to_addr': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'check_to_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
+            'check_to_first_name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+            'check_to_last_name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'documentation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['vouchers.Documentation']", 'null': 'True'}),
+            'expense_area': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'as_expense_area'", 'to': "orm['finance_core.BudgetArea']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+            'printing_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'request_time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'submitter': ('django.db.models.fields.CharField', [], {'max_length': '10'})
+        },
+        'vouchers.voucher': {
+            'account': ('django.db.models.fields.IntegerField', [], {}),
+            'amount': ('django.db.models.fields.DecimalField', [], {'max_digits': '7', 'decimal_places': '2'}),
+            'description': ('django.db.models.fields.TextField', [], {}),
+            'documentation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['vouchers.Documentation']", 'null': 'True'}),
+            'email_address': ('django.db.models.fields.EmailField', [], {'max_length': '50'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
+            'gl': ('django.db.models.fields.IntegerField', [], {}),
+            'group_name': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
+            'mailing_address': ('django.db.models.fields.TextField', [], {}),
+            'processed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+            'signatory': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+            'signatory_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'})
+        }
+    }
+    
+    complete_apps = ['vouchers']
Index: remit/vouchers/models.py
===================================================================
--- remit/vouchers/models.py	(revision c020a3b20bd4d13aaf2e711f22e2c4e7a7cf0db4)
+++ remit/vouchers/models.py	(revision dc17b01800a1d88a58be1b8eaefdadb800ab747c)
@@ -31,4 +31,5 @@
     name = models.CharField(max_length=50, verbose_name='short description', )
     description = models.TextField(blank=True, verbose_name='long description', )
+    documentation = models.ForeignKey('Documentation', null=True, )
 
     class Meta:
@@ -92,4 +93,5 @@
     gl = models.IntegerField()
     processed = models.BooleanField()
+    documentation = models.ForeignKey('Documentation', null=True, )
 
     def mailing_addr_lines(self):
@@ -116,4 +118,11 @@
             ('generate_vouchers', 'Can generate vouchers',),
         )
+
+
+class Documentation(models.Model):
+    backing_file = models.FileField(upload_to='documentation', verbose_name='File', help_text='PDF files only', )
+    label = models.CharField(max_length=50, )
+    submitter = models.CharField(max_length=10) # MIT username of submitter
+    upload_time = models.DateTimeField(default=datetime.datetime.now)
 
 
Index: remit/vouchers/views.py
===================================================================
--- remit/vouchers/views.py	(revision 37c15c4252901ab910f55e0c0de2bd78e4406128)
+++ remit/vouchers/views.py	(revision dc17b01800a1d88a58be1b8eaefdadb800ab747c)
@@ -1,4 +1,4 @@
 import vouchers.models
-from vouchers.models import ReimbursementRequest
+from vouchers.models import ReimbursementRequest, Documentation
 from finance_core.models import BudgetTerm, BudgetArea
 
@@ -52,4 +52,13 @@
     term = ModelChoiceField(queryset = BudgetTerm.objects.all())
 
+class DocUploadForm(ModelForm):
+    class Meta:
+        model = Documentation
+        fields = (
+            'label',
+            'backing_file',
+        )
+
+
 @user_passes_test(lambda u: u.is_authenticated())
 def select_request_basics(http_request, ):
@@ -111,4 +120,5 @@
         form.fields['budget_area'] = CommitteeBudgetAreasField(comm_obj)
         form.fields['expense_area'] = ExpenseAreasField()
+
         if form.is_valid(): # All validation rules pass
             request_obj = form.save()
@@ -165,4 +175,21 @@
             new = False
 
+    # DOCUMENTATION #
+    if request_obj.documentation:
+        doc_upload_form = None
+    else:
+        new_docs = Documentation()
+        new_docs.submitter = http_request.user.username
+        if http_request.method == 'POST': # If the form has been submitted...
+            doc_upload_form = DocUploadForm(http_request.POST, http_request.FILES, instance=new_docs) # A form bound to the POST data
+
+            if doc_upload_form.is_valid(): # All validation rules pass
+                new_docs = doc_upload_form.save()
+
+                return HttpResponseRedirect(reverse(review_request, args=[object_id],)) # Redirect after POST
+        else:
+            doc_upload_form = DocUploadForm(instance=new_docs, ) # An unbound form
+
+    # SEND EMAILS
     show_email = http_request.user.has_perm('vouchers.can_email')
     if show_email:
@@ -181,4 +208,5 @@
                 })
 
+    # APPROVE VOUCHERS
     show_approve = (http_request.user.has_perm('vouchers.can_approve')
         and request_obj.approval_status == vouchers.models.APPROVAL_STATE_PENDING)
@@ -229,4 +257,5 @@
         'pagename':'request_reimbursement',
         'new': new,
+        'doc_form': doc_upload_form,
     }
     if show_approve:
