Allow approvers to adjust project before approving
This commit is contained in:
@@ -67,6 +67,15 @@ class ClaimDecisionForm(forms.Form):
|
||||
|
||||
claim_id = forms.IntegerField(widget=forms.HiddenInput)
|
||||
action = forms.ChoiceField(choices=ACTION_CHOICES)
|
||||
project = forms.ModelChoiceField(
|
||||
queryset=Project.objects.none(),
|
||||
required=False,
|
||||
label=_("Evenemang/Projekt"),
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields["project"].queryset = Project.objects.filter(is_active=True).order_by("name")
|
||||
decision_note = forms.CharField(
|
||||
required=False,
|
||||
widget=forms.Textarea(attrs={"rows": 2, "placeholder": _("Kommentar")}),
|
||||
|
||||
@@ -258,11 +258,20 @@
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
||||
<label class="block text-sm font-medium text-gray-700">{% trans "Kommentar" %}</label>
|
||||
<textarea name="decision_note" rows="3" class="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm text-gray-900 focus:border-brand-600 focus:outline-none focus:ring-2 focus:ring-brand-600">{{ claim.decision_note }}</textarea>
|
||||
<label class="block text-sm font-medium text-gray-700">{% trans "Kommentar" %}</label>
|
||||
<textarea name="decision_note" rows="3" class="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm text-gray-900 focus:border-brand-600 focus:outline-none focus:ring-2 focus:ring-brand-600">{{ claim.decision_note }}</textarea>
|
||||
|
||||
<input type="hidden" name="action_type" value="decision">
|
||||
<button type="submit" class="w-full rounded-full bg-brand-600 px-4 py-2 text-sm font-semibold text-white transition hover:bg-brand-700">
|
||||
<label class="block text-sm font-medium text-gray-700">{% trans "Evenemang/Projekt" %}</label>
|
||||
<select name="project" class="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm text-gray-900 focus:border-brand-600 focus:outline-none focus:ring-2 focus:ring-brand-600">
|
||||
<option value="">{% trans "Behåll nuvarande" %}</option>
|
||||
{% for project in project_options %}
|
||||
<option value="{{ project.id }}"{% if claim.project and project.id == claim.project.id %} selected{% endif %}>{{ project }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<p class="text-xs text-gray-500">{% trans "Justera projekt om underlaget skickats in mot fel evenemang." %}</p>
|
||||
|
||||
<input type="hidden" name="action_type" value="decision">
|
||||
<button type="submit" class="w-full rounded-full bg-brand-600 px-4 py-2 text-sm font-semibold text-white transition hover:bg-brand-700">
|
||||
{% trans "Uppdatera beslut" %}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user