feat: harden dashboard editing and translations

This commit is contained in:
Victor Andersson
2025-11-11 20:27:41 +01:00
parent 559ed671f3
commit 2de32b2083
9 changed files with 1264 additions and 235 deletions

View File

@@ -58,30 +58,23 @@ class ClaimLineForm(forms.ModelForm):
class ClaimDecisionForm(forms.Form): class ClaimDecisionForm(forms.Form):
ACTION_PENDING = "pending"
ACTION_APPROVE = "approve" ACTION_APPROVE = "approve"
ACTION_REJECT = "reject" ACTION_REJECT = "reject"
ACTION_CHOICES = ( ACTION_CHOICES = (
(ACTION_APPROVE, _("Godkänn")), (ACTION_APPROVE, _("Godkänn")),
(ACTION_REJECT, _("Neka")), (ACTION_REJECT, _("Neka")),
(ACTION_PENDING, _("Pending")),
) )
claim_id = forms.IntegerField(widget=forms.HiddenInput) claim_id = forms.IntegerField(widget=forms.HiddenInput)
action = forms.ChoiceField(choices=ACTION_CHOICES) action = forms.ChoiceField(choices=ACTION_CHOICES)
project = forms.ModelChoiceField(
queryset=Project.objects.none(),
required=False,
label=_("Evenemang/Projekt"),
)
decision_note = forms.CharField( decision_note = forms.CharField(
required=False, required=False,
widget=forms.Textarea(attrs={"rows": 2, "placeholder": _("Kommentar")}), widget=forms.Textarea(attrs={"rows": 2, "placeholder": _("Kommentar")}),
) )
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["project"].queryset = Project.objects.filter(is_active=True).order_by("name")
def clean(self): def clean(self):
cleaned = super().clean() cleaned = super().clean()
action = cleaned.get("action") action = cleaned.get("action")

View File

@@ -91,5 +91,6 @@
{% endif %} {% endif %}
{% block content %}{% endblock %} {% block content %}{% endblock %}
</main> </main>
{% block modals %}{% endblock %}
</body> </body>
</html> </html>

View File

@@ -85,82 +85,6 @@
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
{% if can_change %}
<div class="fixed inset-0 z-40 hidden items-center justify-center bg-slate-900/80 p-4"
data-edit-panel="{{ claim.id }}"
data-edit-backdrop="{{ claim.id }}"
aria-hidden="true"
role="dialog"
aria-modal="true">
<div class="w-full max-w-2xl rounded-3xl bg-white p-6 text-left shadow-2xl">
<div class="flex items-center justify-between">
<div>
<p class="text-xs font-semibold uppercase tracking-wide text-gray-500">{% trans "Redigera utlägg" %}</p>
<h3 class="text-xl font-semibold text-gray-900">{{ claim.full_name }}</h3>
</div>
<button type="button"
class="rounded-full bg-gray-100 px-3 py-1 text-xs font-semibold text-gray-600 transition hover:bg-gray-200"
onclick="claimsCloseEdit('{{ claim.id }}'); return false;">
{% trans "Stäng" %}
</button>
</div>
<form method="post" class="mt-4 space-y-4">
{% csrf_token %}
<input type="hidden" name="action_type" value="edit">
<input type="hidden" name="edit_claim_id" value="{{ claim.id }}">
<div class="grid gap-4 md:grid-cols-2">
<label class="text-sm font-medium text-gray-700">
{% trans "Namn" %}
<input type="text" name="full_name" value="{{ claim.full_name }}" class="mt-1 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" required>
</label>
<label class="text-sm font-medium text-gray-700">
{% trans "E-post" %}
<input type="email" name="email" value="{{ claim.email }}" class="mt-1 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" required>
</label>
<label class="text-sm font-medium text-gray-700">
{% trans "Kontonummer" %}
<input type="text" name="account_number" value="{{ claim.account_number }}" class="mt-1 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" required>
</label>
<label class="text-sm font-medium text-gray-700">
{% trans "Belopp" %}
<input type="number" step="0.01" name="amount" value="{{ claim.amount }}" class="mt-1 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" required>
</label>
<label class="text-sm font-medium text-gray-700">
{% trans "Valuta" %}
<select name="currency" class="mt-1 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">
{% for value, label in currency_choices %}
<option value="{{ value }}"{% if claim.currency == value %} selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</label>
<label class="text-sm font-medium text-gray-700">
{% trans "Evenemang/Projekt" %}
<select name="project" class="mt-1 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 "Ingen" %}</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>
</label>
</div>
<div>
<label class="text-sm font-medium text-gray-700" for="edit-description-{{ claim.id }}">{% trans "Beskrivning" %}</label>
<textarea id="edit-description-{{ claim.id }}" name="description" rows="4" class="mt-1 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.description }}</textarea>
</div>
<div class="flex items-center justify-end gap-3">
<button type="button"
class="rounded-full border border-gray-300 px-4 py-2 text-sm font-semibold text-gray-600 transition hover:bg-gray-100"
onclick="claimsCloseEdit('{{ claim.id }}'); return false;">
{% trans "Avbryt" %}
</button>
<button type="submit" class="rounded-full bg-brand-600 px-4 py-2 text-sm font-semibold text-white transition hover:bg-brand-700">
{% trans "Spara ändringar" %}
</button>
</div>
</form>
</div>
</div>
{% endif %}
</section> </section>
<div class="space-y-6" data-claim-list> <div class="space-y-6" data-claim-list>
@@ -211,7 +135,7 @@
<span class="text-xs text-gray-500">{% trans "Ej markerad som betald" %}</span> <span class="text-xs text-gray-500">{% trans "Ej markerad som betald" %}</span>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if can_change %} {% if can_change and claim.status == 'pending' %}
<button type="button" <button type="button"
data-open-edit="{{ claim.id }}" data-open-edit="{{ claim.id }}"
class="rounded-full border border-gray-300 px-3 py-1 text-xs font-semibold text-gray-700 transition hover:bg-gray-100"> class="rounded-full border border-gray-300 px-3 py-1 text-xs font-semibold text-gray-700 transition hover:bg-gray-100">
@@ -344,15 +268,6 @@
<label class="block text-sm font-medium text-gray-700">{% trans "Kommentar" %}</label> <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> <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 "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"> <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"> <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" %} {% trans "Uppdatera beslut" %}
@@ -432,18 +347,33 @@
</section> </section>
<script> <script>
(function () { (function () {
function lockBodyScroll() {
document.body.classList.add("overflow-hidden");
}
function unlockBodyScrollIfNeeded() {
const anyOpen = Array.from(document.querySelectorAll("[data-edit-panel]")).some(
(panel) => !panel.classList.contains("hidden")
);
if (!anyOpen) {
document.body.classList.remove("overflow-hidden");
}
}
function openPanel(id) { function openPanel(id) {
const panel = document.querySelector(`[data-edit-panel="${id}"]`); const panel = document.querySelector(`[data-edit-panel="${id}"]`);
if (!panel) return; if (!panel) return;
panel.classList.remove("hidden"); panel.classList.remove("hidden");
panel.classList.add("flex"); panel.classList.add("flex");
panel.setAttribute("aria-hidden", "false"); panel.setAttribute("aria-hidden", "false");
lockBodyScroll();
} }
function closePanelElement(panel) { function closePanelElement(panel) {
panel.classList.add("hidden"); panel.classList.add("hidden");
panel.classList.remove("flex"); panel.classList.remove("flex");
panel.setAttribute("aria-hidden", "true"); panel.setAttribute("aria-hidden", "true");
unlockBodyScrollIfNeeded();
} }
document.addEventListener("click", (event) => { document.addEventListener("click", (event) => {
@@ -553,3 +483,87 @@
})(); })();
</script> </script>
{% endblock %} {% endblock %}
{% block modals %}
{{ block.super }}
{% if can_change %}
{% for claim in claims %}
{% if claim.status == 'pending' %}
<div class="fixed inset-0 z-40 hidden items-center justify-center bg-slate-900/80 p-4"
data-edit-panel="{{ claim.id }}"
data-edit-backdrop="{{ claim.id }}"
aria-hidden="true"
role="dialog"
aria-modal="true">
<div class="w-full max-w-2xl rounded-3xl bg-white p-6 text-left shadow-2xl">
<div class="flex items-center justify-between">
<div>
<p class="text-xs font-semibold uppercase tracking-wide text-gray-500">{% trans "Redigera utlägg" %}</p>
<h3 class="text-xl font-semibold text-gray-900">{{ claim.full_name }}</h3>
</div>
<button type="button"
data-close-edit
class="rounded-full bg-gray-100 px-3 py-1 text-xs font-semibold text-gray-600 transition hover:bg-gray-200">
{% trans "Stäng" %}
</button>
</div>
<form method="post" class="mt-4 space-y-4">
{% csrf_token %}
<input type="hidden" name="action_type" value="edit">
<input type="hidden" name="edit_claim_id" value="{{ claim.id }}">
<div class="grid gap-4 md:grid-cols-2">
<label class="text-sm font-medium text-gray-700">
{% trans "Namn" %}
<input type="text" name="full_name" value="{{ claim.full_name }}" class="mt-1 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" required>
</label>
<label class="text-sm font-medium text-gray-700">
{% trans "E-post" %}
<input type="email" name="email" value="{{ claim.email }}" class="mt-1 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" required>
</label>
<label class="text-sm font-medium text-gray-700">
{% trans "Kontonummer" %}
<input type="text" name="account_number" value="{{ claim.account_number }}" class="mt-1 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" required>
</label>
<label class="text-sm font-medium text-gray-700">
{% trans "Belopp" %}
<input type="number" step="0.01" name="amount" value="{{ claim.amount }}" class="mt-1 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" required>
</label>
<label class="text-sm font-medium text-gray-700">
{% trans "Valuta" %}
<select name="currency" class="mt-1 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">
{% for value, label in currency_choices %}
<option value="{{ value }}"{% if claim.currency == value %} selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</label>
<label class="text-sm font-medium text-gray-700">
{% trans "Evenemang/Projekt" %}
<select name="project" class="mt-1 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 "Ingen" %}</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>
</label>
</div>
<div>
<label class="text-sm font-medium text-gray-700" for="edit-description-{{ claim.id }}">{% trans "Beskrivning" %}</label>
<textarea id="edit-description-{{ claim.id }}" name="description" rows="4" class="mt-1 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.description }}</textarea>
</div>
<div class="flex items-center justify-end gap-3">
<button type="button"
data-close-edit
class="rounded-full border border-gray-300 px-4 py-2 text-sm font-semibold text-gray-600 transition hover:bg-gray-100">
{% trans "Avbryt" %}
</button>
<button type="submit" class="rounded-full bg-brand-600 px-4 py-2 text-sm font-semibold text-white transition hover:bg-brand-700">
{% trans "Spara ändringar" %}
</button>
</div>
</form>
</div>
</div>
{% endif %}
{% endfor %}
{% endif %}
{% endblock %}

View File

@@ -125,26 +125,26 @@ class DashboardViewTests(TestCase):
response = self.client.get(reverse("claims:admin-list") + "?status=approved") response = self.client.get(reverse("claims:admin-list") + "?status=approved")
self.assertFalse(response.context["has_filtered_claims"]) self.assertFalse(response.context["has_filtered_claims"])
def test_attester_can_update_project_when_deciding(self): def test_attester_can_reset_claim_to_pending(self):
project_old = Project.objects.create(name="Original", is_active=True) claim = self._create_claim(status=Claim.Status.APPROVED)
project_new = Project.objects.create(name="Corrected", is_active=True)
claim = self._create_claim(project=project_old)
response = self.client.post( response = self.client.post(
reverse("claims:admin-list"), reverse("claims:admin-list"),
{ {
"action_type": "decision", "action_type": "decision",
"claim_id": claim.id, "claim_id": claim.id,
"action": ClaimDecisionForm.ACTION_APPROVE, "action": ClaimDecisionForm.ACTION_PENDING,
"decision_note": "Updated project", "decision_note": "Behöver komplettering",
"project": project_new.id,
}, },
follow=True, follow=True,
) )
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
claim.refresh_from_db() claim.refresh_from_db()
self.assertEqual(claim.project, project_new) self.assertEqual(claim.status, Claim.Status.PENDING)
self.assertTrue(claim.logs.filter(action=ClaimLog.Action.PROJECT_CHANGED).exists()) log = claim.logs.filter(action=ClaimLog.Action.STATUS_CHANGED).first()
self.assertIsNotNone(log)
self.assertEqual(log.from_status, Claim.Status.APPROVED)
self.assertEqual(log.to_status, Claim.Status.PENDING)
def test_attester_can_edit_details(self): def test_attester_can_edit_details(self):
project = Project.objects.create(name="Event", is_active=True) project = Project.objects.create(name="Event", is_active=True)
@@ -174,3 +174,26 @@ class DashboardViewTests(TestCase):
edit_log = claim.logs.filter(action=ClaimLog.Action.DETAILS_EDITED).first() edit_log = claim.logs.filter(action=ClaimLog.Action.DETAILS_EDITED).first()
self.assertIsNotNone(edit_log) self.assertIsNotNone(edit_log)
self.assertIn("Namn", edit_log.note) self.assertIn("Namn", edit_log.note)
self.assertIn("Changed Name", edit_log.note)
def test_edit_blocked_for_non_pending_claims(self):
claim = self._create_claim(status=Claim.Status.APPROVED)
response = self.client.post(
reverse("claims:admin-list"),
{
"action_type": "edit",
"edit_claim_id": claim.id,
"full_name": "Blocked",
"email": "blocked@example.com",
"account_number": "456",
"amount": "200",
"currency": Claim.Currency.SEK,
"project": "",
"description": "Blocked edit",
},
follow=True,
)
self.assertEqual(response.status_code, 200)
claim.refresh_from_db()
self.assertNotEqual(claim.full_name, "Blocked")
self.assertFalse(claim.logs.filter(action=ClaimLog.Action.DETAILS_EDITED).exists())

View File

@@ -201,23 +201,26 @@ class ClaimDashboardView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
return redirect(request.get_full_path()) return redirect(request.get_full_path())
previous_status = claim.status previous_status = claim.status
claim.decision_note = decision_note 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: if action == ClaimDecisionForm.ACTION_APPROVE:
claim.status = Claim.Status.APPROVED target_status = Claim.Status.APPROVED
messages.success(request, _("%(claim)s markerades som godkänd.") % {"claim": claim}) feedback = messages.success
feedback_msg = _("%(claim)s markerades som godkänd.")
elif action == ClaimDecisionForm.ACTION_REJECT:
target_status = Claim.Status.REJECTED
feedback = messages.warning
feedback_msg = _("%(claim)s markerades som nekad.")
else: else:
claim.status = Claim.Status.REJECTED target_status = Claim.Status.PENDING
messages.warning(request, _("%(claim)s markerades som nekad.") % {"claim": claim}) feedback = messages.info
feedback_msg = _("%(claim)s återställdes till väntande status.")
update_fields = ["status", "decision_note", "updated_at"] status_changed = previous_status != target_status
if project_changed: update_fields = ["decision_note", "updated_at"]
update_fields.append("project") if status_changed:
claim.status = target_status
update_fields.append("status")
claim.save(update_fields=update_fields) claim.save(update_fields=update_fields)
feedback(request, feedback_msg % {"claim": claim})
claim.add_log( claim.add_log(
action=ClaimLog.Action.STATUS_CHANGED, action=ClaimLog.Action.STATUS_CHANGED,
performed_by=request.user, performed_by=request.user,
@@ -225,12 +228,6 @@ class ClaimDashboardView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
to_status=claim.status, to_status=claim.status,
note=decision_note, note=decision_note,
) )
if project_changed:
claim.add_log(
action=ClaimLog.Action.PROJECT_CHANGED,
performed_by=request.user,
note=_("Project updated during decision."),
)
return redirect(request.get_full_path()) return redirect(request.get_full_path())
def _handle_payment(self, request): def _handle_payment(self, request):
@@ -265,6 +262,12 @@ class ClaimDashboardView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
messages.error(request, _("Du har inte behörighet att uppdatera utlägg.")) messages.error(request, _("Du har inte behörighet att uppdatera utlägg."))
return redirect(request.get_full_path()) return redirect(request.get_full_path())
claim = get_object_or_404(Claim, pk=request.POST.get("edit_claim_id")) claim = get_object_or_404(Claim, pk=request.POST.get("edit_claim_id"))
if claim.status != Claim.Status.PENDING:
messages.error(request, _("Endast väntande utlägg kan redigeras via panelen."))
return redirect(request.get_full_path())
original_values = {}
for field in ClaimEditForm.Meta.fields:
original_values[field] = getattr(claim, field)
form = ClaimEditForm(request.POST, instance=claim) form = ClaimEditForm(request.POST, instance=claim)
if not form.is_valid(): if not form.is_valid():
for error in form.errors.get("__all__", []): for error in form.errors.get("__all__", []):
@@ -277,12 +280,19 @@ class ClaimDashboardView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
return redirect(request.get_full_path()) return redirect(request.get_full_path())
updated_claim = form.save() updated_claim = form.save()
changed_fields = [] def _format_value(value):
if value is None:
return "-"
return str(value)
change_notes = []
for field in form.changed_data: for field in form.changed_data:
label = form.fields[field].label or field label = form.fields[field].label or field
changed_fields.append(str(label)) old_value = _format_value(original_values.get(field))
if changed_fields: new_value = _format_value(getattr(updated_claim, field))
note = _("Fields updated: %(fields)s") % {"fields": ", ".join(changed_fields)} change_notes.append(f"{label}: {old_value}{new_value}")
if change_notes:
note = _("Följande fält uppdaterades: %(fields)s") % {"fields": "; ".join(change_notes)}
claim.add_log( claim.add_log(
action=ClaimLog.Action.DETAILS_EDITED, action=ClaimLog.Action.DETAILS_EDITED,
performed_by=request.user, performed_by=request.user,

Binary file not shown.

View File

@@ -2,7 +2,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: claims-system 0.1\n" "Project-Id-Version: claims-system 0.1\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-09 21:45+0100\n" "POT-Creation-Date: 2025-11-11 19:06+0000\n"
"PO-Revision-Date: 2025-11-08 23:40+0100\n" "PO-Revision-Date: 2025-11-08 23:40+0100\n"
"Last-Translator: ChatGPT <noreply@example.com>\n" "Last-Translator: ChatGPT <noreply@example.com>\n"
"Language-Team: English\n" "Language-Team: English\n"
@@ -12,43 +12,43 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: claims/forms.py:19 claims/forms.py:107 #: claims/forms.py:19 claims/forms.py:100
#: claims/templates/claims/dashboard.html:516
msgid "Namn" msgid "Namn"
msgstr "Name" msgstr "Name"
#: claims/forms.py:23 claims/forms.py:108 claims/forms.py:119 #: claims/forms.py:23 claims/forms.py:101 claims/forms.py:112
#: claims/templates/claims/dashboard.html:176 #: claims/templates/claims/dashboard.html:176
#: claims/templates/claims/dashboard.html:326 #: claims/templates/claims/dashboard.html:520
msgid "E-post" msgid "E-post"
msgstr "Email" msgstr "Email"
#: claims/forms.py:28 claims/forms.py:109 #: claims/forms.py:28 claims/forms.py:102
#: claims/templates/claims/dashboard.html:164 #: claims/templates/claims/dashboard.html:164
#: claims/templates/claims/dashboard.html:330 #: claims/templates/claims/dashboard.html:524
msgid "Kontonummer" msgid "Kontonummer"
msgstr "Account number" msgstr "Account number"
#: claims/forms.py:49 claims/forms.py:113 #: claims/forms.py:49 claims/forms.py:106
#: claims/templates/claims/dashboard.html:211 #: claims/templates/claims/dashboard.html:211
#: claims/templates/claims/dashboard.html:356 #: claims/templates/claims/dashboard.html:550
msgid "Beskrivning" msgid "Beskrivning"
msgstr "Description" msgstr "Description"
#: claims/forms.py:50 claims/forms.py:110 #: claims/forms.py:50 claims/forms.py:103
#: claims/templates/claims/dashboard.html:160 #: claims/templates/claims/dashboard.html:160
#: claims/templates/claims/dashboard.html:334 #: claims/templates/claims/dashboard.html:528
#: claims/templates/claims/my_claims.html:23 #: claims/templates/claims/my_claims.html:23
msgid "Belopp" msgid "Belopp"
msgstr "Amount" msgstr "Amount"
#: claims/forms.py:51 claims/forms.py:111 #: claims/forms.py:51 claims/forms.py:104
#: claims/templates/claims/dashboard.html:338 #: claims/templates/claims/dashboard.html:532
msgid "Valuta" msgid "Valuta"
msgstr "Currency" msgstr "Currency"
#: claims/forms.py:52 claims/forms.py:73 claims/forms.py:112 #: claims/forms.py:52 claims/forms.py:105
#: claims/templates/claims/dashboard.html:271 #: claims/templates/claims/dashboard.html:540
#: claims/templates/claims/dashboard.html:346
msgid "Evenemang/Projekt" msgid "Evenemang/Projekt"
msgstr "Project" msgstr "Project"
@@ -56,84 +56,85 @@ msgstr "Project"
msgid "Kvitto" msgid "Kvitto"
msgstr "Receipt" msgstr "Receipt"
#: claims/forms.py:64 #: claims/forms.py:65
msgid "Godkänn" msgid "Godkänn"
msgstr "Approve" msgstr "Approve"
#: claims/forms.py:65 #: claims/forms.py:66
msgid "Neka" msgid "Neka"
msgstr "Reject" msgstr "Reject"
#: claims/forms.py:78 claims/templates/claims/dashboard.html:126 #: claims/forms.py:67 claims/models.py:29
#: claims/templates/claims/dashboard.html:332
msgid "Pending"
msgstr "Pending"
#: claims/forms.py:75 claims/templates/claims/dashboard.html:126
#: claims/templates/claims/dashboard.html:268 #: claims/templates/claims/dashboard.html:268
msgid "Kommentar" msgid "Kommentar"
msgstr "Comment" msgstr "Comment"
#: claims/forms.py:90 #: claims/forms.py:83
msgid "Kommentar krävs när du nekar ett utlägg." msgid "Kommentar krävs när du nekar ett utlägg."
msgstr "A comment is required when you reject an expense." msgstr "A comment is required when you reject an expense."
#: claims/forms.py:118 #: claims/forms.py:111
msgid "Användarnamn" msgid "Användarnamn"
msgstr "Username" msgstr "Username"
#: claims/forms.py:120 #: claims/forms.py:113
msgid "Förnamn" msgid "Förnamn"
msgstr "First name" msgstr "First name"
#: claims/forms.py:121 #: claims/forms.py:114
msgid "Efternamn" msgid "Efternamn"
msgstr "Last name" msgstr "Last name"
#: claims/forms.py:122 #: claims/forms.py:115
msgid "Lösenord" msgid "Lösenord"
msgstr "Password" msgstr "Password"
#: claims/forms.py:123 #: claims/forms.py:116
msgid "Bekräfta lösenord" msgid "Bekräfta lösenord"
msgstr "Confirm password" msgstr "Confirm password"
#: claims/forms.py:124 #: claims/forms.py:117
msgid "Administratör (staff)" msgid "Administratör (staff)"
msgstr "Administrator (staff)" msgstr "Administrator (staff)"
#: claims/forms.py:125 #: claims/forms.py:118
msgid "Ge behörighet att se utlägg" msgid "Ge behörighet att se utlägg"
msgstr "Allow viewing claims" msgstr "Allow viewing claims"
#: claims/forms.py:126 #: claims/forms.py:119
msgid "Ge behörighet att besluta utlägg" msgid "Ge behörighet att besluta utlägg"
msgstr "Allow deciding claims" msgstr "Allow deciding claims"
#: claims/forms.py:131 #: claims/forms.py:124
msgid "Användarnamnet är upptaget." msgid "Användarnamnet är upptaget."
msgstr "That username is already taken." msgstr "That username is already taken."
#: claims/forms.py:137 #: claims/forms.py:130
msgid "Lösenorden matchar inte." msgid "Lösenorden matchar inte."
msgstr "Passwords do not match." msgstr "Passwords do not match."
#: claims/forms.py:155 claims/templates/claims/user_management.html:116 #: claims/forms.py:148 claims/templates/claims/user_management.html:116
msgid "Admin/staff" msgid "Admin/staff"
msgstr "Admin/staff" msgstr "Admin/staff"
#: claims/forms.py:156 claims/templates/claims/user_management.html:120 #: claims/forms.py:149 claims/templates/claims/user_management.html:120
msgid "Får se utlägg" msgid "Får se utlägg"
msgstr "May view claims" msgstr "May view claims"
#: claims/forms.py:157 claims/templates/claims/user_management.html:124 #: claims/forms.py:150 claims/templates/claims/user_management.html:124
msgid "Får besluta utlägg" msgid "Får besluta utlägg"
msgstr "May decide claims" msgstr "May decide claims"
#: claims/models.py:29 claims/templates/claims/dashboard.html:413 #: claims/models.py:30 claims/templates/claims/dashboard.html:336
msgid "Pending"
msgstr "Pending"
#: claims/models.py:30 claims/templates/claims/dashboard.html:417
msgid "Approved" msgid "Approved"
msgstr "Approved" msgstr "Approved"
#: claims/models.py:31 claims/templates/claims/dashboard.html:421 #: claims/models.py:31 claims/templates/claims/dashboard.html:340
msgid "Rejected" msgid "Rejected"
msgstr "Rejected" msgstr "Rejected"
@@ -458,78 +459,66 @@ msgid "Åtgärd"
msgstr "Action" msgstr "Action"
#: claims/templates/claims/dashboard.html:273 #: claims/templates/claims/dashboard.html:273
msgid "Behåll nuvarande"
msgstr "Keep current"
#: claims/templates/claims/dashboard.html:278
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:282
msgid "Uppdatera beslut" msgid "Uppdatera beslut"
msgstr "Update decision" msgstr "Update decision"
#: claims/templates/claims/dashboard.html:293 #: claims/templates/claims/dashboard.html:284
#: claims/templates/claims/my_claims.html:78 #: claims/templates/claims/my_claims.html:78
msgid "Inga utlägg ännu" msgid "Inga utlägg ännu"
msgstr "No claims yet" msgstr "No claims yet"
#: claims/templates/claims/dashboard.html:294 #: claims/templates/claims/dashboard.html:285
msgid "När formuläret tas emot visas posterna automatiskt här." msgid "När formuläret tas emot visas posterna automatiskt här."
msgstr "As soon as submissions arrive they will appear here." msgstr "As soon as submissions arrive they will appear here."
#: claims/templates/claims/dashboard.html:300 #: claims/templates/claims/dashboard.html:291
msgid "Inga utlägg matchar filtret" msgid "Inga utlägg matchar filtret"
msgstr "No claims match the filter" msgstr "No claims match the filter"
#: claims/templates/claims/dashboard.html:301 #: claims/templates/claims/dashboard.html:292
msgid "Välj en annan status för att se fler poster." msgid "Välj en annan status för att se fler poster."
msgstr "Choose another status to see more entries." msgstr "Choose another status to see more entries."
#: claims/templates/claims/dashboard.html:309 #: claims/templates/claims/dashboard.html:300
msgid "Redigera utlägg"
msgstr "Edit claim"
#: claims/templates/claims/dashboard.html:313
msgid "Stäng"
msgstr "Close"
#: claims/templates/claims/dashboard.html:348
msgid "Ingen"
msgstr "None"
#: claims/templates/claims/dashboard.html:361
msgid "Avbryt"
msgstr "Cancel"
#: claims/templates/claims/dashboard.html:364
msgid "Spara ändringar"
msgstr "Save changes"
#: claims/templates/claims/dashboard.html:370
msgid "Aktivera JavaScript för att kunna redigera uppgifter direkt här."
msgstr "Enable JavaScript to edit the information directly here."
#: claims/templates/claims/dashboard.html:381
msgid "Senaste inskick" msgid "Senaste inskick"
msgstr "Latest submissions" msgstr "Latest submissions"
#: claims/templates/claims/dashboard.html:382 #: claims/templates/claims/dashboard.html:301
msgid "Aktivitet" msgid "Aktivitet"
msgstr "Activity" msgstr "Activity"
#: claims/templates/claims/dashboard.html:400 #: claims/templates/claims/dashboard.html:319
msgid "Inga aktiviteter än." msgid "Inga aktiviteter än."
msgstr "No activity yet." msgstr "No activity yet."
#: claims/templates/claims/dashboard.html:408 #: claims/templates/claims/dashboard.html:327
msgid "Statusfördelning" msgid "Statusfördelning"
msgstr "Status breakdown" msgstr "Status breakdown"
#: claims/templates/claims/dashboard.html:409 #: claims/templates/claims/dashboard.html:328
msgid "Snabbstatistik" msgid "Snabbstatistik"
msgstr "Quick stats" msgstr "Quick stats"
#: claims/templates/claims/dashboard.html:501
msgid "Redigera utlägg"
msgstr "Edit claim"
#: claims/templates/claims/dashboard.html:507
msgid "Stäng"
msgstr "Close"
#: claims/templates/claims/dashboard.html:542
msgid "Ingen"
msgstr "None"
#: claims/templates/claims/dashboard.html:557
msgid "Avbryt"
msgstr "Cancel"
#: claims/templates/claims/dashboard.html:560
msgid "Spara ändringar"
msgstr "Save changes"
#: claims/templates/claims/export_placeholder.html:8 #: claims/templates/claims/export_placeholder.html:8
msgid "Export till redovisningssystem" msgid "Export till redovisningssystem"
msgstr "Export to bookkeeping system" msgstr "Export to bookkeeping system"
@@ -883,102 +872,104 @@ msgstr ""
msgid "Kunde inte spara utläggen. Kontrollera formuläret." msgid "Kunde inte spara utläggen. Kontrollera formuläret."
msgstr "" msgstr ""
#: claims/views.py:186 claims/views.py:241 claims/views.py:265 #: claims/views.py:186 claims/views.py:238 claims/views.py:262
#, fuzzy #, fuzzy
#| msgid "Ge behörighet att besluta utlägg" #| msgid "Ge behörighet att besluta utlägg"
msgid "Du har inte behörighet att uppdatera utlägg." msgid "Du har inte behörighet att uppdatera utlägg."
msgstr "Allow deciding claims" msgstr "Allow deciding claims"
#: claims/views.py:200 #: claims/views.py:200
#, 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." msgid "Utlägget är redan markerat som betalt och kan inte ändras."
msgstr "The claim is marked as paid. Decision/comments are locked." msgstr "This claim is already marked as paid and cannot be changed."
#: claims/views.py:212 #: claims/views.py:207
#, python-format #, python-format
msgid "%(claim)s markerades som godkänd." msgid "%(claim)s markerades som godkänd."
msgstr "%(claim)s was marked as approved." msgstr "%(claim)s was marked as approved."
#: claims/views.py:215 #: claims/views.py:211
#, python-format #, python-format
msgid "%(claim)s markerades som nekad." msgid "%(claim)s markerades som nekad."
msgstr "%(claim)s was marked as rejected." msgstr "%(claim)s was marked as rejected."
#: claims/views.py:232 #: claims/views.py:215
msgid "Project updated during decision." #, python-format
msgstr "Project updated during decision." msgid "%(claim)s återställdes till väntande status."
msgstr "%(claim)s was reset to pending status."
#: claims/views.py:238 #: claims/views.py:235
msgid "Betalningshantering är inte aktiverad." msgid "Betalningshantering är inte aktiverad."
msgstr "Payment handling is not enabled." msgstr "Payment handling is not enabled."
#: claims/views.py:246 #: claims/views.py:243
msgid "Endast godkända utlägg kan markeras som betalda." msgid "Endast godkända utlägg kan markeras som betalda."
msgstr "Only approved claims can be marked as paid." msgstr "Only approved claims can be marked as paid."
#: claims/views.py:249 #: claims/views.py:246
msgid "Detta utlägg är redan markerat som betalt." msgid "Detta utlägg är redan markerat som betalt."
msgstr "This claim is already marked as paid." msgstr "This claim is already marked as paid."
#: claims/views.py:260 #: claims/views.py:257
#, python-format #, python-format
msgid "%(claim)s markerades som betald." msgid "%(claim)s markerades som betald."
msgstr "%(claim)s was marked as paid." msgstr "%(claim)s was marked as paid."
#: claims/views.py:287 #: claims/views.py:266
#, python-format msgid "Endast väntande utlägg kan redigeras via panelen."
msgid "Fields updated: %(fields)s" msgstr "Only pending claims can be edited via the panel."
msgstr "Fields updated: %(fields)s"
#: claims/views.py:293 #: claims/views.py:295
#, python-format
msgid "Följande fält uppdaterades: %(fields)s"
msgstr "The following fields were updated: %(fields)s"
#: claims/views.py:301
msgid "Informationen uppdaterades." msgid "Informationen uppdaterades."
msgstr "Information updated." msgstr "Information updated."
#: claims/views.py:295 #: claims/views.py:303
msgid "Inga förändringar att spara." msgid "Inga förändringar att spara."
msgstr "No changes to save." msgstr "No changes to save."
#: claims/views.py:361 #: claims/views.py:369
msgid "Du saknar behörighet för åtgärden." msgid "Du saknar behörighet för åtgärden."
msgstr "You do not have permission to perform this action." msgstr "You do not have permission to perform this action."
#: claims/views.py:408 #: claims/views.py:416
#, python-format #, python-format
msgid "Användaren %(user)s skapades." msgid "Användaren %(user)s skapades."
msgstr "" msgstr ""
#: claims/views.py:419 #: claims/views.py:427
msgid "Du kan inte ta bort din egen staff-status." msgid "Du kan inte ta bort din egen staff-status."
msgstr "" msgstr ""
#: claims/views.py:425 #: claims/views.py:433
#, python-format #, python-format
msgid "Behörigheter uppdaterades för %(user)s." msgid "Behörigheter uppdaterades för %(user)s."
msgstr "" msgstr ""
#: claims/views.py:427 #: claims/views.py:435
#, fuzzy #, fuzzy
#| msgid "Justera behörigheter" #| msgid "Justera behörigheter"
msgid "Kunde inte uppdatera behörigheter." msgid "Kunde inte uppdatera behörigheter."
msgstr "Adjust permissions" msgstr "Adjust permissions"
#: claims/views.py:437 #: claims/views.py:445
msgid "Du kan inte ta bort ditt eget konto." msgid "Du kan inte ta bort ditt eget konto."
msgstr "" msgstr ""
#: claims/views.py:439 #: claims/views.py:447
msgid "Du kan inte ta bort en superuser via detta gränssnitt." msgid "Du kan inte ta bort en superuser via detta gränssnitt."
msgstr "" msgstr ""
#: claims/views.py:442 #: claims/views.py:450
#, fuzzy #, fuzzy
#| msgid "Användare" #| msgid "Användare"
msgid "Användaren togs bort." msgid "Användaren togs bort."
msgstr "Users" msgstr "Users"
#: claims/views.py:445 #: claims/views.py:453
msgid "Okänd åtgärd." msgid "Okänd åtgärd."
msgstr "" msgstr ""
@@ -1028,6 +1019,19 @@ msgstr "Use your admin credentials to manage claims."
msgid "Behöver du ett konto? Kontakta en superuser i organisationen." msgid "Behöver du ett konto? Kontakta en superuser i organisationen."
msgstr "Need an account? Contact a superuser in your organization." msgstr "Need an account? Contact a superuser in your organization."
#~ msgid "Behåll nuvarande"
#~ msgstr "Keep current"
#~ msgid "Justera projekt om underlaget skickats in mot fel evenemang."
#~ msgstr ""
#~ "Adjust the project if the submission was sent against the wrong event."
#~ msgid "Aktivera JavaScript för att kunna redigera uppgifter direkt här."
#~ msgstr "Enable JavaScript to edit the information directly here."
#~ msgid "Project updated during decision."
#~ msgstr "Project updated during decision."
#~ msgid "Admin Utlägg" #~ msgid "Admin Utlägg"
#~ msgstr "Admin Claims" #~ msgstr "Admin Claims"

Binary file not shown.

View File

@@ -0,0 +1,984 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 19:06+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: claims/forms.py:19 claims/forms.py:100
#: claims/templates/claims/dashboard.html:516
msgid "Namn"
msgstr ""
#: claims/forms.py:23 claims/forms.py:101 claims/forms.py:112
#: claims/templates/claims/dashboard.html:176
#: claims/templates/claims/dashboard.html:520
msgid "E-post"
msgstr ""
#: claims/forms.py:28 claims/forms.py:102
#: claims/templates/claims/dashboard.html:164
#: claims/templates/claims/dashboard.html:524
msgid "Kontonummer"
msgstr ""
#: claims/forms.py:49 claims/forms.py:106
#: claims/templates/claims/dashboard.html:211
#: claims/templates/claims/dashboard.html:550
msgid "Beskrivning"
msgstr ""
#: claims/forms.py:50 claims/forms.py:103
#: claims/templates/claims/dashboard.html:160
#: claims/templates/claims/dashboard.html:528
#: claims/templates/claims/my_claims.html:23
msgid "Belopp"
msgstr ""
#: claims/forms.py:51 claims/forms.py:104
#: claims/templates/claims/dashboard.html:532
msgid "Valuta"
msgstr ""
#: claims/forms.py:52 claims/forms.py:105
#: claims/templates/claims/dashboard.html:540
msgid "Evenemang/Projekt"
msgstr ""
#: claims/forms.py:53 claims/templates/claims/my_claims.html:44
msgid "Kvitto"
msgstr ""
#: claims/forms.py:65
msgid "Godkänn"
msgstr "Godkänn"
#: claims/forms.py:66
msgid "Neka"
msgstr "Neka"
#: claims/forms.py:67 claims/models.py:29
#: claims/templates/claims/dashboard.html:332
msgid "Pending"
msgstr "Väntande"
#: claims/forms.py:75 claims/templates/claims/dashboard.html:126
#: claims/templates/claims/dashboard.html:268
msgid "Kommentar"
msgstr ""
#: claims/forms.py:83
msgid "Kommentar krävs när du nekar ett utlägg."
msgstr ""
#: claims/forms.py:111
msgid "Användarnamn"
msgstr ""
#: claims/forms.py:113
msgid "Förnamn"
msgstr ""
#: claims/forms.py:114
msgid "Efternamn"
msgstr ""
#: claims/forms.py:115
msgid "Lösenord"
msgstr ""
#: claims/forms.py:116
msgid "Bekräfta lösenord"
msgstr ""
#: claims/forms.py:117
msgid "Administratör (staff)"
msgstr ""
#: claims/forms.py:118
msgid "Ge behörighet att se utlägg"
msgstr ""
#: claims/forms.py:119
msgid "Ge behörighet att besluta utlägg"
msgstr ""
#: claims/forms.py:124
msgid "Användarnamnet är upptaget."
msgstr ""
#: claims/forms.py:130
msgid "Lösenorden matchar inte."
msgstr ""
#: claims/forms.py:148 claims/templates/claims/user_management.html:116
msgid "Admin/staff"
msgstr ""
#: claims/forms.py:149 claims/templates/claims/user_management.html:120
msgid "Får se utlägg"
msgstr ""
#: claims/forms.py:150 claims/templates/claims/user_management.html:124
msgid "Får besluta utlägg"
msgstr ""
#: claims/models.py:30 claims/templates/claims/dashboard.html:336
msgid "Approved"
msgstr "Godkänd"
#: claims/models.py:31 claims/templates/claims/dashboard.html:340
msgid "Rejected"
msgstr "Nekad"
#: claims/models.py:34
msgid "Swedish krona (SEK)"
msgstr ""
#: claims/models.py:35
msgid "Euro (EUR)"
msgstr ""
#: claims/models.py:36
msgid "US dollar (USD)"
msgstr ""
#: claims/models.py:37
msgid "British pound (GBP)"
msgstr ""
#: claims/models.py:54
msgid "Describe what the reimbursement is for"
msgstr ""
#: claims/models.py:122
msgid "Submitted"
msgstr ""
#: claims/models.py:123
msgid "Status changed"
msgstr ""
#: claims/models.py:124
msgid "Marked as paid"
msgstr ""
#: claims/models.py:125
msgid "Project changed"
msgstr ""
#: claims/models.py:126
msgid "Details edited"
msgstr ""
#: claims/templates/claims/base.html:8
msgid "Claims"
msgstr ""
#: claims/templates/claims/base.html:29
msgid "claims-system"
msgstr ""
#: claims/templates/claims/base.html:32
#: claims/templates/claims/submit_claim.html:4
msgid "Skicka utlägg"
msgstr ""
#: claims/templates/claims/base.html:37
msgid "Interna vyer"
msgstr ""
#: claims/templates/claims/base.html:43
msgid "Dashboard"
msgstr ""
#: claims/templates/claims/base.html:44
#: claims/templates/claims/my_claims.html:4
#: claims/templates/claims/my_claims.html:10
msgid "Mina utlägg"
msgstr ""
#: claims/templates/claims/base.html:46
msgid "Användare"
msgstr ""
#: claims/templates/claims/base.html:48
#: claims/templates/claims/export_placeholder.html:5
msgid "Export"
msgstr ""
#: claims/templates/claims/base.html:50
msgid "Django admin"
msgstr ""
#: claims/templates/claims/base.html:58
msgid "Språk"
msgstr ""
#: claims/templates/claims/base.html:69
msgid "Inloggad som"
msgstr ""
#: claims/templates/claims/base.html:73
msgid "Logga ut"
msgstr ""
#: claims/templates/claims/base.html:77
#: claims/templates/claims/submit_success.html:22
#: templates/registration/login.html:4 templates/registration/login.html:11
#: templates/registration/login.html:43
msgid "Logga in"
msgstr ""
#: claims/templates/claims/dashboard.html:4
msgid "Admin Dashboard"
msgstr ""
#: claims/templates/claims/dashboard.html:10
#: claims/templates/claims/my_claims.html:9
msgid "Översikt"
msgstr ""
#: claims/templates/claims/dashboard.html:11
msgid "Dashboard för utlägg"
msgstr ""
#: claims/templates/claims/dashboard.html:12
msgid ""
"Få koll på inflödet, beslutsläget och utbetalningar och hantera ärenden "
"direkt."
msgstr ""
#: claims/templates/claims/dashboard.html:15
msgid ""
"Tips: använd filtren för att fokusera på specifika statusar eller projekt. "
"Dashboarden uppdateras i realtid när data ändras."
msgstr ""
#: claims/templates/claims/dashboard.html:21
msgid "Totalt antal utlägg"
msgstr ""
#: claims/templates/claims/dashboard.html:23
msgid "Alla statusar"
msgstr ""
#: claims/templates/claims/dashboard.html:26
msgid "Senaste 7 dagarna"
msgstr ""
#: claims/templates/claims/dashboard.html:28
msgid "Nya inskick sedan en vecka"
msgstr ""
#: claims/templates/claims/dashboard.html:31
msgid "Pågående granskning"
msgstr ""
#: claims/templates/claims/dashboard.html:33
msgid "Behöver beslut"
msgstr ""
#: claims/templates/claims/dashboard.html:36
msgid "Redo för utbetalning"
msgstr ""
#: claims/templates/claims/dashboard.html:38
msgid "Godkända men ej markerade som betalda"
msgstr ""
#: claims/templates/claims/dashboard.html:44
msgid "Belopp att besluta"
msgstr ""
#: claims/templates/claims/dashboard.html:46
msgid "Summa av väntande utlägg (alla valutor)"
msgstr ""
#: claims/templates/claims/dashboard.html:49
msgid "Godkända belopp"
msgstr ""
#: claims/templates/claims/dashboard.html:51
msgid "Summa för alla godkända utlägg"
msgstr ""
#: claims/templates/claims/dashboard.html:54
msgid "Utbetalda belopp"
msgstr ""
#: claims/templates/claims/dashboard.html:56
msgid "Markerade som betalda"
msgstr ""
#: claims/templates/claims/dashboard.html:65
msgid "Filtrera"
msgstr ""
#: claims/templates/claims/dashboard.html:66
msgid "Hantera utlägg"
msgstr ""
#: claims/templates/claims/dashboard.html:67
msgid "Välj status för att fokusera listan nedan."
msgstr ""
#: claims/templates/claims/dashboard.html:75
msgid "Alla"
msgstr ""
#: claims/templates/claims/dashboard.html:106
#: claims/templates/claims/dashboard.html:172
msgid "Skapad"
msgstr ""
#: claims/templates/claims/dashboard.html:109
msgid "Person"
msgstr ""
#: claims/templates/claims/dashboard.html:112
msgid "Konto"
msgstr ""
#: claims/templates/claims/dashboard.html:114
msgid "Inloggad användare"
msgstr ""
#: claims/templates/claims/dashboard.html:116
msgid "Inskickad av gäst"
msgstr ""
#: claims/templates/claims/dashboard.html:131
#: claims/templates/claims/my_claims.html:33
msgid "Betald"
msgstr ""
#: claims/templates/claims/dashboard.html:132
msgid "av"
msgstr ""
#: claims/templates/claims/dashboard.html:135
msgid "Ej markerad som betald"
msgstr ""
#: claims/templates/claims/dashboard.html:142
msgid "Redigera"
msgstr ""
#: claims/templates/claims/dashboard.html:152
msgid "Utbetalningsdetaljer"
msgstr ""
#: claims/templates/claims/dashboard.html:168
msgid "Referens (Claim ID)"
msgstr ""
#: claims/templates/claims/dashboard.html:180
#: claims/templates/claims/my_claims.html:24
msgid "Projekt"
msgstr ""
#: claims/templates/claims/dashboard.html:184
msgid ""
"Använd referensen och beloppet när du lägger upp betalningen hjälper att "
"undvika dubbletter."
msgstr ""
#: claims/templates/claims/dashboard.html:189
msgid ""
"Är du säker på att du har lagt upp betalningen? Markera endast som betald om "
"beloppet skickas till banken."
msgstr ""
#: claims/templates/claims/dashboard.html:194
msgid "Markera som betald"
msgstr ""
#: claims/templates/claims/dashboard.html:197
msgid "Dubbelkolla belopp och kontonummer i panelen innan du bekräftar."
msgstr ""
#: claims/templates/claims/dashboard.html:202
msgid ""
"Intern betalningshantering är av markera betalning i ekonomisystemet och "
"resetta status vid behov."
msgstr ""
#: claims/templates/claims/dashboard.html:219
msgid "Visa kvitto"
msgstr ""
#: claims/templates/claims/dashboard.html:222
msgid "Inget kvitto bifogat"
msgstr ""
#: claims/templates/claims/dashboard.html:224
msgid "Senast uppdaterad"
msgstr ""
#: claims/templates/claims/dashboard.html:229
msgid "Logg"
msgstr ""
#: claims/templates/claims/dashboard.html:236
#: claims/templates/claims/my_claims.html:62
msgid "Status"
msgstr ""
#: claims/templates/claims/dashboard.html:242
msgid "Av"
msgstr ""
#: claims/templates/claims/dashboard.html:246
#: claims/templates/claims/my_claims.html:69
msgid "Ingen logg än."
msgstr ""
#: claims/templates/claims/dashboard.html:254
msgid ""
"Utlägget är markerat som betalt. Ändringar av beslut/kommentar är låsta."
msgstr ""
#: claims/templates/claims/dashboard.html:261
msgid "Åtgärd"
msgstr ""
#: claims/templates/claims/dashboard.html:273
msgid "Uppdatera beslut"
msgstr ""
#: claims/templates/claims/dashboard.html:284
#: claims/templates/claims/my_claims.html:78
msgid "Inga utlägg ännu"
msgstr ""
#: claims/templates/claims/dashboard.html:285
msgid "När formuläret tas emot visas posterna automatiskt här."
msgstr ""
#: claims/templates/claims/dashboard.html:291
msgid "Inga utlägg matchar filtret"
msgstr ""
#: claims/templates/claims/dashboard.html:292
msgid "Välj en annan status för att se fler poster."
msgstr ""
#: claims/templates/claims/dashboard.html:300
msgid "Senaste inskick"
msgstr ""
#: claims/templates/claims/dashboard.html:301
msgid "Aktivitet"
msgstr ""
#: claims/templates/claims/dashboard.html:319
msgid "Inga aktiviteter än."
msgstr ""
#: claims/templates/claims/dashboard.html:327
msgid "Statusfördelning"
msgstr ""
#: claims/templates/claims/dashboard.html:328
msgid "Snabbstatistik"
msgstr ""
#: claims/templates/claims/dashboard.html:501
msgid "Redigera utlägg"
msgstr ""
#: claims/templates/claims/dashboard.html:507
msgid "Stäng"
msgstr ""
#: claims/templates/claims/dashboard.html:542
msgid "Ingen"
msgstr ""
#: claims/templates/claims/dashboard.html:557
msgid "Avbryt"
msgstr ""
#: claims/templates/claims/dashboard.html:560
msgid "Spara ändringar"
msgstr ""
#: claims/templates/claims/export_placeholder.html:8
msgid "Export till redovisningssystem"
msgstr ""
#: claims/templates/claims/export_placeholder.html:9
msgid "Detta är ett framtida steg. Här kommer du att kunna:"
msgstr ""
#: claims/templates/claims/export_placeholder.html:11
msgid "Välja tidsperiod eller status"
msgstr ""
#: claims/templates/claims/export_placeholder.html:12
msgid "Exportera till t.ex. bankfil eller SIE"
msgstr ""
#: claims/templates/claims/export_placeholder.html:13
msgid "Skicka data via API till externa system"
msgstr ""
#: claims/templates/claims/export_placeholder.html:15
msgid "Planerade åtgärder:"
msgstr ""
#: claims/templates/claims/export_placeholder.html:17
msgid "Definiera format"
msgstr ""
#: claims/templates/claims/export_placeholder.html:18
msgid "Implementera exportkommando/API"
msgstr ""
#: claims/templates/claims/export_placeholder.html:19
msgid "Bygga integrationsinställningar"
msgstr ""
#: claims/templates/claims/export_placeholder.html:21
msgid ""
"Tills vidare kan du ladda ner data via Django admin eller med ett enkelt SQL-"
"utdrag."
msgstr ""
#: claims/templates/claims/includes/claim_formset.html:7
msgid "Steg 2"
msgstr ""
#: claims/templates/claims/includes/claim_formset.html:8
msgid "Utläggsrader"
msgstr ""
#: claims/templates/claims/includes/claim_formset.html:9
msgid ""
"Lägg till ett block per kvitto eller kostnad. Projektväljaren hjälper "
"ekonomin att bokföra rätt."
msgstr ""
#: claims/templates/claims/includes/claim_formset.html:13
#, python-format
msgid "Totalt <span data-current-count>%(current_forms)s</span> rader"
msgstr ""
#: claims/templates/claims/includes/claim_formset.html:22
msgid "justera"
msgstr ""
#: claims/templates/claims/includes/claim_formset.html:36
#, python-format
msgid "Utlägg %(forloop.counter)s"
msgstr ""
#: claims/templates/claims/includes/claim_formset.html:37
#: claims/templates/claims/includes/claim_formset.html:120
msgid "Obligatoriska fält markeras med *"
msgstr ""
#: claims/templates/claims/includes/claim_formset.html:76
#: claims/templates/claims/includes/claim_formset.html:150
msgid "Avancerat: justera valuta (standard SEK)"
msgstr ""
#: claims/templates/claims/includes/claim_formset.html:86
#: claims/templates/claims/includes/claim_formset.html:157
msgid "Använd detta om kvittot är i annan valuta än svenska kronor."
msgstr ""
#: claims/templates/claims/includes/claim_formset.html:105
msgid ""
"När du skickar in skickas du vidare mot adminvyn. Saknar du inloggning får "
"du möjlighet att logga in."
msgstr ""
#: claims/templates/claims/includes/claim_formset.html:108
msgid "Skicka in utlägg"
msgstr ""
#: claims/templates/claims/includes/claim_formset.html:119
msgid "Ny utläggsrad"
msgstr ""
#: claims/templates/claims/includes/claim_formset.html:164
msgid "PDF, JPG eller PNG max 10 MB."
msgstr ""
#: claims/templates/claims/my_claims.html:11
msgid "Här ser du status för de utlägg du skickat in när du varit inloggad."
msgstr ""
#: claims/templates/claims/my_claims.html:20
msgid "Skickad"
msgstr ""
#: claims/templates/claims/my_claims.html:21
#: claims/templates/claims/submit_claim.html:9
msgid "Utlägg"
msgstr ""
#: claims/templates/claims/my_claims.html:40
msgid "Detaljer"
msgstr ""
#: claims/templates/claims/my_claims.html:47
msgid "Visa fil"
msgstr ""
#: claims/templates/claims/my_claims.html:50
msgid "Inget kvitto bifogat."
msgstr ""
#: claims/templates/claims/my_claims.html:55
msgid "Visa logg"
msgstr ""
#: claims/templates/claims/my_claims.html:79
msgid ""
"Du har inte skickat in några utlägg ännu eller så gjordes de utan inloggning."
msgstr ""
#: claims/templates/claims/submit_claim.html:10
msgid "Skicka in dina kostnader"
msgstr ""
#: claims/templates/claims/submit_claim.html:18
msgid "Steg 1"
msgstr ""
#: claims/templates/claims/submit_claim.html:19
msgid "Dina uppgifter"
msgstr ""
#: claims/templates/claims/submit_claim.html:20
msgid ""
"Vi återkommer via dessa kontaktuppgifter och använder kontonumret för "
"utbetalning."
msgstr ""
#: claims/templates/claims/submit_success.html:5
msgid "Tack för ditt utlägg"
msgstr ""
#: claims/templates/claims/submit_success.html:10
msgid "Tack!"
msgstr ""
#: claims/templates/claims/submit_success.html:11
msgid "Utlägget är skickat"
msgstr ""
#: claims/templates/claims/submit_success.html:13
msgid ""
"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."
msgstr ""
#: claims/templates/claims/submit_success.html:18
msgid "Skicka nytt utlägg"
msgstr ""
#: claims/templates/claims/user_management.html:4
msgid "Användarhantering"
msgstr ""
#: claims/templates/claims/user_management.html:9
msgid "Konton & behörigheter"
msgstr ""
#: claims/templates/claims/user_management.html:10
msgid "Hantera användare"
msgstr ""
#: claims/templates/claims/user_management.html:12
msgid ""
"Skapa nya konton, justera rättigheter för claim-flödet och ta bort användare "
"som inte längre ska ha åtkomst."
msgstr ""
#: claims/templates/claims/user_management.html:15
msgid ""
"Notis: denna sida styr direkta behörigheter. Rättigheter via grupper eller "
"superuser-status gäller även om kryssrutorna avmarkeras."
msgstr ""
#: claims/templates/claims/user_management.html:22
msgid "Nytt konto"
msgstr ""
#: claims/templates/claims/user_management.html:23
#: claims/templates/claims/user_management.html:53
msgid "Skapa användare"
msgstr ""
#: claims/templates/claims/user_management.html:24
msgid "Lösenordet valideras mot Djangos standardregler."
msgstr ""
#: claims/templates/claims/user_management.html:59
msgid "Tips för kontohantering"
msgstr ""
#: claims/templates/claims/user_management.html:63
msgid ""
"Lägg användare i grupper via Django admin om flera personer ska dela samma "
"roll."
msgstr ""
#: claims/templates/claims/user_management.html:68
msgid ""
"Behörigheterna <code class=\"break-normal rounded bg-slate-800 px-2 py-1 "
"text-xs\">claims.view_claim</code>\n"
" och <code class=\"break-normal rounded bg-slate-800 "
"px-2 py-1 text-xs\">claims.change_claim</code>\n"
" styr åtkomst till adminvyn respektive beslutsflödet."
msgstr ""
#: claims/templates/claims/user_management.html:75
msgid ""
"En markerad Admin/staff-användare kan nå Django admin och skapa projekt, "
"exportflöden m.m."
msgstr ""
#: claims/templates/claims/user_management.html:79
msgid ""
"Ta bara bort konton du är säker på historik försvinner inte, men personen "
"tappar all åtkomst."
msgstr ""
#: claims/templates/claims/user_management.html:87
msgid "Befintliga användare"
msgstr ""
#: claims/templates/claims/user_management.html:88
msgid "Justera behörigheter"
msgstr ""
#: claims/templates/claims/user_management.html:99
msgid "Superuser"
msgstr ""
#: claims/templates/claims/user_management.html:103
msgid "Saknar namn"
msgstr ""
#: claims/templates/claims/user_management.html:103
msgid "Ingen e-post"
msgstr ""
#: claims/templates/claims/user_management.html:128
msgid "Spara behörigheter"
msgstr ""
#: claims/templates/claims/user_management.html:132
msgid "Ta bort konto"
msgstr ""
#: claims/templates/claims/user_management.html:134
msgid "Åtgärden går inte att ångra. Användaren förlorar omedelbart åtkomst."
msgstr ""
#: claims/templates/claims/user_management.html:135
#, python-format
msgid "Ta bort %(user.username)s?"
msgstr ""
#: claims/templates/claims/user_management.html:140
msgid "Ta bort användare"
msgstr ""
#: claims/templates/claims/user_management.html:144
msgid "Kan inte tas bort (antingen du själv eller superuser)."
msgstr ""
#: claims/templates/claims/user_management.html:152
msgid "Inga användare upplagda."
msgstr ""
#: claims/templates/claims/user_management.html:153
msgid "Skapa det första kontot via formuläret ovan."
msgstr ""
#: claims/validators.py:87
#, python-format
msgid "Kvitton får vara max %(size)s MB."
msgstr ""
#: claims/validators.py:96
#, python-format
msgid "Otillåtet filformat. Tillåtna format är %(formats)s."
msgstr ""
#: claims/validators.py:105
#, python-format
msgid "Otillåten MIME-typ: %(type)s."
msgstr ""
#: claims/validators.py:113
msgid "Filens innehåll matchar inte förväntat format."
msgstr ""
#: claims/views.py:127
#, python-brace-format
msgid "{} utlägg skickade in."
msgstr ""
#: claims/views.py:130
msgid "Inga utlägg kunde sparas. Fyll i minst en rad."
msgstr ""
#: claims/views.py:132
msgid "Kunde inte spara utläggen. Kontrollera formuläret."
msgstr ""
#: claims/views.py:186 claims/views.py:238 claims/views.py:262
msgid "Du har inte behörighet att uppdatera utlägg."
msgstr ""
#: claims/views.py:200
msgid "Utlägget är redan markerat som betalt och kan inte ändras."
msgstr ""
#: claims/views.py:207
#, python-format
msgid "%(claim)s markerades som godkänd."
msgstr ""
#: claims/views.py:211
#, python-format
msgid "%(claim)s markerades som nekad."
msgstr ""
#: claims/views.py:215
#, python-format
msgid "%(claim)s återställdes till väntande status."
msgstr ""
#: claims/views.py:235
msgid "Betalningshantering är inte aktiverad."
msgstr ""
#: claims/views.py:243
msgid "Endast godkända utlägg kan markeras som betalda."
msgstr ""
#: claims/views.py:246
msgid "Detta utlägg är redan markerat som betalt."
msgstr "Detta utlägg är redan markerat som betalt."
#: claims/views.py:257
#, python-format
msgid "%(claim)s markerades som betald."
msgstr "%(claim)s markerades som betald."
#: claims/views.py:266
msgid "Endast väntande utlägg kan redigeras via panelen."
msgstr "Endast väntande utlägg kan redigeras via panelen."
#: claims/views.py:295
#, python-format
msgid "Följande fält uppdaterades: %(fields)s"
msgstr "Följande fält uppdaterades: %(fields)s"
#: claims/views.py:301
msgid "Informationen uppdaterades."
msgstr "Informationen uppdaterades."
#: claims/views.py:303
msgid "Inga förändringar att spara."
msgstr "Inga förändringar att spara."
#: claims/views.py:369
msgid "Du saknar behörighet för åtgärden."
msgstr "Du saknar behörighet för åtgärden."
#: claims/views.py:416
#, python-format
msgid "Användaren %(user)s skapades."
msgstr ""
#: claims/views.py:427
msgid "Du kan inte ta bort din egen staff-status."
msgstr ""
#: claims/views.py:433
#, python-format
msgid "Behörigheter uppdaterades för %(user)s."
msgstr ""
#: claims/views.py:435
msgid "Kunde inte uppdatera behörigheter."
msgstr ""
#: claims/views.py:445
msgid "Du kan inte ta bort ditt eget konto."
msgstr ""
#: claims/views.py:447
msgid "Du kan inte ta bort en superuser via detta gränssnitt."
msgstr ""
#: claims/views.py:450
msgid "Användaren togs bort."
msgstr ""
#: claims/views.py:453
msgid "Okänd åtgärd."
msgstr ""
#: claims_system/settings.py:114
msgid "Swedish"
msgstr ""
#: claims_system/settings.py:115
msgid "English"
msgstr ""
#: templates/registration/logged_out.html:4
msgid "Utloggad"
msgstr ""
#: templates/registration/logged_out.html:9
msgid "Du är utloggad"
msgstr ""
#: templates/registration/logged_out.html:10
msgid "Vi ses snart igen"
msgstr ""
#: templates/registration/logged_out.html:12
msgid ""
"Din session är avslutad. Du kan när som helst logga in igen för att hantera "
"utlägg eller administrera systemet."
msgstr ""
#: templates/registration/logged_out.html:16
msgid "Till inloggningen"
msgstr ""
#: templates/registration/login.html:10
msgid "Välkommen tillbaka"
msgstr ""
#: templates/registration/login.html:12
msgid "Använd dina administratörsuppgifter för att hantera utlägg."
msgstr ""
#: templates/registration/login.html:46
msgid "Behöver du ett konto? Kontakta en superuser i organisationen."
msgstr ""