72 lines
3.3 KiB
Python
72 lines
3.3 KiB
Python
from django import forms
|
|
from django.utils import timezone
|
|
|
|
from apps.projects.models import Project, ProjectMember
|
|
|
|
from .models import Task
|
|
|
|
|
|
class TaskForm(forms.ModelForm):
|
|
duration_hours = forms.IntegerField(label="Часы", min_value=0, initial=0)
|
|
duration_minutes_input = forms.IntegerField(label="Минуты", min_value=0, max_value=59, initial=0)
|
|
|
|
class Meta:
|
|
model = Task
|
|
fields = ("project", "assignee", "title", "description", "work_date", "status")
|
|
widgets = {
|
|
"work_date": forms.DateInput(format="%Y-%m-%d", attrs={"type": "date"}),
|
|
"description": forms.Textarea(attrs={"rows": 4}),
|
|
}
|
|
|
|
def __init__(self, *args, user, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.user = user
|
|
self.order_fields((
|
|
"project", "assignee", "title", "description", "work_date",
|
|
"duration_hours", "duration_minutes_input", "status",
|
|
))
|
|
if self.instance.pk:
|
|
hours, minutes = divmod(self.instance.duration_minutes, 60)
|
|
self.fields["duration_hours"].initial = hours
|
|
self.fields["duration_minutes_input"].initial = minutes
|
|
elif not self.is_bound:
|
|
self.fields["work_date"].initial = timezone.localdate()
|
|
active_memberships = ProjectMember.objects.filter(is_active=True, project__is_active=True, project__company__is_active=True)
|
|
if user.is_app_admin:
|
|
self.fields["project"].queryset = Project.objects.filter(is_active=True, company__is_active=True)
|
|
self.fields["assignee"].queryset = user.__class__.objects.filter(is_active=True, project_memberships__in=active_memberships).distinct()
|
|
else:
|
|
self.fields["project"].queryset = Project.objects.filter(memberships__user=user, memberships__is_active=True, is_active=True, company__is_active=True)
|
|
self.fields["assignee"].queryset = user.__class__.objects.filter(pk=user.pk)
|
|
self.fields["assignee"].initial = user
|
|
self.fields["assignee"].widget = forms.HiddenInput()
|
|
if self.instance.pk:
|
|
self.fields["project"].disabled = True
|
|
|
|
def clean(self):
|
|
cleaned = super().clean()
|
|
project = cleaned.get("project")
|
|
assignee = cleaned.get("assignee")
|
|
if not self.user.is_app_admin:
|
|
assignee = self.user
|
|
cleaned["assignee"] = self.user
|
|
if project and assignee and not ProjectMember.objects.filter(project=project, user=assignee, is_active=True).exists():
|
|
self.add_error("assignee", "Пользователь не является активным участником проекта.")
|
|
hours = cleaned.get("duration_hours")
|
|
minutes = cleaned.get("duration_minutes_input")
|
|
if hours is not None and minutes is not None:
|
|
total = hours * 60 + minutes
|
|
if total <= 0:
|
|
self.add_error("duration_minutes_input", "Укажите продолжительность больше нуля.")
|
|
else:
|
|
cleaned["duration_minutes"] = total
|
|
return cleaned
|
|
|
|
def save(self, commit=True):
|
|
task = super().save(commit=False)
|
|
task.duration_minutes = self.cleaned_data["duration_minutes"]
|
|
if commit:
|
|
task.save()
|
|
self.save_m2m()
|
|
return task
|