Mapping webform to doctype, get_context not working

I’ve created a DocType, Candidate to allow users to update their Candidate Profiles from the portal.

Following this great tutorial, Webinar on Frappe portals, everything works fine up until auto-populating of the web form. 10:00

To populate a webform with values of a user’s document, you need to add the following to the webform.py, in my case candidate_profile.py:

def get_context(context):
	candidate = frappe.get_doc("Candidate", {'email_id': frappe.session.user})
	context.doc = candidate
	frappe.form_dict.new = 0
	frappe.form_dict.name = candidate.name

The form, located on http://site1.local:8000/candidate-profile is then supposed to auto-populate with information from John Doe’s candidate profile.

However, the form remains blank on refresh.

It is not a permissions issue, as John Doe can view (but not update) his profile on this url:
http://site1.local:8000/candidate-profile?name=john@doe.co

Any ideas?

1 Like

I’ve tried it with the existing Patient doctype which uses the personal-details webform, and it also does not auto-populate. Do you think the get_context function does not execute for some reason?

1 Like

Is it really frappe.form_dict.name = candidate.name, not frappe.form_dict.first_name = candidate.name?

The form has both a name and first_name field, and neither works. But thanks for the comment.

I’ve found a workaround (or maybe this is how to connect web forms with docs):

  1. Create a portal page

  2. Create a button to redirect to the webform (in my case candidate-profile) quering the docname (in my case the user’s email):

<button class="btn btn-default btn-xs btn-info">
<a href="/candidate-profile?name={{ frappe.session.user }}"> Update Profile </a>
</button>

Hello.

I have run into the same issue following the Youtube tutorial. Anyone else have other suggestions? I don’t think one should add a query string to get the right context, since that should have been the purpose of setting the context in the get_context method. This way, a user may freely access other records (correct me if I’m wrong) by changing the URL if they know the email. This must work as it is necessary in creating any customizations in the portal. Help… :sob:

Thank you!

Hi, Check this function. You will get an idea. You have to return context. Also use context.update. Hope this helps. All the best

def get_context(context):
if (frappe.session.user == “Guest” or
frappe.db.get_value(“User”, frappe.session.user, “user_type”)==“Website User”):
frappe.throw(_(“You are not permitted to access this page.”), frappe.PermissionError)

hooks = frappe.get_hooks()
flag = False
company_name = frappe.defaults.get_user_default("company")
try:
	boot = frappe.sessions.get()
except Exception as e:
	boot = frappe._dict(status='failed', error = str(e))
	print(frappe.get_traceback())

if 'Administrator' in frappe.get_roles(frappe.session.user):
	flag = True
# this needs commit
csrf_token = frappe.sessions.get_csrf_token()

frappe.db.commit()
condition = "owner = '{user}'".format(user=frappe.session.user)

boot_json = frappe.as_json(boot)

# remove script tags from boot
boot_json = re.sub("\<script\>[^<]*\</script\>", "", boot_json)
if flag:
	context.update({
	"no_cache": 1,
	"build_version": get_build_version(),
	"include_js": hooks["app_include_js"],
	"include_css": hooks["app_include_css"],
	"sounds": hooks["sounds"],
	"boot": boot if context.get("for_mobile") else boot_json,
	"csrf_token": csrf_token,
	"background_image": (boot.status != 'failed' and
		(boot.user.background_image or boot.default_background_image) or None),
	"google_analytics_id": frappe.conf.get("google_analytics_id"),
	"mixpanel_id": frappe.conf.get("mixpanel_id"),
	"total_qty":(frappe.db.sql("select case when sum(actual_qty) is null then 0 else sum(actual_qty) end as totalqty from `tabStock Ledger Entry`"))[0][0],
	"total_sales_invoice":(frappe.db.sql("SELECT count(*) AS count FROM `tabSales Invoice` WHERE `tabSales Invoice`.docstatus = 1"))[0][0],
	"total_sales_value":format_currency((frappe.db.sql(" SELECT case when  sum(`tabSales Invoice`.grand_total) is null then 0 else sum(round(`tabSales Invoice`.grand_total,2)) end as gtt FROM `tabSales Invoice` WHERE `tabSales Invoice`.docstatus = 1"))[0][0],"INR", locale="en_IN"),
	"today_sales_value":format_currency((frappe.db.sql("SELECT case when  sum(`tabSales Invoice`.grand_total) is null then 0 else sum(round(`tabSales Invoice`.grand_total,2)) end as gtt FROM `tabSales Invoice` WHERE `tabSales Invoice`.docstatus = 1 and `tabSales Invoice`.posting_date = curdate() "))[0][0],"INR", locale="en_IN"),
	"today_sales_invoice":(frappe.db.sql("SELECT count(*) AS count FROM `tabSales Invoice` WHERE (`tabSales Invoice`.docstatus=1 and `tabSales Invoice`.posting_date= curdate()) "))[0][0],
	"supplier_count":(frappe.db.sql("select count(supplier_name) from `tabSupplier`"))[0][0],
	"today_supplier_count":(frappe.db.sql("select count(supplier_name) from `tabSupplier` where DATE(`tabSupplier`.creation)=curdate();"))[0][0],
	"expired":(frappe.db.sql("select count(expiry_date) from `tabBatch` where `tabBatch`.expiry_date<curdate()"))[0][0],
	"today_purchase_invoice":(frappe.db.sql("SELECT count(*) AS count FROM `tabPurchase Invoice` WHERE (`tabPurchase Invoice`.docstatus=1 and `tabPurchase Invoice`.posting_date= curdate()) "))[0][0],
	"today_purchase_value":format_currency((frappe.db.sql("SELECT case when  sum(`tabPurchase Invoice`.grand_total) is null then 0 else sum(round(`tabPurchase Invoice`.grand_total,2)) end as gtt FROM `tabPurchase Invoice` WHERE `tabPurchase Invoice`.docstatus = 1 and `tabPurchase Invoice`.posting_date = curdate() "))[0][0],"INR", locale="en_IN"),
	"total_batch_count":(frappe.db.sql("select count(batch_id) from `tabBatch` where `tabBatch`.expiry_date>=curdate()"))[0][0],
	"out_of_stock":(frappe.db.sql("select count(`tabItem`.item_code) from (`tabItem` left join `tabBin` on `tabItem`.item_code=`tabBin`.item_code)  where `tabBin`.actual_qty is null"))[0][0],
	"acc_payable":format_currency((frappe.db.sql("select case when sum(outstanding_amount) is null then 0 else sum(outstanding_amount) end as pay from `tabPurchase Invoice`"))[0][0],"INR", locale="en_IN"),
	"acc_receivable":format_currency((frappe.db.sql("select case when sum(outstanding_amount) is null then 0 else sum(outstanding_amount) end as pay from `tabSales Invoice`"))[0][0],"INR", locale="en_IN"),
	"company_name":company_name
	
	})

