From f61361c961e45c211eb548a4a1753232f064fa0e Mon Sep 17 00:00:00 2001 From: phot0n Date: Wed, 27 Jul 2022 02:15:44 +0530 Subject: [PATCH] feat: override webform's whitelisted accept method --- payments/hooks.py | 6 +- payments/overrides/payment_webform.py | 110 ++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 3 deletions(-) diff --git a/payments/hooks.py b/payments/hooks.py index 024a01b..9ccf5f0 100644 --- a/payments/hooks.py +++ b/payments/hooks.py @@ -127,9 +127,9 @@ scheduler_events = { # Overriding Methods # ------------------------------ # -# override_whitelisted_methods = { -# "frappe.desk.doctype.event.event.get_events": "pay.event.get_events" -# } +override_whitelisted_methods = { + "frappe.website.doctype.web_form.web_form.accept": "payments.overrides.payment_webform.accept" +} # # each overriding function accepts a `data` argument; # generated from the base implementation of the doctype dashboard, diff --git a/payments/overrides/payment_webform.py b/payments/overrides/payment_webform.py index d9149e2..e2a9fd2 100644 --- a/payments/overrides/payment_webform.py +++ b/payments/overrides/payment_webform.py @@ -1,4 +1,8 @@ +import json + import frappe +from frappe.core.doctype.file import remove_file_by_url +from frappe.rate_limiter import rate_limit from frappe.website.doctype.web_form.web_form import WebForm from payments.utils import get_payment_gateway_controller @@ -45,3 +49,109 @@ class PaymentWebForm(WebForm): # Redirect the user to this url return controller.get_payment_url(**payment_details) + + + +@frappe.whitelist(allow_guest=True) +@rate_limit(key="web_form", limit=5, seconds=60, methods=["POST"]) +def accept(web_form, data, docname=None, for_payment=False): + """Save the web form""" + data = frappe._dict(json.loads(data)) + for_payment = frappe.parse_json(for_payment) + + files = [] + files_to_delete = [] + + web_form = frappe.get_doc("Web Form", web_form) + + if data.name and not web_form.allow_edit: + frappe.throw(_("You are not allowed to update this Web Form Document")) + + frappe.flags.in_web_form = True + meta = frappe.get_meta(data.doctype) + + if docname: + # update + doc = frappe.get_doc(data.doctype, docname) + else: + # insert + doc = frappe.new_doc(data.doctype) + + # set values + for field in web_form.web_form_fields: + fieldname = field.fieldname + df = meta.get_field(fieldname) + value = data.get(fieldname, None) + + if df and df.fieldtype in ("Attach", "Attach Image"): + if value and "data:" and "base64" in value: + files.append((fieldname, value)) + if not doc.name: + doc.set(fieldname, "") + continue + + elif not value and doc.get(fieldname): + files_to_delete.append(doc.get(fieldname)) + + doc.set(fieldname, value) + + if for_payment: + web_form.validate_mandatory(doc) + doc.run_method("validate_payment") + + if doc.name: + if web_form.has_web_form_permission(doc.doctype, doc.name, "write"): + doc.save(ignore_permissions=True) + else: + # only if permissions are present + doc.save() + + else: + # insert + if web_form.login_required and frappe.session.user == "Guest": + frappe.throw(_("You must login to submit this form")) + + ignore_mandatory = True if files else False + + doc.insert(ignore_permissions=True, ignore_mandatory=ignore_mandatory) + + # add files + if files: + for f in files: + fieldname, filedata = f + + # remove earlier attached file (if exists) + if doc.get(fieldname): + remove_file_by_url(doc.get(fieldname), doctype=doc.doctype, name=doc.name) + + # save new file + filename, dataurl = filedata.split(",", 1) + _file = frappe.get_doc( + { + "doctype": "File", + "file_name": filename, + "attached_to_doctype": doc.doctype, + "attached_to_name": doc.name, + "content": dataurl, + "decode": True, + } + ) + _file.save() + + # update values + doc.set(fieldname, _file.file_url) + + doc.save(ignore_permissions=True) + + if files_to_delete: + for f in files_to_delete: + if f: + remove_file_by_url(f, doctype=doc.doctype, name=doc.name) + + frappe.flags.web_form_doc = doc + + if for_payment: + # this is needed for Payments app + return web_form.get_payment_gateway_url(doc) + else: + return doc