2023-08-01 16:48:48 +05:30
|
|
|
"""
|
|
|
|
|
forms.py
|
|
|
|
|
|
|
|
|
|
This module is used to register the forms for pms models
|
|
|
|
|
"""
|
2024-03-10 19:37:46 +05:30
|
|
|
|
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
|
2024-03-08 22:35:28 +05:30
|
|
|
from django.template.loader import render_to_string
|
2023-05-10 15:06:57 +05:30
|
|
|
from django.utils.translation import gettext_lazy as _
|
2024-03-08 22:35:28 +05:30
|
|
|
from employee.filters import EmployeeFilter
|
2023-08-01 16:48:48 +05:30
|
|
|
from employee.models import Department, JobPosition
|
2023-12-13 19:12:42 +05:30
|
|
|
from django.forms import ModelForm
|
2024-01-17 14:19:51 +05:30
|
|
|
from base.forms import ModelForm as BaseForm
|
2024-03-08 22:35:28 +05:30
|
|
|
from horilla_widgets.widgets.horilla_multi_select_field import HorillaMultiSelectField
|
|
|
|
|
from horilla_widgets.widgets.select_widgets import HorillaMultiSelectWidget
|
2023-08-01 16:48:48 +05:30
|
|
|
from pms.models import (
|
2024-01-17 14:19:51 +05:30
|
|
|
AnonymousFeedback,
|
2024-03-08 22:35:28 +05:30
|
|
|
KeyResult,
|
|
|
|
|
Objective,
|
2023-08-01 16:48:48 +05:30
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
class ObjectiveForm(BaseForm):
|
2023-05-10 15:06:57 +05:30
|
|
|
"""
|
2024-03-08 22:35:28 +05:30
|
|
|
A form to create or update instances of the Objective, model.
|
2023-05-10 15:06:57 +05:30
|
|
|
"""
|
2023-08-01 16:48:48 +05:30
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
# period = forms.ModelChoiceField(
|
|
|
|
|
# queryset=Period.objects.all(),
|
|
|
|
|
# widget=forms.Select(
|
|
|
|
|
# attrs={
|
|
|
|
|
# "onChange": "periodCheck(this)",
|
|
|
|
|
# },
|
|
|
|
|
# ),
|
|
|
|
|
# required=False,
|
|
|
|
|
# )
|
|
|
|
|
# assignees = forms.ModelMultipleChoiceField(
|
|
|
|
|
# queryset=Employee.objects.all(),
|
|
|
|
|
# required=False,
|
|
|
|
|
# widget=forms.SelectMultiple(attrs={'style': 'display:none;'})
|
|
|
|
|
# )
|
|
|
|
|
# assignees = HorillaMultiSelectField(
|
|
|
|
|
# queryset=Employee.objects.all(),
|
|
|
|
|
# widget=HorillaMultiSelectWidget(
|
|
|
|
|
# filter_route_name="employee-widget-filter",
|
|
|
|
|
# filter_class=EmployeeFilter,
|
|
|
|
|
# filter_instance_contex_name="f",
|
|
|
|
|
# filter_template_path="employee_filters.html",
|
|
|
|
|
# required=True,
|
|
|
|
|
# ),
|
|
|
|
|
# label="Assignees",
|
|
|
|
|
# )
|
|
|
|
|
start_date = forms.DateField(
|
2023-08-01 16:48:48 +05:30
|
|
|
required=False,
|
2024-03-10 19:37:46 +05:30
|
|
|
widget=forms.DateInput(attrs={"class": "oh-input w-100", "type": "date"}),
|
2023-08-01 16:48:48 +05:30
|
|
|
)
|
2024-03-08 22:35:28 +05:30
|
|
|
add_assignees = forms.BooleanField(required=False)
|
2024-03-26 14:11:47 +05:30
|
|
|
# default_key_results = forms.ModelMultipleChoiceField(
|
|
|
|
|
# queryset=KeyResult.objects.all(),
|
|
|
|
|
# required=False,
|
|
|
|
|
# widget=forms.SelectMultiple(
|
|
|
|
|
# attrs={
|
|
|
|
|
# "class": "oh-select oh-select-2 select2-hidden-accessible",
|
|
|
|
|
# "onchange": "keyResultChange($(this))",
|
|
|
|
|
# }
|
|
|
|
|
# ),
|
|
|
|
|
# # widget=forms.SelectMultiple(attrs={'style': 'display:none;'})
|
|
|
|
|
# )
|
|
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
# archive = forms.BooleanField()
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
"""
|
|
|
|
|
A nested class that specifies the model,fields and style of fields for the form.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
model = Objective
|
2024-03-10 19:37:46 +05:30
|
|
|
fields = [
|
|
|
|
|
"title",
|
|
|
|
|
"managers",
|
|
|
|
|
"description",
|
|
|
|
|
"duration",
|
2024-03-26 14:11:47 +05:30
|
|
|
'key_result_id',
|
2024-03-10 19:37:46 +05:30
|
|
|
"add_assignees",
|
|
|
|
|
"assignees",
|
2024-03-08 22:35:28 +05:30
|
|
|
# 'period',
|
2024-03-10 19:37:46 +05:30
|
|
|
"start_date",
|
2024-03-08 22:35:28 +05:30
|
|
|
# 'end_date',
|
|
|
|
|
# 'archive',
|
|
|
|
|
]
|
2024-03-26 14:11:47 +05:30
|
|
|
widgets = {
|
|
|
|
|
"key_result_id":forms.SelectMultiple(
|
|
|
|
|
attrs={
|
|
|
|
|
"class": "oh-select oh-select-2 select2-hidden-accessible",
|
|
|
|
|
"onchange": "keyResultChange($(this))",
|
|
|
|
|
}
|
|
|
|
|
),
|
2024-03-08 22:35:28 +05:30
|
|
|
# "start_date": forms.DateInput(
|
|
|
|
|
# attrs={"class": "oh-input w-100", "type": "date"}
|
|
|
|
|
# ),
|
|
|
|
|
# "end_date": forms.DateInput(
|
|
|
|
|
# attrs={"class": "oh-input w-100", "type": "date"}
|
|
|
|
|
# ),
|
2024-03-26 14:11:47 +05:30
|
|
|
}
|
2024-03-08 22:35:28 +05:30
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
"""
|
|
|
|
|
Constructor for ObjectiveForm. If an instance is provided, set initial values for date fields
|
|
|
|
|
"""
|
|
|
|
|
# if instance := kwargs.get("instance"):
|
|
|
|
|
# kwargs["initial"] = set_date_field_initial(instance)
|
|
|
|
|
|
|
|
|
|
employee = kwargs.pop(
|
|
|
|
|
"employee", None
|
|
|
|
|
) # access the logged-in user's information
|
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
|
if self.instance.pk is None:
|
|
|
|
|
self.fields["assignees"] = HorillaMultiSelectField(
|
|
|
|
|
queryset=Employee.objects.all(),
|
|
|
|
|
widget=HorillaMultiSelectWidget(
|
|
|
|
|
filter_route_name="employee-widget-filter",
|
|
|
|
|
filter_class=EmployeeFilter,
|
|
|
|
|
filter_instance_contex_name="f",
|
|
|
|
|
filter_template_path="employee_filters.html",
|
2024-03-10 18:54:38 +05:30
|
|
|
required=False,
|
2024-03-08 22:35:28 +05:30
|
|
|
),
|
|
|
|
|
label="Assignees",
|
|
|
|
|
)
|
|
|
|
|
reload_queryset(self.fields)
|
2024-03-26 14:11:47 +05:30
|
|
|
self.fields["key_result_id"].choices = list(
|
|
|
|
|
self.fields["key_result_id"].choices
|
|
|
|
|
)
|
|
|
|
|
self.fields["key_result_id"].choices.append(
|
|
|
|
|
("create_new_key_result", "Create new Key result")
|
|
|
|
|
)
|
|
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
# self.fields['start_date'].widget.attrs.update({"style":"display:none;"})
|
|
|
|
|
# self.fields['assignees'].widget.attrs.update({"style":"display:none;"})
|
|
|
|
|
|
|
|
|
|
# self.fields["period"].choices = list(self.fields["period"].choices)
|
|
|
|
|
# self.fields["period"].choices.append(("create_new_period", "Create new period"))
|
|
|
|
|
|
|
|
|
|
def clean(self):
|
|
|
|
|
"""
|
|
|
|
|
Validates form fields and raises a validation error if any fields are invalid
|
|
|
|
|
"""
|
|
|
|
|
cleaned_data = super().clean()
|
|
|
|
|
add_assignees = cleaned_data.get("add_assignees")
|
|
|
|
|
for field_name, field_instance in self.fields.items():
|
|
|
|
|
if isinstance(field_instance, HorillaMultiSelectField):
|
|
|
|
|
self.errors.pop(field_name, None)
|
2024-03-11 12:20:47 +05:30
|
|
|
if (
|
|
|
|
|
add_assignees
|
|
|
|
|
and len(self.data.getlist(field_name)) < 1
|
|
|
|
|
and add_assignees
|
|
|
|
|
):
|
2024-03-08 22:35:28 +05:30
|
|
|
raise forms.ValidationError({field_name: "This field is required"})
|
|
|
|
|
cleaned_data = super().clean()
|
|
|
|
|
data = self.fields[field_name].queryset.filter(
|
|
|
|
|
id__in=self.data.getlist(field_name)
|
|
|
|
|
)
|
|
|
|
|
cleaned_data[field_name] = data
|
|
|
|
|
cleaned_data = super().clean()
|
|
|
|
|
add_assignees = cleaned_data.get("add_assignees")
|
|
|
|
|
assignees = cleaned_data.get("assignees")
|
|
|
|
|
start_date = cleaned_data.get("start_date")
|
2024-03-10 19:37:46 +05:30
|
|
|
managers = cleaned_data.get("managers")
|
2024-03-08 22:35:28 +05:30
|
|
|
if not managers or managers == None:
|
2024-03-10 19:37:46 +05:30
|
|
|
raise forms.ValidationError("Managers is a required field")
|
|
|
|
|
if add_assignees:
|
|
|
|
|
if not assignees.exists() or start_date is None:
|
|
|
|
|
raise forms.ValidationError("Assign employees and start date")
|
2024-03-08 22:35:28 +05:30
|
|
|
start_date = cleaned_data.get("start_date")
|
|
|
|
|
end_date = cleaned_data.get("end_date")
|
|
|
|
|
# Check that start date is before end date
|
|
|
|
|
validate_date(start_date, end_date)
|
|
|
|
|
return cleaned_data
|
2024-03-10 19:37:46 +05:30
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
def as_p(self):
|
|
|
|
|
"""
|
|
|
|
|
Render the form fields as HTML table rows with Bootstrap styling.
|
|
|
|
|
"""
|
|
|
|
|
context = {"form": self}
|
|
|
|
|
table_html = render_to_string("common_form.html", context)
|
|
|
|
|
return table_html
|
|
|
|
|
|
2024-03-10 19:37:46 +05:30
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
class AddAssigneesForm(BaseForm):
|
|
|
|
|
"""
|
|
|
|
|
A form to create or update instances of the EmployeeObjective, model.
|
|
|
|
|
"""
|
2024-03-10 19:37:46 +05:30
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
start_date = forms.DateField(
|
2023-08-01 16:48:48 +05:30
|
|
|
required=False,
|
2024-03-10 19:37:46 +05:30
|
|
|
widget=forms.DateInput(attrs={"class": "oh-input w-100", "type": "date"}),
|
2023-08-01 16:48:48 +05:30
|
|
|
)
|
2024-03-10 19:37:46 +05:30
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
class Meta:
|
|
|
|
|
"""
|
|
|
|
|
A nested class that specifies the model,fields and style of fields for the form.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
model = Objective
|
2024-03-10 19:37:46 +05:30
|
|
|
fields = [
|
|
|
|
|
"assignees",
|
2024-03-08 22:35:28 +05:30
|
|
|
]
|
2024-03-10 19:37:46 +05:30
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
def as_p(self):
|
|
|
|
|
"""
|
|
|
|
|
Render the form fields as HTML table rows with Bootstrap styling.
|
|
|
|
|
"""
|
|
|
|
|
context = {"form": self}
|
|
|
|
|
table_html = render_to_string("common_form.html", context)
|
|
|
|
|
return table_html
|
2024-03-10 19:37:46 +05:30
|
|
|
|
2024-03-11 12:20:47 +05:30
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
|
if self.instance:
|
|
|
|
|
self.fields["assignees"].queryset = self.fields[
|
|
|
|
|
"assignees"
|
|
|
|
|
].queryset.exclude(id__in=self.instance.assignees.all())
|
|
|
|
|
|
2024-03-10 19:37:46 +05:30
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
class EmployeeObjectiveForm(BaseForm):
|
|
|
|
|
"""
|
|
|
|
|
A form to create or update instances of the EmployeeObjective, model.
|
|
|
|
|
"""
|
2024-03-10 19:37:46 +05:30
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
key_result_id = forms.ModelChoiceField(
|
|
|
|
|
queryset=KeyResult.objects.all(),
|
|
|
|
|
label=_("Key result"),
|
2023-08-01 16:48:48 +05:30
|
|
|
widget=forms.Select(
|
|
|
|
|
attrs={
|
2024-03-08 22:35:28 +05:30
|
|
|
"class": "oh-select oh-select-2 select2-hidden-accessible",
|
|
|
|
|
"onchange": "keyResultChange($(this))",
|
2023-08-01 16:48:48 +05:30
|
|
|
}
|
|
|
|
|
),
|
|
|
|
|
)
|
2024-03-10 19:37:46 +05:30
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
class Meta:
|
|
|
|
|
"""
|
|
|
|
|
A nested class that specifies the model,fields and style of fields for the form.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
model = EmployeeObjective
|
2024-03-10 19:37:46 +05:30
|
|
|
fields = [
|
|
|
|
|
"objective_id",
|
|
|
|
|
"start_date",
|
|
|
|
|
"end_date",
|
|
|
|
|
"status",
|
|
|
|
|
"archive",
|
2024-03-08 22:35:28 +05:30
|
|
|
]
|
|
|
|
|
widgets = {
|
|
|
|
|
"objective_id": forms.HiddenInput(),
|
|
|
|
|
"start_date": forms.DateInput(
|
|
|
|
|
attrs={"class": "oh-input w-100", "type": "date"}
|
|
|
|
|
),
|
|
|
|
|
"end_date": forms.DateInput(
|
|
|
|
|
attrs={"class": "oh-input w-100", "type": "date"}
|
|
|
|
|
),
|
|
|
|
|
}
|
2024-03-10 19:37:46 +05:30
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
|
reload_queryset(self.fields)
|
2024-03-11 12:20:47 +05:30
|
|
|
try:
|
|
|
|
|
del self.fields["key_result_id"]
|
|
|
|
|
except Exception as _err:
|
|
|
|
|
pass
|
|
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
|
|
|
|
|
def as_p(self):
|
|
|
|
|
"""
|
|
|
|
|
Render the form fields as HTML table rows with Bootstrap styling.
|
|
|
|
|
"""
|
|
|
|
|
context = {"form": self}
|
|
|
|
|
table_html = render_to_string("common_form.html", context)
|
|
|
|
|
return table_html
|
|
|
|
|
|
2024-03-10 19:37:46 +05:30
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
class EmployeekeyResultForm(BaseForm):
|
|
|
|
|
"""
|
|
|
|
|
A form to create or update instances of the EmployeeKeyResult, model.
|
|
|
|
|
"""
|
2024-03-10 19:37:46 +05:30
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
key_result_id = forms.ModelChoiceField(
|
|
|
|
|
queryset=KeyResult.objects.all(),
|
|
|
|
|
label=_("Key result"),
|
2023-08-01 16:48:48 +05:30
|
|
|
widget=forms.Select(
|
|
|
|
|
attrs={
|
2024-03-08 22:35:28 +05:30
|
|
|
"class": "oh-select oh-select-2 select2-hidden-accessible",
|
|
|
|
|
"onchange": "keyResultChange($(this))",
|
2023-08-01 16:48:48 +05:30
|
|
|
}
|
|
|
|
|
),
|
|
|
|
|
)
|
2024-03-10 19:37:46 +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.
|
|
|
|
|
"""
|
2024-03-10 19:37:46 +05:30
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
model = EmployeeKeyResult
|
2024-03-10 19:37:46 +05:30
|
|
|
fields = [
|
|
|
|
|
"employee_objective_id",
|
|
|
|
|
"key_result_id",
|
|
|
|
|
"start_value",
|
|
|
|
|
"current_value",
|
|
|
|
|
"target_value",
|
|
|
|
|
"start_date",
|
|
|
|
|
"end_date",
|
2024-03-08 22:35:28 +05:30
|
|
|
# 'archive',
|
|
|
|
|
]
|
2023-05-10 15:06:57 +05:30
|
|
|
widgets = {
|
2024-03-10 19:37:46 +05:30
|
|
|
"employee_objective_id": forms.HiddenInput(),
|
2023-08-01 16:48:48 +05:30
|
|
|
"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
|
|
|
}
|
|
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
def as_p(self):
|
2023-05-10 15:06:57 +05:30
|
|
|
"""
|
2024-03-08 22:35:28 +05:30
|
|
|
Render the form fields as HTML table rows with Bootstrap styling.
|
2023-05-10 15:06:57 +05:30
|
|
|
"""
|
2024-03-08 22:35:28 +05:30
|
|
|
context = {"form": self}
|
|
|
|
|
table_html = render_to_string("common_form.html", context)
|
|
|
|
|
return table_html
|
2024-03-10 19:37:46 +05:30
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
def __init__(self, *args, **kwargs):
|
2023-12-01 15:36:51 +05:30
|
|
|
super().__init__(*args, **kwargs)
|
2024-03-08 22:35:28 +05:30
|
|
|
if self.initial.get("employee_objective_id"):
|
2024-03-10 19:37:46 +05:30
|
|
|
if type(self.initial.get("employee_objective_id")) == int:
|
|
|
|
|
self.verbose_name = EmployeeObjective.objects.get(
|
|
|
|
|
id=(self.initial.get("employee_objective_id"))
|
|
|
|
|
).employee_id
|
2024-03-08 22:35:28 +05:30
|
|
|
else:
|
2024-03-10 19:37:46 +05:30
|
|
|
self.verbose_name = self.initial.get(
|
|
|
|
|
"employee_objective_id"
|
|
|
|
|
).employee_id
|
2024-03-08 22:35:28 +05:30
|
|
|
|
2023-12-01 15:36:51 +05:30
|
|
|
reload_queryset(self.fields)
|
2024-03-10 19:37:46 +05:30
|
|
|
self.fields["key_result_id"].choices = list(
|
|
|
|
|
self.fields["key_result_id"].choices
|
|
|
|
|
)
|
|
|
|
|
self.fields["key_result_id"].choices.append(
|
|
|
|
|
("create_new_key_result", "Create new Key result")
|
|
|
|
|
)
|
|
|
|
|
|
2023-05-10 15:06:57 +05:30
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
from base.forms import ModelForm as MF
|
2024-03-10 19:37:46 +05:30
|
|
|
|
|
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
class KRForm(MF):
|
|
|
|
|
"""
|
|
|
|
|
A form used for creating KeyResult object
|
|
|
|
|
"""
|
2023-05-10 15:06:57 +05:30
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
class Meta:
|
2023-05-10 15:06:57 +05:30
|
|
|
"""
|
2024-03-08 22:35:28 +05:30
|
|
|
A nested class that specifies the model,fields and exclude fields for the form.
|
2023-05-10 15:06:57 +05:30
|
|
|
"""
|
|
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
model = KeyResult
|
|
|
|
|
fields = "__all__"
|
|
|
|
|
exclude = [
|
|
|
|
|
"history",
|
|
|
|
|
"objects",
|
|
|
|
|
]
|
2024-03-10 19:37:46 +05:30
|
|
|
|
2024-03-08 22:35:28 +05:30
|
|
|
def as_p(self):
|
|
|
|
|
"""
|
|
|
|
|
Render the form fields as HTML table rows with Bootstrap styling.
|
|
|
|
|
"""
|
|
|
|
|
context = {"form": self}
|
|
|
|
|
table_html = render_to_string("common_form.html", context)
|
|
|
|
|
return table_html
|
2024-03-26 14:11:47 +05:30
|
|
|
|
|
|
|
|
def clean(self):
|
|
|
|
|
cleaned_data = super().clean()
|
|
|
|
|
duration = cleaned_data.get('duration')
|
|
|
|
|
target_value = cleaned_data.get('target_value')
|
|
|
|
|
progress_type = cleaned_data.get('progress_type')
|
|
|
|
|
|
|
|
|
|
if duration is None or duration == '':
|
|
|
|
|
raise ValidationError({
|
|
|
|
|
'duration':'This field is required'
|
|
|
|
|
})
|
|
|
|
|
if target_value is None or target_value == '':
|
|
|
|
|
raise ValidationError({
|
|
|
|
|
'target_value':'This field is required'
|
|
|
|
|
})
|
|
|
|
|
if duration <= 0:
|
|
|
|
|
raise ValidationError({
|
|
|
|
|
'duration':'Duration cannot be less than or equal to zero'
|
|
|
|
|
})
|
|
|
|
|
if target_value <= 0:
|
|
|
|
|
raise ValidationError({
|
|
|
|
|
'target_value':'Duration cannot be less than or equal to zero'
|
|
|
|
|
})
|
|
|
|
|
if progress_type == '%' and target_value > 100 :
|
|
|
|
|
raise ValidationError({
|
|
|
|
|
'target_value':'Target value cannot be greater than zero for progress type "percentage"'
|
|
|
|
|
})
|
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(
|
2024-01-04 11:07:14 +05:30
|
|
|
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")
|
2023-11-28 19:50:41 +05:30
|
|
|
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)
|
2023-11-28 19:50:41 +05:30
|
|
|
# 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")
|
2023-11-28 19:50:41 +05:30
|
|
|
# target value and current value comparison
|
|
|
|
|
if target_value <= 0:
|
|
|
|
|
raise ValidationError("Target value should be greater than zero")
|
|
|
|
|
if current_value > target_value:
|
2024-01-04 11:07:14 +05:30
|
|
|
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;",
|
2023-09-05 10:30:37 +05:30
|
|
|
"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;",
|
2023-09-05 10:30:37 +05:30
|
|
|
"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;",
|
2023-09-05 10:30:37 +05:30
|
|
|
"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)
|
2023-09-25 15:53:42 +05:30
|
|
|
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(
|
2024-01-04 11:07:14 +05:30
|
|
|
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(
|
2024-01-04 11:07:14 +05:30
|
|
|
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)
|
2024-01-04 11:07:14 +05:30
|
|
|
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()
|
|
|
|
|
):
|
2024-03-10 19:37:46 +05:30
|
|
|
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)
|
2024-01-04 11:07:14 +05:30
|
|
|
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)
|
2024-01-17 14:19:51 +05:30
|
|
|
|
|
|
|
|
|
|
|
|
|
class AnonymousFeedbackForm(BaseForm):
|
|
|
|
|
class Meta:
|
|
|
|
|
model = AnonymousFeedback
|
|
|
|
|
fields = "__all__"
|
|
|
|
|
exclude = ["status", "archive"]
|