[UPDT] PMS: Updated pms ffeedback creation form

This commit is contained in:
Horilla
2025-03-14 16:15:11 +05:30
parent 31aa1087ee
commit 0dca71f5af
3 changed files with 124 additions and 167 deletions

View File

@@ -18,7 +18,7 @@ from django.template.loader import render_to_string
from django.utils.translation import gettext_lazy as _
from base.forms import ModelForm as BaseForm
from base.forms import ModelForm as MF
from base.forms import ModelForm as HorillaModelForm
from base.methods import (
filtersubordinatesemployeemodel,
is_reportingmanager,
@@ -447,10 +447,7 @@ class EmployeeKeyResultForm(BaseForm):
)
from base.forms import ModelForm as MF
class KRForm(MF):
class KRForm(HorillaModelForm):
"""
A form used for creating KeyResult object
"""
@@ -661,28 +658,20 @@ class KeyResultForm(ModelForm):
return cleaned_data
class FeedbackForm(ModelForm):
class FeedbackForm(HorillaModelForm):
"""
A form used for creating and updating Feedback objects.
FeedbackForm for better performance.
"""
period = forms.ModelChoiceField(
queryset=Period.objects.all(),
queryset=Period.objects.none(),
label=_("Period"),
empty_label="",
widget=forms.Select(
attrs={
"class": " oh-select--period-change ",
"style": "width:100%;",
}
),
widget=forms.Select(attrs={"class": "oh-select--period-change"}),
required=False,
)
class Meta:
"""
A nested class that specifies the model,fields and exclude fields for the form.
"""
model = Feedback
fields = "__all__"
exclude = ["status", "archive", "is_active"]
@@ -692,45 +681,10 @@ class FeedbackForm(ModelForm):
attrs={"placeholder": _("Enter a title"), "class": "oh-input w-100"}
),
"start_date": forms.DateInput(
attrs={"type": "date", "class": "oh-input w-100"}
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 oh-select-2",
"required": "false",
},
),
"manager_id": forms.Select(
attrs={
"class": "oh-select oh-select-2 ",
"style": "width:100%;",
"required": "true",
},
),
"colleague_id": forms.SelectMultiple(
attrs={
"class": "oh-select oh-select-2 w-100",
"multiple": "multiple",
"style": "width:100%;",
}
),
"subordinate_id": forms.SelectMultiple(
attrs={
"class": "oh-select oh-select-2 w-100",
"multiple": "multiple",
"style": "width:100%;",
"required": "false",
}
),
"question_template_id": forms.Select(
attrs={
"class": "oh-select oh-select--lg oh-select-no-search",
"style": "width:100%;",
"required": "true",
}
attrs={"type": "date", "class": "oh-input w-100"}
),
"cyclic_feedback": forms.CheckboxInput(
attrs={
@@ -738,41 +692,41 @@ class FeedbackForm(ModelForm):
"onchange": "changeCyclicFeedback(this)",
}
),
"cyclic_feedback_period": forms.Select(
attrs={
"class": "oh-select oh-select--lg oh-select-no-search",
"style": "width:100%;",
}
),
"cyclic_feedback_days_count": forms.NumberInput(
attrs={
"class": "oh-input",
}
),
}
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.
Initializes the form and queryset filtering.
"""
# fetch request
request = getattr(horilla_middlewares._thread_locals, "request", None)
# get instance
instance = kwargs.get("instance")
# set employee
if instance:
employee = instance.employee_id
else:
employee = request.user.employee_get
if not instance:
today = datetime.datetime.today().date()
kwargs["initial"] = {"start_date": today, "end_date": today}
super().__init__(*args, **kwargs)
# Horilla multi select filter for employee
user = request.user if request else None
user_perms = user.get_all_permissions() if user else set()
self.fields["period"].queryset = Period.objects.all()
self.fields["period"].widget.attrs.update({"class": "w-100"})
if user and ("pms.add_period" in user_perms or is_reportingmanager(request)):
self.fields["period"].choices = [
*self.fields["period"].choices,
("create_new_period", "Create new period"),
]
employee_queryset = Employee.objects.none()
if user and ("pms.add_feedback" in user_perms or is_reportingmanager(request)):
employee_queryset = filtersubordinatesemployeemodel(
request,
Employee.objects.all(),
perm="pms.add_feedback",
)
self.fields["employee_id"].queryset = (
employee_queryset | Employee.objects.filter(employee_user_id=request.user)
)
self.fields["employee_id"].widget.attrs["onchange"] = "get_collegues($(this))"
# Horilla multi-select filter for subordinates
self.fields["subordinate_id"] = HorillaMultiSelectField(
queryset=Employee.objects.all(),
widget=HorillaMultiSelectWidget(
@@ -783,32 +737,10 @@ class FeedbackForm(ModelForm):
instance=self.instance,
required=False,
),
label="Subordinates",
label=_("Subordinates"),
)
reload_queryset(self.fields)
# check the request user has permission to add period
if request.user.has_perm("pms.add_period") or is_reportingmanager(request):
# add dyanamic period creation as choice
self.fields["period"].choices = list(self.fields["period"].choices)
self.fields["period"].choices.append(
("create_new_period", "Create new period")
)
# add onchange function to get employee data
self.fields["employee_id"].widget.attrs.update(
{"onchange": "get_collegues($(this))"}
)
# filtering employees accordig to the request user
if request.user.has_perm("pms.add_feedback") or is_reportingmanager(request):
# Queryset of subordinate employees
employees = filtersubordinatesemployeemodel(
request, Employee.objects.all(), perm="pms.add_feedback"
)
self.fields["employee_id"].queryset = employees | Employee.objects.filter(
employee_user_id=request.user
)
if not instance:
self.fields["employee_id"].initial = employee
reload_queryset(self.fields)
def clean(self):
"""
@@ -1119,7 +1051,7 @@ class MeetingsForm(BaseForm):
pass
class BonusPointSettingForm(MF):
class BonusPointSettingForm(HorillaModelForm):
"""
BonusPointSetting form
"""
@@ -1165,7 +1097,7 @@ class BonusPointSettingForm(MF):
return cleaned_data
class EmployeeBonusPointForm(MF):
class EmployeeBonusPointForm(HorillaModelForm):
"""
EmployeeBonusPoint form
"""

