Hi, I would like to restrict accounting users from viewing journal entries related to payroll. Management staff alone should create or view payroll entries.
User Permissions seems to allow access to specific journal entries by number.
Is there a way to remove access to specific patterns?
I don’t think there’s a simple way to do this. Payroll aggregates individual salary slips into a single Journal Entry via the Payroll Entry for exactly the reasons you imply.
Something functionally similar could probably be done via User Permissions, but it’d be messy and tedious to maintain.
Thanks. I took payroll as an example but there are several situations where it may be important to hide entries based on different attributes.
Especially in a small company, it is important to hide entries related to a certain location, vendor etc. from some users. It would be quite a common requirement.
Solution: set permission query conditions on both Journal Entry and GL Entry as following
Logic: if the user is not Administrator and not assigned the Accounts Manager role, then in both Journal Entry list and General Ledger report the journal entries generated via payroll( booked to the default payroll payable account defined in company master) will be excluded via the query conditions(SQL where clause with subquery), if user is Administrator or has Accounts Manager role assigned, no extra where condition to be applied.
Warning: sub Query in use, if large number of records in Journal Entry and GL Entry, performance impact need to be considered and monitored.
hooks.py, please adapt to your custom app name accordingly
def exclude_payroll_journal_entry(user):
if not user: user = frappe.session.user
if user != 'Administrator' and 'Accounts Manager' not in frappe.get_roles():
return """(name not in (select parent from `tabJournal Entry Account`
where account = (select default_payroll_payable_account from `tabCompany`
where name = company)))"""
def exclude_payroll_gl_entry(user):
if not user: user = frappe.session.user
if user != 'Administrator' and 'Accounts Manager' not in frappe.get_roles():
return """(account <> (select c.default_payroll_payable_account from `tabCompany` as c
where c.name = company) and
against <> (select cc.default_payroll_payable_account from `tabCompany` as cc
where cc.name = company)
)"""
Very cool. I was not aware of that functionality. Every time I feel like I know my way around Frappe, I realize there’s something I’ve completely missed or completely misunderstood!