[ADD] EMPLOYEE: Bonus point system and view inside employee profile view

This commit is contained in:
Horilla
2024-01-22 19:17:12 +05:30
parent a245901b14
commit f2037f5167
19 changed files with 501 additions and 33 deletions

View File

@@ -108,3 +108,11 @@ def user_perms(perms):
permission names return method
"""
return json.dumps(list(perms.values_list("codename", flat="True")))
@register.filter(name="abs_value")
def abs_value(value):
"""
permission names return method
"""
return abs(value)

View File

@@ -5,6 +5,7 @@ This page is used to register the model with admins site.
"""
from django.contrib import admin
from employee.models import (
BonusPoint,
Employee,
EmployeeWorkInformation,
EmployeeBankDetails,
@@ -21,4 +22,4 @@ from simple_history.admin import SimpleHistoryAdmin
admin.site.register(Employee)
admin.site.register(EmployeeBankDetails)
admin.site.register(EmployeeWorkInformation, SimpleHistoryAdmin)
admin.site.register([EmployeeNote, EmployeeTag, PolicyMultipleFile, Policy])
admin.site.register([EmployeeNote, EmployeeTag, PolicyMultipleFile, Policy, BonusPoint])

View File

@@ -28,6 +28,7 @@ from django.forms import DateInput, TextInput
from django.utils.translation import gettext as _
from django.utils.translation import gettext_lazy as trans
from employee.models import (
BonusPoint,
Employee,
EmployeeWorkInformation,
EmployeeBankDetails,
@@ -478,3 +479,19 @@ class PolicyForm(ModelForm):
if commit:
instance.attachments.add(*multiple_attachment_ids)
return instance, attachemnts
class BonusPointAddForm(ModelForm):
class Meta:
model = BonusPoint
fields = ["points", "reason"]
widgets = {
'reason': forms.TextInput(attrs={'required': 'required'}),
}
class BonusPointRedeemForm(ModelForm):
class Meta:
model = BonusPoint
fields = ["points"]

View File

@@ -7,10 +7,14 @@ This module is used to register models for employee app
import datetime as dtime
from datetime import date, datetime
import json
import threading
import time
from typing import Any
from django.conf import settings
from django.db import models
from django.contrib.auth.models import User, Permission
from django.dispatch import receiver
from django.db.models.signals import post_save, pre_delete
from django.utils.translation import gettext_lazy as trans
from django.utils.translation import gettext as _
from django.core.exceptions import ValidationError
@@ -574,3 +578,53 @@ class Policy(models.Model):
def delete(self, *args, **kwargs):
super().delete(*args, **kwargs)
self.attachments.all().delete()
class BonusPoint(models.Model):
CONDITIONS =[
('==',_('equals')),
('>',_('grater than')),
('<',_('less than')),
('>=',_('greater than or equal')),
('<=',_('less than or equal')),
]
employee_id = models.OneToOneField(Employee, on_delete=models.PROTECT ,blank=True, null=True, related_name='bonus_point')
points = models.IntegerField(default=0, help_text="Use negative numbers to reduce points.")
encashment_condition = models.CharField(max_length=100,choices = CONDITIONS,blank=True, null=True)
redeeming_points = models.IntegerField(blank=True, null=True)
reason = models.TextField(blank=True, null=True)
history = HorillaAuditLog(
related_name="history_set",
bases=[
HorillaAuditInfo,
],
)
def __str__(self):
return f"{self.employee_id} - {self.points} Points"
def tracking(self):
"""
This method is used to return the tracked history of the instance
"""
return get_diff(self)
@receiver(post_save, sender=Employee)
def bonus_post_save(sender, instance, **_kwargs):
if not BonusPoint.objects.filter(employee_id__id = instance.id).exists():
BonusPoint.objects.create(
employee_id = instance
)
class BonusPointThreading(threading.Thread):
def run(self):
time.sleep(5)
employees = Employee.objects.all()
for employee in employees:
if not BonusPoint.objects.filter(employee_id__id = employee.id).exists():
BonusPoint.objects.create(
employee_id = employee
)
BonusPointThreading().start()

View File

@@ -214,6 +214,17 @@
>{% trans "Performance" %}</a
>
</li>
<li class="oh-general__tab">
<a
hx-get={% url 'bonus-points-tab' employee.id %}
hx-target="#bonus_points_target"
data-action="general-tab"
data-target="#bonus_points_target"
class="oh-general__tab-link"
role="button"
>{% trans "Bonus Points" %}</a
>
</li>
</ul>
<div
@@ -233,6 +244,12 @@
>
{% include 'tabs/payroll-tab.html' %}
</div>
<div
class="oh-general__tab-target oh-profile__info-tab mb-4 d-none"
id="bonus_points_target"
>
{% include "tabs/bonus_points.html" %}
</div>
<div
class="oh-general__tab-target oh-profile__info-tab mb-4 d-none"
id="allowance_deduction"

View File

@@ -289,6 +289,19 @@
>
</li>
{% endif %}
{% if perms.employee.view_employeenote or request.user|check_manager:employee %}
<li class="oh-general__tab">
<a
hx-get={% url 'bonus-points-tab' employee.id %}
hx-target="#bonus_points_target"
data-action="general-tab"
data-target="#bonus_points_target"
class="oh-general__tab-link"
role="button"
>{% trans "Bonus Points" %}</a
>
</li>
{% endif %}
</ul>
<div
@@ -303,6 +316,12 @@
>
</div>
<div
class="oh-general__tab-target oh-profile__info-tab mb-4 d-none"
id="bonus_points_target"
>
{% include "tabs/bonus_points.html" %}
</div>
<div
class="oh-general__tab-target oh-profile__info-tab mb-4 d-none"
id="note_target"

View File

@@ -14,7 +14,7 @@
{% endfor %}
{% if perms.employee.add_policy %}
<input type="hidden" name="csrfmiddlewaretoken"/>
{% csrf_token %}
<input type="file" name="files" class="d-none" multiple="true" id="addFile_18" onchange="submitForm(this)" />
<input type="submit" class="d-none add_more_submit" value="save" />
<label for="addFile_18" title="Add Files" onclick="console.log($(this).closest('[type=file]'));"

View File

@@ -0,0 +1,112 @@
{% load i18n %} {% load basefilters %}
<div class="oh-wrapper d-flex justify-content-between mt-4">
<div class="oh-faq-cards">
<div class="oh-faq-card">
<div class="d-flex justify-content-between align-items-center">
<h3 class="oh-faq-card__title">{% trans "Bonus Points" %}</h3>
{% if perms.employee.add_bonuspoint or request.user|check_manager:employee %}
<div class="oh-dropdown">
<button
class="oh-btn oh-btn--secondary-outline oh-stop-prop oh-accordion-meta__btn p-2"
title="Add points"
data-toggle="oh-modal-toggle"
data-target="#addPointsModal"
hx-get="{% url 'add-bonus-points' employee.id %}"
hx-target="#addPointTarget"
>
<ion-icon
name="add-outline"
role="img"
class="md hydrated"
aria-label="ellipsis vertical"
></ion-icon>
</button>
</div>
{% endif %}
</div>
<div class="oh-timeoff-modal__profile-content">
<div class="oh-profile mb-2">
<div class="oh-profile__avatar">
<img src="{{employee.get_avatar}}" class="oh-profile__image me-2" />
</div>
<div class="oh-timeoff-modal__profile-info">
<span class="oh-timeoff-modal__user m-0 fw-bold">{{employee}}</span>
<span class="oh-timeoff-modal__user m-0" style="font-size: 12px; color: #4d4a4a">
{{employee.get_department}} / {{employee.get_job_position}}</span>
</div>
</div>
</div>
<div class="card-body d-flex justify-content-between align-items-center p-3" style="height: 100px;">
<h4 style="font-size: 16px; color: #4f5153; width: 60%;"> {% trans "Balance points to redeem:" %} </h4>
<h4 class="float-end fw-bold">{{points.points}}</h4>
</div>
<a
hx-get="{% url 'redeem-points' employee.id %}"
hx-target="#redeemModalTarget"
data-toggle="oh-modal-toggle"
data-target="#redeemModal"
class="oh-btn oh-btn--secondary oh-btn--block"
>{% trans "Redeem Now" %}</a
>
</div>
</div>
<div class="oh-faq-card" style="width: 60%;">
{% for activity in activity_list %}
<div class="oh-helpdesk__chat-update pb-0">
{% if activity.type == 'Bonus point created' %}
<span> --> {% trans "Bonus Account created" %} </span>
<span class="dateformat_changer">{{ activity.date|date:"d N Y"}}</span>
{% else %}
<span
>{% if activity.reason == 'bonus points has been redeemed.' %} <strong> --> {{activity.points|abs_value}} </strong> {% else %}<strong>--> {{activity.user}}</strong> {% trans "Added " %}
<strong>{{activity.points}} </strong> {% trans "bonus points for " %}{% endif %} <a title="{{activity.reason}}">{{activity.reason|truncatechars:40}}</a> </span
>
<span class="dateformat_changer">{{ activity.date|date:"d N Y"}}</span>
{% endif %}
</div>
{% endfor %}
</div>
</div>
<div
class="oh-modal"
id="addPointsModal"
role="dialog"
aria-labelledby="addPointsModal"
aria-hidden="true"
>
<div class="oh-modal__dialog">
<div class="oh-modal__dialog-header">
<span class="oh-modal__dialog-title" id="addPointsModalLabel">
<h5>{% trans "Add Bonus Points" %}</h5>
</span>
<button class="oh-modal__close" aria-label="Close">
<ion-icon name="close-outline"></ion-icon>
</button>
</div>
<div class="oh-modal__dialog-body" id="addPointTarget"></div>
</div>
</div>
<div
class="oh-modal"
id="redeemModal"
role="dialog"
aria-labelledby="redeemModal"
aria-hidden="true"
>
<div class="oh-modal__dialog oh-modal__dialog--timeoff oh-timeoff-modal">
<div class="oh-modal__dialog-header">
<h2 class="oh-modal__dialog-title" id="">{% trans "Redeem bonus points" %}</h2>
<button class="oh-modal__close" aria-label="Close">
<ion-icon name="close-outline"></ion-icon>
</button>
</div>
<div
class="oh-modal__dialog-body oh-modal__dialog-relative oh-timeoff-modal__body"
id="redeemModalTarget"
></div>
</div>
</div>

View File

@@ -0,0 +1,40 @@
{% load i18n %}
<form
class="oh-general__tab-target oh-profile-section"
action="{% url 'add-bonus-points' emp_id %}"
method="post"
>
{% csrf_token %}
<div class="row mb-4">
<div class="col-12 col-sm-12 col-md-12 col-lg-4">
<label
class="oh-label"
for="id_points"
title="{{form.points.help_text|safe}}"
>{% trans "Points :" %}</label
>
<div
class="w-100 d-flex"
style="align-items: center; justify-content: center !important"
>
{{form.points}} {{form.points.errors}}
</div>
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-8">
<label class="oh-label" for="id_reason"
>{% trans "Reason :" %}</label
>
<div
class="w-100 d-flex"
style="align-items: center; justify-content: center !important"
>
{{form.reason}} {{form.reason.errors}}
</div>
</div>
</div>
<div class="d-flex flex-row-reverse">
<button class="oh-btn oh-btn--secondary pr-4 pl-4" type="submit">
{% trans "Add" %}
</button>
</div>
</form>

View File

@@ -0,0 +1,29 @@
{% load i18n %}
<form
class="oh-general__tab-target oh-profile-section"
action="{% url 'redeem-points' employee.id %}"
method="post"
>
{% csrf_token %}
<div class="row mb-4">
<div class="col-12 col-sm-12 col-md-12 col-lg-12">
<label
class="oh-label"
for="id_points"
title="{{form.points.help_text|safe}}"
>{% trans "Points :" %}</label
>
<div
class="w-100 d-flex"
style="align-items: center; justify-content: center !important"
>
{{form.points}} {{form.points.errors}}
</div>
</div>
</div>
<div class="d-flex flex-row-reverse">
<button class="oh-btn oh-btn--secondary pr-4 pl-4" type="submit">
{% trans "Add" %}
</button>
</div>
</form>

View File

@@ -211,6 +211,9 @@ urlpatterns = [
name="contract-tab",
kwargs={"model": Employee},
),
path("bonus-points-tab/<int:emp_id>", views.bonus_points_tab, name="bonus-points-tab"),
path("add-bonus-points/<int:emp_id>", views.add_bonus_points, name="add-bonus-points"),
path("redeem-points/<int:emp_id>", views.redeem_points, name="redeem-points"),
path("employee-select/", views.employee_select, name="employee-select"),
path(
"employee-select-filter/",

View File

@@ -69,6 +69,8 @@ from base.methods import (
)
from employee.filters import EmployeeFilter, EmployeeReGroup
from employee.forms import (
BonusPointAddForm,
BonusPointRedeemForm,
BulkUpdateFieldForm,
EmployeeExportExcelForm,
EmployeeForm,
@@ -79,9 +81,15 @@ from employee.forms import (
EmployeeBankDetailsUpdateForm,
excel_columns,
)
from employee.models import Employee, EmployeeNote, EmployeeWorkInformation, EmployeeBankDetails
from employee.models import (
BonusPoint,
Employee,
EmployeeNote,
EmployeeWorkInformation,
EmployeeBankDetails,
)
from payroll.methods.payslip_calc import dynamic_attr
from payroll.models.models import Allowance, Contract, Deduction
from payroll.models.models import Allowance, Contract, Deduction, Reimbursement
from pms.models import Feedback
from recruitment.models import Candidate
@@ -445,7 +453,7 @@ def allowances_deductions_tab(request, emp_id):
"active_contracts": active_contracts,
"allowances": employee_allowances if employee_allowances else None,
"deductions": employee_deductions if employee_deductions else None,
"employee":employee,
"employee": employee,
}
return render(request, "tabs/allowance_deduction-tab.html", context=context)
@@ -1100,7 +1108,7 @@ def employee_filter_view(request):
previous_data = request.GET.urlencode()
field = request.GET.get("field")
queryset = Employee.objects.filter()
employees = EmployeeFilter(request.GET,queryset=queryset).qs
employees = EmployeeFilter(request.GET, queryset=queryset).qs
if request.GET.get("is_active") != "False":
employees = employees.filter(is_active=True)
page_number = request.GET.get("page")
@@ -1342,7 +1350,9 @@ def employee_archive(request, obj_id):
messages.success(request, message)
else:
related_models = ", ".join(model for model in result.get("related_models"))
messages.warning(request, _(f"Can't archive.Employee assigned as {related_models}"))
messages.warning(
request, _(f"Can't archive.Employee assigned as {related_models}")
)
return HttpResponseRedirect(request.META.get("HTTP_REFERER"))
@@ -2132,6 +2142,7 @@ def employee_select_filter(request):
return JsonResponse(context)
@login_required
@manager_can_enter(perm="employee.view_employeenote")
def note_tab(request, emp_id):
@@ -2147,7 +2158,7 @@ def note_tab(request, emp_id):
"""
# employee = Employee.objects.get(id=emp_id)
employee_obj = Employee.objects.get(id=emp_id)
notes = EmployeeNote.objects.filter(employee_id = emp_id)
notes = EmployeeNote.objects.filter(employee_id=emp_id)
return render(
request,
@@ -2173,9 +2184,7 @@ def add_note(request, emp_id=None):
note.updated_by = request.user.employee_get
note.save()
messages.success(request, _("Note added successfully.."))
response = render(
request, "tabs/add_note.html", {"form": form}
)
response = render(request, "tabs/add_note.html", {"form": form})
return HttpResponse(
response.content.decode("utf-8") + "<script>location.reload();</script>"
)
@@ -2221,6 +2230,7 @@ def employee_note_update(request, note_id):
},
)
@login_required
@manager_can_enter(perm="employee.delete_employeenote")
def employee_note_delete(request, note_id):
@@ -2235,3 +2245,101 @@ def employee_note_delete(request, note_id):
messages.success(request, _("Note deleted successfully..."))
return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/"))
@login_required
@manager_can_enter(perm="employee.view_bonuspoint")
def bonus_points_tab(request, emp_id):
"""
This function is used to view performance tab of an employee in employee individual & profile view.
Parameters:
request (HttpRequest): The HTTP request object.
emp_id (int): The id of the employee.
Returns: return note-tab template
"""
employee_obj = Employee.objects.get(id=emp_id)
points = BonusPoint.objects.get(employee_id=emp_id)
trackings = points.tracking()
activity_list = []
for history in trackings:
activity_list.append(
{
"type":history["type"],
"date": history["pair"][0].history_date,
"points": history["pair"][0].points - history["pair"][1].points,
"user":getattr(User.objects.filter(id = history["pair"][0].history_user_id).first(),"employee_get",None),
"reason": history["pair"][0].reason,
}
)
return render(
request,
"tabs/bonus_points.html",
{"employee": employee_obj, "points": points, "activity_list": activity_list},
)
@login_required
@manager_can_enter(perm="employee.add_bonuspoint")
def add_bonus_points(request, emp_id):
bonus_point = BonusPoint.objects.get(employee_id=emp_id)
form = BonusPointAddForm()
if request.method == "POST":
form = BonusPointAddForm(
request.POST,
request.FILES,
)
if form.is_valid():
form.save(commit=False)
bonus_point.points += form.cleaned_data["points"]
bonus_point.reason = form.cleaned_data["reason"]
bonus_point.save()
messages.success(
request,
_("Added {} points to the bonus account").format(
form.cleaned_data["points"]
),
)
return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/"))
return render(
request,
"tabs/forms/add_points.html",
{
"form": form,
"emp_id": emp_id,
},
)
@login_required
@owner_can_enter("employee.view_bonuspoint", Employee)
def redeem_points(request,emp_id):
user = Employee.objects.get(id=emp_id)
form = BonusPointRedeemForm()
if request.method == 'POST':
form = BonusPointRedeemForm(request.POST)
if form.is_valid():
form.save(commit=False)
points = form.cleaned_data['points']
reimbursement = Reimbursement.objects.create(
title = f"Bonus point Redeem for {user}",
type = "bonus_encashment",
employee_id = user,
bonus_to_encash =points,
description = f"{user} want to redeem {points} points",
allowance_on = date.today(),
)
return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/"))
return render(
request,
"tabs/forms/redeem_points_form.html",
{
"form": form,
"employee": user,
},
)

View File

@@ -106,7 +106,10 @@ def get_diff(instance):
}
)
if create_history:
updated_by = create_history.history_user.employee_get
try:
updated_by = create_history.history_user.employee_get
except:
updated_by = Bot()
delta_changes.append(
{
"type": f"{create_history.instance.__class__._meta.verbose_name.capitalize()} created",

View File

@@ -477,7 +477,7 @@ class MultipleFileField(forms.FileField):
result = [single_file_clean(d, initial) for d in data]
else:
result = [single_file_clean(data, initial)]
return result[0]
return result[0] if result else None
class ReimbursementForm(ModelForm):
@@ -535,7 +535,7 @@ class ReimbursementForm(ModelForm):
type = self.data["type"]
elif self.instance is not None:
type = self.instance.type
print(type)
if not request.user.has_perm("payroll.add_reimbursement"):
exclude_fields.append("employee_id")
@@ -544,11 +544,21 @@ class ReimbursementForm(ModelForm):
"leave_type_id",
"cfd_to_encash",
"ad_to_encash",
"bonus_to_encash",
]
elif self.instance.pk or self.data.get("type") == "leave_encashment":
elif self.instance.pk and type == "leave_encashment" or self.data.get("type") == "leave_encashment":
exclude_fields = exclude_fields + [
"attachment",
"amount",
"bonus_to_encash",
]
elif self.instance.pk and type == "bonus_encashment" or self.data.get("type") == "bonus_encashment":
exclude_fields = exclude_fields + [
"attachment",
"amount",
"leave_type_id",
"cfd_to_encash",
"ad_to_encash",
]
if self.instance.pk:
exclude_fields = exclude_fields + ["type", "employee_id"]

View File

@@ -18,7 +18,7 @@ from django.db.models.signals import pre_save, pre_delete
from django.http import QueryDict
from asset.models import Asset
from base import thread_local_middleware
from employee.models import EmployeeWorkInformation
from employee.models import BonusPoint, EmployeeWorkInformation
from employee.models import Employee, Department, JobPosition
from base.models import Company, EmployeeShift, WorkType, JobRole
from base.horilla_company_manager import HorillaCompanyManager
@@ -1497,6 +1497,7 @@ class Reimbursement(models.Model):
reimbursement_types = [
("reimbursement", "Reimbursement"),
("leave_encashment", "Leave Encashment"),
("bonus_encashment", "Bonus Point Encashment"),
]
status_types = [
("requested", "Requested"),
@@ -1526,6 +1527,11 @@ class Reimbursement(models.Model):
help_text="Carry Forward Days to encash",
verbose_name="Carry forward days",
)
bonus_to_encash = models.IntegerField(
default=0,
help_text="Bonus points to encash",
verbose_name="Bonus points",
)
amount = models.FloatField(default=0)
status = models.CharField(
max_length=10, choices=status_types, default="requested", editable=False
@@ -1556,16 +1562,34 @@ class Reimbursement(models.Model):
raise ValidationError({"attachment": "This field is required"})
elif self.type == "leave_encashment" and self.leave_type_id is None:
raise ValidationError({"leave_type_id": "This field is required"})
self.cfd_to_encash = max((round(self.cfd_to_encash * 2) / 2), 0)
self.ad_to_encash = max((round(self.ad_to_encash * 2) / 2), 0)
assigned_leave = self.leave_type_id.employee_available_leave.filter(
employee_id=self.employee_id
).first()
if self.type == "leave_encashment":
self.cfd_to_encash = max((round(self.cfd_to_encash * 2) / 2), 0)
self.ad_to_encash = max((round(self.ad_to_encash * 2) / 2), 0)
assigned_leave = self.leave_type_id.employee_available_leave.filter(
employee_id=self.employee_id
).first()
if self.status != "approved" or self.allowance_id is None:
super().save(*args, **kwargs)
if self.status == "approved" and self.allowance_id is None:
if self.type == "reimbursement":
proceed = True
elif self.type == "bonus_encashment":
proceed = False
bonus_points = BonusPoint.objects.get(employee_id=self.employee_id)
if bonus_points.points >= self.bonus_to_encash:
proceed = True
bonus_points.points -= self.bonus_to_encash
bonus_points.reason = "bonus points has been redeemed."
bonus_points.save()
else:
request = getattr(
thread_local_middleware._thread_locals, "request", None
)
if request:
messages.info(
request,
"The employee don't have that much bonus points to encash.",
)
else:
proceed = False
if assigned_leave:

View File

@@ -3,7 +3,7 @@
hx-encoding="multipart/form-data">
{{form.as_p}}
</form>
<table class="oh-table oh-table--sortable" {% if not form.instance.id or form.instance.type == "reimbursement" %}
<table class="oh-table oh-table--sortable" {% if not form.instance.id or form.instance.type == "reimbursement" or form.instance.type == "bonus_encashment" %}
id="availableTable" style="display: none;" {% endif %}>
<thead>
<tr>

View File

@@ -80,6 +80,15 @@
<p class="oh-faq-card__desc" style="height: 150px;">
<iframe id="iframe_pdf" src="{{ req.attachment.url }}" style="width: 100%" frameborder="0"></iframe>
</p>
{% elif req.type == 'bonus_encashment' %}
<p class="oh-faq-card__desc" style="max-height: 180px;">
<i>
{% trans 'Requsted for' %} <span class="text-danger"> {{ req.bonus_to_encash }} </span>
{% trans 'Bonus points to encash.' %}
</i>
<input style="display: block;padding: 10px;margin-top: 10px;" type="number" required default="0" min="0" placeholder="Amount"
name="amount" class="mt-2"{% if req.status == "approved" %}disabled{% endif %} {% if req.amount %} value="{{req.amount}}"{% endif %} />
</p>
{% else %}
<p class="oh-faq-card__desc" style="max-height: 180px;">
<i>

View File

@@ -42,21 +42,32 @@
if (element.val() == 'reimbursement') {
$('#reimbursementModalBody [name=attachment]').parent().show()
$('#reimbursementModalBody [name=attachment]').attr("required",true)
$('#reimbursementModalBody [name=leave_type_id]').parent().hide().attr("required",false)
$('#reimbursementModalBody [name=cfd_to_encash]').parent().hide().attr("required",false)
$('#reimbursementModalBody [name=ad_to_encash]').parent().hide().attr("required",false)
$('#reimbursementModalBody [name=amount]').parent().show().attr("required",true)
$('#reimbursementModalBody #availableTable').hide().attr("required",false)
$('#reimbursementModalBody [name=leave_type_id]').parent().hide().attr("required",false)
$('#reimbursementModalBody [name=cfd_to_encash]').parent().hide().attr("required",false)
$('#reimbursementModalBody [name=ad_to_encash]').parent().hide().attr("required",false)
$('#reimbursementModalBody [name=amount]').parent().show().attr("required",true)
$('#reimbursementModalBody #availableTable').hide().attr("required",false)
$('#reimbursementModalBody [name=bonus_to_encash]').parent().hide().attr("required",false)
} else if(element.val() == 'leave_encashment') {
$('#reimbursementModalBody [name=attachment]').parent().hide()
$('#reimbursementModalBody [name=attachment]').attr("required",false)
$('#reimbursementModalBody [name=leave_type_id]').parent().show().attr("required",true)
$('#reimbursementModalBody [name=cfd_to_encash]').parent().show().attr("required",true)
$('#reimbursementModalBody [name=ad_to_encash]').parent().show().attr("required",true)
$('#reimbursementModalBody [name=amount]').parent().hide().attr("required",false)
$('#reimbursementModalBody #availableTable').show().attr("required",true)
$('#reimbursementModalBody [name=leave_type_id]').parent().show().attr("required",true)
$('#reimbursementModalBody [name=cfd_to_encash]').parent().show().attr("required",true)
$('#reimbursementModalBody [name=ad_to_encash]').parent().show().attr("required",true)
$('#reimbursementModalBody [name=amount]').parent().hide().attr("required",false)
$('#reimbursementModalBody #availableTable').show().attr("required",true)
$('#reimbursementModalBody [name=bonus_to_encash]').parent().hide().attr("required",false)
} else if(element.val() == 'bonus_encashment') {
$('#reimbursementModalBody [name=attachment]').parent().hide()
$('#reimbursementModalBody [name=attachment]').attr("required",false)
$('#reimbursementModalBody [name=leave_type_id]').parent().hide().attr("required",false)
$('#reimbursementModalBody [name=cfd_to_encash]').parent().hide().attr("required",false)
$('#reimbursementModalBody [name=ad_to_encash]').parent().hide().attr("required",false)
$('#reimbursementModalBody [name=amount]').parent().hide().attr("required",false)
$('#reimbursementModalBody #availableTable').hide().attr("required",false)
$('#reimbursementModalBody [name=bonus_to_encash]').parent().show().attr("required",true)
}

View File

@@ -1099,6 +1099,9 @@ def approve_reimbursements(request):
for reimbursement in reimbursements:
if reimbursement.type == "leave_encashment":
reimbursement.amount = amount
elif reimbursement.type == "bonus_encashment" :
reimbursement.amount = amount
emp = reimbursement.employee_id
reimbursement.status = status
reimbursement.save()