View File

@@ -497,13 +497,16 @@ class Feedback(HorillaModel):
("months", _("Months")),
("years", _("Years")),
)
review_cycle = models.CharField(max_length=100, null=False, blank=False)
review_cycle = models.CharField(
max_length=100, null=False, blank=False, verbose_name=_("Title")
)
manager_id = models.ForeignKey(
Employee,
related_name="feedback_manager",
on_delete=models.DO_NOTHING,
null=True,
blank=False,
verbose_name=_("Manager"),
)
employee_id = models.ForeignKey(
Employee,
@@ -511,12 +514,19 @@ class Feedback(HorillaModel):
related_name="feedback_employee",
null=False,
blank=False,
verbose_name=_("Employee"),
)
colleague_id = models.ManyToManyField(
Employee, related_name="feedback_colleague", blank=True
Employee,
related_name="feedback_colleague",
blank=True,
verbose_name=_("Colleague"),
)
subordinate_id = models.ManyToManyField(
Employee, related_name="feedback_subordinate", blank=True
Employee,
related_name="feedback_subordinate",
blank=True,
verbose_name=_("Subordinates"),
)
question_template_id = models.ForeignKey(
QuestionTemplate,
@@ -524,19 +534,23 @@ class Feedback(HorillaModel):
related_name="feedback_question_template",
null=False,
blank=False,
verbose_name=_("Question Template"),
)
status = models.CharField(
max_length=50, choices=STATUS_CHOICES, default="Not Started"
)
archive = models.BooleanField(null=True, blank=True, default=False)
start_date = models.DateField(null=False, blank=False)
end_date = models.DateField(null=True, blank=False)
start_date = models.DateField(null=False, blank=False, verbose_name=_("Start Date"))
end_date = models.DateField(null=True, blank=False, verbose_name=_("End Date"))
employee_key_results_id = models.ManyToManyField(
EmployeeKeyResult,
blank=True,
EmployeeKeyResult, blank=True, verbose_name=_("Key Result")
)
cyclic_feedback = models.BooleanField(
default=False, verbose_name=_("Is Cyclic Feedback")
)
cyclic_feedback_days_count = models.IntegerField(
blank=True, null=True, verbose_name=_("Cycle Period")
)
cyclic_feedback = models.BooleanField(default=False)
cyclic_feedback_days_count = models.IntegerField(blank=True, null=True)
cyclic_feedback_period = models.CharField(
max_length=50, choices=PERIOD, blank=True, null=True
)
@@ -547,6 +561,8 @@ class Feedback(HorillaModel):
class Meta:
ordering = ["-id"]
verbose_name = _("Feedback")
verbose_name_plural = _("Feedbacks")
def save(self, *args, **kwargs):
start_date = self.start_date

