Fixed import, export, delete doc #478
This commit is contained in:
parent
22ee0ef892
commit
ddff84d216
4 changed files with 77 additions and 133 deletions
|
|
@ -351,8 +351,7 @@ def get_meta(doctype, cached=True):
|
|||
import frappe.model.meta
|
||||
return frappe.model.meta.get_meta(doctype, cached=cached)
|
||||
|
||||
def delete_doc(doctype=None, name=None, doclist = None, force=0, ignore_doctypes=None,
|
||||
for_reload=False, ignore_permissions=False):
|
||||
def delete_doc(doctype=None, name=None, force=0, ignore_doctypes=None, for_reload=False, ignore_permissions=False):
|
||||
import frappe.model.delete_doc
|
||||
|
||||
if not ignore_doctypes:
|
||||
|
|
@ -360,11 +359,9 @@ def delete_doc(doctype=None, name=None, doclist = None, force=0, ignore_doctypes
|
|||
|
||||
if isinstance(name, list):
|
||||
for n in name:
|
||||
frappe.model.delete_doc.delete_doc(doctype, n, doclist, force, ignore_doctypes,
|
||||
for_reload, ignore_permissions)
|
||||
frappe.model.delete_doc.delete_doc(doctype, n, force, ignore_doctypes, for_reload, ignore_permissions)
|
||||
else:
|
||||
frappe.model.delete_doc.delete_doc(doctype, name, doclist, force, ignore_doctypes,
|
||||
for_reload, ignore_permissions)
|
||||
frappe.model.delete_doc.delete_doc(doctype, name, force, ignore_doctypes, for_reload, ignore_permissions)
|
||||
|
||||
def reload_doc(module, dt=None, dn=None, force=False):
|
||||
import frappe.modules
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import frappe.defaults
|
|||
from frappe.utils.file_manager import remove_all
|
||||
from frappe import _
|
||||
|
||||
def delete_doc(doctype=None, name=None, doclist = None, force=0, ignore_doctypes=None, for_reload=False, ignore_permissions=False):
|
||||
def delete_doc(doctype=None, name=None, force=0, ignore_doctypes=None, for_reload=False, ignore_permissions=False):
|
||||
"""
|
||||
Deletes a doc(dt, dn) and validates if it is not submitted and not linked in a live record
|
||||
"""
|
||||
|
|
@ -27,20 +27,21 @@ def delete_doc(doctype=None, name=None, doclist = None, force=0, ignore_doctypes
|
|||
if not frappe.db.exists(doctype, name):
|
||||
return
|
||||
|
||||
doc = frappe.get_doc(doctype, name)
|
||||
|
||||
if not for_reload:
|
||||
check_permission_and_not_submitted(doctype, name, ignore_permissions)
|
||||
|
||||
run_on_trash(doctype, name, doclist)
|
||||
check_permission_and_not_submitted(doc, ignore_permissions)
|
||||
doc.run_method("on_trash")
|
||||
# check if links exist
|
||||
if not force:
|
||||
check_if_doc_is_linked(doctype, name)
|
||||
check_if_doc_is_linked(doc)
|
||||
|
||||
try:
|
||||
tablefields = frappe.model.meta.get_table_fields(doctype)
|
||||
frappe.db.sql("delete from `tab%s` where name=%s" % (doctype, "%s"), (name,))
|
||||
for t in tablefields:
|
||||
if t[0] not in ignore_doctypes:
|
||||
frappe.db.sql("delete from `tab%s` where parent = %s" % (t[0], '%s'), (name,))
|
||||
for t in doc.meta.get_table_fields():
|
||||
if t.options not in ignore_doctypes:
|
||||
frappe.db.sql("delete from `tab%s` where parent = %s" % (t.options, '%s'), (name,))
|
||||
|
||||
except Exception, e:
|
||||
if e.args[0]==1451:
|
||||
frappe.msgprint("Cannot delete %s '%s' as it is referenced in another record. You must delete the referred record first" % (doctype, name))
|
||||
|
|
@ -57,41 +58,32 @@ def delete_doc(doctype=None, name=None, doclist = None, force=0, ignore_doctypes
|
|||
|
||||
def check_permission_and_not_submitted(doctype, name, ignore_permissions=False):
|
||||
# permission
|
||||
if not ignore_permissions and frappe.session.user!="Administrator" and not frappe.has_permission(doctype, "cancel"):
|
||||
if not ignore_permissions and frappe.session.user!="Administrator" and not doc.has_permission("cancel"):
|
||||
frappe.msgprint(_("User not allowed to delete."), raise_exception=True)
|
||||
|
||||
# check if submitted
|
||||
if frappe.db.get_value(doctype, name, "docstatus") == 1:
|
||||
frappe.msgprint(_("Submitted Record cannot be deleted")+": "+name+"("+doctype+")",
|
||||
if doc.docstatus == 1:
|
||||
frappe.msgprint(_("Submitted Record cannot be deleted")+": "+doc.name+"("+doc.doctype+")",
|
||||
raise_exception=True)
|
||||
|
||||
def run_on_trash(doctype, name, doclist):
|
||||
# call on_trash if required
|
||||
if doclist:
|
||||
bean = frappe.bean(doclist)
|
||||
else:
|
||||
bean = frappe.bean(doctype, name)
|
||||
|
||||
bean.run_method("on_trash")
|
||||
|
||||
class LinkExistsError(frappe.ValidationError): pass
|
||||
|
||||
def check_if_doc_is_linked(dt, dn, method="Delete"):
|
||||
def check_if_doc_is_linked(doc, method="Delete"):
|
||||
"""
|
||||
Raises excption if the given doc(dt, dn) is linked in another record.
|
||||
"""
|
||||
from frappe.model.rename_doc import get_link_fields
|
||||
link_fields = get_link_fields(dt)
|
||||
link_fields = get_link_fields(doc.doctype)
|
||||
link_fields = [[lf['parent'], lf['fieldname'], lf['issingle']] for lf in link_fields]
|
||||
|
||||
for link_dt, link_field, issingle in link_fields:
|
||||
if not issingle:
|
||||
item = frappe.db.get_value(link_dt, {link_field:dn},
|
||||
item = frappe.db.get_value(link_dt, {link_field:doc.name},
|
||||
["name", "parent", "parenttype", "docstatus"], as_dict=True)
|
||||
|
||||
if item and item.parent != dn and ((method=="Delete" and item.docstatus<2) or
|
||||
if item and item.parent != doc.name and ((method=="Delete" and item.docstatus<2) or
|
||||
(method=="Cancel" and item.docstatus==1)):
|
||||
frappe.msgprint(method + " " + _("Error") + ":"+\
|
||||
("%s (%s) " % (dn, dt)) + _("is linked in") + (" %s (%s)") %
|
||||
("%s (%s) " % (doc.name, doc.doctype)) + _("is linked in") + (" %s (%s)") %
|
||||
(item.parent or item.name, item.parent and item.parenttype or link_dt),
|
||||
raise_exception=LinkExistsError)
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe, os
|
||||
import frappe.model.doc
|
||||
import frappe, os, json
|
||||
import frappe.model
|
||||
from frappe.modules import scrub, get_module_path, lower_case_files_for, scrub_dt_dn
|
||||
|
||||
def export_doc(doc):
|
||||
|
|
@ -17,58 +17,41 @@ def export_to_files(record_list=None, record_module=None, verbose=0, create_init
|
|||
if frappe.flags.in_import:
|
||||
return
|
||||
|
||||
module_doclist =[]
|
||||
if record_list:
|
||||
for record in record_list:
|
||||
write_document_file(frappe.model.doc.get(record[0], record[1]),
|
||||
record_module, create_init=create_init)
|
||||
write_document_file(frappe.get_doc(record[0], record[1]), record_module, create_init=create_init)
|
||||
|
||||
def write_document_file(doclist, record_module=None, create_init=None):
|
||||
from frappe.modules.utils import pprint_doclist
|
||||
def write_document_file(doc, record_module=None, create_init=None):
|
||||
newdoc = doc.as_dict()
|
||||
|
||||
doclist = [filter_fields(d.fields) for d in doclist]
|
||||
|
||||
module = record_module or get_module_name(doclist)
|
||||
# strip out default fields from children
|
||||
for df in doc.get_table_fields():
|
||||
for d in newdoc.get(df.fieldname):
|
||||
for fieldname in frappe.model.default_fields:
|
||||
if fieldname in d:
|
||||
del d[fieldname]
|
||||
|
||||
module = record_module or get_module_name(doc)
|
||||
if create_init is None:
|
||||
create_init = doclist[0]['doctype'] in lower_case_files_for
|
||||
create_init = doc.doctype in lower_case_files_for
|
||||
|
||||
# create folder
|
||||
folder = create_folder(module, doclist[0]['doctype'], doclist[0]['name'], create_init)
|
||||
folder = create_folder(module, doc.doctype, doc.name, create_init)
|
||||
|
||||
# write the data file
|
||||
fname = (doclist[0]['doctype'] in lower_case_files_for and scrub(doclist[0]['name'])) or doclist[0]['name']
|
||||
fname = (doc.doctype in lower_case_files_for and scrub(doc.name)) or doc.name
|
||||
with open(os.path.join(folder, fname +'.txt'),'w+') as txtfile:
|
||||
txtfile.write(pprint_doclist(doclist))
|
||||
txtfile.write(json.dumps(newdoc, indent=1, sort_keys=True))
|
||||
|
||||
def filter_fields(doc):
|
||||
from frappe.model.doctype import get
|
||||
from frappe.model import default_fields
|
||||
|
||||
doctypelist = get(doc.get("doctype"), False)
|
||||
valid_fields = [d.fieldname for d in doctypelist.get({"parent":doc.get("doctype"),
|
||||
"doctype":"DocField"})]
|
||||
to_remove = []
|
||||
|
||||
for key in doc:
|
||||
if (not key in default_fields) and (not key in valid_fields):
|
||||
to_remove.append(key)
|
||||
elif doc[key]==None:
|
||||
to_remove.append(key)
|
||||
|
||||
for key in to_remove:
|
||||
del doc[key]
|
||||
|
||||
return doc
|
||||
|
||||
def get_module_name(doclist):
|
||||
if doclist[0]['doctype'] == 'Module Def':
|
||||
module = doclist[0]['name']
|
||||
elif doclist[0]['doctype']=='Control Panel':
|
||||
def get_module_name(doc):
|
||||
if doc.doctype == 'Module Def':
|
||||
module = doc.name
|
||||
elif doc.doctype=='Control Panel':
|
||||
module = 'Core'
|
||||
elif doclist[0]['doctype']=="Workflow":
|
||||
module = frappe.db.get_value("DocType", doclist[0]["document_type"], "module")
|
||||
elif doc.doctype=="Workflow":
|
||||
module = frappe.db.get_value("DocType", doc.document_type, "module")
|
||||
else:
|
||||
module = doclist[0]['module']
|
||||
module = doc.module
|
||||
|
||||
return module
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe, os
|
||||
import frappe, os, json
|
||||
from frappe.modules import scrub, get_module_path, scrub_dt_dn
|
||||
|
||||
def import_files(module, dt=None, dn=None, force=False):
|
||||
|
|
@ -31,11 +31,9 @@ def get_file_path(module, dt, dn):
|
|||
|
||||
def import_file_by_path(path, force=False):
|
||||
frappe.flags.in_import = True
|
||||
doclist = read_doclist_from_file(path)
|
||||
doc = read_doc_from_file(path)
|
||||
|
||||
if doclist:
|
||||
doc = doclist[0]
|
||||
|
||||
if doc:
|
||||
if not force:
|
||||
# check if timestamps match
|
||||
if doc['modified']==str(frappe.db.get_value(doc['doctype'], doc['name'], 'modified')):
|
||||
|
|
@ -43,7 +41,7 @@ def import_file_by_path(path, force=False):
|
|||
|
||||
original_modified = doc["modified"]
|
||||
|
||||
import_doclist(doclist)
|
||||
import_doc(doc)
|
||||
|
||||
# since there is a new timestamp on the file, update timestamp in
|
||||
frappe.db.sql("update `tab%s` set modified=%s where name=%s" % \
|
||||
|
|
@ -53,17 +51,15 @@ def import_file_by_path(path, force=False):
|
|||
frappe.flags.in_import = False
|
||||
return True
|
||||
|
||||
def read_doclist_from_file(path):
|
||||
doclist = None
|
||||
def read_doc_from_file(path):
|
||||
doc = None
|
||||
if os.path.exists(path):
|
||||
from frappe.modules.utils import peval_doclist
|
||||
|
||||
with open(path, 'r') as f:
|
||||
doclist = peval_doclist(f.read())
|
||||
doc = json.loads(f.read())
|
||||
else:
|
||||
raise Exception, '%s missing' % path
|
||||
|
||||
return doclist
|
||||
return doc
|
||||
|
||||
ignore_values = {
|
||||
"Report": ["disabled"],
|
||||
|
|
@ -71,56 +67,32 @@ ignore_values = {
|
|||
|
||||
ignore_doctypes = ["Page Role", "DocPerm"]
|
||||
|
||||
def import_doclist(doclist):
|
||||
doctype = doclist[0]["doctype"]
|
||||
name = doclist[0]["name"]
|
||||
old_doc = None
|
||||
|
||||
doctypes = set([d["doctype"] for d in doclist])
|
||||
ignore = list(doctypes.intersection(set(ignore_doctypes)))
|
||||
|
||||
if doctype in ignore_values:
|
||||
if frappe.db.exists(doctype, name):
|
||||
old_doc = frappe.doc(doctype, name)
|
||||
def import_doc(docdict):
|
||||
docdict["__islocal"] = 1
|
||||
doc = frappe.get_doc(docdict)
|
||||
|
||||
old_doc = None
|
||||
if doctype in ignore_values:
|
||||
if frappe.db.exists(doc.doctype, doc.name):
|
||||
old_doc = frappe.get_doc(doc.doctype, doc.name)
|
||||
|
||||
# update ignore values
|
||||
for key in ignore_values.get(doctype) or []:
|
||||
doc.set(key, old_doc.get(key))
|
||||
|
||||
# update ignored docs into new doc
|
||||
for df in doc.get_table_fields():
|
||||
if df.options in ignore_doctypes:
|
||||
doc.set(df.fieldname, [])
|
||||
|
||||
# delete old
|
||||
frappe.delete_doc(doctype, name, force=1, ignore_doctypes=ignore, for_reload=True)
|
||||
|
||||
# don't overwrite ignored docs
|
||||
doclist1 = remove_ignored_docs_if_they_already_exist(doclist, ignore, name)
|
||||
|
||||
# update old values (if not to be overwritten)
|
||||
if doctype in ignore_values and old_doc:
|
||||
update_original_values(doclist1, doctype, old_doc)
|
||||
|
||||
# reload_new
|
||||
new_bean = frappe.bean(doclist1)
|
||||
new_bean.ignore_children_type = ignore
|
||||
new_bean.ignore_links = True
|
||||
new_bean.ignore_validate = True
|
||||
new_bean.ignore_permissions = True
|
||||
new_bean.ignore_mandatory = True
|
||||
new_bean.ignore_restrictions = True
|
||||
|
||||
if doctype=="DocType" and name in ["DocField", "DocType"]:
|
||||
new_bean.ignore_fields = True
|
||||
|
||||
new_bean.insert()
|
||||
|
||||
def remove_ignored_docs_if_they_already_exist(doclist, ignore, name):
|
||||
doclist1 = doclist
|
||||
if ignore:
|
||||
has_records = []
|
||||
for d in ignore:
|
||||
if frappe.db.get_value(d, {"parent":name}):
|
||||
has_records.append(d)
|
||||
|
||||
if has_records:
|
||||
doclist1 = filter(lambda d: d["doctype"] not in has_records, doclist)
|
||||
|
||||
return doclist1
|
||||
|
||||
def update_original_values(doclist, doctype, old_doc):
|
||||
for key in ignore_values[doctype]:
|
||||
doclist[0][key] = old_doc.fields[key]
|
||||
doc.ignore_children_type = ignore
|
||||
doc.ignore_links = True
|
||||
doc.ignore_validate = True
|
||||
doc.ignore_permissions = True
|
||||
doc.ignore_mandatory = True
|
||||
doc.ignore_restrictions = True
|
||||
doc.insert()
|
||||
|
||||
Loading…
Add table
Reference in a new issue