Add bank details and file uploads for reimbursement claims

This commit is contained in:
Yingtong Li 2020-01-04 16:50:31 +11:00
parent 8ef85addd0
commit 96e45c0c5c
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
5 changed files with 121 additions and 5 deletions

View File

@ -23,7 +23,7 @@
{% block maincontent %} {% block maincontent %}
<h1>{% if request.resolver_match.url_name == 'claim_new' %}New{% else %}Edit{% endif %} reimbursement claim</h1> <h1>{% if request.resolver_match.url_name == 'claim_new' %}New{% else %}Edit{% endif %} reimbursement claim</h1>
<form class="ui form" method="POST"> <form class="ui form" method="POST" enctype="multipart/form-data">
<div class="ui disabled inline grid field"> <div class="ui disabled inline grid field">
<label class="three wide column">ID</label> <label class="three wide column">ID</label>
<input class="eleven wide column" type="text" name="id" value="{{ 'RE-{}'.format(claim.id) if claim.id != None else '' }}"> <input class="eleven wide column" type="text" name="id" value="{{ 'RE-{}'.format(claim.id) if claim.id != None else '' }}">
@ -72,6 +72,31 @@
<textarea class="eleven wide column" rows="2" name="comments">{{ claim.comments }}</textarea> <textarea class="eleven wide column" rows="2" name="comments">{{ claim.comments }}</textarea>
</div> </div>
<div class="ui divider"></div> <div class="ui divider"></div>
<div class="ui required inline grid field">
<label class="three wide column">Payee name</label>
<input class="eleven wide column" type="text" name="payee_name" value="{{ claim.payee_name }}">
</div>
<div class="ui required inline grid field">
<label class="three wide column">Payee BSB</label>
<input class="eleven wide column" type="text" name="payee_bsb" value="{{ claim.payee_bsb }}">
</div>
<div class="ui required inline grid field">
<label class="three wide column">Payee account number</label>
<input class="eleven wide column" type="text" name="payee_account" value="{{ claim.payee_account }}">
</div>
<div class="ui divider"></div>
<div class="ui required inline grid field">
<label class="three wide column">Receipts</label>
<div class="eleven wide column">
<ul>
{% for claim_receipt in claim.claimreceipt_set.all() %}
<li><a href="{{ MEDIA_URL }}{{ claim_receipt.uploaded_file.name }}">{{ claim_receipt.uploaded_file.name.split('/')[-1] }}</a> <button class="ui mini red basic icon button" type="submit" name="submit" value="DeleteFile{{ claim_receipt.id }}" style="margin-left: 1em;" onclick="return confirm('Are you sure you want to delete this file? If you have any unsaved changes, you should save the claim first.');"><i class="trash icon"></i></button></li>
{% endfor %}
</ul>
<input type="file" name="upload_file" multiple>
</div>
</div>
<div class="ui divider"></div>
<div class="ui required inline grid field"> <div class="ui required inline grid field">
<label class="three wide column">Items</label> <label class="three wide column">Items</label>
<div class="eleven wide column"></div> <div class="eleven wide column"></div>
@ -80,6 +105,12 @@
<input type="hidden" name="items" id="items_input"> <input type="hidden" name="items" id="items_input">
<div class="ui divider"></div> <div class="ui divider"></div>
<div class="ui error message"></div> <div class="ui error message"></div>
<div>
<h2 class="ui header">Declaration</h2>
<p>By submitting this form for processing with my MUMUS account, I agree that MUMUS Inc. will accept this communication as containing my signature for the purposes of the Electronic Transactions Acts. I certify that the information on this form is true and accurate. I acknowledge that incorrect information may result in the forfeiture of this reimbursement.</p>
<p>Under the Pay As You Go legislation and guidelines produced by the Australian Taxation Office, I state that the supply to MUMUS Inc. described on this form is wholly of a private or domestic nature for me, I have no reasonable expectation of profit or gain from the activity undertaken, and I consider that I do not meet the definition of enterprise for tax purposes. Therefore, I do not need to quote an Australian Business Number and MUMUS Inc. is not required to withhold tax from my payment.</p>
</div>
<div class="ui divider"></div>
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}"> <input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
<input class="ui primary button" type="submit" name='submit' value="Save"> <input class="ui primary button" type="submit" name='submit' value="Save">
<input class="ui button" type="submit" name='submit' value="Save and continue editing"> <input class="ui button" type="submit" name='submit' value="Save and continue editing">

View File

@ -77,6 +77,35 @@
<td>Comments</td> <td>Comments</td>
<td>{{ claim.comments }}</td> <td>{{ claim.comments }}</td>
</tr> </tr>
<tr>
<td>Payee</td>
<td>
<div class="ui list">
<div class="item">
<i class="user circle icon"></i>
<div class="content">{{ claim.payee_name }}</div>
</div>
<div class="item">
<i class="building icon"></i>
<div class="content">BSB: {{ claim.payee_bsb }}</div>
</div>
<div class="item">
<i class="dollar sign icon"></i>
<div class="content">Account: {{ claim.payee_account }}</div>
</div>
</div>
</td>
</tr>
<tr>
<td>Receipts</td>
<td>
<ul>
{% for claim_receipt in claim.claimreceipt_set.all() %}
<li><a href="{{ MEDIA_URL }}{{ claim_receipt.uploaded_file.name }}">{{ claim_receipt.uploaded_file.name.split('/')[-1] }}</a></li>
{% endfor %}
</ul>
</td>
</tr>
<tr> <tr>
<td>Items</td> <td>Items</td>
<td> <td>