View File

@@ -9,32 +9,29 @@
{% block content %}
{% if feedback_form.errors %}
<!-- form errors -->
<div class="oh-wrapper">
<div class="oh-alert-container">
{% for error in feedback_form.non_field_errors %}
<div class="oh-alert oh-alert--animated oh-alert--danger">
{{ error }}
<div class="oh-wrapper">
<div class="oh-alert-container">
{% for error in feedback_form.non_field_errors %}
<div class="oh-alert oh-alert--animated oh-alert--danger">
{{ error }}
</div>
{% endfor %}
</div>
{% endfor %}
</div>
</div>
{% endif %}
<div class="oh-wrapper" id="message">
</div>
<div class="oh-wrapper" id="message"></div>
<!-- Feedback form'-->
<main class="oh-onboarding">
<div class="oh-onboarding-card oh-profile-section" style="max-width: 868px;">
<form action="{%url 'feedback-creation' %}" id="feedbackCreationForm" method="post">
{{feedback_form.non_field_errors}}
{{feedback_form.non_field_errors}}
{% csrf_token %}
<div class="oh-onboarding-card__address-group">
<h2 class="oh-onboarding-card__section-title">{% trans "Feedback" %}</h2>
<h2 class="oh-onboarding-card__section-title">{{feedback_form.verbose_name}}</h2>
<div class="oh-input__group ">
<label class="oh-input__label" for="{{feedback_form.review_cycle.id_for_label}}">{% trans "Title" %}</label>
<label class="oh-input__label"
for="{{feedback_form.review_cycle.id_for_label}}">{{feedback_form.review_cycle.label}}</label>
{{feedback_form.review_cycle}}
{{feedback_form.review_cycle.errors}}
</div>
@@ -42,7 +39,8 @@
<div class="col-12 col-sm-12 col-md-6 col-lg-6">
<div class="oh-input__group">
<div class="oh-input__group">
<label class="oh-input__label" for="{{feedback_form.employee_id.id_for_label}}">{% trans "Employee" %}</label>
<label class="oh-input__label"
for="{{feedback_form.employee_id.id_for_label}}">{{feedback_form.employee_id.label}}</label>
{{feedback_form.employee_id }}
{{feedback_form.employee_id.errors }}
<ul id="error-list" class="errorlist" style="display: none">
@@ -54,7 +52,8 @@
<div class="col-12 col-sm-12 col-md-6 col-lg-6">
<div class="oh-input__group">
<div class="oh-input__group">
<label class="oh-input__label" for="{{feedback_form.manager_id.id_for_label}}">{% trans "Manager" %}</label>
<label class="oh-input__label"
for="{{feedback_form.manager_id.id_for_label}}">{{feedback_form.manager_id.label}}</label>
{{feedback_form.manager_id}}
{{feedback_form.manager_id.errros}}
<ul id="error-list" class="errorlist" style="display: none">
@@ -68,7 +67,8 @@
<div class="col-12 col-sm-12 col-md-6 col-lg-6">
<div class="oh-input__group">
<div class="oh-input__group">
<label class="oh-input__label" for="{{feedback_form.subordinate_id.id_for_label}}">{% trans "Subordinates" %}</label>
<label class="oh-input__label"
for="{{feedback_form.subordinate_id.id_for_label}}">{{feedback_form.subordinate_id.label}}</label>
{{feedback_form.subordinate_id}}
{{feedback_form.subordinate_id.errors}}
</div>
@@ -77,7 +77,8 @@
<div class="col-12 col-sm-12 col-md-6 col-lg-6">
<div class="oh-input__group">
<div class="oh-input__group">
<label class="oh-input__label" for="{{feedback_form.colleague_id.id_for_label}}">{% trans "Colleague" %}</label>
<label class="oh-input__label"
for="{{feedback_form.colleague_id.id_for_label}}">{{feedback_form.colleague_id.label}}</label>
{{feedback_form.colleague_id}}
{{feedback_form.colleague_id.errors}}
</div>
@@ -88,7 +89,8 @@
<div class="col-12 col-sm-12 col-md-6 col-lg-4">
<div class="oh-input__group">
<div class="oh-input__group">
<label class="oh-input__label" for="{{feedback_form.period.id_for_label}}">{% trans "Period" %}</label>
<label class="oh-input__label"
for="{{feedback_form.period.id_for_label}}">{{feedback_form.period.label}}</label>
{{feedback_form.period}}
{{feedback_form.period.errors}}
</div>
@@ -97,7 +99,8 @@
<div class="col-12 col-sm-12 col-md-6 col-lg-4">
<div class="oh-input__group">
<div class="oh-input__group">
<label class="oh-input__label" for="{{feedback_form.start_date.id_for_label}}">{% trans "Start Date" %}</label>
<label class="oh-input__label"
for="{{feedback_form.start_date.id_for_label}}">{{feedback_form.start_date.label}}</label>
{{feedback_form.start_date}}
{{feedback_form.start_date.errors}}
</div>
@@ -106,7 +109,8 @@
<div class="col-12 col-sm-12 col-md-6 col-lg-4">
<div class="oh-input__group">
<div class="oh-input__group">
<label class="oh-input__label" for="{{feedback_form.end_date.id_for_label}}">{% trans "End Date" %}</label>
<label class="oh-input__label"
for="{{feedback_form.end_date.id_for_label}}">{{feedback_form.end_date.label}}</label>
{{feedback_form.end_date}}
{{feedback_form.end_date.errors}}
</div>
@@ -116,7 +120,8 @@
<div class="row">
<div class="col-12 col-sm-12 col-md-6 col-lg-6">
<div class="oh-input__group">
<label class="oh-input__label" for="{{feedback_form.question_template_id.id_for_label}}">{% trans "Question Template" %}</label>
<label class="oh-input__label"
for="{{feedback_form.question_template_id.id_for_label}}">{{feedback_form.question_template_id.label}}</label>
{{feedback_form.question_template_id}}
{{feedback_form.question_template_id.errors}}
<ul id="error-list" class="errorlist" style="display: none">
@@ -126,26 +131,27 @@
</div>
<div class="col-12 col-sm-12 col-md-6 col-lg-6">
<div class="oh-input__group">
<label class="oh-input__label" for="id_employee_key_results_id">{% trans "Key Result" %}</label>
<select name="employee_key_results_id" id="id_employee_key_results_id" class="oh-select oh-select--lg oh-select-no-search w-100 oh-select-2--large" multiple="multiple" style="display: none;">
<option value="">------------------</option>
</select>
<label class="oh-input__label"
for="id_employee_key_results_id">{{feedback_form.employee_key_results_id.label}}</label>
{{feedback_form.employee_key_results_id}}
{{feedback_form.employee_key_results_id.errors}}
</div>
</div>
</div>
<div class="row">
<div class="col-12 col-sm-12 col-md-6 col-lg-6 mb-5" id="">
<div class="oh-input__group">
<label class="oh-input__label" for="{{feedback_form.cyclic_feedback.id_for_label}}">{% trans "Is Cyclic Feedback" %}</label>
<label class="oh-input__label"
for="{{feedback_form.cyclic_feedback.id_for_label}}">{{feedback_form.cyclic_feedback.label}}</label>
<div class="oh-switch">
{{feedback_form.cyclic_feedback}}
{{feedback_form.cyclic_feedback}}
</div>
{{feedback_form.cyclic_feedback.errors}}
</div>
</div>
<div class="col-12 col-sm-12 col-md-6 col-lg-6" style="display:none" id="cyclic_feedback_period">
<div class="oh-input__group">
<label class="oh-input__label">{% trans "Cycle Period" %}</label>
<label class="oh-input__label" for="{{feedback_form.cyclic_feedback_days_count.id_for_label}}">{{feedback_form.cyclic_feedback_days_count.label}}</label>
<div class="w-100 d-flex">
{{feedback_form.cyclic_feedback_days_count}}
{{feedback_form.cyclic_feedback_period}}
@@ -157,10 +163,7 @@
</section>
<div class="w-100 d-flex align-items-center justify-content-end">
<button
type="submit"
class="oh-btn oh-btn--secondary oh-btn--w-100-resp"
>
<button type="submit" class="oh-btn oh-btn--secondary oh-btn--w-100-resp">
{% trans "Save" %}
</button>
</div>
@@ -171,28 +174,36 @@
<!-- period modal -->
<div class="oh-modal" id="PeriodModal" role="dialog" aria-labelledby="editKeyResultModal" aria-hidden="true">
<div class="oh-modal__dialog">
<!-- for creating period -->
<div class="oh-modal__dialog-header">
<button type="button" class="oh-modal__close" aria-label="Close">
<ion-icon name="close-outline"></ion-icon>
</button>
</div>
<div class="oh-modal__dialog-body" id="periodModalTarget">
<!-- for creating period -->
<div class="oh-modal__dialog-header">
<button type="button" class="oh-modal__close" aria-label="Close">
<ion-icon name="close-outline"></ion-icon>
</button>
</div>
<div class="oh-modal__dialog-body" id="periodModalTarget">
</div>
</div>
</div>
<!-- end of period modal -->
</div>
<!-- end of period modal -->
</main>
<button id="colleguesButton" hx-get="{% url 'get-collegues' %}" hx-target="#id_colleague_id" hidden > </button>
<button id="managerButton" hx-get="{% url 'get-collegues' %}" hx-target="#id_manager_id" hidden > </button>
<button id="subordinatesButton" hx-get="{% url 'get-collegues' %}" hx-target="#id_subordinate_id" hidden > </button>
<button id="keyresultButtton" hx-get="{% url 'get-collegues' %}" hx-target="#id_employee_key_results_id" hidden > </button>
<button id="colleguesButton" hx-get="{% url 'get-collegues' %}" hx-target="#id_colleague_id" hidden> </button>
<button id="managerButton" hx-get="{% url 'get-collegues' %}" hx-target="#id_manager_id" hidden> </button>
<button id="subordinatesButton" hx-get="{% url 'get-collegues' %}" hx-target="#id_subordinate_id" hidden> </button>
<button id="keyresultButtton" hx-get="{% url 'get-collegues' %}" hx-target="#id_employee_key_results_id" hidden></button>
<script>
$(document).ready(function(){
get_collegues($('#id_employee_id'))
get_collegues($('#id_employee_id'));
$('#id_colleague_id').on('click', function() {
console.log('Colleague field clicked');
});
$('#id_subordinate_id').on('click', function() {
console.log('Subordinate field clicked');
});
});
function get_collegues(element) {
var employee_id = $(element).val();
@@ -214,6 +225,4 @@
</script>
<script src="{% static 'src/feedback/feedback_creation.js' %}"></script>
<script src="{% static 'src/period/period.js' %}"></script>
{% endblock%}