else:
	print("#33333333333333333333333")
	context.update({
		"no_cache": 1,
		"build_version": get_build_version(),
		"include_js": hooks["app_include_js"],
		"include_css": hooks["app_include_css"],
		"sounds": hooks["sounds"],
		"boot": boot if context.get("for_mobile") else boot_json,
		"csrf_token": csrf_token,
		"background_image": (boot.status != 'failed' and
			(boot.user.background_image or boot.default_background_image) or None),
		"google_analytics_id": frappe.conf.get("google_analytics_id"),
		"mixpanel_id": frappe.conf.get("mixpanel_id"),
		"total_qty":(frappe.db.sql("select case when sum(actual_qty) is null then 0 else sum(actual_qty) end as totalqty from `tabStock Ledger Entry` where {cod} ".format(cod = condition)))[0][0],
		"total_sales_invoice":(frappe.db.sql("SELECT count(*) AS count FROM `tabSales Invoice` WHERE `tabSales Invoice`.docstatus = 1 AND {cod} ".format(cod = condition)))[0][0],
		"total_sales_value":format_currency((frappe.db.sql(" SELECT case when  sum(`tabSales Invoice`.grand_total) is null then 0 else sum(round(`tabSales Invoice`.grand_total,2)) end as gtt FROM `tabSales Invoice` WHERE `tabSales Invoice`.docstatus = 1 AND {cod} ".format(cod = condition)))[0][0],"INR", locale="en_IN"),
		"today_sales_value":format_currency((frappe.db.sql("SELECT case when  sum(`tabSales Invoice`.grand_total) is null then 0 else sum(round(`tabSales Invoice`.grand_total,2)) end as gtt FROM `tabSales Invoice` WHERE `tabSales Invoice`.docstatus = 1 and `tabSales Invoice`.posting_date = curdate() AND {cod} ".format(cod = condition)))[0][0],"INR", locale="en_IN"),
		"today_sales_invoice":(frappe.db.sql("SELECT count(*) AS count FROM `tabSales Invoice` WHERE (`tabSales Invoice`.docstatus=1 and `tabSales Invoice`.posting_date= curdate()) AND {cod} ".format(cod = condition)))[0][0],
		"supplier_count":(frappe.db.sql("select count(supplier_name) from `tabSupplier`"))[0][0],
		"today_supplier_count":(frappe.db.sql("select count(supplier_name) from `tabSupplier` where DATE(`tabSupplier`.creation)=curdate();"))[0][0],
		"expired":(frappe.db.sql("select count(expiry_date) from `tabBatch` tb where tb.expiry_date<curdate() AND tb.{cod} ".format(cod = condition)))[0][0],
		"today_purchase_invoice":(frappe.db.sql("SELECT count(*) AS count FROM `tabPurchase Invoice` tpi WHERE (tpi.docstatus=1 and tpi.posting_date= curdate()) and tpi.{cod} ".format(cod = condition)))[0][0],
		"today_purchase_value":format_currency((frappe.db.sql("SELECT case when  sum(tps.grand_total) is null then 0 else sum(round(tps.grand_total,2)) end as gtt FROM `tabPurchase Invoice` tps WHERE tps.docstatus = 1 and tps.posting_date = curdate() AND {cod} ".format(cod = condition)))[0][0],"INR", locale="en_IN"),
		"total_batch_count":(frappe.db.sql("select count(batch_id) from `tabBatch` tb where tb.expiry_date>=curdate() AND tb.{cod} ".format(cod = condition)))[0][0],
		"out_of_stock":(frappe.db.sql("select count(ts.item_code) from (`tabItem` ts left join `tabBin` on ts.item_code=`tabBin`.item_code)  where `tabBin`.actual_qty is null AND ts.{cod} ".format(cod = condition)))[0][0],
		"acc_payable":format_currency((frappe.db.sql("select case when sum(outstanding_amount) is null then 0 else sum(outstanding_amount) end as pay from `tabPurchase Invoice` where {cod} ".format(cod = condition)))[0][0],"INR", locale="en_IN"),
		"acc_receivable":format_currency((frappe.db.sql("select case when sum(outstanding_amount) is null then 0 else sum(outstanding_amount) end as pay from `tabSales Invoice` where {cod} ".format(cod = condition)))[0][0],"INR", locale="en_IN"),
		"company_name":company_name
	})

return context