129 lines
5.5 KiB
Python
129 lines
5.5 KiB
Python
from django import forms
|
|
from django.contrib.auth import get_user_model, password_validation
|
|
from django.core.exceptions import ValidationError
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
from .models import Claim, Project
|
|
|
|
User = get_user_model()
|
|
|
|
INPUT_CLASSES = "mt-1 block w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 shadow-sm focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500"
|
|
TEXTAREA_CLASSES = "mt-1 block w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 shadow-sm focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500"
|
|
SELECT_CLASSES = "mt-1 block w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 shadow-sm focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500"
|
|
FILE_CLASSES = "mt-1 block w-full text-sm text-gray-700 file:mr-4 file:rounded-md file:border-0 file:bg-indigo-600 file:px-4 file:py-2 file:text-sm file:font-medium file:text-white hover:file:bg-indigo-500"
|
|
|
|
|
|
class ClaimantForm(forms.Form):
|
|
full_name = forms.CharField(
|
|
max_length=255,
|
|
label=_("Namn"),
|
|
widget=forms.TextInput(attrs={"class": INPUT_CLASSES}),
|
|
)
|
|
email = forms.EmailField(
|
|
label=_("E-post"),
|
|
widget=forms.EmailInput(attrs={"class": INPUT_CLASSES}),
|
|
)
|
|
account_number = forms.CharField(
|
|
max_length=50,
|
|
label=_("Kontonummer"),
|
|
widget=forms.TextInput(attrs={"class": INPUT_CLASSES}),
|
|
)
|
|
|
|
|
|
class ClaimLineForm(forms.ModelForm):
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
if not self.is_bound:
|
|
self.fields["currency"].initial = Claim.Currency.SEK
|
|
self.fields["project"].queryset = Project.objects.filter(is_active=True).order_by("name")
|
|
self.fields["project"].required = False
|
|
self.fields["project"].widget.attrs.update({"class": SELECT_CLASSES})
|
|
self.fields["currency"].widget.attrs.update({"class": SELECT_CLASSES})
|
|
self.fields["amount"].widget.attrs.update({"class": INPUT_CLASSES})
|
|
self.fields["receipt"].widget.attrs.update({"class": FILE_CLASSES})
|
|
|
|
class Meta:
|
|
model = Claim
|
|
fields = ["description", "amount", "currency", "project", "receipt"]
|
|
labels = {
|
|
"description": _("Beskrivning"),
|
|
"amount": _("Belopp"),
|
|
"currency": _("Valuta"),
|
|
"project": _("Evenemang/Projekt"),
|
|
"receipt": _("Kvitto"),
|
|
}
|
|
widgets = {
|
|
"description": forms.Textarea(attrs={"rows": 3, "class": TEXTAREA_CLASSES}),
|
|
}
|
|
|
|
|
|
class ClaimDecisionForm(forms.Form):
|
|
ACTION_APPROVE = "approve"
|
|
ACTION_REJECT = "reject"
|
|
ACTION_CHOICES = (
|
|
(ACTION_APPROVE, _("Godkänn")),
|
|
(ACTION_REJECT, _("Neka")),
|
|
)
|
|
|
|
claim_id = forms.IntegerField(widget=forms.HiddenInput)
|
|
action = forms.ChoiceField(choices=ACTION_CHOICES)
|
|
decision_note = forms.CharField(
|
|
required=False,
|
|
widget=forms.Textarea(attrs={"rows": 2, "placeholder": _("Kommentar")}),
|
|
)
|
|
|
|
def clean(self):
|
|
cleaned = super().clean()
|
|
action = cleaned.get("action")
|
|
note = cleaned.get("decision_note", "").strip()
|
|
if action == self.ACTION_REJECT and not note:
|
|
self.add_error("decision_note", _("Kommentar krävs när du nekar ett utlägg."))
|
|
return cleaned
|
|
|
|
|
|
class UserManagementForm(forms.Form):
|
|
username = forms.CharField(max_length=150, label=_("Användarnamn"))
|
|
email = forms.EmailField(required=False, label=_("E-post"))
|
|
first_name = forms.CharField(max_length=150, required=False, label=_("Förnamn"))
|
|
last_name = forms.CharField(max_length=150, required=False, label=_("Efternamn"))
|
|
password1 = forms.CharField(widget=forms.PasswordInput, label=_("Lösenord"))
|
|
password2 = forms.CharField(widget=forms.PasswordInput, label=_("Bekräfta lösenord"))
|
|
is_staff = forms.BooleanField(required=False, initial=True, label=_("Administratör (staff)"))
|
|
grant_view = forms.BooleanField(required=False, initial=True, label=_("Ge behörighet att se utlägg"))
|
|
grant_change = forms.BooleanField(required=False, initial=True, label=_("Ge behörighet att besluta utlägg"))
|
|
|
|
def clean_username(self):
|
|
username = self.cleaned_data["username"]
|
|
if User.objects.filter(username=username).exists():
|
|
raise forms.ValidationError(_("Användarnamnet är upptaget."))
|
|
return username
|
|
|
|
def clean(self):
|
|
cleaned = super().clean()
|
|
if cleaned.get("password1") != cleaned.get("password2"):
|
|
self.add_error("password2", _("Lösenorden matchar inte."))
|
|
password = cleaned.get("password1")
|
|
if password:
|
|
temp_user = User(
|
|
username=cleaned.get("username", ""),
|
|
email=cleaned.get("email", ""),
|
|
first_name=cleaned.get("first_name", ""),
|
|
last_name=cleaned.get("last_name", ""),
|
|
)
|
|
try:
|
|
password_validation.validate_password(password, temp_user)
|
|
except ValidationError as exc:
|
|
self.add_error("password1", exc)
|
|
return cleaned
|
|
|
|
|
|
class UserPermissionForm(forms.Form):
|
|
user_id = forms.IntegerField(widget=forms.HiddenInput)
|
|
is_staff = forms.BooleanField(required=False, label=_("Admin/staff"))
|
|
grant_view = forms.BooleanField(required=False, label=_("Får se utlägg"))
|
|
grant_change = forms.BooleanField(required=False, label=_("Får besluta utlägg"))
|
|
|
|
|
|
class DeleteUserForm(forms.Form):
|
|
user_id = forms.IntegerField(widget=forms.HiddenInput)
|