[FIX] PAYROLL: #819

This commit is contained in:
Horilla
2025-07-16 14:42:59 +05:30
parent 89157fd997
commit e287d22d21

View File

@@ -785,7 +785,7 @@ class MultipleFileField(forms.FileField):
class ReimbursementForm(ModelForm):
"""
ReimbursementForm
Optimized Reimbursement / Encashment Form
"""
verbose_name = "Reimbursement / Encashment"
@@ -795,103 +795,111 @@ class ReimbursementForm(ModelForm):
fields = "__all__"
exclude = ["is_active"]
if apps.is_installed("leave"):
def get_encashable_leaves(self, employee):
LeaveType = get_horilla_model_class(app_label="leave", model="leavetype")
leaves = LeaveType.objects.filter(
employee_available_leave__employee_id=employee,
employee_available_leave__total_leave_days__gte=1,
is_encashable=True,
)
return leaves
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
exclude_fields = []
self.request = getattr(horilla_middlewares._thread_locals, "request", None)
self.employee = self.get_employee() # 819
if not self.instance.pk:
self.initial["allowance_on"] = str(datetime.date.today())
request = getattr(horilla_middlewares._thread_locals, "request", None)
if request:
employee = (
request.user.employee_get
if self.instance.pk is None
self.initial["employee_id"] = self.employee.id if self.employee else None
self.configure_fields()
def get_employee(self):
"""Resolves employee either from form data or request."""
employee_id = self.data.get("employee_id") if self.data else None
if employee_id:
return Employee.objects.filter(id=employee_id).first()
elif self.request:
return (
self.request.user.employee_get
if not self.instance.pk
else self.instance.employee_id
)
self.initial["employee_id"] = employee.id
if apps.is_installed("leave"):
AvailableLeave = get_horilla_model_class(
app_label="leave", model="availableleave"
)
return None
assigned_leaves = self.get_encashable_leaves(employee)
self.assigned_leaves = AvailableLeave.objects.filter(
leave_type_id__in=assigned_leaves, employee_id=employee
)
self.fields["leave_type_id"].queryset = assigned_leaves
self.fields["leave_type_id"].empty_label = None
self.fields["employee_id"].empty_label = None
def get_encashable_leaves(self, employee):
LeaveType = get_horilla_model_class(app_label="leave", model="leavetype")
return LeaveType.objects.filter(
employee_available_leave__employee_id=employee,
employee_available_leave__total_leave_days__gte=1,
is_encashable=True,
)
type_attr = self.fields["type"].widget.attrs
type_attr["onchange"] = "toggleReimbursmentType($(this))"
self.fields["type"].widget.attrs.update(type_attr)
def configure_fields(self):
exclude_fields = []
employee_attr = self.fields["employee_id"].widget.attrs
employee_attr["onchange"] = "getAssignedLeave($(this))"
self.fields["employee_id"].widget.attrs.update(employee_attr)
if self.request and not self.request.user.has_perm("payroll.add_reimbursement"):
exclude_fields.append("employee_id")
self.setup_leave_fields()
self.fields["type"].widget.attrs["onchange"] = "toggleReimbursmentType($(this))"
self.fields["employee_id"].widget.attrs[
"onchange"
] = "getAssignedLeave($(this))"
self.fields["allowance_on"].widget = forms.DateInput(
attrs={"type": "date", "class": "oh-input w-100"}
)
self.fields["attachment"] = MultipleFileField(label="Attachements")
self.fields["attachment"] = MultipleFileField(label="Attachments")
self.fields["attachment"].widget.attrs["accept"] = ".jpg, .jpeg, .png, .pdf"
# deleting fields based on type
type = None
if self.data and not self.instance.pk:
type = self.data["type"]
elif self.instance is not None:
type = self.instance.type
if not request.user.has_perm("payroll.add_reimbursement"):
exclude_fields.append("employee_id")
if type == "reimbursement" and self.instance.pk:
exclude_fields = exclude_fields + [
"leave_type_id",
"cfd_to_encash",
"ad_to_encash",
"bonus_to_encash",
]
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"]
self.exclude_fields_by_type(exclude_fields)
for field in exclude_fields:
if field in self.fields:
del self.fields[field]
self.fields.pop(field, None)
def setup_leave_fields(self):
"""Setup leave-related fields only if leave app is installed."""
if not apps.is_installed("leave") or not self.employee:
return
AvailableLeave = get_horilla_model_class(
app_label="leave", model="availableleave"
)
assigned_leaves = self.get_encashable_leaves(self.employee)
self.assigned_leaves = AvailableLeave.objects.filter(
leave_type_id__in=assigned_leaves, employee_id=self.employee
)
self.fields["leave_type_id"].queryset = assigned_leaves
self.fields["leave_type_id"].empty_label = None
self.fields["employee_id"].empty_label = None
def exclude_fields_by_type(self, exclude_fields):
"""Determine which fields to exclude based on type."""
type = (
self.data.get("type")
if self.data
else self.instance.type if self.instance else None
)
is_edit = self.instance and self.instance.pk
if type == "reimbursement" and is_edit:
exclude_fields += [
"leave_type_id",
"cfd_to_encash",
"ad_to_encash",
"bonus_to_encash",
]
elif type == "leave_encashment" and (is_edit or self.data):
exclude_fields += ["attachment", "amount", "bonus_to_encash"]
elif type == "bonus_encashment" and (is_edit or self.data):
exclude_fields += [
"attachment",
"amount",
"leave_type_id",
"cfd_to_encash",
"ad_to_encash",
]
if is_edit:
exclude_fields += ["type", "employee_id"]
def as_p(self):
"""