Sales Person Wise Sales Order Read/Write Permission

I want to set Sales order Read/write Permission based on Sales Person tree. example:
Modern Trade Manger can able to read only his child sales man’s Sales Order & Retail Manager can only read His child’s Sales Order.

How can i do this ? anyone can help me plz?

1 Like

You should consider checking our Role Permission Manager & Perm levels:

https://erpnext.com/docs/user/manual/en/setting-up/users-and-permissions/role-based-permissions

https://erpnext.com/docs/user/manual/en/setting-up/articles/managing-perm-level/

When you mention this:

He should be able to read only his child salesman’s orders

Do you mean that the Modern Trade Suprervisor will be able to read ONLY the SO’s of Territory Sales Officer or of Territory Sales Officer and also TSO’s childs i.e. Abu Hasnat Sanim, Md Jibon etc ?

This is possible but via the default User Permission - you’ll have to create User Permission entries to allow Modern Trade Supervisor Employee those employees. Just to give you a number - that means for Modern Trade you create 9 entries for allowing each employee, then for Territorial Sales Officer you make 8 entries.

The last time I remember that permissions don’t work downstream like you are wanting it to. I think this could be possible via code. using the perm_query in hooks.py. It could roughly be something like this:

  1. Get current user’s employee id
  2. using the above employee id find the exact sales person entry.
  3. If the above sales person entry exists, then find all the immediate child sales person of the current employee
  4. Finally, allow that sales person all the sales order where the immediate root is either the user or any of his immediate child sales person.

perm_query does work but I’m not sure how to utilise the child doctype here because I’ll have to pull data from a child doctype which mentions the sales person who has worked on the sales order.

I Will try it. Thank you so much.

here’s an example of how to use permission query feature:

NOTE : This answer edits the sales_order.py file in erpnext app, which is not the standard practice and was done for demonstration only. The correct practice is to create a custom app, which has been written down in detail below.


This function works:

I saved this function in sales_order.py, but if you have a custom app save it in an appropriate python file

def perm_query(arg):
	#get current user's employee id
	current_employee = frappe.get_value("Employee",{"user_id":frappe.session.user},"name")
	print("Current employee : {}".format(current_employee))
	#get the salesperson entry name	
	sales_person = frappe.get_value("Sales Person",{"is_group":1,"employee":current_employee},"name")
	print("Sales Person : {}".format(sales_person))
	if sales_person:
		allowed_sp_list = [sales_person]
		print("Sales Person List : {}".format(allowed_sp_list))
		#get all immediate child of the sales person
		immediate_sp = [
			each_sp.get("name") for each_sp in frappe.get_all("Sales Person",{"parent_sales_person":sales_person},["name"])
		]
		
		allowed_sp_list.extend(immediate_sp)
		print("Sales Person List : {}".format(allowed_sp_list))

		final_string = ",".join( ["\"" + each_sp +"\"" for each_sp in allowed_sp_list] )
		print("Sales Person String : {}".format(final_string))
		return """name IN (SELECT parent FROM `tabSales Team` WHERE sales_person IN ({}))""".format(final_string)

Then include in erpnext/hooks.py:

permission_query_conditions = {
	"Sales Order" : "erpnext.selling.doctype.sales_order.sales_order.perm_query"
}

Thanks you

Also, that path mentioned in hooks.py must match the location of your function. Keep that in mind

i don’t uderstand where i push/save sales_order.py…
would u please tell more details?

Do you have a self hosted erpnext ? only then this will work for you.

Hello aamunim,

If you have hosted your own setup of ERPNext, then in your Custom App folder create Custom Script folder then in that create Sales Order folder in which you can place your sales order customised python and js files. In your customised sales_order.py file you can write the above permission query function and call that function from hooks.py file as described by @root13F Please give the accurate path of the folder in hooks.py for the script to work properly as expected.

i can’t change sales_order.py or hooks.py , every permission denied. help me plz ee

Before everything else, you need to provide your user frappe all permissions on the frappe-bench folder and all the folders and files inside it. Using this command:

chown -R frappe /home/frappe/frappe-bench


Now you should be able to create files and folders. But I’ll not let you edit the Sales Order python file because that is not the correct way to do it.

Now, since you do have a server, I’ll help you create a new app and you can store your code there.

You can create a new app by executing this command with frappe-bench folder in context

user@pc:~/frappe-bench$ bench new-app any-name-here

Then, install this app on the current site (You can find your currentsite written in the file named sites.txt in folder frappe-bench/sites).

Assuming your site is named site1.local, and your app name is customapp

user@pc:~/frappe-bench$ bench --site site1.local install-app customapp

This will be over in a matter of seconds because you have no doctype.

Then you can go ahead and make a new folder in path frappe-bench/apps/customapp/customapp/customapp. You can name your folder validations and then make a new py file named sales_order.py

Open this github gist and copy the code and paste it in your file:

Github Gist - Sales order Permission Query function

Then in hooks.py, copy and paste this:

permission_query_conditions = {
    "Sales Order": "customapp.customapp.validations.sales_call.sales_order.perm_query",
}

Replace word customapp with your app’s name everywhere. Also, perm_query is the function’s name that will return the condition string. So if you wish to rename the function to something else such as view_downline_orders or any relevant names, please be sure to update the same in hooks.py else you will encounter errors.

I have successfully done this. thank you so much

1 Like

Please test it thoroughly. It is bound to have bugs, and if there are let me know so I can fix them

1 Like