def get_form_data(doctype, docname=None, web_form_name=None): web_form = frappe.get_doc('Web Form', web_form_name) if web_form.login_required and frappe.session.user == 'Guest': frappe.throw(_("Not Permitted"), frappe.PermissionError) out = frappe._dict() out.web_form = web_form if frappe.session.user != 'Guest' and not docname and not web_form.allow_multiple: docname = frappe.db.get_value(doctype, {"owner": frappe.session.user}, "name") if docname: doc = frappe.get_doc(doctype, docname) if has_web_form_permission(doctype, docname, ptype='read'): out.doc = doc else: frappe.throw(_("Not permitted"), frappe.PermissionError) # For Table fields, server-side processing for meta for field in out.web_form.web_form_fields: if field.fieldtype == "Table": field.fields = get_in_list_view_fields(field.options) out.update({field.fieldname: field.fields}) if field.fieldtype == "Link": field.fieldtype = "Autocomplete" field.options = get_link_options( web_form_name, field.options, field.allow_read_on_all_link_options ) return out
def has_permission(doc, ptype=None, user=None): has_access = False user = user or frappe.session.user if ptype == 'create': has_access = frappe.has_permission('File', 'create', user=user) if not doc.is_private or doc.owner in [user, 'Guest' ] or user == 'Administrator': has_access = True if doc.attached_to_doctype and doc.attached_to_name: attached_to_doctype = doc.attached_to_doctype attached_to_name = doc.attached_to_name try: ref_doc = frappe.get_doc(attached_to_doctype, attached_to_name) if ptype in ['write', 'create', 'delete']: has_access = ref_doc.has_permission( 'write') or has_web_form_permission( attached_to_doctype, attached_to_name, ptype='write') if ptype == 'delete' and not has_access: frappe.throw( _("Cannot delete file as it belongs to {0} {1} for which you do not have permissions" ).format(doc.attached_to_doctype, doc.attached_to_name), frappe.PermissionError) else: has_access = ref_doc.has_permission('read') except frappe.DoesNotExistError: # if parent doc is not created before file is created # we cannot check its permission so we will use file's permission pass return has_access
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 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(doc.get(fieldname), doctype=doc.doctype, name=doc.name) frappe.flags.web_form_doc = doc if for_payment: return web_form.get_payment_gateway_url(doc) else: return doc
def get_context(self, context): '''Build context to render the `web_form.html` template''' self.set_web_form_module() context._login_required = False if self.login_required and frappe.session.user == "Guest": context._login_required = True doc, delimeter = make_route_string(frappe.form_dict) context.doc = doc context.delimeter = delimeter # check permissions if frappe.session.user == "Guest" and frappe.form_dict.name: frappe.throw(_("You need to be logged in to access this {0}.").format(self.doc_type), frappe.PermissionError) if frappe.form_dict.name and not has_web_form_permission(self.doc_type, frappe.form_dict.name): frappe.throw(_("You don't have the permissions to access this document"), frappe.PermissionError) self.reset_field_parent() if self.is_standard: self.use_meta_fields() if not context._login_required: if self.allow_edit: if self.allow_multiple: if not frappe.form_dict.name and not frappe.form_dict.new: # list data is queried via JS context.is_list = True else: if frappe.session.user != 'Guest' and not frappe.form_dict.name: frappe.form_dict.name = frappe.db.get_value(self.doc_type, {"owner": frappe.session.user}, "name") if not frappe.form_dict.name: # only a single doc allowed and no existing doc, hence new frappe.form_dict.new = 1 # always render new form if login is not required or doesn't allow editing existing ones if not self.login_required or not self.allow_edit: frappe.form_dict.new = 1 self.load_document(context) context.parents = self.get_parents(context) if self.breadcrumbs: context.parents = frappe.safe_eval(self.breadcrumbs, { "_": _ }) context.has_header = ((frappe.form_dict.name or frappe.form_dict.new) and (frappe.session.user!="Guest" or not self.login_required)) if context.success_message: context.success_message = frappe.db.escape(context.success_message.replace("\n", "<br>")).strip("'") self.add_custom_context_and_script(context) if not context.max_attachment_size: context.max_attachment_size = get_max_file_size() / 1024 / 1024 context.show_in_grid = self.show_in_grid self.load_translations(context)