2020-02-12 12:10:41 +00:00
|
|
|
import os
|
2018-08-29 22:52:32 +00:00
|
|
|
|
2020-02-12 12:10:41 +00:00
|
|
|
import magic
|
2020-06-22 15:25:08 +00:00
|
|
|
from camps.mixins import CampViewMixin
|
2018-08-29 22:52:32 +00:00
|
|
|
from django.conf import settings
|
|
|
|
from django.contrib import messages
|
|
|
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
2020-02-12 12:10:41 +00:00
|
|
|
from django.db.models import Sum
|
|
|
|
from django.http import HttpResponse, HttpResponseRedirect
|
|
|
|
from django.shortcuts import redirect
|
2018-08-29 22:52:32 +00:00
|
|
|
from django.urls import reverse
|
2019-04-02 10:32:12 +00:00
|
|
|
from django.views.generic import (
|
|
|
|
CreateView,
|
|
|
|
DetailView,
|
2020-02-12 12:10:41 +00:00
|
|
|
ListView,
|
2019-04-02 10:32:12 +00:00
|
|
|
TemplateView,
|
|
|
|
UpdateView,
|
|
|
|
)
|
2020-02-12 12:10:41 +00:00
|
|
|
from teams.models import Team
|
2018-08-29 22:52:32 +00:00
|
|
|
from utils.email import add_outgoing_email
|
|
|
|
from utils.mixins import RaisePermissionRequiredMixin
|
2020-02-12 12:10:41 +00:00
|
|
|
|
|
|
|
from .forms import (
|
|
|
|
ExpenseCreateForm,
|
|
|
|
ExpenseUpdateForm,
|
|
|
|
RevenueCreateForm,
|
|
|
|
RevenueUpdateForm,
|
|
|
|
)
|
|
|
|
from .mixins import (
|
|
|
|
ChainViewMixin,
|
|
|
|
CredebtorViewMixin,
|
|
|
|
ExpensePermissionMixin,
|
|
|
|
ReimbursementPermissionMixin,
|
|
|
|
RevenuePermissionMixin,
|
|
|
|
)
|
|
|
|
from .models import Chain, Credebtor, Expense, Reimbursement, Revenue
|
2018-08-29 22:52:32 +00:00
|
|
|
|
|
|
|
|
2018-11-20 16:12:32 +00:00
|
|
|
class EconomyDashboardView(LoginRequiredMixin, CampViewMixin, TemplateView):
|
2019-04-02 10:32:12 +00:00
|
|
|
template_name = "dashboard.html"
|
2018-11-20 16:12:32 +00:00
|
|
|
|
|
|
|
def get_context_data(self, **kwargs):
|
|
|
|
"""
|
|
|
|
Add expenses, reimbursements and revenues to the context
|
|
|
|
"""
|
|
|
|
context = super().get_context_data(**kwargs)
|
|
|
|
|
|
|
|
# get reimbursement stats
|
2019-04-02 10:32:12 +00:00
|
|
|
context["reimbursement_count"] = Reimbursement.objects.filter(
|
|
|
|
reimbursement_user=self.request.user, camp=self.camp
|
|
|
|
).count()
|
|
|
|
context["unpaid_reimbursement_count"] = Reimbursement.objects.filter(
|
|
|
|
reimbursement_user=self.request.user, paid=False, camp=self.camp
|
|
|
|
).count()
|
|
|
|
context["paid_reimbursement_count"] = Reimbursement.objects.filter(
|
|
|
|
reimbursement_user=self.request.user, paid=True, camp=self.camp
|
|
|
|
).count()
|
2018-11-20 16:12:32 +00:00
|
|
|
reimbursement_total = 0
|
2019-04-02 10:32:12 +00:00
|
|
|
for reimbursement in Reimbursement.objects.filter(
|
|
|
|
reimbursement_user=self.request.user, camp=self.camp
|
|
|
|
):
|
2018-11-20 16:12:32 +00:00
|
|
|
reimbursement_total += reimbursement.amount
|
2019-04-02 10:32:12 +00:00
|
|
|
context["reimbursement_total"] = reimbursement_total
|
2018-11-20 16:12:32 +00:00
|
|
|
|
|
|
|
# get expense stats
|
2019-04-02 10:32:12 +00:00
|
|
|
context["expense_count"] = Expense.objects.filter(
|
|
|
|
user=self.request.user, camp=self.camp
|
|
|
|
).count()
|
|
|
|
context["unapproved_expense_count"] = Expense.objects.filter(
|
|
|
|
user=self.request.user, approved__isnull=True, camp=self.camp
|
|
|
|
).count()
|
|
|
|
context["approved_expense_count"] = Expense.objects.filter(
|
|
|
|
user=self.request.user, approved=True, camp=self.camp
|
|
|
|
).count()
|
|
|
|
context["rejected_expense_count"] = Expense.objects.filter(
|
|
|
|
user=self.request.user, approved=False, camp=self.camp
|
|
|
|
).count()
|
|
|
|
context["expense_total"] = Expense.objects.filter(
|
|
|
|
user=self.request.user, camp=self.camp
|
|
|
|
).aggregate(Sum("amount"))["amount__sum"]
|
2018-11-20 16:12:32 +00:00
|
|
|
|
|
|
|
# get revenue stats
|
2019-04-02 10:32:12 +00:00
|
|
|
context["revenue_count"] = Revenue.objects.filter(
|
|
|
|
user=self.request.user, camp=self.camp
|
|
|
|
).count()
|
|
|
|
context["unapproved_revenue_count"] = Revenue.objects.filter(
|
|
|
|
user=self.request.user, approved__isnull=True, camp=self.camp
|
|
|
|
).count()
|
|
|
|
context["approved_revenue_count"] = Revenue.objects.filter(
|
|
|
|
user=self.request.user, approved=True, camp=self.camp
|
|
|
|
).count()
|
|
|
|
context["rejected_revenue_count"] = Revenue.objects.filter(
|
|
|
|
user=self.request.user, approved=False, camp=self.camp
|
|
|
|
).count()
|
|
|
|
context["revenue_total"] = Revenue.objects.filter(
|
|
|
|
user=self.request.user, camp=self.camp
|
|
|
|
).aggregate(Sum("amount"))["amount__sum"]
|
2018-11-20 16:12:32 +00:00
|
|
|
|
|
|
|
return context
|
|
|
|
|
|
|
|
|
2020-02-12 12:10:41 +00:00
|
|
|
############################################
|
|
|
|
# Chain/Credebtor related views
|
2019-03-28 06:04:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
class ChainCreateView(CampViewMixin, RaisePermissionRequiredMixin, CreateView):
|
|
|
|
model = Chain
|
2019-04-02 10:32:12 +00:00
|
|
|
template_name = "chain_create.html"
|
|
|
|
permission_required = "camps.expense_create_permission"
|
|
|
|
fields = ["name", "notes"]
|
2019-03-28 06:04:53 +00:00
|
|
|
|
|
|
|
def form_valid(self, form):
|
|
|
|
chain = form.save()
|
|
|
|
|
|
|
|
# a message for the user
|
|
|
|
messages.success(
|
|
|
|
self.request,
|
2019-04-02 10:32:12 +00:00
|
|
|
"The new Chain %s has been saved. You can now add Creditor(s)/Debtor(s) for it."
|
|
|
|
% chain.name,
|
2019-03-28 06:04:53 +00:00
|
|
|
)
|
|
|
|
|
2019-04-02 10:32:12 +00:00
|
|
|
return HttpResponseRedirect(
|
|
|
|
reverse(
|
|
|
|
"economy:credebtor_create",
|
|
|
|
kwargs={"camp_slug": self.camp.slug, "chain_slug": chain.slug},
|
|
|
|
)
|
|
|
|
)
|
2019-03-28 06:04:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
class ChainListView(CampViewMixin, RaisePermissionRequiredMixin, ListView):
|
|
|
|
model = Chain
|
2019-04-02 10:32:12 +00:00
|
|
|
template_name = "chain_list.html"
|
|
|
|
permission_required = "camps.expense_create_permission"
|
2019-03-28 06:04:53 +00:00
|
|
|
|
|
|
|
|
2019-04-02 10:32:12 +00:00
|
|
|
class CredebtorCreateView(
|
|
|
|
CampViewMixin, ChainViewMixin, RaisePermissionRequiredMixin, CreateView
|
|
|
|
):
|
2019-03-28 06:04:53 +00:00
|
|
|
model = Credebtor
|
2019-04-02 10:32:12 +00:00
|
|
|
template_name = "credebtor_create.html"
|
|
|
|
permission_required = "camps.expense_create_permission"
|
|
|
|
fields = ["name", "address", "notes"]
|
2019-03-28 06:04:53 +00:00
|
|
|
|
|
|
|
def get_context_data(self, **kwargs):
|
|
|
|
"""
|
|
|
|
Add chain to context
|
|
|
|
"""
|
|
|
|
context = super().get_context_data(**kwargs)
|
2019-04-02 10:32:12 +00:00
|
|
|
context["chain"] = self.chain
|
2019-03-28 06:04:53 +00:00
|
|
|
return context
|
|
|
|
|
|
|
|
def form_valid(self, form):
|
|
|
|
credebtor = form.save(commit=False)
|
|
|
|
credebtor.chain = self.chain
|
|
|
|
credebtor.save()
|
|
|
|
|
|
|
|
# a message for the user
|
|
|
|
messages.success(
|
|
|
|
self.request,
|
2019-04-02 10:32:12 +00:00
|
|
|
"The Creditor/Debtor %s has been saved. You can now add Expenses/Revenues for it."
|
|
|
|
% credebtor.name,
|
2019-03-28 06:04:53 +00:00
|
|
|
)
|
|
|
|
|
2019-04-02 10:32:12 +00:00
|
|
|
return HttpResponseRedirect(
|
|
|
|
reverse(
|
|
|
|
"economy:credebtor_list",
|
|
|
|
kwargs={"camp_slug": self.camp.slug, "chain_slug": self.chain.slug},
|
|
|
|
)
|
|
|
|
)
|
2019-03-28 06:04:53 +00:00
|
|
|
|
|
|
|
|
2019-04-02 10:32:12 +00:00
|
|
|
class CredebtorListView(
|
|
|
|
CampViewMixin, ChainViewMixin, RaisePermissionRequiredMixin, ListView
|
|
|
|
):
|
2019-03-28 06:04:53 +00:00
|
|
|
model = Credebtor
|
2019-04-02 10:32:12 +00:00
|
|
|
template_name = "credebtor_list.html"
|
|
|
|
permission_required = "camps.expense_create_permission"
|
2019-03-28 06:04:53 +00:00
|
|
|
|
|
|
|
def get_context_data(self, **kwargs):
|
|
|
|
"""
|
|
|
|
Add chain to context
|
|
|
|
"""
|
|
|
|
context = super().get_context_data(**kwargs)
|
2019-04-02 10:32:12 +00:00
|
|
|
context["chain"] = self.chain
|
2019-03-28 06:04:53 +00:00
|
|
|
return context
|
|
|
|
|
|
|
|
|
2020-02-12 12:10:41 +00:00
|
|
|
############################################
|
|
|
|
# Expense related views
|
2018-11-20 16:12:32 +00:00
|
|
|
|
2019-03-28 06:04:53 +00:00
|
|
|
|
2018-08-29 22:52:32 +00:00
|
|
|
class ExpenseListView(LoginRequiredMixin, CampViewMixin, ListView):
|
|
|
|
model = Expense
|
2019-04-02 10:32:12 +00:00
|
|
|
template_name = "expense_list.html"
|
2018-08-29 22:52:32 +00:00
|
|
|
|
|
|
|
def get_queryset(self):
|
|
|
|
# only return Expenses belonging to the current user
|
|
|
|
return super().get_queryset().filter(user=self.request.user)
|
|
|
|
|
|
|
|
|
|
|
|
class ExpenseDetailView(CampViewMixin, ExpensePermissionMixin, DetailView):
|
|
|
|
model = Expense
|
2019-04-02 10:32:12 +00:00
|
|
|
template_name = "expense_detail.html"
|
2018-08-29 22:52:32 +00:00
|
|
|
|
|
|
|
|
2019-04-02 10:32:12 +00:00
|
|
|
class ExpenseCreateView(
|
|
|
|
CampViewMixin, CredebtorViewMixin, RaisePermissionRequiredMixin, CreateView
|
|
|
|
):
|
2018-08-29 22:52:32 +00:00
|
|
|
model = Expense
|
2019-04-02 10:32:12 +00:00
|
|
|
template_name = "expense_form.html"
|
|
|
|
permission_required = "camps.expense_create_permission"
|
2018-08-30 10:18:56 +00:00
|
|
|
form_class = ExpenseCreateForm
|
2018-08-29 22:52:32 +00:00
|
|
|
|
|
|
|
def get_context_data(self, **kwargs):
|
|
|
|
"""
|
|
|
|
Do not show teams that are not part of the current camp in the dropdown
|
|
|
|
"""
|
|
|
|
context = super().get_context_data(**kwargs)
|
2019-04-02 10:32:12 +00:00
|
|
|
context["form"].fields["responsible_team"].queryset = Team.objects.filter(
|
|
|
|
camp=self.camp
|
|
|
|
)
|
|
|
|
context["creditor"] = self.credebtor
|
2018-08-29 22:52:32 +00:00
|
|
|
return context
|
|
|
|
|
|
|
|
def form_valid(self, form):
|
|
|
|
expense = form.save(commit=False)
|
|
|
|
expense.user = self.request.user
|
|
|
|
expense.camp = self.camp
|
2019-03-28 06:04:53 +00:00
|
|
|
expense.creditor = self.credebtor
|
2018-08-29 22:52:32 +00:00
|
|
|
expense.save()
|
|
|
|
|
|
|
|
# a message for the user
|
|
|
|
messages.success(
|
|
|
|
self.request,
|
|
|
|
"The expense has been saved. It is now awaiting approval by the economy team.",
|
|
|
|
)
|
|
|
|
|
|
|
|
# send an email to the economy team
|
|
|
|
add_outgoing_email(
|
2020-06-22 15:25:08 +00:00
|
|
|
responsible_team=Team.objects.get(
|
|
|
|
camp=self.camp, name=settings.ECONOMY_TEAM_NAME
|
|
|
|
),
|
|
|
|
text_template="emails/expense_awaiting_approval_email.txt",
|
2018-08-29 22:52:32 +00:00
|
|
|
formatdict=dict(expense=expense),
|
2019-04-02 10:32:12 +00:00
|
|
|
subject="New %s expense for %s Team is awaiting approval"
|
|
|
|
% (expense.camp.title, expense.responsible_team.name),
|
2018-08-29 22:52:32 +00:00
|
|
|
to_recipients=[settings.ECONOMYTEAM_EMAIL],
|
|
|
|
)
|
|
|
|
|
|
|
|
# return to the expense list page
|
2019-04-02 10:32:12 +00:00
|
|
|
return HttpResponseRedirect(
|
|
|
|
reverse("economy:expense_list", kwargs={"camp_slug": self.camp.slug})
|
|
|
|
)
|
2018-08-29 22:52:32 +00:00
|
|
|
|
|
|
|
|
2018-11-20 16:12:32 +00:00
|
|
|
class ExpenseUpdateView(CampViewMixin, ExpensePermissionMixin, UpdateView):
|
|
|
|
model = Expense
|
2019-04-02 10:32:12 +00:00
|
|
|
template_name = "expense_form.html"
|
2018-11-20 16:12:32 +00:00
|
|
|
form_class = ExpenseUpdateForm
|
|
|
|
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
|
|
response = super().dispatch(request, *args, **kwargs)
|
|
|
|
if self.get_object().approved:
|
2019-04-02 10:32:12 +00:00
|
|
|
messages.error(
|
|
|
|
self.request,
|
|
|
|
"This expense has already been approved, it cannot be updated",
|
|
|
|
)
|
|
|
|
return redirect(
|
|
|
|
reverse("economy:expense_list", kwargs={"camp_slug": self.camp.slug})
|
|
|
|
)
|
2018-11-20 16:12:32 +00:00
|
|
|
return response
|
|
|
|
|
|
|
|
def get_context_data(self, **kwargs):
|
|
|
|
"""
|
|
|
|
Do not show teams that are not part of the current camp in the dropdown
|
|
|
|
"""
|
|
|
|
context = super().get_context_data(**kwargs)
|
2019-04-02 10:32:12 +00:00
|
|
|
context["form"].fields["responsible_team"].queryset = Team.objects.filter(
|
|
|
|
camp=self.camp
|
|
|
|
)
|
|
|
|
context["creditor"] = self.get_object().creditor
|
2018-11-20 16:12:32 +00:00
|
|
|
return context
|
|
|
|
|
|
|
|
def get_success_url(self):
|
2019-04-02 10:32:12 +00:00
|
|
|
messages.success(
|
|
|
|
self.request, "Expense %s has been updated" % self.get_object().pk
|
|
|
|
)
|
|
|
|
return reverse("economy:expense_list", kwargs={"camp_slug": self.camp.slug})
|
2018-11-20 16:12:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
class ExpenseDeleteView(CampViewMixin, ExpensePermissionMixin, UpdateView):
|
|
|
|
model = Expense
|
2019-04-02 10:32:12 +00:00
|
|
|
template_name = "expense_delete.html"
|
2018-11-20 16:12:32 +00:00
|
|
|
fields = []
|
|
|
|
|
|
|
|
def form_valid(self, form):
|
|
|
|
expense = self.get_object()
|
|
|
|
if expense.approved:
|
2019-04-02 10:32:12 +00:00
|
|
|
messages.error(
|
|
|
|
self.request,
|
|
|
|
"This expense has already been approved, it cannot be deleted",
|
|
|
|
)
|
2018-11-20 16:12:32 +00:00
|
|
|
else:
|
|
|
|
message = "Expense %s has been deleted" % expense.pk
|
|
|
|
expense.delete()
|
|
|
|
messages.success(self.request, message)
|
|
|
|
return redirect(self.get_success_url())
|
|
|
|
|
|
|
|
def get_success_url(self):
|
2019-04-02 10:32:12 +00:00
|
|
|
return reverse("economy:expense_list", kwargs={"camp_slug": self.camp.slug})
|
2018-11-20 16:12:32 +00:00
|
|
|
|
|
|
|
|
2018-08-29 22:52:32 +00:00
|
|
|
class ExpenseInvoiceView(CampViewMixin, ExpensePermissionMixin, DetailView):
|
|
|
|
"""
|
|
|
|
This view returns the invoice for an Expense with the proper mimetype
|
|
|
|
Uses ExpensePermissionMixin to make sure the user is allowed to see the image
|
|
|
|
"""
|
2019-04-02 10:32:12 +00:00
|
|
|
|
2018-08-29 22:52:32 +00:00
|
|
|
model = Expense
|
|
|
|
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
|
|
# get expense
|
|
|
|
expense = self.get_object()
|
|
|
|
# read invoice file
|
|
|
|
invoicedata = expense.invoice.read()
|
|
|
|
# find mimetype
|
|
|
|
mimetype = magic.from_buffer(invoicedata, mime=True)
|
2018-08-30 10:18:56 +00:00
|
|
|
# check if we have a PDF, no preview if so, load a pdf icon instead
|
2019-04-02 10:32:12 +00:00
|
|
|
if mimetype == "application/pdf" and "preview" in request.GET:
|
|
|
|
invoicedata = open(
|
|
|
|
os.path.join(settings.DJANGO_BASE_PATH, "static_src/img/pdf.png"), "rb"
|
|
|
|
).read()
|
|
|
|
mimetype = magic.from_buffer(invoicedata, mime=True)
|
2018-08-29 22:52:32 +00:00
|
|
|
# put the response together and return it
|
|
|
|
response = HttpResponse(content_type=mimetype)
|
|
|
|
response.write(invoicedata)
|
|
|
|
return response
|
|
|
|
|
|
|
|
|
2020-02-12 12:10:41 +00:00
|
|
|
############################################
|
|
|
|
# Reimbursement related views
|
2018-11-20 16:12:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
class ReimbursementListView(LoginRequiredMixin, CampViewMixin, ListView):
|
|
|
|
model = Reimbursement
|
2019-04-02 10:32:12 +00:00
|
|
|
template_name = "reimbursement_list.html"
|
2018-11-20 16:12:32 +00:00
|
|
|
|
|
|
|
def get_queryset(self):
|
|
|
|
# only return Expenses belonging to the current user
|
|
|
|
return super().get_queryset().filter(reimbursement_user=self.request.user)
|
|
|
|
|
|
|
|
|
2018-08-29 22:52:32 +00:00
|
|
|
class ReimbursementDetailView(CampViewMixin, ReimbursementPermissionMixin, DetailView):
|
|
|
|
model = Reimbursement
|
2019-04-02 10:32:12 +00:00
|
|
|
template_name = "reimbursement_detail.html"
|
2018-08-29 22:52:32 +00:00
|
|
|
|
2018-11-20 16:12:32 +00:00
|
|
|
|
2020-02-12 12:10:41 +00:00
|
|
|
############################################
|
|
|
|
# Revenue related views
|
2018-11-20 16:12:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
class RevenueListView(LoginRequiredMixin, CampViewMixin, ListView):
|
|
|
|
model = Revenue
|
2019-04-02 10:32:12 +00:00
|
|
|
template_name = "revenue_list.html"
|
2018-11-20 16:12:32 +00:00
|
|
|
|
|
|
|
def get_queryset(self):
|
|
|
|
# only return Revenues belonging to the current user
|
|
|
|
return super().get_queryset().filter(user=self.request.user)
|
|
|
|
|
|
|
|
|
|
|
|
class RevenueDetailView(CampViewMixin, RevenuePermissionMixin, DetailView):
|
|
|
|
model = Revenue
|
2019-04-02 10:32:12 +00:00
|
|
|
template_name = "revenue_detail.html"
|
2018-11-20 16:12:32 +00:00
|
|
|
|
|
|
|
|
2019-04-02 10:32:12 +00:00
|
|
|
class RevenueCreateView(
|
|
|
|
CampViewMixin, CredebtorViewMixin, RaisePermissionRequiredMixin, CreateView
|
|
|
|
):
|
2018-11-20 16:12:32 +00:00
|
|
|
model = Revenue
|
2019-04-02 10:32:12 +00:00
|
|
|
template_name = "revenue_form.html"
|
|
|
|
permission_required = "camps.revenue_create_permission"
|
2018-11-20 16:12:32 +00:00
|
|
|
form_class = RevenueCreateForm
|
|
|
|
|
|
|
|
def get_context_data(self, **kwargs):
|
|
|
|
"""
|
|
|
|
Do not show teams that are not part of the current camp in the dropdown
|
|
|
|
"""
|
|
|
|
context = super().get_context_data(**kwargs)
|
2019-04-02 10:32:12 +00:00
|
|
|
context["form"].fields["responsible_team"].queryset = Team.objects.filter(
|
|
|
|
camp=self.camp
|
|
|
|
)
|
|
|
|
context["debtor"] = self.credebtor
|
2018-11-20 16:12:32 +00:00
|
|
|
return context
|
|
|
|
|
|
|
|
def form_valid(self, form):
|
|
|
|
revenue = form.save(commit=False)
|
|
|
|
revenue.user = self.request.user
|
|
|
|
revenue.camp = self.camp
|
2019-03-28 06:04:53 +00:00
|
|
|
revenue.debtor = self.credebtor
|
2018-11-20 16:12:32 +00:00
|
|
|
revenue.save()
|
|
|
|
|
|
|
|
# a message for the user
|
|
|
|
messages.success(
|
|
|
|
self.request,
|
|
|
|
"The revenue has been saved. It is now awaiting approval by the economy team.",
|
|
|
|
)
|
|
|
|
|
|
|
|
# send an email to the economy team
|
|
|
|
add_outgoing_email(
|
2020-06-22 15:25:08 +00:00
|
|
|
responsible_team=Team.objects.get(
|
|
|
|
camp=self.camp, name=settings.ECONOMY_TEAM_NAME
|
|
|
|
),
|
|
|
|
text_template="emails/revenue_awaiting_approval_email.txt",
|
2018-11-20 16:12:32 +00:00
|
|
|
formatdict=dict(revenue=revenue),
|
2019-04-02 10:32:12 +00:00
|
|
|
subject="New %s revenue for %s Team is awaiting approval"
|
|
|
|
% (revenue.camp.title, revenue.responsible_team.name),
|
2018-11-20 16:12:32 +00:00
|
|
|
to_recipients=[settings.ECONOMYTEAM_EMAIL],
|
|
|
|
)
|
|
|
|
|
|
|
|
# return to the revenue list page
|
2019-04-02 10:32:12 +00:00
|
|
|
return HttpResponseRedirect(
|
|
|
|
reverse("economy:revenue_list", kwargs={"camp_slug": self.camp.slug})
|
|
|
|
)
|
2018-11-20 16:12:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
class RevenueUpdateView(CampViewMixin, RevenuePermissionMixin, UpdateView):
|
|
|
|
model = Revenue
|
2019-04-02 10:32:12 +00:00
|
|
|
template_name = "revenue_form.html"
|
2018-11-20 16:12:32 +00:00
|
|
|
form_class = RevenueUpdateForm
|
|
|
|
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
|
|
response = super().dispatch(request, *args, **kwargs)
|
|
|
|
if self.get_object().approved:
|
2019-04-02 10:32:12 +00:00
|
|
|
messages.error(
|
|
|
|
self.request,
|
|
|
|
"This revenue has already been approved, it cannot be updated",
|
|
|
|
)
|
|
|
|
return redirect(
|
|
|
|
reverse("economy:revenue_list", kwargs={"camp_slug": self.camp.slug})
|
|
|
|
)
|
2018-11-20 16:12:32 +00:00
|
|
|
return response
|
|
|
|
|
|
|
|
def get_context_data(self, **kwargs):
|
|
|
|
"""
|
|
|
|
Do not show teams that are not part of the current camp in the dropdown
|
|
|
|
"""
|
|
|
|
context = super().get_context_data(**kwargs)
|
2019-04-02 10:32:12 +00:00
|
|
|
context["form"].fields["responsible_team"].queryset = Team.objects.filter(
|
|
|
|
camp=self.camp
|
|
|
|
)
|
2018-11-20 16:12:32 +00:00
|
|
|
return context
|
|
|
|
|
|
|
|
def get_success_url(self):
|
2019-04-02 10:32:12 +00:00
|
|
|
messages.success(
|
|
|
|
self.request, "Revenue %s has been updated" % self.get_object().pk
|
|
|
|
)
|
|
|
|
return reverse("economy:revenue_list", kwargs={"camp_slug": self.camp.slug})
|
2018-11-20 16:12:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
class RevenueDeleteView(CampViewMixin, RevenuePermissionMixin, UpdateView):
|
|
|
|
model = Revenue
|
2019-04-02 10:32:12 +00:00
|
|
|
template_name = "revenue_delete.html"
|
2018-11-20 16:12:32 +00:00
|
|
|
fields = []
|
|
|
|
|
|
|
|
def form_valid(self, form):
|
|
|
|
revenue = self.get_object()
|
|
|
|
if revenue.approved:
|
2019-04-02 10:32:12 +00:00
|
|
|
messages.error(
|
|
|
|
self.request,
|
|
|
|
"This revenue has already been approved, it cannot be deleted",
|
|
|
|
)
|
2018-11-20 16:12:32 +00:00
|
|
|
else:
|
|
|
|
message = "Revenue %s has been deleted" % revenue.pk
|
|
|
|
revenue.delete()
|
|
|
|
messages.success(self.request, message)
|
|
|
|
return redirect(self.get_success_url())
|
|
|
|
|
|
|
|
def get_success_url(self):
|
2019-04-02 10:32:12 +00:00
|
|
|
return reverse("economy:revenue_list", kwargs={"camp_slug": self.camp.slug})
|
2018-11-20 16:12:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
class RevenueInvoiceView(CampViewMixin, RevenuePermissionMixin, DetailView):
|
|
|
|
"""
|
|
|
|
This view returns a http response with the invoice for a Revenue object, with the proper mimetype
|
|
|
|
Uses RevenuePermissionMixin to make sure the user is allowed to see the file
|
|
|
|
"""
|
2019-04-02 10:32:12 +00:00
|
|
|
|
2018-11-20 16:12:32 +00:00
|
|
|
model = Revenue
|
|
|
|
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
|
|
# get revenue
|
|
|
|
revenue = self.get_object()
|
|
|
|
# read invoice file
|
|
|
|
invoicedata = revenue.invoice.read()
|
|
|
|
# find mimetype
|
|
|
|
mimetype = magic.from_buffer(invoicedata, mime=True)
|
|
|
|
# check if we have a PDF, no preview if so, load a pdf icon instead
|
2019-04-02 10:32:12 +00:00
|
|
|
if mimetype == "application/pdf" and "preview" in request.GET:
|
|
|
|
invoicedata = open(
|
|
|
|
os.path.join(settings.DJANGO_BASE_PATH, "static_src/img/pdf.png"), "rb"
|
|
|
|
).read()
|
|
|
|
mimetype = magic.from_buffer(invoicedata, mime=True)
|
2018-11-20 16:12:32 +00:00
|
|
|
# put the response together and return it
|
|
|
|
response = HttpResponse(content_type=mimetype)
|
|
|
|
response.write(invoicedata)
|
|
|
|
return response
|