mirror of
https://gitlab.crans.org/bde/nk20
synced 2025-06-21 18:08:21 +02:00
Merge branch 'beta' into 'main'
api errors (fix #113), sortable tables, calendar (fix #95), opener (fix #117), colored linters, inclusif, bug july 31, 403 (fix #65) Closes #65, #117, #95, and #113 See merge request bde/nk20!260
This commit is contained in:
@ -2,7 +2,7 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from rest_framework.filters import SearchFilter
|
||||
from api.filters import RegexSafeSearchFilter
|
||||
from api.viewsets import ReadProtectedModelViewSet
|
||||
|
||||
from .serializers import InvoiceSerializer, ProductSerializer, RemittanceTypeSerializer, RemittanceSerializer, \
|
||||
@ -18,7 +18,7 @@ class InvoiceViewSet(ReadProtectedModelViewSet):
|
||||
"""
|
||||
queryset = Invoice.objects.order_by('id')
|
||||
serializer_class = InvoiceSerializer
|
||||
filter_backends = [DjangoFilterBackend, SearchFilter]
|
||||
filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter]
|
||||
filterset_fields = ['bde', 'object', 'description', 'name', 'address', 'date', 'acquitted', 'locked', ]
|
||||
search_fields = ['$object', '$description', '$name', '$address', ]
|
||||
|
||||
@ -31,7 +31,7 @@ class ProductViewSet(ReadProtectedModelViewSet):
|
||||
"""
|
||||
queryset = Product.objects.order_by('invoice_id', 'id')
|
||||
serializer_class = ProductSerializer
|
||||
filter_backends = [DjangoFilterBackend, SearchFilter]
|
||||
filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter]
|
||||
filterset_fields = ['invoice', 'designation', 'quantity', 'amount', ]
|
||||
search_fields = ['$designation', '$invoice__object', ]
|
||||
|
||||
@ -44,7 +44,7 @@ class RemittanceTypeViewSet(ReadProtectedModelViewSet):
|
||||
"""
|
||||
queryset = RemittanceType.objects.order_by('id')
|
||||
serializer_class = RemittanceTypeSerializer
|
||||
filter_backends = [DjangoFilterBackend, SearchFilter]
|
||||
filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter]
|
||||
filterset_fields = ['note', ]
|
||||
search_fields = ['$note__special_type', ]
|
||||
|
||||
@ -57,7 +57,7 @@ class RemittanceViewSet(ReadProtectedModelViewSet):
|
||||
"""
|
||||
queryset = Remittance.objects.order_by('id')
|
||||
serializer_class = RemittanceSerializer
|
||||
filter_backends = [DjangoFilterBackend, SearchFilter]
|
||||
filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter]
|
||||
filterset_fields = ['date', 'remittance_type', 'comment', 'closed', 'transaction_proxies__transaction', ]
|
||||
search_fields = ['$remittance_type__note__special_type', '$comment', ]
|
||||
|
||||
@ -70,7 +70,7 @@ class SogeCreditViewSet(ReadProtectedModelViewSet):
|
||||
"""
|
||||
queryset = SogeCredit.objects.order_by('id')
|
||||
serializer_class = SogeCreditSerializer
|
||||
filter_backends = [DjangoFilterBackend, SearchFilter]
|
||||
filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter]
|
||||
filterset_fields = ['user', 'user__last_name', 'user__first_name', 'user__email', 'user__note__alias__name',
|
||||
'user__note__alias__normalized_name', 'transactions', 'credit_transaction', ]
|
||||
search_fields = ['$user__last_name', '$user__first_name', '$user__email', '$user__note__alias__name',
|
||||
|
@ -19,7 +19,8 @@ from django.utils.translation import gettext_lazy as _
|
||||
from django.views.generic import UpdateView, DetailView
|
||||
from django.views.generic.base import View, TemplateView
|
||||
from django.views.generic.edit import BaseFormView, DeleteView
|
||||
from django_tables2 import SingleTableView
|
||||
from django_tables2 import MultiTableMixin, SingleTableMixin, SingleTableView
|
||||
from api.viewsets import is_regex
|
||||
from note.models import SpecialTransaction, NoteSpecial, Alias
|
||||
from note_kfet.settings.base import BASE_DIR
|
||||
from permission.backends import PermissionBackend
|
||||
@ -251,21 +252,26 @@ class RemittanceCreateView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
||||
context["table"] = RemittanceTable(
|
||||
data=Remittance.objects.filter(
|
||||
PermissionBackend.filter_queryset(self.request, Remittance, "view")).all())
|
||||
context["special_transactions"] = SpecialTransactionTable(data=SpecialTransaction.objects.none())
|
||||
|
||||
return context
|
||||
|
||||
|
||||
class RemittanceListView(LoginRequiredMixin, TemplateView):
|
||||
class RemittanceListView(LoginRequiredMixin, MultiTableMixin, TemplateView):
|
||||
"""
|
||||
List existing Remittances
|
||||
"""
|
||||
template_name = "treasury/remittance_list.html"
|
||||
extra_context = {"title": _("Remittances list")}
|
||||
|
||||
tables = [
|
||||
lambda data: RemittanceTable(data, prefix="opened-remittances-"),
|
||||
lambda data: RemittanceTable(data, prefix="closed-remittances-"),
|
||||
lambda data: SpecialTransactionTable(data, prefix="no-remittance-", exclude=('remittance_remove', )),
|
||||
lambda data: SpecialTransactionTable(data, prefix="with-remittance-", exclude=('remittance_add', )),
|
||||
]
|
||||
paginate_by = 10 # number of rows in tables
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
# Check that the user is authenticated
|
||||
if not request.user.is_authenticated:
|
||||
@ -275,49 +281,37 @@ class RemittanceListView(LoginRequiredMixin, TemplateView):
|
||||
raise PermissionDenied(_("You are not able to see the treasury interface."))
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_tables_data(self):
|
||||
return [
|
||||
Remittance.objects.filter(closed=False).filter(
|
||||
PermissionBackend.filter_queryset(self.request, Remittance, "view")),
|
||||
Remittance.objects.filter(closed=True).filter(
|
||||
PermissionBackend.filter_queryset(self.request, Remittance, "view")),
|
||||
SpecialTransaction.objects.filter(source__in=NoteSpecial.objects.filter(~Q(remittancetype=None)),
|
||||
specialtransactionproxy__remittance=None).filter(
|
||||
PermissionBackend.filter_queryset(self.request, Remittance, "view")),
|
||||
SpecialTransaction.objects.filter(source__in=NoteSpecial.objects.filter(~Q(remittancetype=None)),
|
||||
specialtransactionproxy__remittance__closed=False).filter(
|
||||
PermissionBackend.filter_queryset(self.request, Remittance, "view")),
|
||||
]
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
||||
opened_remittances = RemittanceTable(
|
||||
data=Remittance.objects.filter(closed=False).filter(
|
||||
PermissionBackend.filter_queryset(self.request, Remittance, "view")).all(),
|
||||
prefix="opened-remittances-",
|
||||
)
|
||||
opened_remittances.paginate(page=self.request.GET.get("opened-remittances-page", 1), per_page=10)
|
||||
context["opened_remittances"] = opened_remittances
|
||||
|
||||
closed_remittances = RemittanceTable(
|
||||
data=Remittance.objects.filter(closed=True).filter(
|
||||
PermissionBackend.filter_queryset(self.request, Remittance, "view")).all(),
|
||||
prefix="closed-remittances-",
|
||||
)
|
||||
closed_remittances.paginate(page=self.request.GET.get("closed-remittances-page", 1), per_page=10)
|
||||
context["closed_remittances"] = closed_remittances
|
||||
|
||||
no_remittance_tr = SpecialTransactionTable(
|
||||
data=SpecialTransaction.objects.filter(source__in=NoteSpecial.objects.filter(~Q(remittancetype=None)),
|
||||
specialtransactionproxy__remittance=None).filter(
|
||||
PermissionBackend.filter_queryset(self.request, Remittance, "view")).all(),
|
||||
exclude=('remittance_remove', ),
|
||||
prefix="no-remittance-",
|
||||
)
|
||||
no_remittance_tr.paginate(page=self.request.GET.get("no-remittance-page", 1), per_page=10)
|
||||
context["special_transactions_no_remittance"] = no_remittance_tr
|
||||
|
||||
with_remittance_tr = SpecialTransactionTable(
|
||||
data=SpecialTransaction.objects.filter(source__in=NoteSpecial.objects.filter(~Q(remittancetype=None)),
|
||||
specialtransactionproxy__remittance__closed=False).filter(
|
||||
PermissionBackend.filter_queryset(self.request, Remittance, "view")).all(),
|
||||
exclude=('remittance_add', ),
|
||||
prefix="with-remittance-",
|
||||
)
|
||||
with_remittance_tr.paginate(page=self.request.GET.get("with-remittance-page", 1), per_page=10)
|
||||
context["special_transactions_with_remittance"] = with_remittance_tr
|
||||
tables = context["tables"]
|
||||
names = [
|
||||
"opened_remittances",
|
||||
"closed_remittances",
|
||||
"special_transactions_no_remittance",
|
||||
"special_transactions_with_remittance",
|
||||
]
|
||||
for name, table in zip(names, tables):
|
||||
context[name] = table
|
||||
|
||||
return context
|
||||
|
||||
|
||||
class RemittanceUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
|
||||
class RemittanceUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableMixin, UpdateView):
|
||||
"""
|
||||
Update Remittance
|
||||
"""
|
||||
@ -325,19 +319,18 @@ class RemittanceUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView)
|
||||
form_class = RemittanceForm
|
||||
extra_context = {"title": _("Update a remittance")}
|
||||
|
||||
table_class = SpecialTransactionTable
|
||||
context_table_name = "special_transactions"
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse_lazy('treasury:remittance_list')
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
def get_table_data(self):
|
||||
return SpecialTransaction.objects.filter(specialtransactionproxy__remittance=self.object).filter(
|
||||
PermissionBackend.filter_queryset(self.request, Remittance, "view"))
|
||||
|
||||
data = SpecialTransaction.objects.filter(specialtransactionproxy__remittance=self.object).filter(
|
||||
PermissionBackend.filter_queryset(self.request, Remittance, "view")).all()
|
||||
context["special_transactions"] = SpecialTransactionTable(
|
||||
data=data,
|
||||
exclude=('remittance_add', 'remittance_remove', ) if self.object.closed else ('remittance_add', ))
|
||||
|
||||
return context
|
||||
def get_table_kwargs(self):
|
||||
return {"exclude": ('remittance_add', 'remittance_remove', ) if self.object.closed else ('remittance_add', )}
|
||||
|
||||
|
||||
class LinkTransactionToRemittanceView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
|
||||
@ -411,11 +404,16 @@ class SogeCreditListView(LoginRequiredMixin, ProtectQuerysetMixin, SingleTableVi
|
||||
if "search" in self.request.GET:
|
||||
pattern = self.request.GET["search"]
|
||||
if pattern:
|
||||
# Check if this is a valid regex. If not, we won't check regex
|
||||
valid_regex = is_regex(pattern)
|
||||
suffix_alias = "__iregex" if valid_regex else "__icontains"
|
||||
suffix = "__iregex" if valid_regex else "__istartswith"
|
||||
prefix = "^" if valid_regex else ""
|
||||
qs = qs.filter(
|
||||
Q(user__first_name__iregex=pattern)
|
||||
| Q(user__last_name__iregex=pattern)
|
||||
| Q(user__note__alias__name__iregex="^" + pattern)
|
||||
| Q(user__note__alias__normalized_name__iregex="^" + Alias.normalize(pattern))
|
||||
Q(**{f"user__first_name{suffix}": pattern})
|
||||
| Q(**{f"user__last_name{suffix}": pattern})
|
||||
| Q(**{f"user__note__alias__name{suffix_alias}": prefix + pattern})
|
||||
| Q(**{f"user__note__alias__normalized_name{suffix_alias}": prefix + Alias.normalize(pattern)})
|
||||
)
|
||||
|
||||
if "valid" not in self.request.GET or not self.request.GET["valid"]:
|
||||
|
Reference in New Issue
Block a user