Add button to update invoice

Allow the recipient on an invoice to be updated without creating a new invoice.
This allows fixing of mistakes easily, especially for when it is given to someone
else to pay and a new invoice would be confusing.
This commit is contained in:
Joel Addison 2019-10-30 09:16:55 +10:00
parent e529983759
commit f52477c9b4
4 changed files with 46 additions and 12 deletions

View file

@ -32,10 +32,15 @@
{% elif invoice.is_paid %} {% elif invoice.is_paid %}
{% if user.is_staff %} {% if user.is_staff %}
<a class="btn btn-default" href="{% url "manual_payment" invoice.id %}">Apply manual payment/refund</a> <a class="btn btn-primary" href="{% url "manual_payment" invoice.id %}">Apply manual payment/refund</a>
<a class="btn btn-default" href="{% url "refund" invoice.id %}">Refund by issuing credit note</a> <a class="btn btn-secondary" href="{% url "refund" invoice.id %}">Refund by issuing credit note</a>
{% endif %}
{% endif %}
{% if user.is_staff %}
<a class="btn btn-info" href="{% url "attendee" invoice.user.id %}">View attendee</a>
<a class="btn btn-light" href="{% url "invoice_update" invoice.id %}">Refresh recipient</a>
{% endif %} {% endif %}
{% endif %}
</div> </div>
{% endblock %} {% endblock %}

View file

@ -172,12 +172,7 @@ class InvoiceController(ForId, object):
issued = timezone.now() issued = timezone.now()
due = max(issued, min_due_time) due = max(issued, min_due_time)
# Get the invoice recipient recipient = cls._recipient(user)
profile = people.AttendeeProfileBase.objects.get_subclass(
id=user.attendee.attendeeprofilebase.id,
)
recipient = profile.invoice_recipient()
invoice_value = sum(item.quantity * item.price for item in line_items) invoice_value = sum(item.quantity * item.price for item in line_items)
invoice = commerce.Invoice.objects.create( invoice = commerce.Invoice.objects.create(
@ -228,6 +223,22 @@ class InvoiceController(ForId, object):
invoice.refresh_from_db() invoice.refresh_from_db()
@classmethod
def _recipient(cls, user):
''' Get the invoice recipient. '''
profile = people.AttendeeProfileBase.objects.get_subclass(
id=user.attendee.attendeeprofilebase.id,
)
recipient = profile.invoice_recipient()
return recipient
def update_recipient(self):
''' Update the recipient of the invoice based on the current
attendee data. '''
self.invoice.recipient = self._recipient(self.invoice.user)
self.invoice.save()
def can_view(self, user=None, access_code=None): def can_view(self, user=None, access_code=None):
''' Returns true if the accessing user is allowed to view this invoice, ''' Returns true if the accessing user is allowed to view this invoice,
or if the given access code matches this invoice's user's access code. or if the given access code matches this invoice's user's access code.

View file

@ -17,6 +17,7 @@ from .views import (
invoice, invoice,
invoice_access, invoice_access,
invoice_mailout, invoice_mailout,
invoice_update,
manual_payment, manual_payment,
product_category, product_category,
refund, refund,
@ -43,8 +44,8 @@ public = [
url(r"^invoice/([0-9]+)/([A-Z0-9]+)$", invoice, name="invoice"), url(r"^invoice/([0-9]+)/([A-Z0-9]+)$", invoice, name="invoice"),
url(r"^invoice/([0-9]+)/manual_payment$", url(r"^invoice/([0-9]+)/manual_payment$",
manual_payment, name="manual_payment"), manual_payment, name="manual_payment"),
url(r"^invoice/([0-9]+)/refund$", url(r"^invoice/([0-9]+)/refund$", refund, name="refund"),
refund, name="refund"), url(r"^invoice/([0-9]+)/update$", invoice_update, name="invoice_update"),
url(r"^invoice_access/([A-Z0-9]+)$", invoice_access, url(r"^invoice_access/([A-Z0-9]+)$", invoice_access,
name="invoice_access"), name="invoice_access"),
url(r"^invoice_mailout$", invoice_mailout, name="invoice_mailout"), url(r"^invoice_mailout$", invoice_mailout, name="invoice_mailout"),

View file

@ -711,7 +711,8 @@ def checkout(request, user_id=None):
current_cart = CartController.for_user(user) current_cart = CartController.for_user(user)
if "fix_errors" in request.GET and request.GET["fix_errors"] == "true": fix_errors = request.GET.get("fix_errors") == "true"
if fix_errors:
current_cart.fix_simple_errors() current_cart.fix_simple_errors()
try: try:
@ -719,6 +720,9 @@ def checkout(request, user_id=None):
except ValidationError as ve: except ValidationError as ve:
return _checkout_errors(request, ve) return _checkout_errors(request, ve)
if fix_errors:
current_invoice.update_recipient()
return redirect("invoice", current_invoice.invoice.id) return redirect("invoice", current_invoice.invoice.id)
@ -825,6 +829,19 @@ def invoice(request, invoice_id, access_code=None):
return render(request, "registrasion/invoice.html", data) return render(request, "registrasion/invoice.html", data)
def invoice_update(request, invoice_id):
''' Updates an invoice to have the latest recipient information. '''
current_invoice = InvoiceController.for_id_or_404(invoice_id)
if not current_invoice.can_view(user=request.user):
raise Http404()
current_invoice.update_recipient()
return redirect("invoice", current_invoice.invoice.id)
def _staff_only(user): def _staff_only(user):
''' Returns true if the user is staff. ''' ''' Returns true if the user is staff. '''
return user.is_staff return user.is_staff