Files
ihrm/pms/forms.py

684 lines
23 KiB
Python
Raw Normal View History

2023-08-01 16:48:48 +05:30
"""
forms.py
This module is used to register the forms for pms models
"""
2023-12-01 15:36:51 +05:30
from typing import Any
2023-05-10 15:06:57 +05:30
import uuid
2023-08-01 16:48:48 +05:30
from django import forms
2023-09-09 14:10:09 +05:30
from django.core.exceptions import ValidationError
2023-12-01 15:36:51 +05:30
from django.core.files.base import File
from django.db.models.base import Model
from django.forms.utils import ErrorList
2023-05-10 15:06:57 +05:30
from django.utils.translation import gettext_lazy as _
2023-08-01 16:48:48 +05:30
from employee.models import Department, JobPosition
from django.forms import ModelForm
2023-08-01 16:48:48 +05:30
from pms.models import (
Question,
EmployeeObjective,
EmployeeKeyResult,
Feedback,
Period,
Comment,
QuestionOptions,
Employee,
QuestionTemplate,
)
2023-12-01 15:36:51 +05:30
from base.methods import reload_queryset
2023-05-10 15:06:57 +05:30
def validate_date(start_date, end_date):
2023-09-09 14:10:09 +05:30
"""
Validates that the start date is before or equal to the end date.
"""
2023-05-10 15:06:57 +05:30
if start_date and end_date and start_date > end_date:
2023-08-01 16:48:48 +05:30
raise forms.ValidationError("The start date must be before the end date.")
2023-05-10 15:06:57 +05:30
def set_date_field_initial(instance):
2023-08-01 16:48:48 +05:30
"""this is used to update change the date value format"""
2023-05-10 15:06:57 +05:30
initial = {}
if instance.start_date is not None:
2023-08-01 16:48:48 +05:30
initial["start_date"] = instance.start_date.strftime("%Y-%m-%d")
2023-05-10 15:06:57 +05:30
if instance.end_date is not None:
2023-08-01 16:48:48 +05:30
initial["end_date"] = instance.end_date.strftime("%Y-%m-%d")
2023-05-10 15:06:57 +05:30
return initial
2023-12-01 15:36:51 +05:30
class ObjectiveForm(ModelForm):
2023-05-10 15:06:57 +05:30
"""
A form to create or update instances of the EmployeeObjective model.
"""
2023-08-01 16:48:48 +05:30
2023-05-10 15:06:57 +05:30
OBJECTIVE_TYPES = (
2023-08-01 16:48:48 +05:30
("none", "----------"),
("individual", _("Individual")),
("job_position", _("Job position")),
("department", _("Department")),
2023-05-10 15:06:57 +05:30
)
2023-08-01 16:48:48 +05:30
objective_type = forms.ChoiceField(
choices=OBJECTIVE_TYPES,
widget=forms.Select(
attrs={
"class": " oh-input-objective-type-choices oh-input",
"style": "width:100%",
}
),
required=False,
)
department = forms.ModelChoiceField(
queryset=Department.objects.all(),
widget=forms.Select(
attrs={
"class": "oh-select oh-select--lg oh-select-no-search w-100 oh-input-objective-type-choices",
"style": "width:100%; display:none;",
}
),
required=False,
)
job_position = forms.ModelChoiceField(
queryset=JobPosition.objects.all(),
widget=forms.Select(
attrs={
"class": "oh-select oh-select--lg oh-select-no-search w-100 oh-input-objective-type-choices",
"style": "width:100%; display:none;",
}
),
required=False,
)
period = forms.ModelChoiceField(
queryset=Period.objects.all(),
empty_label="",
widget=forms.Select(
attrs={
"class": " oh-select--period-change",
"style": "width:100%; display:none;",
}
),
required=False,
)
employee_id = forms.ModelChoiceField(
queryset=Employee.objects.filter(is_active=True),
2023-08-01 16:48:48 +05:30
widget=forms.Select(
attrs={
"class": "oh-select oh-select-2 ",
"style": "width:100%; display:none;",
}
),
required=False,
)
2023-05-10 15:06:57 +05:30
class Meta:
2023-09-09 14:10:09 +05:30
"""
A nested class that specifies the model,fields and style of fields for the form.
"""
2023-05-10 15:06:57 +05:30
model = EmployeeObjective
2023-08-01 16:48:48 +05:30
exclude = ["status"]
2023-05-10 15:06:57 +05:30
widgets = {
2023-08-01 16:48:48 +05:30
"objective": forms.TextInput(
2023-09-09 14:10:09 +05:30
attrs={
"class": "oh-input oh-input--block",
"placeholder": _("Objective"),
}
2023-08-01 16:48:48 +05:30
),
"objective_description": forms.Textarea(
attrs={
"class": "oh-input oh-input--textarea oh-input--block",
2023-08-07 13:02:24 +05:30
"placeholder": _("Objective description goes here."),
2023-08-01 16:48:48 +05:30
"rows": 3,
"cols": 40,
}
),
"start_date": forms.DateInput(
attrs={"class": "oh-input w-100", "type": "date"}
),
"end_date": forms.DateInput(
attrs={"class": "oh-input w-100", "type": "date"}
),
2023-05-10 15:06:57 +05:30
}
def __init__(self, *args, **kwargs):
"""
Constructor for ObjectiveForm. If an instance is provided, set initial values for date fields
"""
2023-08-01 16:48:48 +05:30
if instance := kwargs.get("instance"):
kwargs["initial"] = set_date_field_initial(instance)
2023-05-10 15:06:57 +05:30
2023-08-01 16:48:48 +05:30
employee = kwargs.pop(
"employee", None
) # access the logged-in user's information
2023-12-01 15:36:51 +05:30
super().__init__(*args, **kwargs)
reload_queryset(self.fields)
self.fields["period"].choices = list(self.fields["period"].choices)
2023-12-01 15:36:51 +05:30
self.fields["period"].choices.append(("create_new_period", "Create new period"))
2023-08-01 16:48:48 +05:30
if employee and Employee.objects.filter(
is_active=True, employee_work_info__reporting_manager_id=employee
2023-08-01 16:48:48 +05:30
):
# manager level access
department = employee.employee_work_info.department_id
employees = Employee.objects.filter(
is_active=True, employee_work_info__department_id=department
2023-08-01 16:48:48 +05:30
)
self.fields["employee_id"].queryset = employees
self.fields["department"].queryset = Department.objects.filter(
id=department.id
)
self.fields["job_position"].queryset = department.job_position.all()
2023-05-10 15:06:57 +05:30
# Set unique IDs for employee_id fields to prevent conflicts with other forms on the same page
2023-08-01 16:48:48 +05:30
self.fields["employee_id"].widget.attrs.update({"id": str(uuid.uuid4())})
2023-05-10 15:06:57 +05:30
def clean(self):
"""
Validates form fields and raises a validation error if any fields are invalid
"""
cleaned_data = super().clean()
2023-08-01 16:48:48 +05:30
start_date = cleaned_data.get("start_date")
end_date = cleaned_data.get("end_date")
2023-05-10 15:06:57 +05:30
objective_type = cleaned_data.get("objective_type")
department = cleaned_data.get("department")
job_position = cleaned_data.get("job_position")
employee_id = cleaned_data.get("employee_id")
2023-08-01 16:48:48 +05:30
2023-05-10 15:06:57 +05:30
# Check that start date is before end date
validate_date(start_date, end_date)
# Check that employee ID is provided for individual objective type
if objective_type == "individual" and not employee_id:
2023-08-01 16:48:48 +05:30
self.add_error(
"employee_id",
"Employee field is required for individual objective type.",
)
2023-05-10 15:06:57 +05:30
# Check that job position is provided for job position objective type
if objective_type == "job_position" and not job_position:
2023-08-01 16:48:48 +05:30
self.add_error(
"job_position",
"Job position field is required for job position objective type.",
)
2023-05-10 15:06:57 +05:30
# Check that department is provided for department objective type
if objective_type == "department" and not department:
2023-08-01 16:48:48 +05:30
self.add_error(
"department",
"Department field is required for department objective type.",
)
2023-05-10 15:06:57 +05:30
# Check that an objective type is selected
if objective_type == "none":
self.add_error("objective_type", "Please fill the objective type.")
2023-08-01 16:48:48 +05:30
2023-05-10 15:06:57 +05:30
return cleaned_data
2023-08-01 16:48:48 +05:30
2023-12-01 15:36:51 +05:30
class KeyResultForm(ModelForm):
2023-05-10 15:06:57 +05:30
"""
A form used for creating and updating EmployeeKeyResult objects.
Includes fields for title, description, current value, target value,
start date, end date, progress type, and the associated period and employee.
Excludes fields for status, progress_boolean, progress_integer,
employee_objective_id, and start value.
"""
2023-08-01 16:48:48 +05:30
period = forms.ModelChoiceField(
queryset=Period.objects.all(),
empty_label="",
widget=forms.Select(attrs={"style": "width:100%; display:none;"}),
required=False,
)
2023-05-10 15:06:57 +05:30
class Meta:
2023-09-09 14:10:09 +05:30
"""
A nested class that specifies the model,fields and exclude fields for the form.
"""
2023-05-10 15:06:57 +05:30
model = EmployeeKeyResult
2023-08-01 16:48:48 +05:30
fields = "__all__"
exclude = [
"status",
"progress_boolean",
"progress_integer",
"employee_objective_id",
"start_value",
]
2023-05-10 15:06:57 +05:30
widgets = {
2023-08-01 16:48:48 +05:30
"key_result": forms.TextInput(
attrs={
2023-08-07 13:02:24 +05:30
"placeholder": _("Enter a title"),
2023-08-01 16:48:48 +05:30
"class": "oh-input w-100",
"required": True,
}
),
"key_result_description": forms.Textarea(
attrs={
2023-08-07 13:02:24 +05:30
"placeholder": _("Enter a description"),
2023-08-01 16:48:48 +05:30
"class": "oh-input oh-input--textarea w-100",
"required": True,
"rows": 3,
"cols": 40,
}
),
"employee_id": forms.Select(
attrs={
"class": "oh-select oh-select-2 select2-hidden-accessible",
"style": "display:none;",
}
),
"current_value": forms.NumberInput(
attrs={"class": "oh-input w-100", "required": True}
),
"target_value": forms.NumberInput(
attrs={"class": "oh-input w-100", "required": True}
),
"start_date": forms.DateInput(
attrs={"type": "date", "class": "oh-input w-100", "required": True}
),
"end_date": forms.DateInput(
attrs={"type": "date", "class": "oh-input w-100", "required": True}
),
"progress_type": forms.Select(
attrs={
"class": "oh-select oh-select--lg oh-select-no-search w-100",
"required": True,
}
),
2023-05-10 15:06:57 +05:30
}
2023-08-01 16:48:48 +05:30
2023-05-10 15:06:57 +05:30
def __init__(self, *args, **kwargs):
2023-08-01 16:48:48 +05:30
instance = kwargs.get("instance")
2023-05-10 15:06:57 +05:30
if instance:
2023-08-01 16:48:48 +05:30
kwargs["initial"] = set_date_field_initial(instance)
employee = kwargs.pop(
"employee", None
) # access the logged-in user's information
2023-05-10 15:06:57 +05:30
super().__init__(*args, **kwargs)
2023-12-01 15:36:51 +05:30
reload_queryset(self.fields)
2023-08-01 16:48:48 +05:30
employees = Employee.objects.filter(
is_active=True, employee_work_info__reporting_manager_id=employee
2023-08-01 16:48:48 +05:30
)
2023-05-10 15:06:57 +05:30
if employee and employees:
2023-08-01 16:48:48 +05:30
# manager level access
self.fields["employee_id"].queryset = employees
2023-05-10 15:06:57 +05:30
# Set unique IDs for employee_id fields to prevent conflicts with other forms on the same page
2023-08-01 16:48:48 +05:30
self.fields["employee_id"].widget.attrs.update({"id": str(uuid.uuid4())})
2023-05-10 15:06:57 +05:30
def clean_value(self, value_type):
2023-09-09 14:10:09 +05:30
"""
Validate the 'current_value' and 'target_value' field of model EmployeeKeyResult.
"""
2023-05-10 15:06:57 +05:30
value = self.cleaned_data.get(value_type)
2023-08-01 16:48:48 +05:30
other_value = self.cleaned_data.get(
"current_value" if value_type == "target_value" else "target_value"
)
if (
value is not None
and other_value is not None
and value_type == "current_value"
and value > other_value
):
raise forms.ValidationError(
"Current value cannot be greater than target value"
)
elif (
value is not None
and other_value is not None
and value_type == "target_value"
and value < other_value
):
raise forms.ValidationError(
"Target value cannot be less than current value"
)
2023-05-10 15:06:57 +05:30
return value
2023-08-01 16:48:48 +05:30
2023-05-10 15:06:57 +05:30
def clean(self):
cleaned_data = super().clean()
2023-08-01 16:48:48 +05:30
employee_objective_id = self.initial.get("employee_objective_id")
start_date = cleaned_data.get("start_date")
end_date = cleaned_data.get("end_date")
target_value = cleaned_data.get("target_value")
current_value = cleaned_data.get("current_value")
2023-08-01 16:48:48 +05:30
validate_date(start_date, end_date)
# date comparing with objective start and end date
2023-05-10 15:06:57 +05:30
if employee_objective_id and start_date and end_date:
if start_date < employee_objective_id.start_date:
2023-08-01 16:48:48 +05:30
raise ValidationError("Start date should be after Objective start date")
2023-05-10 15:06:57 +05:30
if end_date > employee_objective_id.end_date:
2023-08-01 16:48:48 +05:30
raise ValidationError("End date should be below Objective end date")
2023-05-10 15:06:57 +05:30
else:
2023-08-01 16:48:48 +05:30
raise forms.ValidationError("Employee Objective not found")
# target value and current value comparison
if target_value <= 0:
raise ValidationError("Target value should be greater than zero")
if current_value > target_value:
raise forms.ValidationError(
"Current value cannot be greater than target value"
)
2023-05-10 15:06:57 +05:30
return cleaned_data
2023-08-01 16:48:48 +05:30
2023-12-01 15:36:51 +05:30
class FeedbackForm(ModelForm):
2023-05-10 15:06:57 +05:30
"""
A form used for creating and updating Feedback objects.
"""
2023-08-01 16:48:48 +05:30
period = forms.ModelChoiceField(
queryset=Period.objects.all(),
empty_label="",
widget=forms.Select(
attrs={
"class": " oh-select--period-change ",
"style": "width:100%; display:none;",
}
),
required=False,
)
2023-05-10 15:06:57 +05:30
class Meta:
2023-09-09 14:10:09 +05:30
"""
A nested class that specifies the model,fields and exclude fields for the form.
"""
2023-05-10 15:06:57 +05:30
model = Feedback
2023-08-01 16:48:48 +05:30
fields = "__all__"
exclude = ["status", "archive"]
2023-05-10 15:06:57 +05:30
widgets = {
2023-08-01 16:48:48 +05:30
"review_cycle": forms.TextInput(
2023-08-07 13:02:24 +05:30
attrs={"placeholder": _("Enter a title"), "class": "oh-input w-100"}
2023-08-01 16:48:48 +05:30
),
"start_date": forms.DateInput(
attrs={"type": "date", "class": "oh-input w-100"}
),
"end_date": forms.DateInput(
attrs={"type": "date", "class": "oh-input w-100"}
),
"employee_id": forms.Select(
attrs={
"class": " oh-select--employee-change",
"style": "width:100%; display:none;",
"required": "false",
2023-08-01 16:48:48 +05:30
},
),
"manager_id": forms.Select(
attrs={
"class": "oh-select oh-select-2 ",
"style": "width:100%; display:none;",
"required": "false",
2023-08-01 16:48:48 +05:30
},
),
"colleague_id": forms.SelectMultiple(
attrs={
"class": "oh-select oh-select-2 w-100",
"multiple": "multiple",
"style": "width:100%; display:none;",
}
),
"subordinate_id": forms.SelectMultiple(
attrs={
"class": "oh-select oh-select-2 w-100",
"multiple": "multiple",
"style": "width:100%; display:none;",
}
),
"question_template_id": forms.Select(
attrs={
"class": "oh-select oh-select--lg oh-select-no-search",
"style": "width:100%; display:none;",
"required": "false",
2023-08-01 16:48:48 +05:30
}
),
2023-05-10 15:06:57 +05:30
}
def __init__(self, *args, **kwargs):
"""
Initializes the feedback form instance.
If an instance is provided, sets the initial value for the form's date fields.
"""
2023-08-01 16:48:48 +05:30
instance = kwargs.get("instance")
employee = kwargs.pop(
"employee", None
) # access the logged-in user's information
2023-05-10 15:06:57 +05:30
if instance:
2023-08-01 16:48:48 +05:30
kwargs["initial"] = set_date_field_initial(instance)
2023-05-10 15:06:57 +05:30
super().__init__(*args, **kwargs)
2023-12-01 15:36:51 +05:30
reload_queryset(self.fields)
self.fields["period"].choices = list(self.fields["period"].choices)
2023-12-01 15:36:51 +05:30
self.fields["period"].choices.append(("create_new_period", "Create new period"))
2023-05-10 15:06:57 +05:30
if instance:
2023-08-01 16:48:48 +05:30
self.fields["employee_id"].widget.attrs.update(
{"class": "oh-select oh-select-2"}
)
employees = Employee.objects.filter(
is_active=True, employee_work_info__reporting_manager_id=employee
2023-08-01 16:48:48 +05:30
)
2023-05-10 15:06:57 +05:30
if employee and employees:
2023-08-01 16:48:48 +05:30
department = employee.employee_work_info.department_id
employees = Employee.objects.filter(
is_active=True, employee_work_info__department_id=department
2023-08-01 16:48:48 +05:30
)
# manager level access
self.fields["employee_id"].queryset = employees
self.fields["manager_id"].queryset = employees
self.fields["colleague_id"].queryset = employees
self.fields["subordinate_id"].queryset = employees
2023-05-10 15:06:57 +05:30
def clean(self):
"""
Cleans and validates the feedback form data.
Ensures that the start date is before the end date and validates the start date.
"""
cleaned_data = super().clean()
2023-08-01 16:48:48 +05:30
start_date = cleaned_data.get("start_date")
end_date = cleaned_data.get("end_date")
2023-05-10 15:06:57 +05:30
2023-08-01 16:48:48 +05:30
if "employee_key_results_id" in self.errors:
del self.errors["employee_key_results_id"]
2023-05-10 15:06:57 +05:30
self.instance
2023-08-01 16:48:48 +05:30
validate_date(start_date, end_date)
2023-05-10 15:06:57 +05:30
return cleaned_data
2023-08-01 16:48:48 +05:30
2023-12-01 15:36:51 +05:30
class QuestionTemplateForm(ModelForm):
2023-05-10 15:06:57 +05:30
"""
Form for creating or updating a question template instance
"""
2023-08-01 16:48:48 +05:30
question_template = forms.CharField(
widget=forms.TextInput(
attrs={
"class": "oh-input oh-input--small oh-input--res-height w-100",
2023-08-07 13:02:24 +05:30
"placeholder": _("For Developer"),
2023-08-01 16:48:48 +05:30
}
)
)
2023-05-10 15:06:57 +05:30
class Meta:
2023-09-09 14:10:09 +05:30
"""
A nested class that specifies the model and fields for the form.
"""
2023-05-10 15:06:57 +05:30
model = QuestionTemplate
2023-08-01 16:48:48 +05:30
fields = "__all__"
2023-12-01 15:36:51 +05:30
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
reload_queryset(self.fields)
self.fields["company_id"].widget.attrs.update(
{
"class": "oh-select oh-select-2 w-100",
}
)
2023-12-01 15:36:51 +05:30
2023-08-01 16:48:48 +05:30
2023-12-01 15:36:51 +05:30
class QuestionForm(ModelForm):
2023-05-10 15:06:57 +05:30
"""
Form for creating or updating a question instance
"""
2023-08-01 16:48:48 +05:30
question = forms.CharField(
widget=forms.TextInput(
attrs={
"class": "oh-input oh-input--small oh-input--res-height w-100",
2023-08-07 13:02:24 +05:30
"placeholder": _("Enter question"),
2023-08-01 16:48:48 +05:30
}
),
required=True,
)
options = forms.ModelChoiceField(
queryset=QuestionOptions.objects.all(), required=False
)
option_a = forms.CharField(
widget=forms.TextInput(
attrs={"class": "oh-input oh-input--res-height w-100", "type": "text"}
),
max_length=240,
required=False,
)
option_b = forms.CharField(
widget=forms.TextInput(
attrs={"class": "oh-input oh-input--res-height w-100", "type": "text"}
),
max_length=240,
required=False,
)
option_c = forms.CharField(
widget=forms.TextInput(
attrs={"class": "oh-input oh-input--res-height w-100", "type": "text"}
),
max_length=240,
required=False,
)
option_d = forms.CharField(
widget=forms.TextInput(
attrs={"class": "oh-input oh-input--res-height w-100", "type": "text"}
),
max_length=240,
required=False,
)
2023-05-10 15:06:57 +05:30
class Meta:
2023-09-09 14:10:09 +05:30
"""
A nested class that specifies the model,exclude fields and style of fields for the form.
"""
2023-08-01 16:48:48 +05:30
2023-09-09 14:10:09 +05:30
model = Question
2023-05-10 15:06:57 +05:30
exclude = ["question_option_id", "template_id"]
widgets = {
2023-08-01 16:48:48 +05:30
"question_type": forms.Select(
attrs={
"class": "oh-select oh-select--sm oh-select-no-search oh-select--qa-change w-100",
"required": True,
}
)
2023-05-10 15:06:57 +05:30
}
2023-08-01 16:48:48 +05:30
fields = "__all__"
2023-05-10 15:06:57 +05:30
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
2023-12-01 15:36:51 +05:30
reload_queryset(self.fields)
2023-08-01 16:48:48 +05:30
self.fields["question_type"].widget.attrs.update({"id": str(uuid.uuid4())})
if (
self.instance.pk
and self.instance.question_type == "4"
and self.instance.question_options.first()
):
self.fields[
"option_a"
].initial = self.instance.question_options.first().option_a
self.fields[
"option_b"
].initial = self.instance.question_options.first().option_b
self.fields[
"option_c"
].initial = self.instance.question_options.first().option_c
self.fields[
"option_d"
].initial = self.instance.question_options.first().option_d
2023-05-10 15:06:57 +05:30
2023-12-01 15:36:51 +05:30
class ObjectiveCommentForm(ModelForm):
2023-05-10 15:06:57 +05:30
"""
A form used to add a comment to an employee's objective.
Excludes fields for the employee and employee objective and uses a textarea widget for the comment field.
"""
2023-08-01 16:48:48 +05:30
2023-05-10 15:06:57 +05:30
class Meta:
2023-09-09 14:10:09 +05:30
"""
A nested class that specifies the model,exclude fields and style of fields for the form.
"""
2023-05-10 15:06:57 +05:30
model = Comment
exclude = ["employee_id", "employee_objective_id"]
widgets = {
2023-08-01 16:48:48 +05:30
"comment": forms.Textarea(
attrs={
"class": "oh-input oh-input--small oh-input--textarea",
"rows": "4",
"placeholder": _("Add a comment..."),
}
),
2023-05-10 15:06:57 +05:30
}
2023-12-01 15:36:51 +05:30
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
reload_queryset(self.fields)
2023-08-01 16:48:48 +05:30
2023-12-01 15:36:51 +05:30
class PeriodForm(ModelForm):
2023-05-10 15:06:57 +05:30
"""
A form for creating or updating a Period object.
"""
2023-08-01 16:48:48 +05:30
2023-05-10 15:06:57 +05:30
class Meta:
2023-09-09 14:10:09 +05:30
"""
A nested class that specifies the model,fields and style of fields for the form.
"""
2023-05-10 15:06:57 +05:30
model = Period
2023-08-01 16:48:48 +05:30
fields = "__all__"
2023-05-10 15:06:57 +05:30
widgets = {
2023-08-01 16:48:48 +05:30
"period_name": forms.TextInput(
attrs={"placeholder": "Q1.", "class": "oh-input w-100"}
),
"start_date": forms.DateInput(
attrs={"type": "date", "class": "oh-input w-100"}
),
"end_date": forms.DateInput(
attrs={"type": "date", "class": "oh-input w-100"}
),
2023-05-10 15:06:57 +05:30
}
2023-08-01 16:48:48 +05:30
2023-05-10 15:06:57 +05:30
def __init__(self, *args, **kwargs):
2023-09-09 14:10:09 +05:30
"""
django forms not showing value inside the date, time html element.
so here overriding default forms instance method to set initial value
"""
2023-08-01 16:48:48 +05:30
if instance := kwargs.get("instance"):
kwargs["initial"] = set_date_field_initial(instance)
2023-12-01 15:36:51 +05:30
super().__init__(*args, **kwargs)
reload_queryset(self.fields)
self.fields["company_id"].widget.attrs.update(
{
"class": "oh-select oh-select-2 w-100",
}
)
2023-05-10 15:06:57 +05:30
def clean(self):
cleaned_data = super().clean()
2023-08-01 16:48:48 +05:30
start_date = cleaned_data.get("start_date")
end_date = cleaned_data.get("end_date")
validate_date(start_date, end_date)