+
+
{{ claim.amount }} {{ claim.currency }}
@@ -47,25 +47,67 @@
{% endif %}
Skapad {{ claim.created_at|date:"Y-m-d H:i" }}
-
{{ claim.full_name }}
-
- {{ claim.email }} · Konto: {{ claim.account_number }}
- {% if claim.submitted_by %}
- Inloggad användare: {{ claim.submitted_by.get_username }}
- {% else %}
- Inskickad av gäst
- {% endif %}
-
+
+
Person
+
{{ claim.full_name }}
+
+ {{ claim.email }} · Konto: {{ claim.account_number }}
+ {% if claim.submitted_by %}
+ Inloggad användare: {{ claim.submitted_by.get_username }}
+ {% else %}
+ Inskickad av gäst
+ {% endif %}
+
+
-
+
{{ claim.get_status_display }}
{% if claim.decision_note %}
Kommentar: {{ claim.decision_note }}
{% endif %}
+ {% if payments_enabled and claim.status == 'approved' %}
+ {% if claim.is_paid %}
+
+ Betald {{ claim.paid_at|date:"Y-m-d H:i" }}
+ {% if claim.paid_by %}av {{ claim.paid_by.get_username }}{% endif %}
+
+ {% else %}
+
Ej markerad som betald
+ {% endif %}
+ {% endif %}
+
+ {% if claim.status == 'approved' %}
+
+
+
+
Sammanfattning
+
{{ claim.full_name }}
+
Belopp: {{ claim.amount }} {{ claim.currency }} · Konto: {{ claim.account_number }}
+
+ {% if payments_enabled %}
+ {% if claim.is_paid %}
+
Markerad som betald
+ {% else %}
+
+ {% endif %}
+ {% else %}
+
Intern betalningshantering är av – markera betalning i ekonomisystemet.
+ {% endif %}
+
+
+ {% endif %}
+
Beskrivning
@@ -110,24 +152,31 @@
{% if can_change %}
-
+
+
+
+ {% endif %}
{% endif %}
diff --git a/claims/templates/claims/base.html b/claims/templates/claims/base.html
index ddb74d6..00da0ad 100644
--- a/claims/templates/claims/base.html
+++ b/claims/templates/claims/base.html
@@ -24,21 +24,27 @@
-
- claims-system
-
-
{% else %}
- Du har inte skickat in några utlägg ännu eller så gjordes de utan inloggning.
+
+
Inga utlägg ännu
+
När du skickar in utlägg medan du är inloggad dyker de upp här.
+
{% endif %}
+
{% endblock %}
diff --git a/claims/templates/claims/submit_success.html b/claims/templates/claims/submit_success.html
new file mode 100644
index 0000000..b7af359
--- /dev/null
+++ b/claims/templates/claims/submit_success.html
@@ -0,0 +1,26 @@
+{% extends "claims/base.html" %}
+
+{% block title %}Tack för ditt utlägg{% endblock %}
+
+{% block content %}
+
+
+
Tack!
+
Utlägget är skickat
+
+ Vi har tagit emot underlaget. Om du har fler kvitton kan du fylla i ett nytt formulär direkt,
+ annars kan du logga in för att följa statusen.
+
+
+
+
+{% endblock %}
diff --git a/claims/templates/claims/user_management.html b/claims/templates/claims/user_management.html
index 72272f0..784f968 100644
--- a/claims/templates/claims/user_management.html
+++ b/claims/templates/claims/user_management.html
@@ -3,76 +3,175 @@
{% block title %}Användarhantering{% endblock %}
{% block content %}
- Användare & behörigheter
- Skapa nya konton, underhåll behörigheter och ta bort användare kopplat till utläggssystemet.
+
+
+ Konton & behörigheter
+ Hantera användare
+
+ Skapa nya konton, justera rättigheter för claim-flödet och ta bort användare som inte längre ska ha åtkomst.
+
+
+ Notis: denna sida styr direkta behörigheter. Rättigheter via grupper eller superuser-status gäller även om kryssrutorna avmarkeras.
+
+
- Notis: sidan hanterar direkta behörigheter. Behörigheter via grupper eller superuser-status gäller även om kryssrutorna avmarkeras.
-
-
- Skapa ny användare
-
-
-
-
-
-
- Befintliga användare
-
-
-
- | Användare |
- Namn |
- E-post |
- Behörigheter |
- Ta bort |
-
-
-
- {% for row in user_rows %}
- {% with user=row.user %}
-
- |
- {{ user.username }}
- {% if user.is_superuser %}⭐{% endif %}
- |
- {{ user.get_full_name|default:"-" }} |
- {{ user.email|default:"-" }} |
-
- {% with form=row.permission_form %}
-
- {% endwith %}
- |
-
- {% if row.delete_form %}
-
+
+
+
+ Nytt konto
+ Skapa användare
+ Lösenordet valideras mot Djangos standardregler.
+
+ |
-
+ {% if field.help_text %}
+ {{ field.help_text }}
+ {% endif %}
+ {% for error in field.errors %}
+ {{ error }}
+ {% endfor %}
+
+ {% endfor %}
+
+
+
+
+
+
Tips för kontohantering
+
+ -
+
+ Lägg användare i grupper via Django admin om flera personer ska dela samma roll.
+
+ -
+
+
+ Behörigheterna
claims.view_claim
+ och claims.change_claim
+ styr åtkomst till adminvyn respektive beslutsflödet.
+
+
+ -
+
+ En markerad Admin/staff-användare kan nå Django admin och skapa projekt, exportflöden m.m.
+
+ -
+
+ Ta bara bort konton du är säker på – historik försvinner inte, men personen tappar all åtkomst.
+
+
+
+
+
+
+
+
Befintliga användare
+
Justera behörigheter
+
+
+ {% for row in user_rows %}
+ {% with user=row.user form=row.permission_form delete_form=row.delete_form %}
+
+
+
+
+
{{ user.username }}
+ {% if user.is_superuser %}
+ Superuser
+ {% endif %}
+
+
+ {{ user.get_full_name|default:"Saknar namn" }} · {{ user.email|default:"Ingen e-post" }}
+
+
+
+ ID: {{ user.id }}
+
+
+
+
+
+
Ta bort konto
+ {% if delete_form %}
+
Åtgärden går inte att ångra. Användaren förlorar omedelbart åtkomst.
+
+ {% else %}
+
Kan inte tas bort (antingen du själv eller superuser).
+ {% endif %}
+
+
+
{% endwith %}
{% empty %}
-
| Inga användare upplagda. |
+
+
Inga användare ännu
+
Skapa det första kontot via formuläret ovan.
+
{% endfor %}
-
-
+
+
{% endblock %}
diff --git a/claims/urls.py b/claims/urls.py
index 5dfa971..4f06a76 100644
--- a/claims/urls.py
+++ b/claims/urls.py
@@ -6,12 +6,14 @@ from .views import (
MyClaimsView,
SubmitClaimView,
UserManagementView,
+ SubmitClaimSuccessView,
)
app_name = "claims"
urlpatterns = [
path("new/", SubmitClaimView.as_view(), name="submit"),
+ path("submitted/", SubmitClaimSuccessView.as_view(), name="submit-success"),
path("admin/", ClaimAdminListView.as_view(), name="admin-list"),
path("export/", ClaimExportMenuView.as_view(), name="export"),
path("mine/", MyClaimsView.as_view(), name="my-claims"),
diff --git a/claims/views.py b/claims/views.py
index 3e0716c..9406a76 100644
--- a/claims/views.py
+++ b/claims/views.py
@@ -1,3 +1,4 @@
+from django.conf import settings
from django.contrib import messages
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Permission
@@ -5,6 +6,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMix
from django.forms import formset_factory
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
+from django.utils import timezone
from django.views import View
from django.views.generic import ListView, TemplateView
@@ -16,7 +18,7 @@ from .forms import (
UserManagementForm,
UserPermissionForm,
)
-from .models import Claim, ClaimLog
+from .models import Claim, ClaimLog, SystemSetting
User = get_user_model()
@@ -110,7 +112,7 @@ class SubmitClaimView(View):
if created:
messages.success(request, f"{created} utlägg skickade in.")
- return redirect(reverse("claims:admin-list"))
+ return redirect(reverse("claims:submit-success"))
messages.error(request, "Inga utlägg kunde sparas. Fyll i minst en rad.")
else:
@@ -133,7 +135,7 @@ class ClaimAdminListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
def get_queryset(self):
queryset = (
- Claim.objects.select_related("submitted_by", "project")
+ Claim.objects.select_related("submitted_by", "project", "paid_by")
.prefetch_related("logs__performed_by")
.all()
)
@@ -148,9 +150,16 @@ class ClaimAdminListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
context["status_choices"] = Claim.Status.choices
context["decision_choices"] = ClaimDecisionForm().fields["action"].choices
context["can_change"] = self.request.user.has_perm("claims.change_claim")
+ context["payments_enabled"] = SystemSetting.internal_payments_active()
return context
def post(self, request, *args, **kwargs):
+ action_type = request.POST.get("action_type", "decision")
+ if action_type == "payment":
+ return self._handle_payment(request)
+ return self._handle_decision(request)
+
+ def _handle_decision(self, request):
if not request.user.has_perm("claims.change_claim"):
messages.error(request, "Du har inte behörighet att uppdatera utlägg.")
return redirect(request.get_full_path())
@@ -165,6 +174,9 @@ class ClaimAdminListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
claim = get_object_or_404(Claim, pk=form.cleaned_data["claim_id"])
action = form.cleaned_data["action"]
decision_note = form.cleaned_data.get("decision_note", "")
+ if claim.is_paid:
+ messages.error(request, "Utlägget är redan markerat som betalt och kan inte ändras.")
+ return redirect(request.get_full_path())
previous_status = claim.status
claim.decision_note = decision_note
@@ -185,6 +197,33 @@ class ClaimAdminListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
)
return redirect(request.get_full_path())
+ def _handle_payment(self, request):
+ if not SystemSetting.internal_payments_active():
+ messages.error(request, "Betalningshantering är inte aktiverad.")
+ return redirect(request.get_full_path())
+ if not request.user.has_perm("claims.change_claim"):
+ messages.error(request, "Du har inte behörighet att uppdatera utlägg.")
+ return redirect(request.get_full_path())
+
+ claim = get_object_or_404(Claim, pk=request.POST.get("payment_claim_id"))
+ if claim.status != Claim.Status.APPROVED:
+ messages.error(request, "Endast godkända utlägg kan markeras som betalda.")
+ return redirect(request.get_full_path())
+ if claim.is_paid:
+ messages.info(request, "Detta utlägg är redan markerat som betalt.")
+ return redirect(request.get_full_path())
+
+ claim.paid_by = request.user
+ claim.paid_at = timezone.now()
+ claim.save(update_fields=["paid_by", "paid_at"])
+ claim.add_log(
+ action=ClaimLog.Action.MARKED_PAID,
+ performed_by=request.user,
+ note="Markerad som betald via systemet.",
+ )
+ messages.success(request, f"{claim} markerades som betald.")
+ return redirect(request.get_full_path())
+
class ClaimExportMenuView(LoginRequiredMixin, PermissionRequiredMixin, TemplateView):
template_name = "claims/export_placeholder.html"
@@ -311,3 +350,7 @@ class UserManagementView(LoginRequiredMixin, PermissionRequiredMixin, TemplateVi
user.user_permissions.add(perm)
else:
user.user_permissions.remove(perm)
+
+
+class SubmitClaimSuccessView(TemplateView):
+ template_name = "claims/submit_success.html"
diff --git a/claims_system/settings.py b/claims_system/settings.py
index 96c7151..31ef487 100644
--- a/claims_system/settings.py
+++ b/claims_system/settings.py
@@ -10,6 +10,7 @@ For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.2/ref/settings/
"""
+import os
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
@@ -120,6 +121,10 @@ MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'
LOGIN_REDIRECT_URL = '/claims/admin/'
+LOGOUT_REDIRECT_URL = '/accounts/login/'
+
+os.environ.setdefault("CLAIMS_ENABLE_INTERNAL_PAYMENTS", "true")
+CLAIMS_ENABLE_INTERNAL_PAYMENTS = os.getenv("CLAIMS_ENABLE_INTERNAL_PAYMENTS", "true").lower() in {"1", "true", "yes"}
# Default primary key field type
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field
diff --git a/templates/registration/logged_out.html b/templates/registration/logged_out.html
new file mode 100644
index 0000000..bc48f7a
--- /dev/null
+++ b/templates/registration/logged_out.html
@@ -0,0 +1,19 @@
+{% extends "claims/base.html" %}
+
+{% block title %}Utloggad{% endblock %}
+
+{% block content %}
+
+
+
Du är utloggad
+
Vi ses snart igen
+
+ Din session är avslutad. Du kan när som helst logga in igen för att hantera utlägg eller administrera systemet.
+
+
+ Till inloggningen
+
+
+
+{% endblock %}
diff --git a/templates/registration/login.html b/templates/registration/login.html
index dc5bda4..cb4e0d6 100644
--- a/templates/registration/login.html
+++ b/templates/registration/login.html
@@ -3,11 +3,46 @@
{% block title %}Logga in{% endblock %}
{% block content %}
-
Logga in
-
+
+
+
+
Välkommen tillbaka
+
Logga in
+
Använd dina administratörsuppgifter för att hantera utlägg.
+
+
+
Behöver du ett konto? Kontakta en superuser i organisationen.
+
+
{% endblock %}