def get_dynamic_linked_fields(doctype, without_ignore_user_permissions_enabled=False): ret = {} filters=[['fieldtype','=', 'Dynamic Link']] if without_ignore_user_permissions_enabled: filters.append(['ignore_user_permissions', '!=', 1]) # find dynamic links of parents links = frappe.get_all("DocField", fields=["parent as doctype", "fieldname", "options as doctype_fieldname"], filters=filters) links+= frappe.get_all("Custom Field", fields=["dt as doctype", "fieldname", "options as doctype_fieldname"], filters=filters) for df in links: if is_single(df.doctype): continue # optimized to get both link exists and parenttype possible_link = frappe.get_all(df.doctype, filters={df.doctype_fieldname: doctype}, fields=['parenttype'], distinct=True) if not possible_link: continue for d in possible_link: # is child if d.parenttype: ret[d.parenttype] = { "child_doctype": df.doctype, "fieldname": [df.fieldname], "doctype_fieldname": df.doctype_fieldname } else: ret[df.doctype] = { "fieldname": [df.fieldname], "doctype_fieldname": df.doctype_fieldname } return ret
def get_dynamic_linked_fields(doctype): ret = {} links = frappe.db.sql("""select parent as doctype, fieldname, options as doctype_fieldname from `tabDocField` where fieldtype='Dynamic Link'""", as_dict=True) links += frappe.db.sql("""select dt as doctype, fieldname, options as doctype_fieldname from `tabCustom Field` where fieldtype='Dynamic Link'""", as_dict=True) for df in links: if is_single(df.doctype): continue # optimized to get both link exists and parenttype possible_link = frappe.db.sql("""select distinct `{doctype_fieldname}`, parenttype from `tab{doctype}` where `{doctype_fieldname}`=%s""".format(**df), doctype, as_dict=True) if possible_link: for d in possible_link: # is child if d.parenttype: ret[d.parenttype] = { "child_doctype": df.doctype, "fieldname": df.fieldname, "doctype_fieldname": df.doctype_fieldname } else: ret[df.doctype] = { "fieldname": df.fieldname, "doctype_fieldname": df.doctype_fieldname } return ret
def check_if_latest(self, method="save"): from frappe.model.meta import is_single conflict = False if not cint(self.doc.fields.get('__islocal')): if is_single(self.doc.doctype): modified = frappe.db.get_value(self.doc.doctype, self.doc.name, "modified") if isinstance(modified, list): modified = modified[0] if cstr(modified) and cstr(modified) != cstr( self.doc.modified): conflict = True else: tmp = frappe.db.sql("""select modified, docstatus from `tab%s` where name="%s" for update""" % (self.doc.doctype, self.doc.name), as_dict=True) if not tmp: frappe.msgprint( """This record does not exist. Please refresh.""", raise_exception=1) modified = cstr(tmp[0].modified) if modified and modified != cstr(self.doc.modified): conflict = True self.check_docstatus_transition(tmp[0].docstatus, method) if conflict: frappe.msgprint(_("Error: Document has been modified after you have opened it") \ + (" (%s, %s). " % (modified, self.doc.modified)) \ + _("Please refresh to get the latest document."), raise_exception=TimestampMismatchError)
def get_dynamic_linked_fields(doctype, without_ignore_user_permissions_enabled=False): ret = {} filters=[['fieldtype','=', 'Dynamic Link']] if without_ignore_user_permissions_enabled: filters.append(['ignore_user_permissions', '!=', 1]) # find dynamic links of parents links = frappe.get_all("DocField", fields=["parent as doctype", "fieldname", "options as doctype_fieldname"], filters=filters) links+= frappe.get_all("Custom Field", fields=["dt as doctype", "fieldname", "options as doctype_fieldname"], filters=filters) for df in links: if is_single(df.doctype): continue # optimized to get both link exists and parenttype possible_link = frappe.db.sql("""select distinct `{doctype_fieldname}`, parenttype from `tab{doctype}` where `{doctype_fieldname}`=%s""".format(**df), doctype, as_dict=True) if not possible_link: continue for d in possible_link: # is child if d.parenttype: ret[d.parenttype] = { "child_doctype": df.doctype, "fieldname": [df.fieldname], "doctype_fieldname": df.doctype_fieldname } else: ret[df.doctype] = { "fieldname": [df.fieldname], "doctype_fieldname": df.doctype_fieldname } return ret
def default_field_resolver(obj: Any, info: GraphQLResolveInfo, **kwargs): parent_type: GraphQLObjectType = info.parent_type if not isinstance(info.parent_type, GraphQLObjectType): frappe.throw("Invalid GraphQL") if parent_type.name == "Query": # This section is executed on root query type fields dt = get_singular_doctype(info.field_name) if dt: if is_single(dt): kwargs["name"] = dt elif not frappe.db.exists(dt, kwargs.get("name")): raise frappe.DoesNotExistError( frappe._("{0} {1} not found").format(frappe._(dt), kwargs.get("name"))) return frappe._dict( doctype=dt, name=kwargs.get("name") ) plural_doctype = get_plural_doctype(info.field_name) if plural_doctype: frappe.has_permission(doctype=plural_doctype, throw=True) return CursorPaginator(doctype=plural_doctype).resolve(obj, info, **kwargs) if not isinstance(obj, (dict, Document)): return None should_resolve_from_doc = not not (obj.get("name") and ( obj.get("doctype") or get_singular_doctype(parent_type.name))) # check if requested field can be resolved # - default resolver for simple objects # - these form the resolvers for # "SET_VALUE_TYPE", "SAVE_DOC_TYPE", "DELETE_DOC_TYPE" mutations if obj.get(info.field_name) is not None: value = obj.get(info.field_name) if isinstance(value, CursorPaginator): return value.resolve(obj, info, **kwargs) if not should_resolve_from_doc: return value if should_resolve_from_doc: # this section is executed for Fields on DocType object types. hooks_cmd = frappe.get_hooks("gql_default_document_resolver") resolver = document_resolver if len(hooks_cmd): resolver = frappe.get_attr(hooks_cmd[-1]) return resolver( obj=obj, info=info, **kwargs ) return None
def fix_attach_field_urls(): # taken from an old patch attach_fields = (frappe.db.sql("""select parent, fieldname from `tabDocField` where fieldtype in ('Attach', 'Attach Image')""") + frappe.db.sql("""select dt, fieldname from `tabCustom Field` where fieldtype in ('Attach', 'Attach Image')""")) for doctype, fieldname in attach_fields: if is_single(doctype): frappe.db.sql("""update `tabSingles` set value=concat("/", `value`) where doctype=%(doctype)s and field=%(fieldname)s and value like 'files/%%'""", {"doctype": doctype, "fieldname": fieldname}) else: frappe.db.sql("""update `tab{doctype}` set `{fieldname}`=concat("/", `{fieldname}`) where `{fieldname}` like 'files/%'""".format(doctype=doctype, fieldname=fieldname))
def save_doc_resolver(obj, info: GraphQLResolveInfo, **kwargs): new_doc = frappe.parse_json(kwargs.get("doc")) new_doc.doctype = kwargs.get("doctype") if is_single(new_doc.doctype): new_doc.name = new_doc.doctype if new_doc.name and frappe.db.exists(new_doc.doctype, new_doc.name): doc = frappe.get_doc(new_doc.doctype, new_doc.name) else: doc = frappe.new_doc(new_doc.doctype) doc.update(new_doc) doc.save() doc.reload() return {"doctype": doc.doctype, "name": doc.name, "doc": doc.as_dict()}
def fix_attach_field_urls(): # taken from an old patch attach_fields = (frappe.db.sql( """select parent, fieldname from `tabDocField` where fieldtype in ('Attach', 'Attach Image')""" ) + frappe.db.sql( """select dt, fieldname from `tabCustom Field` where fieldtype in ('Attach', 'Attach Image')""" )) for doctype, fieldname in attach_fields: if is_single(doctype): frappe.db.sql( """update `tabSingles` set value=concat("/", `value`) where doctype=%(doctype)s and field=%(fieldname)s and value like 'files/%%'""", { "doctype": doctype, "fieldname": fieldname }) else: frappe.db.sql( """update `tab{doctype}` set `{fieldname}`=concat("/", `{fieldname}`) where `{fieldname}` like 'files/%'""".format(doctype=doctype, fieldname=fieldname))
def get_translations(language: str, doctype: str, docname: str = None, docfield: str = None): """ Try and get all possible translations as seen in Translation doctype only.. Arguments: language: [Required] doctype: [Required] docname: [Optional] docfield: [Optional] """ __check_read_renovation_translation_tool_perm() if is_single(doctype): docname = doctype possible_contexts = __formulate_possible_contexts(doctype=doctype, fieldname=docfield, docname=docname) if frappe.is_table(doctype): possible_parenttypes_and_parents = frappe.get_all(doctype, fields="Distinct parent,parenttype", filters=[["parenttype", "!=", ""], ['parent', '!=', '']]) for p in possible_parenttypes_and_parents: possible_contexts.extend( __formulate_possible_contexts(parenttype=p.get("parenttype"), parent=p.get("parent"))) filters = [["language", "=", language]] context_filters = [["context", "in", possible_contexts]] filters_conditions = [] context_filters_conditions = [] DatabaseQuery("Translation").build_filter_conditions(filters, filters_conditions, ignore_permissions=True) DatabaseQuery("Translation").build_filter_conditions(context_filters, context_filters_conditions, ignore_permissions=True) filters_conditions = ' and '.join(filters_conditions) where_conditions = filters_conditions context_filters_conditions = ' or '.join(context_filters_conditions) if doctype and not docname and not docfield: context_filters_conditions += f" or context LIKE '{doctype}:%'" if doctype and docfield and not docname: context_filters_conditions += f" or (context LIKE '{doctype}:%' and context LIKE '%:{docfield}')" if doctype and docname and not docfield: context_filters_conditions += f" or context LIKE '{doctype}:{docname}%'" where_conditions += f" and ( {context_filters_conditions} )" sql = """ SELECT `tabTranslation`.name, # extract doctype from context SUBSTRING_INDEX(context, ':', 1) as 'document_type', # extract docname from context CASE LENGTH(context) - LENGTH(REPLACE(context, ':', '')) WHEN 2 THEN SUBSTR(context, LOCATE(':', context) + 1, LOCATE(':', SUBSTR(context, LOCATE(':', context) + 1), 1) - 1) WHEN 1 THEN SUBSTRING_INDEX(context, ':', -1) ELSE '' END as 'docname', # extract docfield from context IF(LENGTH(context) - LENGTH(REPLACE(context, ':', '')) = 2, SUBSTRING_INDEX(context, ':', -1),'') as 'docfield', # extract value from context if docname and docfield are present IF(length(SUBSTRING_INDEX(context, ':', 1)) and length((SUBSTR(context, LOCATE(':', context) + 1, LOCATE(':', SUBSTR(context, LOCATE(':', context) + 1), 1) - 1))) and length(IF(LENGTH(context) - LENGTH(REPLACE(context, ':', '')) = 2, SUBSTRING_INDEX(context, ':', -1), '')),({select_condition}), '') as 'value', source_text, translated_text , context from `tabTranslation` where {where_conditions} """.format(where_conditions=where_conditions, select_condition=( "(SELECT `tab{doctype}`.{docfield} from `tab{doctype}` WHERE `tab{doctype}`.name ='{docname}')".format( doctype=doctype, docfield=docfield, docname=docname) if not is_single(doctype) else """ (SELECT `tabSingles`.value from `tabSingles` WHERE `tabSingles`.doctype = '{doctype}' and `tabSingles`.field = '{docfield}') """.format(doctype=doctype, docfield=docfield)) if docfield else frappe.db.escape("")) translations = [{**translation, 'value': frappe.get_cached_value(translation.get("document_type"), translation.get("docname"), translation.get("docfield")) if translation.get( "document_type") and translation.get("docname") and translation.get( "docfield") and (frappe.db.table_exists(translation.get("document_type")) or is_single( translation.get("document_type"))) and frappe.db.exists( translation.get("document_type"), translation.get("docname")) else translation.get("value") } for translation in frappe.db.sql(sql, as_dict=1, debug=0)] return { "translations": translations }