Get rid of wrapt hack. Django 2.2 introduced setup() method on views. Yay!
This commit is contained in:
parent
63890131c8
commit
75c8db4577
|
@ -1,208 +1,176 @@
|
|||
import os
|
||||
import wrapt
|
||||
import django.views
|
||||
|
||||
from .environment_settings import *
|
||||
|
||||
|
||||
def local_dir(entry):
|
||||
return os.path.join(
|
||||
os.path.dirname(os.path.dirname(__file__)),
|
||||
entry
|
||||
)
|
||||
|
||||
|
||||
# We do this hacky monkeypatching to enable us to define a setup method
|
||||
# on class based views for setting up variables without touching the dispatch
|
||||
# method.
|
||||
@wrapt.patch_function_wrapper(django.views.View, 'dispatch')
|
||||
def monkey_patched_dispatch(wrapped, instance, args, kwargs):
|
||||
if hasattr(instance, 'setup'):
|
||||
instance.setup(*args, **kwargs)
|
||||
return wrapped(*args, **kwargs)
|
||||
return os.path.join(os.path.dirname(os.path.dirname(__file__)), entry)
|
||||
|
||||
|
||||
DJANGO_BASE_PATH = os.path.dirname(os.path.dirname(__file__))
|
||||
|
||||
WSGI_APPLICATION = 'bornhack.wsgi.application'
|
||||
ASGI_APPLICATION = 'bornhack.routing.application'
|
||||
ROOT_URLCONF = 'bornhack.urls'
|
||||
WSGI_APPLICATION = "bornhack.wsgi.application"
|
||||
ASGI_APPLICATION = "bornhack.routing.application"
|
||||
ROOT_URLCONF = "bornhack.urls"
|
||||
|
||||
ACCOUNT_ADAPTER = 'allauth_2fa.adapter.OTPAdapter'
|
||||
ACCOUNT_ADAPTER = "allauth_2fa.adapter.OTPAdapter"
|
||||
|
||||
SITE_ID = 1
|
||||
|
||||
ADMINS = (
|
||||
('bornhack sysadm', 'sysadm@bornhack.org'),
|
||||
)
|
||||
ADMINS = (("bornhack sysadm", "sysadm@bornhack.org"),)
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'django.contrib.sites',
|
||||
|
||||
'graphene_django',
|
||||
'channels',
|
||||
'corsheaders',
|
||||
|
||||
'profiles',
|
||||
'camps',
|
||||
'shop',
|
||||
'news',
|
||||
'utils',
|
||||
'villages',
|
||||
'program',
|
||||
'info',
|
||||
'sponsors',
|
||||
'ircbot',
|
||||
'teams',
|
||||
'people',
|
||||
'tickets',
|
||||
'bar',
|
||||
'backoffice',
|
||||
'events',
|
||||
'rideshare',
|
||||
'tokens',
|
||||
'feedback',
|
||||
'economy',
|
||||
|
||||
'allauth',
|
||||
'allauth.account',
|
||||
'allauth_2fa',
|
||||
'django_otp',
|
||||
'django_otp.plugins.otp_totp',
|
||||
'django_otp.plugins.otp_static',
|
||||
'bootstrap3',
|
||||
'django_extensions',
|
||||
'reversion',
|
||||
'betterforms',
|
||||
"django.contrib.admin",
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
"django.contrib.sessions",
|
||||
"django.contrib.messages",
|
||||
"django.contrib.staticfiles",
|
||||
"django.contrib.sites",
|
||||
"graphene_django",
|
||||
"channels",
|
||||
"corsheaders",
|
||||
"profiles",
|
||||
"camps",
|
||||
"shop",
|
||||
"news",
|
||||
"utils",
|
||||
"villages",
|
||||
"program",
|
||||
"info",
|
||||
"sponsors",
|
||||
"ircbot",
|
||||
"teams",
|
||||
"people",
|
||||
"tickets",
|
||||
"bar",
|
||||
"backoffice",
|
||||
"events",
|
||||
"rideshare",
|
||||
"tokens",
|
||||
"feedback",
|
||||
"economy",
|
||||
"allauth",
|
||||
"allauth.account",
|
||||
"allauth_2fa",
|
||||
"django_otp",
|
||||
"django_otp.plugins.otp_totp",
|
||||
"django_otp.plugins.otp_static",
|
||||
"bootstrap3",
|
||||
"django_extensions",
|
||||
"reversion",
|
||||
"betterforms",
|
||||
]
|
||||
|
||||
#MEDIA_URL = '/media/'
|
||||
STATIC_URL = '/static/'
|
||||
STATIC_ROOT = local_dir('static')
|
||||
STATICFILES_DIRS = [local_dir('static_src')]
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
#USE_I18N = True
|
||||
#USE_L10N = True
|
||||
# MEDIA_URL = '/media/'
|
||||
STATIC_URL = "/static/"
|
||||
STATIC_ROOT = local_dir("static")
|
||||
STATICFILES_DIRS = [local_dir("static_src")]
|
||||
LANGUAGE_CODE = "en-us"
|
||||
# USE_I18N = True
|
||||
# USE_L10N = True
|
||||
USE_TZ = True
|
||||
SHORT_DATE_FORMAT = 'd/m-Y'
|
||||
DATE_FORMAT = 'd/m-Y'
|
||||
DATETIME_FORMAT = 'd/m-Y H:i'
|
||||
TIME_FORMAT = 'H:i'
|
||||
SHORT_DATE_FORMAT = "d/m-Y"
|
||||
DATE_FORMAT = "d/m-Y"
|
||||
DATETIME_FORMAT = "d/m-Y H:i"
|
||||
TIME_FORMAT = "H:i"
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [local_dir('templates')],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'django.template.context_processors.debug',
|
||||
'django.template.context_processors.request',
|
||||
'django.template.context_processors.media',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
'shop.context_processors.current_order',
|
||||
'camps.context_processors.camp',
|
||||
],
|
||||
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||
"DIRS": [local_dir("templates")],
|
||||
"APP_DIRS": True,
|
||||
"OPTIONS": {
|
||||
"context_processors": [
|
||||
"django.template.context_processors.debug",
|
||||
"django.template.context_processors.request",
|
||||
"django.template.context_processors.media",
|
||||
"django.contrib.auth.context_processors.auth",
|
||||
"django.contrib.messages.context_processors.messages",
|
||||
"shop.context_processors.current_order",
|
||||
"camps.context_processors.camp",
|
||||
]
|
||||
},
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
AUTHENTICATION_BACKENDS = (
|
||||
'django.contrib.auth.backends.ModelBackend', # Handles login to admin with username
|
||||
'allauth.account.auth_backends.AuthenticationBackend', # Handles regular logins
|
||||
"django.contrib.auth.backends.ModelBackend", # Handles login to admin with username
|
||||
"allauth.account.auth_backends.AuthenticationBackend", # Handles regular logins
|
||||
)
|
||||
|
||||
ACCOUNT_AUTHENTICATION_METHOD = 'email'
|
||||
ACCOUNT_AUTHENTICATION_METHOD = "email"
|
||||
ACCOUNT_EMAIL_REQUIRED = True
|
||||
ACCOUNT_EMAIL_VERIFICATION = True
|
||||
ACCOUNT_EMAIL_SUBJECT_PREFIX = '[bornhack] '
|
||||
ACCOUNT_EMAIL_SUBJECT_PREFIX = "[bornhack] "
|
||||
ACCOUNT_USERNAME_REQUIRED = False
|
||||
LOGIN_REDIRECT_URL='/'
|
||||
LOGIN_URL = '/login/'
|
||||
LOGIN_REDIRECT_URL = "/"
|
||||
LOGIN_URL = "/login/"
|
||||
|
||||
ACCOUNT_DEFAULT_HTTP_PROTOCOL = 'https'
|
||||
ACCOUNT_DEFAULT_HTTP_PROTOCOL = "https"
|
||||
|
||||
BOOTSTRAP3 = {
|
||||
'jquery_url': '/static/js/jquery.min.js',
|
||||
'javascript_url': '/static/js/bootstrap.min.js'
|
||||
"jquery_url": "/static/js/jquery.min.js",
|
||||
"javascript_url": "/static/js/bootstrap.min.js",
|
||||
}
|
||||
MIDDLEWARE = [
|
||||
'corsheaders.middleware.CorsMiddleware',
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django_otp.middleware.OTPMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
"corsheaders.middleware.CorsMiddleware",
|
||||
"django.middleware.security.SecurityMiddleware",
|
||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||
"django.middleware.common.CommonMiddleware",
|
||||
"django.middleware.csrf.CsrfViewMiddleware",
|
||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||
"django_otp.middleware.OTPMiddleware",
|
||||
"django.contrib.messages.middleware.MessageMiddleware",
|
||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||
]
|
||||
|
||||
CORS_ORIGIN_ALLOW_ALL = True
|
||||
CORS_URLS_REGEX = r'^/api/*$'
|
||||
CORS_URLS_REGEX = r"^/api/*$"
|
||||
|
||||
if DEBUG:
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||
INSTALLED_APPS += [
|
||||
'debug_toolbar',
|
||||
]
|
||||
MIDDLEWARE = ['debug_toolbar.middleware.DebugToolbarMiddleware'] + MIDDLEWARE
|
||||
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
|
||||
INSTALLED_APPS += ["debug_toolbar"]
|
||||
MIDDLEWARE = ["debug_toolbar.middleware.DebugToolbarMiddleware"] + MIDDLEWARE
|
||||
INTERNAL_IPS = "127.0.0.1"
|
||||
DEBUG_TOOLBAR_PANELS = [
|
||||
'debug_toolbar.panels.versions.VersionsPanel',
|
||||
'debug_toolbar.panels.timer.TimerPanel',
|
||||
'debug_toolbar.panels.settings.SettingsPanel',
|
||||
'debug_toolbar.panels.headers.HeadersPanel',
|
||||
'debug_toolbar.panels.request.RequestPanel',
|
||||
'debug_toolbar.panels.sql.SQLPanel',
|
||||
'debug_toolbar.panels.staticfiles.StaticFilesPanel',
|
||||
'debug_toolbar.panels.templates.TemplatesPanel',
|
||||
'debug_toolbar.panels.cache.CachePanel',
|
||||
'debug_toolbar.panels.signals.SignalsPanel',
|
||||
'debug_toolbar.panels.logging.LoggingPanel',
|
||||
'debug_toolbar.panels.redirects.RedirectsPanel',
|
||||
"debug_toolbar.panels.versions.VersionsPanel",
|
||||
"debug_toolbar.panels.timer.TimerPanel",
|
||||
"debug_toolbar.panels.settings.SettingsPanel",
|
||||
"debug_toolbar.panels.headers.HeadersPanel",
|
||||
"debug_toolbar.panels.request.RequestPanel",
|
||||
"debug_toolbar.panels.sql.SQLPanel",
|
||||
"debug_toolbar.panels.staticfiles.StaticFilesPanel",
|
||||
"debug_toolbar.panels.templates.TemplatesPanel",
|
||||
"debug_toolbar.panels.cache.CachePanel",
|
||||
"debug_toolbar.panels.signals.SignalsPanel",
|
||||
"debug_toolbar.panels.logging.LoggingPanel",
|
||||
"debug_toolbar.panels.redirects.RedirectsPanel",
|
||||
]
|
||||
else:
|
||||
SESSION_COOKIE_SECURE=True
|
||||
CSRF_COOKIE_SECURE=True
|
||||
SESSION_COOKIE_SECURE = True
|
||||
CSRF_COOKIE_SECURE = True
|
||||
|
||||
LOGGING = {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
'formatters': {
|
||||
'syslog': {
|
||||
'format': '%(levelname)s %(name)s.%(funcName)s(): %(message)s'
|
||||
},
|
||||
'console': {
|
||||
'format': '[%(asctime)s] %(name)s.%(funcName)s() %(levelname)s %(message)s',
|
||||
'datefmt': '%d/%b/%Y %H:%M:%S'
|
||||
"version": 1,
|
||||
"disable_existing_loggers": False,
|
||||
"formatters": {
|
||||
"syslog": {"format": "%(levelname)s %(name)s.%(funcName)s(): %(message)s"},
|
||||
"console": {
|
||||
"format": "[%(asctime)s] %(name)s.%(funcName)s() %(levelname)s %(message)s",
|
||||
"datefmt": "%d/%b/%Y %H:%M:%S",
|
||||
},
|
||||
},
|
||||
'handlers': {
|
||||
'console': {
|
||||
'level': 'DEBUG',
|
||||
'class': 'logging.StreamHandler',
|
||||
'formatter': 'console'
|
||||
},
|
||||
"handlers": {
|
||||
"console": {
|
||||
"level": "DEBUG",
|
||||
"class": "logging.StreamHandler",
|
||||
"formatter": "console",
|
||||
}
|
||||
},
|
||||
'loggers': {
|
||||
"loggers": {
|
||||
# send the bornhack logger to console at DEBUG level,
|
||||
# do not propagate bornhack.* messages up to the root logger
|
||||
'bornhack': {
|
||||
'handlers': ['console'],
|
||||
'level': 'DEBUG',
|
||||
'propagate': False,
|
||||
},
|
||||
"bornhack": {"handlers": ["console"], "level": "DEBUG", "propagate": False}
|
||||
},
|
||||
}
|
||||
|
||||
GRAPHENE = {
|
||||
'SCHEMA': 'bornhack.schema.schema'
|
||||
}
|
||||
GRAPHENE = {"SCHEMA": "bornhack.schema.schema"}
|
||||
|
|
|
@ -8,25 +8,21 @@ class ChainViewMixin(object):
|
|||
"""
|
||||
The ChainViewMixin sets self.chain based on chain_slug from the URL
|
||||
"""
|
||||
|
||||
def setup(self, *args, **kwargs):
|
||||
if hasattr(super(), 'setup'):
|
||||
super().setup(*args, **kwargs)
|
||||
self.chain = get_object_or_404(
|
||||
Chain,
|
||||
slug=self.kwargs["chain_slug"],
|
||||
)
|
||||
super().setup(*args, **kwargs)
|
||||
self.chain = get_object_or_404(Chain, slug=self.kwargs["chain_slug"])
|
||||
|
||||
|
||||
class CredebtorViewMixin(object):
|
||||
"""
|
||||
The CredebtorViewMixin sets self.credebtor based on credebtor_slug from the URL
|
||||
"""
|
||||
|
||||
def setup(self, *args, **kwargs):
|
||||
if hasattr(super(), 'setup'):
|
||||
super().setup(*args, **kwargs)
|
||||
super().setup(*args, **kwargs)
|
||||
self.credebtor = get_object_or_404(
|
||||
Credebtor,
|
||||
slug=self.kwargs["credebtor_slug"],
|
||||
Credebtor, slug=self.kwargs["credebtor_slug"]
|
||||
)
|
||||
|
||||
|
||||
|
@ -34,9 +30,12 @@ class ExpensePermissionMixin(object):
|
|||
"""
|
||||
This mixin checks if request.user submitted the Expense, or if request.user has camps.economyteam_permission
|
||||
"""
|
||||
|
||||
def get_object(self, queryset=None):
|
||||
obj = super().get_object(queryset=queryset)
|
||||
if obj.user == self.request.user or self.request.user.has_perm('camps.economyteam_permission'):
|
||||
if obj.user == self.request.user or self.request.user.has_perm(
|
||||
"camps.economyteam_permission"
|
||||
):
|
||||
return obj
|
||||
else:
|
||||
# the current user is different from the user who submitted the expense, and current user is not in the economy team; fuckery is afoot, no thanks
|
||||
|
@ -47,9 +46,12 @@ class RevenuePermissionMixin(object):
|
|||
"""
|
||||
This mixin checks if request.user submitted the Revenue, or if request.user has camps.economyteam_permission
|
||||
"""
|
||||
|
||||
def get_object(self, queryset=None):
|
||||
obj = super().get_object(queryset=queryset)
|
||||
if obj.user == self.request.user or self.request.user.has_perm('camps.economyteam_permission'):
|
||||
if obj.user == self.request.user or self.request.user.has_perm(
|
||||
"camps.economyteam_permission"
|
||||
):
|
||||
return obj
|
||||
else:
|
||||
# the current user is different from the user who submitted the revenue, and current user is not in the economy team; fuckery is afoot, no thanks
|
||||
|
@ -60,11 +62,13 @@ class ReimbursementPermissionMixin(object):
|
|||
"""
|
||||
This mixin checks if request.user owns the Reimbursement, or if request.user has camps.economyteam_permission
|
||||
"""
|
||||
|
||||
def get_object(self, queryset=None):
|
||||
obj = super().get_object(queryset=queryset)
|
||||
if obj.reimbursement_user == self.request.user or self.request.user.has_perm('camps.economyteam_permission'):
|
||||
if obj.reimbursement_user == self.request.user or self.request.user.has_perm(
|
||||
"camps.economyteam_permission"
|
||||
):
|
||||
return obj
|
||||
else:
|
||||
# the current user is different from the user who "owns" the reimbursement, and current user is not in the economy team; fuckery is afoot, no thanks
|
||||
raise Http404()
|
||||
|
||||
|
|
|
@ -6,7 +6,14 @@ from django.contrib import messages
|
|||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.http import HttpResponseRedirect, HttpResponse, Http404
|
||||
from django.urls import reverse
|
||||
from django.views.generic import CreateView, ListView, DetailView, TemplateView, UpdateView, DeleteView
|
||||
from django.views.generic import (
|
||||
CreateView,
|
||||
ListView,
|
||||
DetailView,
|
||||
TemplateView,
|
||||
UpdateView,
|
||||
DeleteView,
|
||||
)
|
||||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||
from django.db.models import Sum
|
||||
|
||||
|
@ -20,7 +27,7 @@ from .forms import *
|
|||
|
||||
|
||||
class EconomyDashboardView(LoginRequiredMixin, CampViewMixin, TemplateView):
|
||||
template_name = 'dashboard.html'
|
||||
template_name = "dashboard.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
"""
|
||||
|
@ -29,27 +36,55 @@ class EconomyDashboardView(LoginRequiredMixin, CampViewMixin, TemplateView):
|
|||
context = super().get_context_data(**kwargs)
|
||||
|
||||
# get reimbursement stats
|
||||
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()
|
||||
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()
|
||||
reimbursement_total = 0
|
||||
for reimbursement in Reimbursement.objects.filter(reimbursement_user=self.request.user, camp=self.camp):
|
||||
for reimbursement in Reimbursement.objects.filter(
|
||||
reimbursement_user=self.request.user, camp=self.camp
|
||||
):
|
||||
reimbursement_total += reimbursement.amount
|
||||
context['reimbursement_total'] = reimbursement_total
|
||||
context["reimbursement_total"] = reimbursement_total
|
||||
|
||||
# get expense stats
|
||||
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']
|
||||
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"]
|
||||
|
||||
# get revenue stats
|
||||
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']
|
||||
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"]
|
||||
|
||||
return context
|
||||
|
||||
|
@ -59,9 +94,9 @@ class EconomyDashboardView(LoginRequiredMixin, CampViewMixin, TemplateView):
|
|||
|
||||
class ChainCreateView(CampViewMixin, RaisePermissionRequiredMixin, CreateView):
|
||||
model = Chain
|
||||
template_name = 'chain_create.html'
|
||||
permission_required = ("camps.expense_create_permission")
|
||||
fields = ['name', 'notes']
|
||||
template_name = "chain_create.html"
|
||||
permission_required = "camps.expense_create_permission"
|
||||
fields = ["name", "notes"]
|
||||
|
||||
def form_valid(self, form):
|
||||
chain = form.save()
|
||||
|
@ -69,33 +104,38 @@ class ChainCreateView(CampViewMixin, RaisePermissionRequiredMixin, CreateView):
|
|||
# a message for the user
|
||||
messages.success(
|
||||
self.request,
|
||||
"The new Chain %s has been saved. You can now add Creditor(s)/Debtor(s) for it." % chain.name,
|
||||
"The new Chain %s has been saved. You can now add Creditor(s)/Debtor(s) for it."
|
||||
% chain.name,
|
||||
)
|
||||
|
||||
return HttpResponseRedirect(reverse('economy:credebtor_create', kwargs={
|
||||
'camp_slug': self.camp.slug,
|
||||
'chain_slug': chain.slug,
|
||||
}))
|
||||
return HttpResponseRedirect(
|
||||
reverse(
|
||||
"economy:credebtor_create",
|
||||
kwargs={"camp_slug": self.camp.slug, "chain_slug": chain.slug},
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class ChainListView(CampViewMixin, RaisePermissionRequiredMixin, ListView):
|
||||
model = Chain
|
||||
template_name = 'chain_list.html'
|
||||
permission_required = ("camps.expense_create_permission")
|
||||
template_name = "chain_list.html"
|
||||
permission_required = "camps.expense_create_permission"
|
||||
|
||||
|
||||
class CredebtorCreateView(CampViewMixin, ChainViewMixin, RaisePermissionRequiredMixin, CreateView):
|
||||
class CredebtorCreateView(
|
||||
CampViewMixin, ChainViewMixin, RaisePermissionRequiredMixin, CreateView
|
||||
):
|
||||
model = Credebtor
|
||||
template_name = 'credebtor_create.html'
|
||||
permission_required = ("camps.expense_create_permission")
|
||||
fields = ['name', 'address', 'notes']
|
||||
template_name = "credebtor_create.html"
|
||||
permission_required = "camps.expense_create_permission"
|
||||
fields = ["name", "address", "notes"]
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
"""
|
||||
Add chain to context
|
||||
"""
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['chain'] = self.chain
|
||||
context["chain"] = self.chain
|
||||
return context
|
||||
|
||||
def form_valid(self, form):
|
||||
|
@ -106,26 +146,31 @@ class CredebtorCreateView(CampViewMixin, ChainViewMixin, RaisePermissionRequired
|
|||
# a message for the user
|
||||
messages.success(
|
||||
self.request,
|
||||
"The Creditor/Debtor %s has been saved. You can now add Expenses/Revenues for it." % credebtor.name,
|
||||
"The Creditor/Debtor %s has been saved. You can now add Expenses/Revenues for it."
|
||||
% credebtor.name,
|
||||
)
|
||||
|
||||
return HttpResponseRedirect(reverse('economy:credebtor_list', kwargs={
|
||||
'camp_slug': self.camp.slug,
|
||||
'chain_slug': self.chain.slug,
|
||||
}))
|
||||
return HttpResponseRedirect(
|
||||
reverse(
|
||||
"economy:credebtor_list",
|
||||
kwargs={"camp_slug": self.camp.slug, "chain_slug": self.chain.slug},
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class CredebtorListView(CampViewMixin, ChainViewMixin, RaisePermissionRequiredMixin, ListView):
|
||||
class CredebtorListView(
|
||||
CampViewMixin, ChainViewMixin, RaisePermissionRequiredMixin, ListView
|
||||
):
|
||||
model = Credebtor
|
||||
template_name = 'credebtor_list.html'
|
||||
permission_required = ("camps.expense_create_permission")
|
||||
template_name = "credebtor_list.html"
|
||||
permission_required = "camps.expense_create_permission"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
"""
|
||||
Add chain to context
|
||||
"""
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['chain'] = self.chain
|
||||
context["chain"] = self.chain
|
||||
return context
|
||||
|
||||
|
||||
|
@ -134,7 +179,7 @@ class CredebtorListView(CampViewMixin, ChainViewMixin, RaisePermissionRequiredMi
|
|||
|
||||
class ExpenseListView(LoginRequiredMixin, CampViewMixin, ListView):
|
||||
model = Expense
|
||||
template_name = 'expense_list.html'
|
||||
template_name = "expense_list.html"
|
||||
|
||||
def get_queryset(self):
|
||||
# only return Expenses belonging to the current user
|
||||
|
@ -143,13 +188,15 @@ class ExpenseListView(LoginRequiredMixin, CampViewMixin, ListView):
|
|||
|
||||
class ExpenseDetailView(CampViewMixin, ExpensePermissionMixin, DetailView):
|
||||
model = Expense
|
||||
template_name = 'expense_detail.html'
|
||||
template_name = "expense_detail.html"
|
||||
|
||||
|
||||
class ExpenseCreateView(CampViewMixin, CredebtorViewMixin, RaisePermissionRequiredMixin, CreateView):
|
||||
class ExpenseCreateView(
|
||||
CampViewMixin, CredebtorViewMixin, RaisePermissionRequiredMixin, CreateView
|
||||
):
|
||||
model = Expense
|
||||
template_name = 'expense_form.html'
|
||||
permission_required = ("camps.expense_create_permission")
|
||||
template_name = "expense_form.html"
|
||||
permission_required = "camps.expense_create_permission"
|
||||
form_class = ExpenseCreateForm
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
|
@ -157,8 +204,10 @@ class ExpenseCreateView(CampViewMixin, CredebtorViewMixin, RaisePermissionRequir
|
|||
Do not show teams that are not part of the current camp in the dropdown
|
||||
"""
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['form'].fields['responsible_team'].queryset = Team.objects.filter(camp=self.camp)
|
||||
context['creditor'] = self.credebtor
|
||||
context["form"].fields["responsible_team"].queryset = Team.objects.filter(
|
||||
camp=self.camp
|
||||
)
|
||||
context["creditor"] = self.credebtor
|
||||
return context
|
||||
|
||||
def form_valid(self, form):
|
||||
|
@ -178,24 +227,32 @@ class ExpenseCreateView(CampViewMixin, CredebtorViewMixin, RaisePermissionRequir
|
|||
add_outgoing_email(
|
||||
"emails/expense_awaiting_approval_email.txt",
|
||||
formatdict=dict(expense=expense),
|
||||
subject="New %s expense for %s Team is awaiting approval" % (expense.camp.title, expense.responsible_team.name),
|
||||
subject="New %s expense for %s Team is awaiting approval"
|
||||
% (expense.camp.title, expense.responsible_team.name),
|
||||
to_recipients=[settings.ECONOMYTEAM_EMAIL],
|
||||
)
|
||||
|
||||
# return to the expense list page
|
||||
return HttpResponseRedirect(reverse('economy:expense_list', kwargs={'camp_slug': self.camp.slug}))
|
||||
return HttpResponseRedirect(
|
||||
reverse("economy:expense_list", kwargs={"camp_slug": self.camp.slug})
|
||||
)
|
||||
|
||||
|
||||
class ExpenseUpdateView(CampViewMixin, ExpensePermissionMixin, UpdateView):
|
||||
model = Expense
|
||||
template_name = 'expense_form.html'
|
||||
template_name = "expense_form.html"
|
||||
form_class = ExpenseUpdateForm
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
response = super().dispatch(request, *args, **kwargs)
|
||||
if self.get_object().approved:
|
||||
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}))
|
||||
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})
|
||||
)
|
||||
return response
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
|
@ -203,24 +260,31 @@ class ExpenseUpdateView(CampViewMixin, ExpensePermissionMixin, UpdateView):
|
|||
Do not show teams that are not part of the current camp in the dropdown
|
||||
"""
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['form'].fields['responsible_team'].queryset = Team.objects.filter(camp=self.camp)
|
||||
context['creditor'] = self.get_object().creditor
|
||||
context["form"].fields["responsible_team"].queryset = Team.objects.filter(
|
||||
camp=self.camp
|
||||
)
|
||||
context["creditor"] = self.get_object().creditor
|
||||
return context
|
||||
|
||||
def get_success_url(self):
|
||||
messages.success(self.request, "Expense %s has been updated" % self.get_object().pk)
|
||||
return(reverse('economy:expense_list', kwargs={'camp_slug': self.camp.slug}))
|
||||
messages.success(
|
||||
self.request, "Expense %s has been updated" % self.get_object().pk
|
||||
)
|
||||
return reverse("economy:expense_list", kwargs={"camp_slug": self.camp.slug})
|
||||
|
||||
|
||||
class ExpenseDeleteView(CampViewMixin, ExpensePermissionMixin, UpdateView):
|
||||
model = Expense
|
||||
template_name = 'expense_delete.html'
|
||||
template_name = "expense_delete.html"
|
||||
fields = []
|
||||
|
||||
def form_valid(self, form):
|
||||
expense = self.get_object()
|
||||
if expense.approved:
|
||||
messages.error(self.request, "This expense has already been approved, it cannot be deleted")
|
||||
messages.error(
|
||||
self.request,
|
||||
"This expense has already been approved, it cannot be deleted",
|
||||
)
|
||||
else:
|
||||
message = "Expense %s has been deleted" % expense.pk
|
||||
expense.delete()
|
||||
|
@ -228,7 +292,7 @@ class ExpenseDeleteView(CampViewMixin, ExpensePermissionMixin, UpdateView):
|
|||
return redirect(self.get_success_url())
|
||||
|
||||
def get_success_url(self):
|
||||
return(reverse('economy:expense_list', kwargs={'camp_slug': self.camp.slug}))
|
||||
return reverse("economy:expense_list", kwargs={"camp_slug": self.camp.slug})
|
||||
|
||||
|
||||
class ExpenseInvoiceView(CampViewMixin, ExpensePermissionMixin, DetailView):
|
||||
|
@ -236,6 +300,7 @@ 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
|
||||
"""
|
||||
|
||||
model = Expense
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
|
@ -246,9 +311,11 @@ class ExpenseInvoiceView(CampViewMixin, ExpensePermissionMixin, DetailView):
|
|||
# find mimetype
|
||||
mimetype = magic.from_buffer(invoicedata, mime=True)
|
||||
# check if we have a PDF, no preview if so, load a pdf icon instead
|
||||
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)
|
||||
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)
|
||||
# put the response together and return it
|
||||
response = HttpResponse(content_type=mimetype)
|
||||
response.write(invoicedata)
|
||||
|
@ -260,7 +327,7 @@ class ExpenseInvoiceView(CampViewMixin, ExpensePermissionMixin, DetailView):
|
|||
|
||||
class ReimbursementListView(LoginRequiredMixin, CampViewMixin, ListView):
|
||||
model = Reimbursement
|
||||
template_name = 'reimbursement_list.html'
|
||||
template_name = "reimbursement_list.html"
|
||||
|
||||
def get_queryset(self):
|
||||
# only return Expenses belonging to the current user
|
||||
|
@ -269,7 +336,7 @@ class ReimbursementListView(LoginRequiredMixin, CampViewMixin, ListView):
|
|||
|
||||
class ReimbursementDetailView(CampViewMixin, ReimbursementPermissionMixin, DetailView):
|
||||
model = Reimbursement
|
||||
template_name = 'reimbursement_detail.html'
|
||||
template_name = "reimbursement_detail.html"
|
||||
|
||||
|
||||
########### Revenue related views ###############
|
||||
|
@ -277,7 +344,7 @@ class ReimbursementDetailView(CampViewMixin, ReimbursementPermissionMixin, Detai
|
|||
|
||||
class RevenueListView(LoginRequiredMixin, CampViewMixin, ListView):
|
||||
model = Revenue
|
||||
template_name = 'revenue_list.html'
|
||||
template_name = "revenue_list.html"
|
||||
|
||||
def get_queryset(self):
|
||||
# only return Revenues belonging to the current user
|
||||
|
@ -286,13 +353,15 @@ class RevenueListView(LoginRequiredMixin, CampViewMixin, ListView):
|
|||
|
||||
class RevenueDetailView(CampViewMixin, RevenuePermissionMixin, DetailView):
|
||||
model = Revenue
|
||||
template_name = 'revenue_detail.html'
|
||||
template_name = "revenue_detail.html"
|
||||
|
||||
|
||||
class RevenueCreateView(CampViewMixin, CredebtorViewMixin, RaisePermissionRequiredMixin, CreateView):
|
||||
class RevenueCreateView(
|
||||
CampViewMixin, CredebtorViewMixin, RaisePermissionRequiredMixin, CreateView
|
||||
):
|
||||
model = Revenue
|
||||
template_name = 'revenue_form.html'
|
||||
permission_required = ("camps.revenue_create_permission")
|
||||
template_name = "revenue_form.html"
|
||||
permission_required = "camps.revenue_create_permission"
|
||||
form_class = RevenueCreateForm
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
|
@ -300,8 +369,10 @@ class RevenueCreateView(CampViewMixin, CredebtorViewMixin, RaisePermissionRequir
|
|||
Do not show teams that are not part of the current camp in the dropdown
|
||||
"""
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['form'].fields['responsible_team'].queryset = Team.objects.filter(camp=self.camp)
|
||||
context['debtor'] = self.credebtor
|
||||
context["form"].fields["responsible_team"].queryset = Team.objects.filter(
|
||||
camp=self.camp
|
||||
)
|
||||
context["debtor"] = self.credebtor
|
||||
return context
|
||||
|
||||
def form_valid(self, form):
|
||||
|
@ -321,24 +392,32 @@ class RevenueCreateView(CampViewMixin, CredebtorViewMixin, RaisePermissionRequir
|
|||
add_outgoing_email(
|
||||
"emails/revenue_awaiting_approval_email.txt",
|
||||
formatdict=dict(revenue=revenue),
|
||||
subject="New %s revenue for %s Team is awaiting approval" % (revenue.camp.title, revenue.responsible_team.name),
|
||||
subject="New %s revenue for %s Team is awaiting approval"
|
||||
% (revenue.camp.title, revenue.responsible_team.name),
|
||||
to_recipients=[settings.ECONOMYTEAM_EMAIL],
|
||||
)
|
||||
|
||||
# return to the revenue list page
|
||||
return HttpResponseRedirect(reverse('economy:revenue_list', kwargs={'camp_slug': self.camp.slug}))
|
||||
return HttpResponseRedirect(
|
||||
reverse("economy:revenue_list", kwargs={"camp_slug": self.camp.slug})
|
||||
)
|
||||
|
||||
|
||||
class RevenueUpdateView(CampViewMixin, RevenuePermissionMixin, UpdateView):
|
||||
model = Revenue
|
||||
template_name = 'revenue_form.html'
|
||||
template_name = "revenue_form.html"
|
||||
form_class = RevenueUpdateForm
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
response = super().dispatch(request, *args, **kwargs)
|
||||
if self.get_object().approved:
|
||||
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}))
|
||||
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})
|
||||
)
|
||||
return response
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
|
@ -346,23 +425,30 @@ class RevenueUpdateView(CampViewMixin, RevenuePermissionMixin, UpdateView):
|
|||
Do not show teams that are not part of the current camp in the dropdown
|
||||
"""
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['form'].fields['responsible_team'].queryset = Team.objects.filter(camp=self.camp)
|
||||
context["form"].fields["responsible_team"].queryset = Team.objects.filter(
|
||||
camp=self.camp
|
||||
)
|
||||
return context
|
||||
|
||||
def get_success_url(self):
|
||||
messages.success(self.request, "Revenue %s has been updated" % self.get_object().pk)
|
||||
return(reverse('economy:revenue_list', kwargs={'camp_slug': self.camp.slug}))
|
||||
messages.success(
|
||||
self.request, "Revenue %s has been updated" % self.get_object().pk
|
||||
)
|
||||
return reverse("economy:revenue_list", kwargs={"camp_slug": self.camp.slug})
|
||||
|
||||
|
||||
class RevenueDeleteView(CampViewMixin, RevenuePermissionMixin, UpdateView):
|
||||
model = Revenue
|
||||
template_name = 'revenue_delete.html'
|
||||
template_name = "revenue_delete.html"
|
||||
fields = []
|
||||
|
||||
def form_valid(self, form):
|
||||
revenue = self.get_object()
|
||||
if revenue.approved:
|
||||
messages.error(self.request, "This revenue has already been approved, it cannot be deleted")
|
||||
messages.error(
|
||||
self.request,
|
||||
"This revenue has already been approved, it cannot be deleted",
|
||||
)
|
||||
else:
|
||||
message = "Revenue %s has been deleted" % revenue.pk
|
||||
revenue.delete()
|
||||
|
@ -370,7 +456,7 @@ class RevenueDeleteView(CampViewMixin, RevenuePermissionMixin, UpdateView):
|
|||
return redirect(self.get_success_url())
|
||||
|
||||
def get_success_url(self):
|
||||
return(reverse('economy:revenue_list', kwargs={'camp_slug': self.camp.slug}))
|
||||
return reverse("economy:revenue_list", kwargs={"camp_slug": self.camp.slug})
|
||||
|
||||
|
||||
class RevenueInvoiceView(CampViewMixin, RevenuePermissionMixin, DetailView):
|
||||
|
@ -378,6 +464,7 @@ 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
|
||||
"""
|
||||
|
||||
model = Revenue
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
|
@ -388,11 +475,12 @@ class RevenueInvoiceView(CampViewMixin, RevenuePermissionMixin, DetailView):
|
|||
# find mimetype
|
||||
mimetype = magic.from_buffer(invoicedata, mime=True)
|
||||
# check if we have a PDF, no preview if so, load a pdf icon instead
|
||||
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)
|
||||
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)
|
||||
# put the response together and return it
|
||||
response = HttpResponse(content_type=mimetype)
|
||||
response.write(invoicedata)
|
||||
return response
|
||||
|
||||
|
|
|
@ -38,5 +38,4 @@ six==1.12.0
|
|||
sqlparse==0.3.0
|
||||
venusian==1.2.0
|
||||
webencodings==0.5.1
|
||||
wrapt==1.11.1
|
||||
graphene-django==2.2.0
|
||||
|
|
Loading…
Reference in a new issue