more creditnote stuff

This commit is contained in:
Thomas Steen Rasmussen 2016-06-19 21:37:25 +02:00
parent 3e401f03bc
commit 062f7502d0
5 changed files with 99 additions and 9 deletions

View file

@ -285,6 +285,9 @@ class EpayPayment(CreatedUpdatedModel, UUIDModel):
class CreditNote(CreatedUpdatedModel):
class Meta:
ordering = ['-created']
amount = models.DecimalField(max_digits=10, decimal_places=2)
text = models.TextField()
pdf = models.FileField(
@ -300,7 +303,7 @@ class CreditNote(CreatedUpdatedModel):
)
paid = models.BooleanField(
verbose_name=_('Paid?'),
help_text=_('Whether this creditnote has been paid.'),
help_text=_('Whether the amount in this creditnote has been paid back to the customer.'),
default=False,
)
sent_to_customer = models.BooleanField(default=False)

View file

@ -0,0 +1,36 @@
{% extends 'shop_base.html' %}
{% load bootstrap3 %}
{% load shop_tags %}
{% block shop_content %}
<h3>Credit Notes</h3>
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>Credit Note ID</th>
<th>Text</th>
<th class="text-right">Amount</th>
<th>Paid?</th>
<th>PDF</th>
</tr>
</thead>
<tbody>
{% for creditnote in creditnotes %}
<tr>
<td>{{ creditnote.id }}</td>
<td>{{ creditnote.text }}</td>
<td class="text-right">{{ creditnote.amount|currency }}</td>
<td class="text-center">{{ creditnote.paid|truefalseicon }}</td>
<td>
{% if creditnote.pdf %}
{% url 'shop:download_creditnote' pk=creditnote.pk as creditnote_download_url %}
{% bootstrap_button "PDF" icon="save-file" href=creditnote_download_url button_class="btn-primary btn-xs" %}
{% else %}
N/A
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

View file

@ -7,16 +7,19 @@
<ol class="breadcrumb">
<li><a href="{% url 'shop:index' %}">Shop</a></li>
{% if product %}
<li><a href="{% url 'shop:index' %}?category={{product.category.slug}}">{{ product.category }}</a></li>
<li class="active">{{ product.name }}</li>
<li><a href="{% url 'shop:index' %}?category={{product.category.slug}}">{{ product.category }}</a></li>
<li class="active">{{ product.name }}</li>
{% elif current_category %}
<li class="active">{{ current_category }}</li>
<li class="active">{{ current_category }}</li>
{% endif %}
{% if user.is_authenticated and user.orders.exists %}
{% if has_tickets %}
<li class="pull-right"><a href="{% url 'shop:ticket_list' %}">Tickets</a></li>
{% endif %}
<li class="pull-right no-before"><a href="{% url 'shop:order_list' %}">Orders</a></li>
{% if has_tickets %}
<li class="pull-right"><a href="{% url 'shop:ticket_list' %}">Tickets</a></li>
{% endif %}
<li class="pull-right no-before"><a href="{% url 'shop:order_list' %}">Orders</a></li>
{% if user.creditnotes.exists %}
<li class="pull-right"><a href="{% url 'shop:creditnote_list' %}">Credit Notes</a></li>
{% endif %}
{% endif %}
</ol>
</div>

View file

@ -23,4 +23,7 @@ urlpatterns = [
url(r'tickets/$', TicketListView.as_view(), name='ticket_list'),
url(r'tickets/(?P<pk>\b[0-9A-Fa-f]{8}\b(-\b[0-9A-Fa-f]{4}\b){3}-\b[0-9A-Fa-f]{12}\b)$', TicketDetailView.as_view(), name='ticket_detail'),
url(r'creditnotes/$', CreditNoteListView.as_view(), name='creditnote_list'),
url(r'creditnotes/(?P<pk>[0-9]+)/pdf/$', DownloadCreditNoteView.as_view(), name='download_creditnote'),
]

View file

@ -40,11 +40,38 @@ from vendor.coinify_callback import CoinifyCallback
import json, time
class EnsureCreditNoteHasPDFMixin(SingleObjectMixin):
model = CreditNote
def dispatch(self, request, *args, **kwargs):
if not self.get_object().pdf:
messages.error(request, "This creditnote has no PDF yet!")
return HttpResponseRedirect(reverse_lazy('shop:creditnote_list'))
return super(EnsureCreditNoteHasPDFMixin, self).dispatch(
request, *args, **kwargs
)
class EnsureUserOwnsCreditNoteMixin(SingleObjectMixin):
model = CreditNote
def dispatch(self, request, *args, **kwargs):
# If the user does not own this creditnote OR is not staff
if not request.user.is_staff:
if self.get_object().user != request.user:
raise Http404("CreditNote not found")
return super(EnsureUserOwnsCreditNoteMixin, self).dispatch(
request, *args, **kwargs
)
class EnsureUserOwnsOrderMixin(SingleObjectMixin):
model = Order
def dispatch(self, request, *args, **kwargs):
# If the user does not own this ticket OR is not staff
# If the user does not own this order OR is not staff
if not request.user.is_staff:
if self.get_object().user != request.user:
raise Http404("Order not found")
@ -319,6 +346,24 @@ class DownloadInvoiceView(LoginRequiredMixin, EnsureUserOwnsOrderMixin, EnsurePa
response.write(self.get_object().invoice.pdf.read())
return response
class CreditNoteListView(LoginRequiredMixin, ListView):
model = CreditNote
template_name = "creditnote_list.html"
context_object_name = 'creditnotes'
class DownloadCreditNoteView(LoginRequiredMixin, EnsureUserOwnsCreditNoteMixin, EnsureCreditNoteHasPDFMixin, SingleObjectMixin, View):
model = CreditNote
def get(self, request, *args, **kwargs):
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="%s"' % self.get_object().filename
response.write(self.get_object().invoice.pdf.read())
return response
#################################################################################
class EpayFormView(LoginRequiredMixin, EnsureUserOwnsOrderMixin, EnsureUnpaidOrderMixin, EnsureClosedOrderMixin, EnsureOrderHasProductsMixin, DetailView):