'Returns list of invalid links and also updates fetch values if not set'

def get_invalid_links(self, is_submittable=False):

    def get_msg(df, docname):
        if self.parentfield:
            return u'{}    #{}:    {}:    {}'.format(_(u'Row'), self.idx, _(df.label), docname)
        else:
            return u'{}:    {}'.format(_(df.label), docname)
    invalid_links = []
    cancelled_links = []
    for df in (self.meta.get_link_fields() + self.meta.get(u'fields', {u'fieldtype': (u'=', u'Dynamic    Link')})):
        docname = self.get(df.fieldname)
        if docname:
            if (df.fieldtype == u'Link'):
                doctype = df.options
                if (not doctype):
                    frappe.throw(_(u'Options    not    set    for    link    field    {0}').format(df.fieldname))
            else:
                doctype = self.get(df.options)
                if (not doctype):
                    frappe.throw(_(u'{0}    must    be    set    first').format(self.meta.get_label(df.options)))
            fields_to_fetch = [_df for _df in self.meta.get_fields_to_fetch(df.fieldname) if (not self.get(_df.fieldname))]
            if (not fields_to_fetch):
                values = frappe._dict(name=frappe.db.get_value(doctype, docname, u'name', cache=True))
            else:
                values_to_fetch = ([u'name'] + [_df.options.split(u'.')[(-1)] for _df in fields_to_fetch])
                values = frappe.db.get_value(doctype, docname, values_to_fetch, as_dict=True)
            if frappe.get_meta(doctype).issingle:
                values.name = doctype
            setattr(self, df.fieldname, values.name)
            for _df in fields_to_fetch:
                setattr(self, _df.fieldname, values[_df.options.split(u'.')[(-1)]])
            notify_link_count(doctype, docname)
            if (not values.name):
                invalid_links.append((df.fieldname, docname, get_msg(df, docname)))
            elif ((df.fieldname != u'amended_from') and (is_submittable or self.meta.is_submittable) and frappe.get_meta(doctype).is_submittable and (cint(frappe.db.get_value(doctype, docname, u'docstatus')) == 2)):
                cancelled_links.append((df.fieldname, docname, get_msg(df, docname)))
    return (invalid_links, cancelled_links)