View File

@ -105,6 +105,35 @@
<td>Comments</td> <td>Comments</td>
<td>{{ claim.comments }}</td> <td>{{ claim.comments }}</td>
</tr> </tr>
<tr>
<td>Payee</td>
<td>
<div class="ui list">
<div class="item">
<i class="user circle icon"></i>
<div class="content">{{ claim.payee_name }}</div>
</div>
<div class="item">
<i class="building icon"></i>
<div class="content">BSB: {{ claim.payee_bsb }}</div>
</div>
<div class="item">
<i class="dollar sign icon"></i>
<div class="content">Account: {{ claim.payee_account }}</div>
</div>
</div>
</td>
</tr>
<tr>
<td>Receipts</td>
<td>
<ul>
{% for claim_receipt in claim.claimreceipt_set.all() %}
<li><a href="{{ MEDIA_URL }}{{ claim_receipt.uploaded_file.name }}">{{ claim_receipt.uploaded_file.name.split('/')[-1] }}</a></li>
{% endfor %}
</ul>
</td>
</tr>
<tr> <tr>
<td>Items</td> <td>Items</td>
<td> <td>

View File

@ -195,6 +195,10 @@ class ReimbursementClaim(models.Model):
items = JSONField(default=[]) items = JSONField(default=[])
payee_name = models.TextField()
payee_bsb = models.CharField(max_length=7)
payee_account = models.TextField(max_length=20)
def update_state(self, user, state): def update_state(self, user, state):
self.state = state.value self.state = state.value
self.save() self.save()
@ -270,7 +274,7 @@ class ReimbursementClaim(models.Model):
class ClaimReceipt(models.Model): class ClaimReceipt(models.Model):
claim = models.ForeignKey(ReimbursementClaim, on_delete=models.CASCADE) claim = models.ForeignKey(ReimbursementClaim, on_delete=models.CASCADE)
uploaded_file = models.FileField() uploaded_file = models.FileField(upload_to='receipt_uploads/%Y/%m/%d/')
class ClaimComment(models.Model): class ClaimComment(models.Model):
claim = models.ForeignKey(ReimbursementClaim, on_delete=models.CASCADE) claim = models.ForeignKey(ReimbursementClaim, on_delete=models.CASCADE)

View File

@ -112,7 +112,7 @@ def revision_from_form(budget, revision, form):
return revision return revision
def claim_from_form(claim, form): def claim_from_form(claim, form, files):
claim.purpose = form['purpose'] claim.purpose = form['purpose']
claim.date = form['date'] if form['date'] else None claim.date = form['date'] if form['date'] else None
claim.budget_id = form['budget_id'] claim.budget_id = form['budget_id']
@ -121,8 +121,19 @@ def claim_from_form(claim, form):
claim.state = models.ClaimState.DRAFT.value claim.state = models.ClaimState.DRAFT.value
claim.items = json.loads(form['items']) claim.items = json.loads(form['items'])
claim.payee_name = form['payee_name']
claim.payee_bsb = form['payee_bsb']
claim.payee_account = form['payee_account']
claim.save() claim.save()
if files:
for f in files.getlist('upload_file'):
claim_receipt = models.ClaimReceipt()
claim_receipt.claim = claim
claim_receipt.uploaded_file = f
claim_receipt.save()
return claim return claim
# INDEX VIEW # INDEX VIEW
@ -392,7 +403,7 @@ def claim_new(request):
claim.author = request.user claim.author = request.user
claim.time = timezone.now() claim.time = timezone.now()
claim.state = models.BudgetState.DRAFT.value claim.state = models.BudgetState.DRAFT.value
claim = claim_from_form(claim, request.POST) claim = claim_from_form(claim, request.POST, request.FILES)
claim_history = models.ClaimHistory() claim_history = models.ClaimHistory()
claim_history.claim = claim claim_history.claim = claim
@ -456,12 +467,24 @@ def claim_print(request, claim):
@claim_editable @claim_editable
def claim_edit(request, claim): def claim_edit(request, claim):
if request.method == 'POST': if request.method == 'POST':
if request.POST['submit'].startswith('DeleteFile'):
file_id = int(request.POST['submit'][10:])
claim_receipt = models.ClaimReceipt.objects.get(id=file_id)
if claim_receipt.claim != claim:
raise PermissionDenied
claim_receipt.delete()
claim_receipt.uploaded_file.delete(save=False)
return redirect(reverse('claim_edit', kwargs={'id': claim.id}))
if request.POST['submit'] == 'Delete': if request.POST['submit'] == 'Delete':
claim.delete() claim.delete()
return redirect(reverse('claim_list')) return redirect(reverse('claim_list'))
with transaction.atomic(): with transaction.atomic():
claim = claim_from_form(claim, request.POST) claim = claim_from_form(claim, request.POST, request.FILES)
claim_history = models.ClaimHistory() claim_history = models.ClaimHistory()
claim_history.claim = claim claim_history.claim = claim