diff --git a/base/templates/base/general_settings.html b/base/templates/base/general_settings.html
index 9825ff155..3a839bc8a 100644
--- a/base/templates/base/general_settings.html
+++ b/base/templates/base/general_settings.html
@@ -2,9 +2,10 @@
{% include "recruitment/settings/settings.html" %}
-{% include "attendance/settings/settings.html" %}
{% include "offboarding/settings/settings.html" %}
+{% include "attendance/settings/settings.html" %}
{% include "payroll/settings/settings.html" %}
{% include "announcement/expiry_day.html" %}
+{% include "settings/encashment_settings.html" %}
{% endblock settings %}
\ No newline at end of file
diff --git a/base/views.py b/base/views.py
index 13a86d5f2..1ad69dcb2 100644
--- a/base/views.py
+++ b/base/views.py
@@ -123,7 +123,9 @@ from base.methods import (
get_key_instances,
sortby,
)
+from payroll.forms.forms import EncashmentGeneralSettingsForm
from payroll.forms.component_forms import PayrollSettingsForm
+from payroll.models.models import EncashmentGeneralSettings
from payroll.models.tax_models import PayrollSettings
from helpdesk.models import TicketType
from helpdesk.forms import TicketTypeForm
@@ -554,7 +556,11 @@ def user_group(request):
return render(
request,
"base/auth/group.html",
- {"permissions": permissions, "form": form, "groups": paginator_qry(groups,request.GET.get("page"))},
+ {
+ "permissions": permissions,
+ "form": form,
+ "groups": paginator_qry(groups, request.GET.get("page")),
+ },
)
@@ -599,7 +605,11 @@ def user_group_search(request):
return render(
request,
"base/auth/group_lines.html",
- {"permissions": permissions, "form": form, "groups": paginator_qry(groups,request.GET.get("page"))},
+ {
+ "permissions": permissions,
+ "form": form,
+ "groups": paginator_qry(groups, request.GET.get("page")),
+ },
)
@@ -3385,14 +3395,22 @@ def general_settings(request):
"""
instance = AnnouncementExpire.objects.first()
form = AnnouncementExpireForm(instance=instance)
+ encashment_instance = EncashmentGeneralSettings.objects.first()
+ encashment_form = EncashmentGeneralSettingsForm(instance=encashment_instance)
if request.method == "POST":
form = AnnouncementExpireForm(request.POST, instance=instance)
if form.is_valid():
form.save()
messages.success(request, _("Settings updated."))
return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/"))
- return render(request, "base/general_settings.html", {'form':form})
-
+ return render(
+ request,
+ "base/general_settings.html",
+ {
+ "form": form,
+ "encashment_form": encashment_form,
+ },
+ )
@login_required
@@ -3783,16 +3801,16 @@ def ticket_type_create(request):
form = TicketTypeForm()
if request.method == "POST":
form = TicketTypeForm(request.POST)
- if request.GET.get('ajax'):
+ if request.GET.get("ajax"):
if form.is_valid():
instance = form.save()
- response= {
- "errors": 'no_error',
- "ticket_id": instance.id,
- "title": instance.title,
- }
+ response = {
+ "errors": "no_error",
+ "ticket_id": instance.id,
+ "title": instance.title,
+ }
return JsonResponse(response)
-
+
errors = form.errors.as_json()
return JsonResponse({"errors": errors})
if form.is_valid():
@@ -3808,6 +3826,7 @@ def ticket_type_create(request):
},
)
+
@login_required
def ticket_type_update(request, t_type_id):
"""
diff --git a/employee/templates/settings/encashment_settings.html b/employee/templates/settings/encashment_settings.html
new file mode 100644
index 000000000..7c74d20b0
--- /dev/null
+++ b/employee/templates/settings/encashment_settings.html
@@ -0,0 +1,51 @@
+{% load i18n %}
+
diff --git a/employee/urls.py b/employee/urls.py
index c93184caa..eaafab4aa 100644
--- a/employee/urls.py
+++ b/employee/urls.py
@@ -282,5 +282,6 @@ urlpatterns = [
path("action-type-details",policies.action_type_details,name="action-type-details",),
path("disciplinary-filter-view", policies.disciplinary_filter_view, name="disciplinary-filter-view"),
path("search-disciplinary", policies.search_disciplinary, name="search-disciplinary"),
+ path("encashment-condition-create", views.encashment_condition_create, name="encashment-condition-create"),
]
diff --git a/employee/views.py b/employee/views.py
index e0bfa526e..554172bee 100755
--- a/employee/views.py
+++ b/employee/views.py
@@ -95,8 +95,9 @@ from employee.models import (
EmployeeWorkInformation,
EmployeeBankDetails,
)
+from payroll.forms.forms import EncashmentGeneralSettingsForm
from payroll.methods.payslip_calc import dynamic_attr
-from payroll.models.models import Allowance, Contract, Deduction, Reimbursement
+from payroll.models.models import Allowance, Contract, Deduction, EncashmentGeneralSettings, Reimbursement
from pms.models import Feedback
from recruitment.models import Candidate
from horilla_documents.models import Document, DocumentRequest
@@ -2745,16 +2746,20 @@ def redeem_points(request, emp_id):
"""
user = Employee.objects.get(id=emp_id)
form = BonusPointRedeemForm()
+ amount_for_bonus_point = EncashmentGeneralSettings.objects.first().bonus_amount if EncashmentGeneralSettings.objects.first() else 1
if request.method == "POST":
form = BonusPointRedeemForm(request.POST)
if form.is_valid():
form.save(commit=False)
points = form.cleaned_data["points"]
+ amount = amount_for_bonus_point * points
+
reimbursement = Reimbursement.objects.create(
title=f"Bonus point Redeem for {user}",
type="bonus_encashment",
employee_id=user,
bonus_to_encash=points,
+ amount = amount,
description=f"{user} want to redeem {points} points",
allowance_on=date.today(),
)
@@ -2854,3 +2859,17 @@ def organisation_chart(request):
"act_manager_id": manager.id,
}
return render(request, "organisation_chart/org_chart.html", context=context)
+
+
+@login_required
+def encashment_condition_create(request):
+ instance = EncashmentGeneralSettings.objects.first()
+ encashment_form = EncashmentGeneralSettingsForm(instance=instance)
+ if request.method == "POST":
+ encashment_form = EncashmentGeneralSettingsForm(request.POST,instance=instance)
+ if encashment_form.is_valid():
+ encashment_form.save()
+ messages.success(request, _("Settings updated."))
+ return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/"))
+
+ return render(request, "settings/encashment_settings.html", {"encashment_form":encashment_form,})
diff --git a/payroll/forms/forms.py b/payroll/forms/forms.py
index db96dc537..b6c61ead9 100644
--- a/payroll/forms/forms.py
+++ b/payroll/forms/forms.py
@@ -7,6 +7,7 @@ from django.forms import widgets
from django.utils.translation import gettext_lazy as trans
from django.template.loader import render_to_string
from payroll.models.models import (
+ EncashmentGeneralSettings,
PayrollGeneralSetting,
ReimbursementrequestComment,
WorkRecord,
@@ -154,3 +155,9 @@ class ReimbursementrequestCommentForm(ModelForm):
model = ReimbursementrequestComment
fields = ("comment",)
+
+
+class EncashmentGeneralSettingsForm(ModelForm):
+ class Meta:
+ model = EncashmentGeneralSettings
+ fields = "__all__"
diff --git a/payroll/models/models.py b/payroll/models/models.py
index 37c5574bd..272229689 100644
--- a/payroll/models/models.py
+++ b/payroll/models/models.py
@@ -1591,6 +1591,7 @@ class Reimbursement(models.Model):
def save(self, *args, **kwargs) -> None:
request = getattr(thread_local_middleware._thread_locals, "request", None)
+ amount_for_leave = EncashmentGeneralSettings.objects.first().leave_amount if EncashmentGeneralSettings.objects.first() else 1
# Setting the created use if the used dont have the permission
has_perm = request.user.has_perm("payroll.add_reimbursement")
@@ -1601,6 +1602,8 @@ class Reimbursement(models.Model):
elif self.type == "leave_encashment" and self.leave_type_id is None:
raise ValidationError({"leave_type_id": "This field is required"})
if self.type == "leave_encashment":
+ if self.status == "requested":
+ self.amount = (self.cfd_to_encash + self.ad_to_encash) * amount_for_leave
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(
@@ -1655,7 +1658,6 @@ class Reimbursement(models.Model):
"The employee don't have that much leaves to encash in CFD / Available days",
)
- # if self.ad
if proceed:
reimbursement = Allowance()
@@ -1677,15 +1679,16 @@ class Reimbursement(models.Model):
elif self.status == "canceled" and self.allowance_id is not None:
cfd_days = self.cfd_to_encash
available_days = self.ad_to_encash
- if assigned_leave:
- assigned_leave.available_days = (
- assigned_leave.available_days + available_days
- )
- assigned_leave.carryforward_days = (
- assigned_leave.carryforward_days + cfd_days
- )
- assigned_leave.save()
- self.allowance_id.delete()
+ if self.type == "leave encashment":
+ if assigned_leave:
+ assigned_leave.available_days = (
+ assigned_leave.available_days + available_days
+ )
+ assigned_leave.carryforward_days = (
+ assigned_leave.carryforward_days + cfd_days
+ )
+ assigned_leave.save()
+ self.allowance_id.delete()
def delete(self, *args, **kwargs):
if self.allowance_id:
@@ -1721,4 +1724,13 @@ class PayrollGeneralSetting(models.Model):
validators=[min_zero],
default=3,
)
- company_id = models.ForeignKey(Company, on_delete=models.CASCADE, null=True)
+ company_id = models.ForeignKey(Company,on_delete=models.CASCADE,null=True)
+
+
+class EncashmentGeneralSettings(models.Model):
+ """
+ BonusPointGeneralSettings model
+ """
+ bonus_amount = models.IntegerField(default = 1)
+ leave_amount = models.IntegerField(blank = True, null = True, verbose_name = "Amount")
+