Skip to content

Commit

Permalink
fix: Webform Permission for custom doctype (frappe#26232)
Browse files Browse the repository at this point in the history
* fix: Webform Permission for custom doctype

* fix: sider fix

* fix: app check condition for getting correct list_context

* chore: Better naming convention

* test: Added test case to check permission for webform of custom doctype

* chore: linting issue

* chore: linting issue

* fix: sider fix

* test: minor changes

* chore: linter and better naming method

* chore: linter fix

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
  • Loading branch information
shariquerik and nabinhait committed Sep 14, 2021
1 parent 95460d9 commit 9aa6f52
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 2 deletions.
36 changes: 34 additions & 2 deletions erpnext/controllers/website_list_for_contact.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import frappe
from frappe import _
from frappe.modules.utils import get_module_app
from frappe.utils import flt, has_common
from frappe.utils.user import is_website_user

Expand All @@ -21,8 +22,32 @@ def get_list_context(context=None):
"get_list": get_transaction_list
}

def get_webform_list_context(module):
if get_module_app(module) != 'erpnext':
return
return {
"get_list": get_webform_transaction_list
}

def get_webform_transaction_list(doctype, txt=None, filters=None, limit_start=0, limit_page_length=20, order_by="modified"):
""" Get List of transactions for custom doctypes """
from frappe.www.list import get_list

if not filters:
filters = []

def get_transaction_list(doctype, txt=None, filters=None, limit_start=0, limit_page_length=20, order_by="modified"):
meta = frappe.get_meta(doctype)

for d in meta.fields:
if d.fieldtype == 'Link' and d.fieldname != 'amended_from':
allowed_docs = [d.name for d in get_transaction_list(doctype=d.options, custom=True)]
allowed_docs.append('')
filters.append((d.fieldname, 'in', allowed_docs))

return get_list(doctype, txt, filters, limit_start, limit_page_length, ignore_permissions=False,
fields=None, order_by="modified")

def get_transaction_list(doctype, txt=None, filters=None, limit_start=0, limit_page_length=20, order_by="modified", custom=False):
user = frappe.session.user
ignore_permissions = False

