Override whitelist method and class method for the same class

this method override

def make_filters(self):

class method

this method override

def fill_employee_details(self):

whitelist method

this method DID NOT override

def set_filter_conditions(query, filters, qb_object):

class method

in hook file i add these

override_doctype_class = {
    "Payroll Entry":"my_app.overrides.payroll_entry.CustomPayrollEntry",
},
override_whitelisted_methods = {
    "Payroll Entry":"my_app.overrides.payroll_entry.CustomPayrollEntry"
}

and in payroll_entry file i add these

import frappe
from hrms.payroll.doctype.payroll_entry.payroll_entry import PayrollEntry,get_employee_list

class CustomPayrollEntry(PayrollEntry):
 # this method override
    def make_filters(self):
        # frappe.throw("make_filters")
        filters = frappe._dict(
            status = self.custom_employee_statuss,
            company=self.company,
            branch=self.branch,
            department=self.department,
            designation=self.designation,
            grade=self.grade,
            currency=self.currency,
            start_date=self.start_date,
            end_date=self.end_date,
            payroll_payable_account=self.payroll_payable_account,
            salary_slip_based_on_timesheet=self.salary_slip_based_on_timesheet,
        )

        if not self.salary_slip_based_on_timesheet:
            filters.update(dict(payroll_frequency=self.payroll_frequency))

        return filters
    @frappe.whitelist()
 # this method override
    def fill_employee_details(self):
        # frappe.throw("fill_employee_details")
        filters = self.make_filters()
        employees = get_employee_list(filters=filters, as_dict=True, ignore_match_conditions=True)
        self.set("employees", [])

        if not employees:
            error_msg = _(
                "No employees found for the mentioned criteria:<br>Company: {0}<br> Currency: {1}<br>Payroll Payable Account: {2}"
            ).format(
                frappe.bold(self.company),
                frappe.bold(self.currency),
                frappe.bold(self.payroll_payable_account),
            )
            if self.branch:
                error_msg += "<br>" + _("Branch: {0}").format(frappe.bold(self.branch))
            if self.department:
                error_msg += "<br>" + _("Department: {0}").format(frappe.bold(self.department))
            if self.custom_employee_statuss:
                error_msg += "<br>" + _("custom_employee_statuss: {0}").format(frappe.bold(self.custom_employee_statuss))
            if self.designation:
                error_msg += "<br>" + _("Designation: {0}").format(frappe.bold(self.designation))
            if self.start_date:
                error_msg += "<br>" + _("Start date: {0}").format(frappe.bold(self.start_date))
            if self.end_date:
                error_msg += "<br>" + _("End date: {0}").format(frappe.bold(self.end_date))
            frappe.throw(error_msg, title=_("No employees found"))

        self.set("employees", employees)
        self.number_of_employees = len(self.employees)
        self.update_employees_with_withheld_salaries()

        return self.get_employees_with_unmarked_attendance()
  # this method DID NOT override
    def set_filter_conditions(query, filters, qb_object):
        frappe.throw("set_filter_conditions")
        """Append optional filters to employee query"""
        if filters.get("employees"):
            query = query.where(qb_object.name.notin(filters.get("employees")))

        for fltr_key in ["branch", "department", "designation", "grade","status"]:
            if filters.get(fltr_key):
                query = query.where(qb_object[fltr_key] == filters[fltr_key])

        return query

Because set_filter_conditions method is outside the class you will have to do monkey patching to override this method

i read both artical and i did not get it
could you share other artical could help me more with example?

from hrms.payroll.doctype.payroll_entry import payroll_entry as _payroll_entry
from custom_app.app_module.overrides.payroll_entry import custom_payroll_entry as _custom_payroll_entry

_payroll_entry.set_filter_conditions = _custom_payroll_entry.set_filter_conditions

Paste this code in hooks.py file
Make sure you have created function and change file path according to your file structure

1 Like


when i paste it and restrart the server i get this message
internal server error

from custom_app.app_module.overrides.payroll_entry import custom_payroll_entry as _custom_payroll_entry

Change the above path according to your custom app structure, and also check the payroll entry form path. I have just given an example of how it works.

1 Like

the gold border is the right thing that i must to focued in it
the above error was because the uncorrect path as you warned me in advance

from  hrms.payroll.doctype.payroll_entry import payroll_entry as payroll_entry

from my_app.overrides import payroll_entry as custom_payroll_entry


this is the right thing

thx a lot for your help and i learn new thing in frappe @ejaaz :+1:

1 Like