diff --git a/frappe/frappeclient.py b/frappe/frappeclient.py index 659822660c..13015821ac 100644 --- a/frappe/frappeclient.py +++ b/frappe/frappeclient.py @@ -192,7 +192,7 @@ class FrappeClient(object): res = self.session.get(self.url + "/api/resource/" + doctype + "/" + name, params=params, verify=self.verify, headers=self.headers) - return self.post_process(res) + return frappe._dict(self.post_process(res)) def rename_doc(self, doctype, old_name, new_name): '''Rename remote document diff --git a/frappe/offline/doctype/node_configuration/node_configuration.py b/frappe/offline/doctype/node_configuration/node_configuration.py index f1a5664b31..c53feb800c 100644 --- a/frappe/offline/doctype/node_configuration/node_configuration.py +++ b/frappe/offline/doctype/node_configuration/node_configuration.py @@ -9,7 +9,7 @@ import json from frappe.model.document import Document from frappe.frappeclient import FrappeClient from frappe.model.document import check_doctype_has_followers -from frappe.custom.doctype.custom_field.custom_field import create_custom_field +from frappe.desk.form.linked_with import get_linked_doctypes class NodeConfiguration(Document): def before_insert(self): @@ -42,10 +42,10 @@ def pull_from_node(node_config_name): for update in updates: if update.update_type == 'Create': - set_insert(update) + set_insert(update, master) if update.update_type == 'Update': - set_update(update) + set_update(update, master) if update.update_type == 'Delete': set_delete(update) @@ -53,14 +53,16 @@ def pull_from_node(node_config_name): frappe.db.set_value('Node', config.follower_node, 'last_updated', update.name) frappe.db.commit() -def set_insert(update): - if frappe.db.get_value(update.ref_doctype, dict(remote_docname=update.docname)): +def set_insert(update, master): + if frappe.db.get_value(update.ref_doctype, update.docname): # doc already created return else: + doc = frappe.get_doc(json.loads(update.data)) + check_doc_has_dependencies(doc, master) frappe.get_doc(json.loads(update.data)).insert(set_name=update.docname) -def set_update(update): +def set_update(update, master): local_doc = get_local_doc(update) data = json.loads(update.get('data')) data.pop('name') @@ -68,7 +70,9 @@ def set_update(update): local_doc.db_update_all() def set_delete(update): - get_local_doc(update).delete() + local_doc = get_local_doc(update) + if local_doc: + local_doc.delete() def get_updates(master, last_update, doctypes): last_update_timestamp = master.get_value('Update Log', 'creation', {'name': last_update}).get('creation') @@ -85,7 +89,10 @@ def get_master(config): return master def get_local_doc(update): - return frappe.get_doc(update.ref_doctype, update.docname) + try: + return frappe.get_doc(update.ref_doctype, update.docname) + except frappe.DoesNotExistError: + return def get_current_node(): current_node = frappe.utils.get_url() @@ -95,3 +102,37 @@ def get_current_node(): current_node += ':' + str(port) return frappe.get_doc('Node', current_node) + +def check_doc_has_dependencies(doc, master): + '''Sync child table link fields first, + then sync link fields, + then dynamic links''' + + meta = frappe.get_meta(doc.doctype) + sync_child_table_dependencies(doc, meta.get_table_fields(), master) + sync_link_dependencies(doc, master) + sync_dynamic_link_dependencies(meta.get_dynamic_link_fields()) + +def sync_child_table_dependencies(doc, table_fields, master): + for df in table_fields: + child_table = doc.get(df.fieldname) + for entry in child_table: + set_dependencies(entry, master) + +def sync_link_dependencies(doc, master): + set_dependencies(doc, master) + +def sync_dynamic_link_dependencies(dl_fields): + pass + +def set_dependencies(doc, master): + meta = frappe.get_meta(doc.doctype) + for df in meta.get_link_fields(): + docname = doc.get(df.fieldname) + linked_doctype = df.get_link_doctype() + if docname and not check_dependency_fulfilled(linked_doctype, docname): + master_doc = master.get_doc(linked_doctype, docname) + frappe.get_doc(master_doc).insert(set_name=docname) + +def check_dependency_fulfilled(linked_doctype, docname): + return frappe.db.exists(linked_doctype, docname) \ No newline at end of file