Add view to retrieve bill document.
This commit is contained in:
parent
186d20ec20
commit
c2d865d664
|
@ -28,6 +28,7 @@ API_PATHS = {
|
||||||
|
|
||||||
# other
|
# other
|
||||||
'bill-list': 'bills/',
|
'bill-list': 'bills/',
|
||||||
|
'bill-document': 'bills/{pk}/document/',
|
||||||
'payment-source-list': 'payment-sources/',
|
'payment-source-list': 'payment-sources/',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +60,7 @@ class Orchestra(object):
|
||||||
|
|
||||||
return response.json().get("token", None)
|
return response.json().get("token", None)
|
||||||
|
|
||||||
def request(self, verb, resource=None, querystring=None, url=None, raise_exception=True):
|
def request(self, verb, resource=None, url=None, render_as="json", querystring=None, raise_exception=True):
|
||||||
assert verb in ["HEAD", "GET", "POST", "PATCH", "PUT", "DELETE"]
|
assert verb in ["HEAD", "GET", "POST", "PATCH", "PUT", "DELETE"]
|
||||||
if resource is not None:
|
if resource is not None:
|
||||||
url = self.build_absolute_uri(resource)
|
url = self.build_absolute_uri(resource)
|
||||||
|
@ -77,7 +78,10 @@ class Orchestra(object):
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
|
|
||||||
status = response.status_code
|
status = response.status_code
|
||||||
output = response.json()
|
if render_as == "json":
|
||||||
|
output = response.json()
|
||||||
|
else:
|
||||||
|
output = response.content
|
||||||
|
|
||||||
return status, output
|
return status, output
|
||||||
|
|
||||||
|
@ -94,6 +98,15 @@ class Orchestra(object):
|
||||||
raise PermissionError("Cannot retrieve profile of an anonymous user.")
|
raise PermissionError("Cannot retrieve profile of an anonymous user.")
|
||||||
return UserAccount.new_from_json(output[0])
|
return UserAccount.new_from_json(output[0])
|
||||||
|
|
||||||
|
def retrieve_bill_document(self, pk):
|
||||||
|
path = API_PATHS.get('bill-document').format_map({'pk': pk})
|
||||||
|
|
||||||
|
url = urllib.parse.urljoin(self.base_url, path)
|
||||||
|
status, bill_pdf = self.request("GET", render_as="html", url=url, raise_exception=False)
|
||||||
|
if status == 404:
|
||||||
|
raise Http404(_("No domain found matching the query"))
|
||||||
|
return bill_pdf
|
||||||
|
|
||||||
def retrieve_domain(self, pk):
|
def retrieve_domain(self, pk):
|
||||||
path = API_PATHS.get('domain-detail').format_map({'pk': pk})
|
path = API_PATHS.get('domain-detail').format_map({'pk': pk})
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ class OrchestraModel:
|
||||||
class Bill(OrchestraModel):
|
class Bill(OrchestraModel):
|
||||||
api_name = 'bill'
|
api_name = 'bill'
|
||||||
param_defaults = {
|
param_defaults = {
|
||||||
|
"id": None,
|
||||||
"number": "1",
|
"number": "1",
|
||||||
"type": "INVOICE",
|
"type": "INVOICE",
|
||||||
"total": 0.0,
|
"total": 0.0,
|
||||||
|
@ -60,12 +61,6 @@ class Bill(OrchestraModel):
|
||||||
"comments": "",
|
"comments": "",
|
||||||
}
|
}
|
||||||
|
|
||||||
def pdf_url(self):
|
|
||||||
# TODO (@slamora) create a view that exposes & downloads backend PDF
|
|
||||||
import urllib.parse
|
|
||||||
bill_url = self._json.get('url')
|
|
||||||
return urllib.parse.urljoin(bill_url, 'document/')
|
|
||||||
|
|
||||||
|
|
||||||
class BillingContact(OrchestraModel):
|
class BillingContact(OrchestraModel):
|
||||||
param_defaults = {
|
param_defaults = {
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
<td>{{ bill.created_on }}</td>
|
<td>{{ bill.created_on }}</td>
|
||||||
<td>{{ bill.type }}</td>
|
<td>{{ bill.type }}</td>
|
||||||
<td>{{ bill.total|floatformat:2|localize }}€</td>
|
<td>{{ bill.total|floatformat:2|localize }}€</td>
|
||||||
<td><a class="text-dark" href="{{ bill.pdf_url }}" target="_blank" rel="noopener noreferrer"><i class="fas fa-file-pdf"></i></a></td>
|
<td><a class="text-dark" href="{% url 'musician:bill-download' bill.id %}" target="_blank" rel="noopener noreferrer"><i class="fas fa-file-pdf"></i></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
@ -16,7 +16,8 @@ urlpatterns = [
|
||||||
path('auth/logout/', views.LogoutView.as_view(), name='logout'),
|
path('auth/logout/', views.LogoutView.as_view(), name='logout'),
|
||||||
path('dashboard/', views.DashboardView.as_view(), name='dashboard'),
|
path('dashboard/', views.DashboardView.as_view(), name='dashboard'),
|
||||||
path('domains/<int:pk>/', views.DomainDetailView.as_view(), name='domain-detail'),
|
path('domains/<int:pk>/', views.DomainDetailView.as_view(), name='domain-detail'),
|
||||||
path('billing/', views.BillingView.as_view(), name='billing'),
|
path('bills/', views.BillingView.as_view(), name='billing'),
|
||||||
|
path('bills/<int:pk>/download/', views.BillDownloadView.as_view(), name='bill-download'),
|
||||||
path('profile/', views.ProfileView.as_view(), name='profile'),
|
path('profile/', views.ProfileView.as_view(), name='profile'),
|
||||||
path('mails/', views.MailView.as_view(), name='mails'),
|
path('mails/', views.MailView.as_view(), name='mails'),
|
||||||
path('mailing-lists/', views.MailingListsView.as_view(), name='mailing-lists'),
|
path('mailing-lists/', views.MailingListsView.as_view(), name='mailing-lists'),
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
from itertools import groupby
|
from itertools import groupby
|
||||||
|
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponse, HttpResponseRedirect
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from django.utils.http import is_safe_url
|
from django.utils.http import is_safe_url
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from django.views import View
|
||||||
from django.views.generic.base import RedirectView, TemplateView
|
from django.views.generic.base import RedirectView, TemplateView
|
||||||
from django.views.generic.detail import DetailView
|
from django.views.generic.detail import DetailView
|
||||||
from django.views.generic.edit import FormView
|
from django.views.generic.edit import FormView
|
||||||
|
@ -133,6 +134,14 @@ class BillingView(ServiceListView):
|
||||||
template_name = "musician/billing.html"
|
template_name = "musician/billing.html"
|
||||||
|
|
||||||
|
|
||||||
|
class BillDownloadView(CustomContextMixin, UserTokenRequiredMixin, View):
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
pk = self.kwargs.get('pk')
|
||||||
|
bill = self.orchestra.retrieve_bill_document(pk)
|
||||||
|
|
||||||
|
return HttpResponse(bill)
|
||||||
|
|
||||||
|
|
||||||
class MailView(ServiceListView):
|
class MailView(ServiceListView):
|
||||||
service_class = MailService
|
service_class = MailService
|
||||||
template_name = "musician/mail.html"
|
template_name = "musician/mail.html"
|
||||||
|
|
Loading…
Reference in a new issue