diff --git a/app/vkk/templates/vkk/workhours/accounting/period/details.html b/app/vkk/templates/vkk/workhours/accounting/period/details.html index ad35bafe6d5f12d2c0d8b9ae88fc1619c421eeb5..617dc70205033fe0b947a1d01705f4eb034ce3cf 100644 --- a/app/vkk/templates/vkk/workhours/accounting/period/details.html +++ b/app/vkk/templates/vkk/workhours/accounting/period/details.html @@ -11,7 +11,7 @@ <body> {% for project in projects %} <tr> - <td>{{ project.department__name }}</td> + <td><a href="{% url 'vkk:workhours:accounting:periods:projects_open' view.kwargs.pk project.department__pk %}">{{ project.department__name }}</a></td> <td>{{ project.projects_not_closed }}</td> </tr> {% endfor %} diff --git a/app/vkk/templates/vkk/workhours/accounting/period/projects.html b/app/vkk/templates/vkk/workhours/accounting/period/projects.html new file mode 100644 index 0000000000000000000000000000000000000000..5f7e1aac44ddd194cabc46f96e5cbb554526c9ba --- /dev/null +++ b/app/vkk/templates/vkk/workhours/accounting/period/projects.html @@ -0,0 +1,21 @@ +{% extends "vkk/generic/details.html" %} +{% load i18n %} +{% block main %} +{{ block.super }} + +<table> + <caption>{{ department.name }}</caption> + <thead> + <th>{% translate "Projects not closed" %}</th> + <th></th> + </thead> + <body> + {% for project in projects %} + <tr> + <td>{{ project.name }}</td> + <td><a href="{% url 'vkk:workhours:accounting:projects:project:workhours_sheet' project.invoice_number object.pk %}">{% translate "Workhour Sheet" %}</a></td> + </tr> + {% endfor %} + </tbody> +</table> +{% endblock main %} \ No newline at end of file diff --git a/app/vkk/workhours/accounting/periods/urls.py b/app/vkk/workhours/accounting/periods/urls.py index 915f26cd7d51f0203a4fe9b1a811ff65c45f7412..01b4930dd9fea0070ebd59314d98a9de2a952385 100644 --- a/app/vkk/workhours/accounting/periods/urls.py +++ b/app/vkk/workhours/accounting/periods/urls.py @@ -2,7 +2,7 @@ from django.urls import path from django.utils.translation import gettext_lazy as _ from django.forms import modelform_factory from ..views import * -from .views import AccountingPeriodDetailView +from .views import AccountingPeriodDetailView, AccountingPeriodDetailDepartmentView from vkk.workhours.models import Period from vkk.generic.forms import CustomDateInput, CustomDateTimeInput @@ -31,6 +31,11 @@ urlpatterns = [ AccountingPeriodDetailView.as_view(), name='details' ), + path( + _('<int:pk>/details/projects_open_by_department/<int:department_pk>'), + AccountingPeriodDetailDepartmentView.as_view(), + name='projects_open' + ), path( _('create/'), AccountingCreateView.as_view(**model, **form_class), diff --git a/app/vkk/workhours/accounting/periods/views.py b/app/vkk/workhours/accounting/periods/views.py index a238ab1f4fff1e94366b0289865a3b3edb6ab1aa..c611336a8c85be2a1f4ce79a3fc31260d1e982e1 100644 --- a/app/vkk/workhours/accounting/periods/views.py +++ b/app/vkk/workhours/accounting/periods/views.py @@ -1,6 +1,7 @@ -from django.db.models import Count +from django.db.models import Count, Q +from django.shortcuts import get_object_or_404 from vkk.workhours.accounting.views import AccountingDetailView -from vkk.workhours.models import Period, Project +from vkk.workhours.models import Period, Project, Department class AccountingPeriodDetailView(AccountingDetailView): @@ -10,14 +11,40 @@ class AccountingPeriodDetailView(AccountingDetailView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) + # projects = Project.objects.exclude( + # projectassignment__periodclosure__period=kwargs["object"], + # projectassignment__periodclosure__is_closed_contributor=True, + # projectassignment__periodclosure__is_closed_manager=True, + # ).filter( + # projectassignment__isnull=False + # ) projects = Project.objects.exclude( - projectassignment__periodclosure__period=kwargs["object"], - projectassignment__periodclosure__is_closed_contributor=True, - projectassignment__periodclosure__is_closed_manager=True + Q(projectassignment__isnull=True) | Q(projectassignment__periodclosure__period=kwargs["object"]) & Q( + projectassignment__periodclosure__is_closed_contributor=True) & Q(projectassignment__periodclosure__is_closed_manager=True) ).values( - 'department', 'department__name' + 'department', 'department__name', 'department__pk' ).annotate( projects_not_closed=Count('department') - ).order_by('department__name') + ).exclude(department=None).order_by('department__name') + context["projects"] = projects + return context + + +class AccountingPeriodDetailDepartmentView(AccountingDetailView): + model = Period + fields = ['start', 'end', 'dead_line', 'dead_line_final'] + template_name = "vkk/workhours/accounting/period/projects.html" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + department = get_object_or_404( + Department, pk=self.kwargs["department_pk"]) + projects = Project.objects.exclude( + Q(projectassignment__isnull=True) | Q(projectassignment__periodclosure__period=kwargs["object"]) & Q( + projectassignment__periodclosure__is_closed_contributor=True) & Q(projectassignment__periodclosure__is_closed_manager=True) + ).filter( + department=department, + ) + context["department"] = department context["projects"] = projects return context diff --git a/app/vkk/workhours/accounting/projects/urls.py b/app/vkk/workhours/accounting/projects/urls.py index f3a6a075692a3b4bf267ec9a04df6b696f81c1b5..3aa9c1523e3ba0c7de7e636c4f60d1addf2edf38 100644 --- a/app/vkk/workhours/accounting/projects/urls.py +++ b/app/vkk/workhours/accounting/projects/urls.py @@ -9,17 +9,18 @@ model = {'model': Project} fields = {'fields': ['invoice_number', 'name', 'contractor', 'start', 'end']} form_class = {'form_class': modelform_factory( **model, - fields=['invoice_number', 'name', 'contractor', 'department', 'start', 'end'], - widgets={'start':CustomDateInput, 'end':CustomDateInput} + fields=['invoice_number', 'name', 'contractor', + 'department', 'start', 'end'], + widgets={'start': CustomDateInput, 'end': CustomDateInput} )} action_options = { - 'action_options' : { + 'action_options': { 'project:default': _('Details'), - 'project:export:overview' : _('Export'), - 'delete' : _('Delete'), + 'project:export:overview': _('Export'), + 'delete': _('Delete'), } } -key = { 'slug_field': 'invoice_number', 'slug_url_kwarg' : 'invoice_number'} +key = {'slug_field': 'invoice_number', 'slug_url_kwarg': 'invoice_number'} app_name = 'projects' urlpatterns = [ @@ -60,12 +61,13 @@ urlpatterns = [ '', AccountingFilterView.as_view( **model, - **fields, + **fields, **action_options, keys=key['slug_field'], ordering=['invoice_number'], ), - name='default' + name='default' ), - path(_('<int:invoice_number>/project/'), include('vkk.workhours.accounting.projects.project.urls')), -] \ No newline at end of file + path(_('<int:invoice_number>/project/'), + include('vkk.workhours.accounting.projects.project.urls')), +] diff --git a/app/vkkdjango/settings.py b/app/vkkdjango/settings.py index 58fa102cc1df2df94392bcbc0ca6e56dbfbc6a2a..1273a9876239e93824a341a6dee3bbc42bdf5d01 100644 --- a/app/vkkdjango/settings.py +++ b/app/vkkdjango/settings.py @@ -85,7 +85,7 @@ DATABASES = { "PASSWORD": os.environ.get("SQL_PASSWORD"), "HOST": os.environ.get("SQL_HOST"), "PORT": os.environ.get("SQL_PORT"), - "CONN_MAX_AGE" : 300, + "CONN_MAX_AGE": 300, "OPTIONS": { "sslmode": "require", "sslrootcert": BASE_DIR / "cert/ca.crt", @@ -105,7 +105,6 @@ LOGIN_URL = reverse_lazy('vkk:users:login') LOGIN_REDIRECT_URL = reverse_lazy('vkk:workhours:overview') - # Password validation # https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators @@ -152,6 +151,12 @@ STATIC_ROOT = BASE_DIR / "staticfiles" DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' +# Sessions +# https://docs.djangoproject.com/en/4.1/topics/http/sessions/ + +SESSION_COOKIE_AGE = 28800 +SESSION_COOKIE_SAMESITE = 'Strict' + # Email # https://docs.djangoproject.com/en/4.0/topics/email/