Expand All @@ -46,7 +71,7 @@ def get_transaction_list(doctype, txt=None, filters=None, limit_start=0, limit_p
filters.append(('customer', 'in', customers))
elif suppliers:
filters.append(('supplier', 'in', suppliers))
else:
elif not custom:
return []

if doctype == 'Request for Quotation':
Expand All @@ -56,9 +81,16 @@ def get_transaction_list(doctype, txt=None, filters=None, limit_start=0, limit_p
# Since customers and supplier do not have direct access to internal doctypes
ignore_permissions = True

if not customers and not suppliers and custom:
ignore_permissions = False
filters = []

transactions = get_list_for_transactions(doctype, txt, filters, limit_start, limit_page_length,
fields='name', ignore_permissions=ignore_permissions, order_by='modified desc')

if custom:
return transactions

return post_process(doctype, transactions)

def get_list_for_transactions(doctype, txt, filters, limit_start, limit_page_length=20,
Expand Down
1 change: 1 addition & 0 deletions erpnext/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
# website
update_website_context = ["erpnext.shopping_cart.utils.update_website_context", "erpnext.education.doctype.education_settings.education_settings.update_website_context"]
my_account_context = "erpnext.shopping_cart.utils.update_my_account_context"
webform_list_context = "erpnext.controllers.website_list_for_contact.get_webform_list_context"

calendars = ["Task", "Work Order", "Leave Application", "Sales Order", "Holiday List", "Course Schedule"]

Expand Down
138 changes: 138 additions & 0 deletions erpnext/tests/test_webform.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import unittest

import frappe

from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order


class TestWebsite(unittest.TestCase):
def test_permission_for_custom_doctype(self):
create_user('Supplier 1', 'supplier1@gmail.com')
create_user('Supplier 2', 'supplier2@gmail.com')
create_supplier_with_contact('Supplier1', 'All Supplier Groups', 'Supplier 1', 'supplier1@gmail.com')
create_supplier_with_contact('Supplier2', 'All Supplier Groups', 'Supplier 2', 'supplier2@gmail.com')
po1 = create_purchase_order(supplier='Supplier1')
po2 = create_purchase_order(supplier='Supplier2')

create_custom_doctype()
create_webform()
create_order_assignment(supplier='Supplier1', po = po1.name)
create_order_assignment(supplier='Supplier2', po = po2.name)

frappe.set_user("Administrator")
# checking if data consist of all order assignment of Supplier1 and Supplier2
self.assertTrue('Supplier1' and 'Supplier2' in [data.supplier for data in get_data()])

frappe.set_user("supplier1@gmail.com")
# checking if data only consist of order assignment of Supplier1
self.assertTrue('Supplier1' in [data.supplier for data in get_data()])
self.assertFalse([data.supplier for data in get_data() if data.supplier != 'Supplier1'])

frappe.set_user("supplier2@gmail.com")
# checking if data only consist of order assignment of Supplier2
self.assertTrue('Supplier2' in [data.supplier for data in get_data()])
self.assertFalse([data.supplier for data in get_data() if data.supplier != 'Supplier2'])

frappe.set_user("Administrator")

def get_data():
webform_list_contexts = frappe.get_hooks('webform_list_context')
if webform_list_contexts:
context = frappe._dict(frappe.get_attr(webform_list_contexts[0])('Buying') or {})
kwargs = dict(doctype='Order Assignment', order_by = 'modified desc')
return context.get_list(**kwargs)

def create_user(name, email):
frappe.get_doc({
'doctype': 'User',
'send_welcome_email': 0,
'user_type': 'Website User',
'first_name': name,
'email': email,
'roles': [{"doctype": "Has Role", "role": "Supplier"}]
}).insert(ignore_if_duplicate = True)

def create_supplier_with_contact(name, group, contact_name, contact_email):
supplier = frappe.get_doc({
'doctype': 'Supplier',
'supplier_name': name,
'supplier_group': group
}).insert(ignore_if_duplicate = True)

if not frappe.db.exists('Contact', contact_name+'-1-'+name):
new_contact = frappe.new_doc("Contact")
new_contact.first_name = contact_name
new_contact.is_primary_contact = True,
new_contact.append('links', {
"link_doctype": "Supplier",
"link_name": supplier.name
})
new_contact.append('email_ids', {
"email_id": contact_email,
"is_primary": 1
})

new_contact.insert(ignore_mandatory=True)

def create_custom_doctype():
frappe.get_doc({
'doctype': 'DocType',
'name': 'Order Assignment',
'module': 'Buying',
'custom': 1,
'autoname': 'field:po',
'fields': [
{'label': 'PO', 'fieldname': 'po', 'fieldtype': 'Link', 'options': 'Purchase Order'},
{'label': 'Supplier', 'fieldname': 'supplier', 'fieldtype': 'Data', "fetch_from": "po.supplier"}
],
'permissions': [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
},
{
"read": 1,
"role": "Supplier"
}
]
}).insert(ignore_if_duplicate = True)

def create_webform():
frappe.get_doc({
'doctype': 'Web Form',
'module': 'Buying',
'title': 'SO Schedule',
'route': 'so-schedule',
'doc_type': 'Order Assignment',
'web_form_fields': [
{
'doctype': 'Web Form Field',
'fieldname': 'po',
'fieldtype': 'Link',
'options': 'Purchase Order',
'label': 'PO'
},
{
'doctype': 'Web Form Field',
'fieldname': 'supplier',
'fieldtype': 'Data',
'label': 'Supplier'
}
]

}).insert(ignore_if_duplicate = True)

def create_order_assignment(supplier, po):
frappe.get_doc({
'doctype': 'Order Assignment',
'po': po,
'supplier': supplier,
}).insert(ignore_if_duplicate = True)

0 comments on commit 9aa6f52

Please sign in to comment.