+ {% trans "Evenemang/Projekt" %}
+
+ {% trans "Behåll nuvarande" %}
+ {% for project in project_options %}
+ {{ project }}
+ {% endfor %}
+
+ {% trans "Justera projekt om underlaget skickats in mot fel evenemang." %}
+
+
+
{% trans "Uppdatera beslut" %}
diff --git a/claims/tests.py b/claims/tests.py
index bbd0be9..7fc67ac 100644
--- a/claims/tests.py
+++ b/claims/tests.py
@@ -8,7 +8,8 @@ from django.test import TestCase, override_settings
from django.urls import reverse
from django.utils import timezone
-from .models import Claim
+from .forms import ClaimDecisionForm
+from .models import Claim, Project
from .validators import validate_receipt_file
from .views import SubmitClaimView
@@ -79,7 +80,8 @@ class DashboardViewTests(TestCase):
User = get_user_model()
self.user = User.objects.create_user(username="admin", password="test123", email="admin@example.com")
view_perm = Permission.objects.get(codename="view_claim")
- self.user.user_permissions.add(view_perm)
+ change_perm = Permission.objects.get(codename="change_claim")
+ self.user.user_permissions.add(view_perm, change_perm)
self.client.force_login(self.user)
def _create_claim(self, **kwargs):
@@ -122,3 +124,23 @@ class DashboardViewTests(TestCase):
self._create_claim(status=Claim.Status.PENDING)
response = self.client.get(reverse("claims:admin-list") + "?status=approved")
self.assertFalse(response.context["has_filtered_claims"])
+
+ def test_attester_can_update_project_when_deciding(self):
+ project_old = Project.objects.create(name="Original", is_active=True)
+ project_new = Project.objects.create(name="Corrected", is_active=True)
+ claim = self._create_claim(project=project_old)
+
+ response = self.client.post(
+ reverse("claims:admin-list"),
+ {
+ "action_type": "decision",
+ "claim_id": claim.id,
+ "action": ClaimDecisionForm.ACTION_APPROVE,
+ "decision_note": "Updated project",
+ "project": project_new.id,
+ },
+ follow=True,
+ )
+ self.assertEqual(response.status_code, 200)
+ claim.refresh_from_db()
+ self.assertEqual(claim.project, project_new)
diff --git a/claims/views.py b/claims/views.py
index d154e42..e556eca 100644
--- a/claims/views.py
+++ b/claims/views.py
@@ -24,7 +24,7 @@ from .forms import (
UserPermissionForm,
)
from .email_utils import notify_admin_of_claim, send_claimant_confirmation_email
-from .models import Claim, ClaimLog
+from .models import Claim, ClaimLog, Project
User = get_user_model()
@@ -161,6 +161,7 @@ class ClaimDashboardView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
context["can_change"] = self.request.user.has_perm("claims.change_claim")
context["payments_enabled"] = getattr(settings, "CLAIMS_ENABLE_INTERNAL_PAYMENTS", False)
context["summary"] = self._build_summary()
+ context["project_options"] = Project.objects.filter(is_active=True).order_by("name")
context["has_any_claims"] = context["summary"]["total_claims"] > 0
context["has_filtered_claims"] = self._has_filtered_claims(context["status_filter"], context["summary"])
context["recent_claims"] = (
@@ -196,6 +197,11 @@ class ClaimDashboardView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
return redirect(request.get_full_path())
previous_status = claim.status
claim.decision_note = decision_note
+ new_project = form.cleaned_data.get("project")
+ project_changed = False
+ if new_project is not None and new_project != claim.project:
+ claim.project = new_project
+ project_changed = True
if action == ClaimDecisionForm.ACTION_APPROVE:
claim.status = Claim.Status.APPROVED
@@ -204,7 +210,10 @@ class ClaimDashboardView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
claim.status = Claim.Status.REJECTED
messages.warning(request, _("%(claim)s markerades som nekad.") % {"claim": claim})
- claim.save(update_fields=["status", "decision_note", "updated_at"])
+ update_fields = ["status", "decision_note", "updated_at"]
+ if project_changed:
+ update_fields.append("project")
+ claim.save(update_fields=update_fields)
claim.add_log(
action=ClaimLog.Action.STATUS_CHANGED,
performed_by=request.user,
diff --git a/locale/en/LC_MESSAGES/django.mo b/locale/en/LC_MESSAGES/django.mo
index d97c1c8..1f2c5a6 100644
Binary files a/locale/en/LC_MESSAGES/django.mo and b/locale/en/LC_MESSAGES/django.mo differ
diff --git a/locale/en/LC_MESSAGES/django.po b/locale/en/LC_MESSAGES/django.po
index f373ee4..30d2986 100644
--- a/locale/en/LC_MESSAGES/django.po
+++ b/locale/en/LC_MESSAGES/django.po
@@ -2,7 +2,7 @@ msgid ""
msgstr ""
"Project-Id-Version: claims-system 0.1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2025-11-09 13:13+0100\n"
+"POT-Creation-Date: 2025-11-09 13:48+0100\n"
"PO-Revision-Date: 2025-11-08 23:40+0100\n"
"Last-Translator: ChatGPT \n"
"Language-Team: English\n"
@@ -16,7 +16,7 @@ msgstr ""
msgid "Namn"
msgstr "Name"
-#: claims/forms.py:23 claims/forms.py:86
+#: claims/forms.py:23 claims/forms.py:95
#: claims/templates/claims/dashboard.html:169
msgid "E-post"
msgstr "Email"
@@ -38,7 +38,8 @@ msgstr "Amount"
msgid "Valuta"
msgstr "Currency"
-#: claims/forms.py:52
+#: claims/forms.py:52 claims/forms.py:73
+#: claims/templates/claims/dashboard.html:264
msgid "Evenemang/Projekt"
msgstr "Project"
@@ -54,76 +55,76 @@ msgstr "Approve"
msgid "Neka"
msgstr "Reject"
-#: claims/forms.py:72 claims/templates/claims/dashboard.html:126
+#: claims/forms.py:81 claims/templates/claims/dashboard.html:126
#: claims/templates/claims/dashboard.html:261
msgid "Kommentar"
msgstr "Comment"
-#: claims/forms.py:80
+#: claims/forms.py:89
msgid "Kommentar krävs när du nekar ett utlägg."
msgstr "A comment is required when you reject an expense."
-#: claims/forms.py:85
+#: claims/forms.py:94
msgid "Användarnamn"
msgstr "Username"
-#: claims/forms.py:87
+#: claims/forms.py:96
msgid "Förnamn"
msgstr "First name"
-#: claims/forms.py:88
+#: claims/forms.py:97
msgid "Efternamn"
msgstr "Last name"
-#: claims/forms.py:89
+#: claims/forms.py:98
msgid "Lösenord"
msgstr "Password"
-#: claims/forms.py:90
+#: claims/forms.py:99
msgid "Bekräfta lösenord"
msgstr "Confirm password"
-#: claims/forms.py:91
+#: claims/forms.py:100
msgid "Administratör (staff)"
msgstr "Administrator (staff)"
-#: claims/forms.py:92
+#: claims/forms.py:101
msgid "Ge behörighet att se utlägg"
msgstr "Allow viewing claims"
-#: claims/forms.py:93
+#: claims/forms.py:102
msgid "Ge behörighet att besluta utlägg"
msgstr "Allow deciding claims"
-#: claims/forms.py:98
+#: claims/forms.py:107
msgid "Användarnamnet är upptaget."
msgstr "That username is already taken."
-#: claims/forms.py:104
+#: claims/forms.py:113
msgid "Lösenorden matchar inte."
msgstr "Passwords do not match."
-#: claims/forms.py:122 claims/templates/claims/user_management.html:116
+#: claims/forms.py:131 claims/templates/claims/user_management.html:116
msgid "Admin/staff"
msgstr "Admin/staff"
-#: claims/forms.py:123 claims/templates/claims/user_management.html:120
+#: claims/forms.py:132 claims/templates/claims/user_management.html:120
msgid "Får se utlägg"
msgstr "May view claims"
-#: claims/forms.py:124 claims/templates/claims/user_management.html:124
+#: claims/forms.py:133 claims/templates/claims/user_management.html:124
msgid "Får besluta utlägg"
msgstr "May decide claims"
-#: claims/models.py:29 claims/templates/claims/dashboard.html:325
+#: claims/models.py:29 claims/templates/claims/dashboard.html:334
msgid "Pending"
msgstr "Pending"
-#: claims/models.py:30 claims/templates/claims/dashboard.html:329
+#: claims/models.py:30 claims/templates/claims/dashboard.html:338
msgid "Approved"
msgstr "Approved"
-#: claims/models.py:31 claims/templates/claims/dashboard.html:333
+#: claims/models.py:31 claims/templates/claims/dashboard.html:342
msgid "Rejected"
msgstr "Rejected"
@@ -241,7 +242,9 @@ msgstr "Track inflow, decisions, and payouts – and act on claims immediately."
msgid ""
"Tips: använd filtren för att fokusera på specifika statusar eller projekt. "
"Dashboarden uppdateras i realtid när data ändras."
-msgstr "Tip: use the filters to focus on statuses or projects. The dashboard updates in real time."
+msgstr ""
+"Tip: use the filters to focus on statuses or projects. The dashboard updates "
+"in real time."
#: claims/templates/claims/dashboard.html:21
msgid "Totalt antal utlägg"
@@ -366,7 +369,9 @@ msgstr "Project"
msgid ""
"Använd referensen och beloppet när du lägger upp betalningen – hjälper att "
"undvika dubbletter."
-msgstr "Use the reference and amount when entering the payment – it helps avoid duplicates."
+msgstr ""
+"Use the reference and amount when entering the payment – it helps avoid "
+"duplicates."
#: claims/templates/claims/dashboard.html:182
msgid ""
@@ -434,43 +439,51 @@ msgid "Åtgärd"
msgstr "Action"
#: claims/templates/claims/dashboard.html:266
+msgid "Behåll nuvarande"
+msgstr "Keep current"
+
+#: claims/templates/claims/dashboard.html:271
+msgid "Justera projekt om underlaget skickats in mot fel evenemang."
+msgstr "Adjust the project if the submission was sent against the wrong event."
+
+#: claims/templates/claims/dashboard.html:275
msgid "Uppdatera beslut"
msgstr "Update decision"
-#: claims/templates/claims/dashboard.html:277
+#: claims/templates/claims/dashboard.html:286
#: claims/templates/claims/my_claims.html:78
msgid "Inga utlägg ännu"
msgstr "No claims yet"
-#: claims/templates/claims/dashboard.html:278
+#: claims/templates/claims/dashboard.html:287
msgid "När formuläret tas emot visas posterna automatiskt här."
msgstr "As soon as submissions arrive they will appear here."
-#: claims/templates/claims/dashboard.html:284
+#: claims/templates/claims/dashboard.html:293
msgid "Inga utlägg matchar filtret"
msgstr "No claims match the filter"
-#: claims/templates/claims/dashboard.html:285
+#: claims/templates/claims/dashboard.html:294
msgid "Välj en annan status för att se fler poster."
msgstr "Choose another status to see more entries."
-#: claims/templates/claims/dashboard.html:293
+#: claims/templates/claims/dashboard.html:302
msgid "Senaste inskick"
msgstr "Latest submissions"
-#: claims/templates/claims/dashboard.html:294
+#: claims/templates/claims/dashboard.html:303
msgid "Aktivitet"
msgstr "Activity"
-#: claims/templates/claims/dashboard.html:312
+#: claims/templates/claims/dashboard.html:321
msgid "Inga aktiviteter än."
msgstr "No activity yet."
-#: claims/templates/claims/dashboard.html:320
+#: claims/templates/claims/dashboard.html:329
msgid "Statusfördelning"
msgstr "Status breakdown"
-#: claims/templates/claims/dashboard.html:321
+#: claims/templates/claims/dashboard.html:330
msgid "Snabbstatistik"
msgstr "Quick stats"
@@ -827,87 +840,87 @@ msgstr ""
msgid "Kunde inte spara utläggen. Kontrollera formuläret."
msgstr ""
-#: claims/views.py:181 claims/views.py:222
+#: claims/views.py:182 claims/views.py:231
#, fuzzy
#| msgid "Ge behörighet att besluta utlägg"
msgid "Du har inte behörighet att uppdatera utlägg."
msgstr "Allow deciding claims"
-#: claims/views.py:195
+#: claims/views.py:196
#, fuzzy
#| msgid ""
#| "Utlägget är markerat som betalt. Ändringar av beslut/kommentar är låsta."
msgid "Utlägget är redan markerat som betalt och kan inte ändras."
msgstr "The claim is marked as paid. Decision/comments are locked."
-#: claims/views.py:202
+#: claims/views.py:208
#, python-format
msgid "%(claim)s markerades som godkänd."
msgstr ""
-#: claims/views.py:205
+#: claims/views.py:211
#, fuzzy, python-format
#| msgid "Ej markerad som betald"
msgid "%(claim)s markerades som nekad."
msgstr "Not marked as paid"
-#: claims/views.py:219
+#: claims/views.py:228
msgid "Betalningshantering är inte aktiverad."
msgstr ""
-#: claims/views.py:227
+#: claims/views.py:236
msgid "Endast godkända utlägg kan markeras som betalda."
msgstr ""
-#: claims/views.py:230
+#: claims/views.py:239
msgid "Detta utlägg är redan markerat som betalt."
msgstr ""
-#: claims/views.py:241
+#: claims/views.py:250
#, fuzzy, python-format
#| msgid "Ej markerad som betald"
msgid "%(claim)s markerades som betald."
msgstr "Not marked as paid"
-#: claims/views.py:307
+#: claims/views.py:316
msgid "Du saknar behörighet för åtgärden."
msgstr ""
-#: claims/views.py:354
+#: claims/views.py:363
#, python-format
msgid "Användaren %(user)s skapades."
msgstr ""
-#: claims/views.py:365
+#: claims/views.py:374
msgid "Du kan inte ta bort din egen staff-status."
msgstr ""
-#: claims/views.py:371
+#: claims/views.py:380
#, python-format
msgid "Behörigheter uppdaterades för %(user)s."
msgstr ""
-#: claims/views.py:373
+#: claims/views.py:382
#, fuzzy
#| msgid "Justera behörigheter"
msgid "Kunde inte uppdatera behörigheter."
msgstr "Adjust permissions"
-#: claims/views.py:383
+#: claims/views.py:392
msgid "Du kan inte ta bort ditt eget konto."
msgstr ""
-#: claims/views.py:385
+#: claims/views.py:394
msgid "Du kan inte ta bort en superuser via detta gränssnitt."
msgstr ""
-#: claims/views.py:388
+#: claims/views.py:397
#, fuzzy
#| msgid "Användare"
msgid "Användaren togs bort."
msgstr "Users"
-#: claims/views.py:391
+#: claims/views.py:400
msgid "Okänd åtgärd."
msgstr ""