fix: Move field_order sync logic to DocType controller and introduce hooks
before_export, before_import and prepare_docdict_for_import
This commit is contained in:
parent
e2b199120f
commit
9db45f6fab
4 changed files with 65 additions and 52 deletions
|
|
@ -17,7 +17,9 @@ from frappe.desk.notifications import delete_notification_count_for
|
|||
from frappe.modules import make_boilerplate, get_doc_path
|
||||
from frappe.model.db_schema import validate_column_name, validate_column_length, type_map
|
||||
from frappe.model.docfield import supports_translation
|
||||
from frappe.modules.import_file import get_file_path
|
||||
import frappe.website.render
|
||||
import json
|
||||
|
||||
# imports - third-party imports
|
||||
import pymysql
|
||||
|
|
@ -390,6 +392,57 @@ class DocType(Document):
|
|||
if naming_series[0].default:
|
||||
make_property_setter(self.name, "naming_series", "default", naming_series[0].default, "Text", validate_fields_for_doctype=False)
|
||||
|
||||
def before_export(self, docdict):
|
||||
# retain order of 'fields' table and change order in 'field_order'
|
||||
docdict["field_order"] = [f.fieldname for f in self.fields]
|
||||
|
||||
path = get_file_path(self.module, "DocType", self.name)
|
||||
if os.path.exists(path):
|
||||
try:
|
||||
with open(path, 'r') as txtfile:
|
||||
olddoc = json.loads(txtfile.read())
|
||||
|
||||
old_field_names = [f['fieldname'] for f in olddoc.get("fields", [])]
|
||||
if old_field_names:
|
||||
new_field_dicts = []
|
||||
remaining_field_names = [f.fieldname for f in self.fields]
|
||||
|
||||
for fieldname in old_field_names:
|
||||
field_dict = filter(lambda d: d['fieldname'] == fieldname, docdict['fields'])
|
||||
if field_dict:
|
||||
new_field_dicts.append(field_dict[0])
|
||||
remaining_field_names.remove(fieldname)
|
||||
|
||||
for fieldname in remaining_field_names:
|
||||
field_dict = filter(lambda d: d['fieldname'] == fieldname, docdict['fields'])
|
||||
new_field_dicts.append(field_dict[0])
|
||||
|
||||
docdict['fields'] = new_field_dicts
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def prepare_docdict_for_import(docdict):
|
||||
# set order of fields from field_order
|
||||
if docdict.get("field_order"):
|
||||
new_field_dicts = []
|
||||
remaining_field_names = [f['fieldname'] for f in docdict.get('fields', [])]
|
||||
|
||||
for fieldname in docdict.get('field_order'):
|
||||
field_dict = filter(lambda d: d['fieldname'] == fieldname, docdict.get('fields', []))
|
||||
if field_dict:
|
||||
new_field_dicts.append(field_dict[0])
|
||||
remaining_field_names.remove(fieldname)
|
||||
|
||||
for fieldname in remaining_field_names:
|
||||
field_dict = filter(lambda d: d['fieldname'] == fieldname, docdict.get('fields', []))
|
||||
new_field_dicts.append(field_dict[0])
|
||||
|
||||
docdict['fields'] = new_field_dicts
|
||||
|
||||
if "field_order" in docdict:
|
||||
del docdict["field_order"]
|
||||
|
||||
def export_doc(self):
|
||||
"""Export to standard folder `[module]/doctype/[name]/[name].json`."""
|
||||
from frappe.modules.export_file import export_to_files
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ class TestDocType(unittest.TestCase):
|
|||
if condition:
|
||||
self.assertFalse(re.match(pattern, condition))
|
||||
|
||||
def test_load_file_field_order(self):
|
||||
def test_sync_field_order(self):
|
||||
from frappe.modules.import_file import get_file_path
|
||||
import os
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ def export_to_files(record_list=None, record_module=None, verbose=0, create_init
|
|||
|
||||
def write_document_file(doc, record_module=None, create_init=True):
|
||||
newdoc = doc.as_dict(no_nulls=True)
|
||||
doc.run_method("before_export", newdoc)
|
||||
|
||||
# strip out default fields from children
|
||||
for df in doc.meta.get_table_fields():
|
||||
|
|
@ -39,35 +40,7 @@ def write_document_file(doc, record_module=None, create_init=True):
|
|||
|
||||
# write the data file
|
||||
fname = scrub(doc.name)
|
||||
with open(os.path.join(folder, fname + ".json"), 'a+') as txtfile:
|
||||
# if exporting DocType, retain order of 'fields' table and change order in 'field_order'
|
||||
if doc.doctype == "DocType":
|
||||
newdoc["field_order"] = [f.fieldname for f in doc.fields]
|
||||
|
||||
try:
|
||||
olddoc = json.loads(txtfile.read())
|
||||
old_field_names = [f['fieldname'] for f in olddoc.get("fields", [])]
|
||||
|
||||
if old_field_names:
|
||||
new_field_dicts = []
|
||||
remaining_field_names = [f.fieldname for f in doc.fields]
|
||||
|
||||
for fieldname in old_field_names:
|
||||
field_dict = filter(lambda d: d['fieldname'] == fieldname, newdoc['fields'])
|
||||
if field_dict:
|
||||
new_field_dicts.append(field_dict[0])
|
||||
remaining_field_names.remove(fieldname)
|
||||
|
||||
for fieldname in remaining_field_names:
|
||||
field_dict = filter(lambda d: d['fieldname'] == fieldname, newdoc['fields'])
|
||||
new_field_dicts.append(field_dict[0])
|
||||
|
||||
newdoc['fields'] = new_field_dicts
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
txtfile.seek(0)
|
||||
txtfile.truncate()
|
||||
with open(os.path.join(folder, fname + ".json"), 'w+') as txtfile:
|
||||
txtfile.write(frappe.as_json(newdoc))
|
||||
|
||||
def get_module_name(doc):
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@
|
|||
from __future__ import unicode_literals, print_function
|
||||
|
||||
import frappe, os, json
|
||||
from frappe.modules import get_module_path, scrub_dt_dn
|
||||
from frappe.modules import get_module_path, scrub_dt_dn, load_doctype_module
|
||||
from frappe.utils import get_datetime_str
|
||||
from frappe.model.base_document import get_controller
|
||||
|
||||
ignore_values = {
|
||||
"Report": ["disabled", "prepared_report"],
|
||||
|
|
@ -89,27 +90,6 @@ def read_doc_from_file(path):
|
|||
else:
|
||||
raise IOError('%s missing' % path)
|
||||
|
||||
# set order of fields from field_order
|
||||
if doc.get("doctype") == "DocType":
|
||||
if doc.get("field_order") and doc.get("fields"):
|
||||
new_field_dicts = []
|
||||
remaining_field_names = [f['fieldname'] for f in doc['fields']]
|
||||
|
||||
for fieldname in doc['field_order']:
|
||||
field_dict = filter(lambda d: d['fieldname'] == fieldname, doc['fields'])
|
||||
if field_dict:
|
||||
new_field_dicts.append(field_dict[0])
|
||||
remaining_field_names.remove(fieldname)
|
||||
|
||||
for fieldname in remaining_field_names:
|
||||
field_dict = filter(lambda d: d['fieldname'] == fieldname, doc['fields'])
|
||||
new_field_dicts.append(field_dict[0])
|
||||
|
||||
doc['fields'] = new_field_dicts
|
||||
|
||||
if "field_order" in doc:
|
||||
del doc['field_order']
|
||||
|
||||
return doc
|
||||
|
||||
ignore_doctypes = [""]
|
||||
|
|
@ -118,8 +98,15 @@ def import_doc(docdict, force=False, data_import=False, pre_process=None,
|
|||
ignore_version=None, reset_permissions=False):
|
||||
frappe.flags.in_import = True
|
||||
docdict["__islocal"] = 1
|
||||
|
||||
controller = get_controller(docdict['doctype'])
|
||||
if controller and hasattr(controller, 'prepare_docdict_for_import') and callable(getattr(controller, 'prepare_docdict_for_import')):
|
||||
controller.prepare_docdict_for_import(docdict)
|
||||
|
||||
doc = frappe.get_doc(docdict)
|
||||
|
||||
doc.run_method("before_import")
|
||||
|
||||
doc.flags.ignore_version = ignore_version
|
||||
if pre_process:
|
||||
pre_process(doc)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue