updated sync
This commit is contained in:
parent
d592bd1abb
commit
255cea887a
16 changed files with 156 additions and 410 deletions
|
|
@ -38,6 +38,7 @@ CREATE TABLE `tabDocField` (
|
|||
`default` text,
|
||||
`description` text,
|
||||
`in_filter` int(1) DEFAULT NULL,
|
||||
`in_list_view` int(1) DEFAULT NULL,
|
||||
`no_column` int(1) DEFAULT NULL,
|
||||
`read_only` int(1) DEFAULT NULL,
|
||||
`print_width` varchar(180) DEFAULT NULL,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ files_path = 'public/files'
|
|||
max_file_size = 1000000
|
||||
|
||||
# generate schema (.txt files)
|
||||
developer_mode = 1
|
||||
developer_mode = 0
|
||||
|
||||
# clear cache on refresh
|
||||
auto_cache_clear = 0
|
||||
|
|
|
|||
|
|
@ -79,28 +79,30 @@ class DocType:
|
|||
validate_fields(self.doclist.get({"doctype":"DocField"}))
|
||||
validate_permissions(self.doclist.get({"doctype":"DocPerm"}))
|
||||
self.set_version()
|
||||
|
||||
def on_update(self):
|
||||
self.make_amendable()
|
||||
self.make_file_list()
|
||||
|
||||
sql = webnotes.conn.sql
|
||||
# make schma changes
|
||||
|
||||
def on_update(self):
|
||||
from webnotes.model.db_schema import updatedb
|
||||
updatedb(self.doc.name)
|
||||
|
||||
self.change_modified_of_parent()
|
||||
|
||||
import conf
|
||||
from webnotes.modules.import_merge import in_transfer
|
||||
from webnotes.modules.import_file import in_import
|
||||
|
||||
if (not in_transfer) and getattr(conf,'developer_mode', 0):
|
||||
if (not in_import) and getattr(conf,'developer_mode', 0):
|
||||
self.export_doc()
|
||||
self.make_controller_template()
|
||||
|
||||
webnotes.clear_cache(doctype=self.doc.name)
|
||||
|
||||
|
||||
def on_trash(self):
|
||||
webnotes.conn.sql("delete from `tabCustom Field` where dt = %s", name)
|
||||
webnotes.conn.sql("delete from `tabCustom Script` where dt = %s", name)
|
||||
webnotes.conn.sql("delete from `tabProperty Setter` where doc_type = %s", name)
|
||||
webnotes.conn.sql("delete from `tabSearch Criteria` where doc_type = %s", name)
|
||||
|
||||
def export_doc(self):
|
||||
from webnotes.modules.export_file import export_to_files
|
||||
export_to_files(record_list=[['DocType', self.doc.name]])
|
||||
|
|
@ -142,7 +144,6 @@ class DocType:
|
|||
idx_list = [d.idx for d in temp_doclist if d.idx]
|
||||
max_idx = idx_list and max(idx_list) or 0
|
||||
new.idx = max_idx + 1
|
||||
new.save()
|
||||
|
||||
def make_amendable(self):
|
||||
"""
|
||||
|
|
@ -166,7 +167,6 @@ class DocType:
|
|||
new.print_hide = 1
|
||||
new.no_copy = 1
|
||||
new.idx = max_idx + 1
|
||||
new.save()
|
||||
max_idx += 1
|
||||
|
||||
def validate_fields_for_doctype(doctype):
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@
|
|||
"doctype": "DocType",
|
||||
"autoname": "field:letter_head_name",
|
||||
"name": "__common__",
|
||||
"colour": "White:FFF",
|
||||
"server_code_error": " ",
|
||||
"max_attachments": 3,
|
||||
"version": 1
|
||||
|
|
@ -55,7 +54,6 @@
|
|||
},
|
||||
{
|
||||
"depends_on": "letter_head_name",
|
||||
"colour": "White:FFF",
|
||||
"doctype": "DocField",
|
||||
"label": "Preview",
|
||||
"fieldname": "preview",
|
||||
|
|
|
|||
|
|
@ -53,8 +53,8 @@ class DocType:
|
|||
it will write out a .html file
|
||||
"""
|
||||
import conf
|
||||
from webnotes.modules.import_merge import in_transfer
|
||||
if not in_transfer and getattr(conf,'developer_mode', 0) and self.doc.standard=='Yes':
|
||||
from webnotes.modules.import_file import in_import
|
||||
if not in_import and getattr(conf,'developer_mode', 0) and self.doc.standard=='Yes':
|
||||
from webnotes.modules.export_file import export_to_files
|
||||
from webnotes.modules import get_module_path, scrub
|
||||
import os
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@
|
|||
"parent": "Page",
|
||||
"read": 1,
|
||||
"cancel": 0,
|
||||
"execute": 0,
|
||||
"name": "__common__",
|
||||
"create": 1,
|
||||
"doctype": "DocPerm",
|
||||
|
|
|
|||
|
|
@ -312,9 +312,9 @@ def get_doctype(doctype, processed=False):
|
|||
import webnotes.model.doctype
|
||||
return webnotes.model.doctype.get(doctype, processed)
|
||||
|
||||
def delete_doc(doctype=None, name=None, doclist = None, force=0):
|
||||
import webnotes.model
|
||||
webnotes.model.delete_doc(doctype, name, doclist, force)
|
||||
def delete_doc(doctype=None, name=None, doclist = None, force=0, ignore_doctypes=[], for_reload=False):
|
||||
import webnotes.model.utils
|
||||
webnotes.model.utils.delete_doc(doctype, name, doclist, force, ignore_doctypes, for_reload)
|
||||
|
||||
def clear_perms(doctype):
|
||||
conn.sql("""delete from tabDocPerm where parent=%s""", doctype)
|
||||
|
|
|
|||
|
|
@ -144,6 +144,14 @@ class Installer:
|
|||
doc = webnotes.doc(fielddata=d)
|
||||
doc.insert()
|
||||
webnotes.conn.commit()
|
||||
|
||||
# from webnotes.modules.import_file import import_files
|
||||
#
|
||||
# import_files([
|
||||
# ["core", "doctype", "docperm"],
|
||||
# ["core", "doctype", "docfield"],
|
||||
# ["core", "doctype", "doctype"],
|
||||
# ])
|
||||
|
||||
def set_all_patches_as_completed(self):
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -42,7 +42,11 @@ class Bean:
|
|||
def __init__(self, dt=None, dn=None):
|
||||
self.docs = []
|
||||
self.obj = None
|
||||
self.ignore_permissions = 0
|
||||
self.ignore_permissions = False
|
||||
self.ignore_children_type = []
|
||||
self.ignore_check_links = False
|
||||
self.ignore_validate = False
|
||||
|
||||
if isinstance(dt, basestring) and not dn:
|
||||
dn = dt
|
||||
if dt and dn:
|
||||
|
|
@ -75,15 +79,9 @@ class Bean:
|
|||
self.run_method("onload")
|
||||
|
||||
def __iter__(self):
|
||||
"""
|
||||
Make this iterable
|
||||
"""
|
||||
return self.docs.__iter__()
|
||||
|
||||
def from_compressed(self, data, docname):
|
||||
"""
|
||||
Expand called from client
|
||||
"""
|
||||
from webnotes.model.utils import expand
|
||||
self.docs = expand(data)
|
||||
self.set_doclist(self.docs)
|
||||
|
|
@ -100,27 +98,18 @@ class Bean:
|
|||
self.obj.doc = self.doc
|
||||
|
||||
def make_obj(self):
|
||||
"""
|
||||
Create a DocType object
|
||||
"""
|
||||
if self.obj: return self.obj
|
||||
self.obj = webnotes.get_obj(doc=self.doc, doclist=self.doclist)
|
||||
self.controller = self.obj
|
||||
return self.obj
|
||||
|
||||
def to_dict(self):
|
||||
"""
|
||||
return as a list of dictionaries
|
||||
"""
|
||||
return [d.fields for d in self.docs]
|
||||
|
||||
def check_if_latest(self, method="save"):
|
||||
"""
|
||||
Raises exception if the modified time is not the same as in the database
|
||||
"""
|
||||
from webnotes.model.meta import is_single
|
||||
|
||||
if (not is_single(self.doc.doctype)) and (not cint(self.doc.fields.get('__islocal'))):
|
||||
if not cint(self.doc.fields.get('__islocal')) and not is_single(self.doc.doctype):
|
||||
tmp = webnotes.conn.sql("""
|
||||
SELECT modified, docstatus FROM `tab%s` WHERE name="%s" for update"""
|
||||
% (self.doc.doctype, self.doc.name), as_dict=True)
|
||||
|
|
@ -158,6 +147,8 @@ class Bean:
|
|||
labels[self.to_docstatus], raise_exception=DocstatusTransitionError)
|
||||
|
||||
def check_links(self):
|
||||
if self.ignore_check_links:
|
||||
return
|
||||
ref, err_list = {}, []
|
||||
for d in self.docs:
|
||||
if not ref.get(d.doctype):
|
||||
|
|
@ -209,6 +200,7 @@ class Bean:
|
|||
|
||||
def run_method(self, method):
|
||||
self.make_obj()
|
||||
|
||||
if hasattr(self.obj, method):
|
||||
getattr(self.obj, method)()
|
||||
if hasattr(self.obj, 'custom_' + method):
|
||||
|
|
@ -224,7 +216,7 @@ class Bean:
|
|||
|
||||
def save_main(self):
|
||||
try:
|
||||
self.doc.save(cint(self.doc.fields.get('__islocal')))
|
||||
self.doc.save(check_links = False)
|
||||
except NameError, e:
|
||||
webnotes.msgprint('%s "%s" already exists' % (self.doc.doctype, self.doc.name))
|
||||
|
||||
|
|
@ -241,7 +233,7 @@ class Bean:
|
|||
d.parent = self.doc.name # rename if reqd
|
||||
d.parenttype = self.doc.doctype
|
||||
|
||||
d.save(new = cint(d.fields.get('__islocal')))
|
||||
d.save(check_links=False)
|
||||
|
||||
child_map.setdefault(d.doctype, []).append(d.name)
|
||||
|
||||
|
|
@ -251,14 +243,15 @@ class Bean:
|
|||
tablefields = webnotes.model.meta.get_table_fields(self.doc.doctype)
|
||||
|
||||
for dt in tablefields:
|
||||
cnames = child_map.get(dt[0]) or []
|
||||
if cnames:
|
||||
webnotes.conn.sql("""delete from `tab%s` where parent=%s and parenttype=%s and
|
||||
name not in (%s)""" % (dt[0], '%s', '%s', ','.join(['%s'] * len(cnames))),
|
||||
tuple([self.doc.name, self.doc.doctype] + cnames))
|
||||
else:
|
||||
webnotes.conn.sql("""delete from `tab%s` where parent=%s and parenttype=%s""" \
|
||||
% (dt[0], '%s', '%s'), (self.doc.name, self.doc.doctype))
|
||||
if dt[0] not in self.ignore_children_type:
|
||||
cnames = child_map.get(dt[0]) or []
|
||||
if cnames:
|
||||
webnotes.conn.sql("""delete from `tab%s` where parent=%s and parenttype=%s and
|
||||
name not in (%s)""" % (dt[0], '%s', '%s', ','.join(['%s'] * len(cnames))),
|
||||
tuple([self.doc.name, self.doc.doctype] + cnames))
|
||||
else:
|
||||
webnotes.conn.sql("""delete from `tab%s` where parent=%s and parenttype=%s""" \
|
||||
% (dt[0], '%s', '%s'), (self.doc.name, self.doc.doctype))
|
||||
|
||||
def insert(self):
|
||||
self.doc.fields["__islocal"] = 1
|
||||
|
|
@ -271,7 +264,8 @@ class Bean:
|
|||
if self.ignore_permissions or webnotes.has_permission(self.doc.doctype, "write", self.doc):
|
||||
self.to_docstatus = 0
|
||||
self.prepare_for_save("save")
|
||||
self.run_method('validate')
|
||||
if not self.ignore_validate:
|
||||
self.run_method('validate')
|
||||
self.save_main()
|
||||
self.save_children()
|
||||
self.run_method('on_update')
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ def get_server_obj(doc, doclist = [], basedoctype = ''):
|
|||
from core.doctype.custom_script.custom_script import get_custom_server_script
|
||||
|
||||
# get doctype details
|
||||
module = get_doctype_module(doc.doctype)
|
||||
module = get_doctype_module(doc.doctype) or "core"
|
||||
|
||||
if not module:
|
||||
return
|
||||
|
|
|
|||
|
|
@ -67,8 +67,13 @@ def get_table_fields(doctype):
|
|||
child_tables = [[d[0], d[1]] for d in webnotes.conn.sql("select options, fieldname from tabDocField \
|
||||
where parent='%s' and fieldtype='Table'" % doctype, as_list=1)]
|
||||
|
||||
custom_child_tables = [[d[0], d[1]] for d in webnotes.conn.sql("select options, fieldname from `tabCustom Field` \
|
||||
where dt='%s' and fieldtype='Table'" % doctype, as_list=1)]
|
||||
try:
|
||||
custom_child_tables = [[d[0], d[1]] for d in webnotes.conn.sql("select options, fieldname from `tabCustom Field` \
|
||||
where dt='%s' and fieldtype='Table'" % doctype, as_list=1)]
|
||||
except Exception, e:
|
||||
if e.args[0]!=1146:
|
||||
raise e
|
||||
custom_child_tables = []
|
||||
|
||||
return child_tables + custom_child_tables
|
||||
|
||||
|
|
|
|||
|
|
@ -34,89 +34,10 @@ def walk_and_sync(start_path, force=0, sync_everything = False):
|
|||
module_name = path.split(os.sep)[-3]
|
||||
doctype = path.split(os.sep)[-2]
|
||||
name = path.split(os.sep)[-1]
|
||||
|
||||
if doctype == 'doctype':
|
||||
sync_doctype(module_name, name, force)
|
||||
else:
|
||||
if reload_doc(module_name, doctype, name, force):
|
||||
print module_name + ' | ' + doctype + ' | ' + name
|
||||
|
||||
|
||||
if reload_doc(module_name, doctype, name, force):
|
||||
print module_name + ' | ' + doctype + ' | ' + name
|
||||
webnotes.conn.commit()
|
||||
|
||||
return modules
|
||||
|
||||
|
||||
# docname in small letters with underscores
|
||||
def sync_doctype(module_name, docname, force=0):
|
||||
"""sync doctype from file if modified"""
|
||||
with open(get_file_path(module_name, docname), 'r') as f:
|
||||
from webnotes.modules.utils import peval_doclist
|
||||
doclist = peval_doclist(f.read())
|
||||
|
||||
if merge_doctype(doclist, force):
|
||||
print module_name, '|', docname
|
||||
|
||||
#raise Exception
|
||||
return doclist[0].get('name')
|
||||
|
||||
def merge_doctype(doclist, force=False):
|
||||
modified = doclist[0]['modified']
|
||||
if not doclist:
|
||||
raise Exception('Bean could not be evaluated')
|
||||
|
||||
db_modified = str(webnotes.conn.get_value(doclist[0].get('doctype'),
|
||||
doclist[0].get('name'), 'modified'))
|
||||
|
||||
if modified == db_modified and not force:
|
||||
return
|
||||
|
||||
webnotes.conn.begin()
|
||||
|
||||
delete_doctype_docfields(doclist)
|
||||
save_doctype_docfields(doclist)
|
||||
save_perms_if_none_exist(doclist)
|
||||
webnotes.conn.sql("""UPDATE `tab{doctype}`
|
||||
SET modified=%s WHERE name=%s""".format(doctype=doclist[0]['doctype']),
|
||||
(modified, doclist[0]['name']))
|
||||
|
||||
webnotes.conn.commit()
|
||||
return True
|
||||
|
||||
def get_file_path(module_name, docname):
|
||||
if not (module_name and docname):
|
||||
raise Exception('No Module Name or DocName specified')
|
||||
module = __import__(module_name)
|
||||
module_init_path = os.path.abspath(module.__file__)
|
||||
module_path = os.sep.join(module_init_path.split(os.sep)[:-1])
|
||||
return os.sep.join([module_path, 'doctype', docname, docname + '.txt'])
|
||||
|
||||
def delete_doctype_docfields(doclist):
|
||||
parent = doclist[0].get('name')
|
||||
if not parent: raise Exception('Could not determine parent')
|
||||
webnotes.conn.sql("DELETE FROM `tabDocType` WHERE name=%s", parent)
|
||||
webnotes.conn.sql("DELETE FROM `tabDocField` WHERE parent=%s", parent)
|
||||
|
||||
def save_doctype_docfields(doclist):
|
||||
from webnotes.model.doc import Document
|
||||
parent_doc = Document(fielddata=doclist[0])
|
||||
parent_doc.save(1, check_links=0,
|
||||
ignore_fields=1)
|
||||
idx = 1
|
||||
for d in doclist:
|
||||
if d.get('doctype') != 'DocField': continue
|
||||
d['idx'] = idx
|
||||
Document(fielddata=d).save(1, check_links=0, ignore_fields=1)
|
||||
idx += 1
|
||||
|
||||
update_schema(parent_doc.name)
|
||||
|
||||
def update_schema(docname):
|
||||
from webnotes.model.db_schema import updatedb
|
||||
updatedb(docname)
|
||||
|
||||
webnotes.clear_cache(doctype=docname)
|
||||
|
||||
def save_perms_if_none_exist(doclist):
|
||||
if not webnotes.conn.sql("""select count(*) from tabDocPerm
|
||||
where parent=%s""", doclist[0].name)[0][0]:
|
||||
for d in doclist:
|
||||
if d.get('doctype') != 'DocPerm': continue
|
||||
webnotes.doc(fielddata=d).save(1, check_links=0, ignore_fields=1)
|
||||
return modules
|
||||
|
|
@ -143,12 +143,11 @@ def getvaluelist(doclist, fieldname):
|
|||
l.append(d.fields[fieldname])
|
||||
return l
|
||||
|
||||
def delete_doc(doctype=None, name=None, doclist = None, force=0):
|
||||
def delete_doc(doctype=None, name=None, doclist = None, force=0, ignore_doctypes=[], for_reload=False):
|
||||
"""
|
||||
Deletes a doc(dt, dn) and validates if it is not submitted and not linked in a live record
|
||||
"""
|
||||
import webnotes.model.meta
|
||||
sql = webnotes.conn.sql
|
||||
|
||||
# get from form
|
||||
if not doctype:
|
||||
|
|
@ -162,42 +161,19 @@ def delete_doc(doctype=None, name=None, doclist = None, force=0):
|
|||
if not webnotes.conn.exists(doctype, name):
|
||||
return
|
||||
|
||||
# permission
|
||||
if webnotes.session.user!="Administrator" and not webnotes.has_permission(doctype, "cancel"):
|
||||
webnotes.msgprint("User not allowed to delete.", raise_exception=1)
|
||||
|
||||
tablefields = webnotes.model.meta.get_table_fields(doctype)
|
||||
|
||||
# check if submitted
|
||||
d = webnotes.conn.sql("select docstatus from `tab%s` where name=%s" % (doctype, '%s'), name)
|
||||
if d and int(d[0][0]) == 1:
|
||||
webnotes.msgprint("Submitted Record '%s' '%s' cannot be deleted" % (doctype, name))
|
||||
raise Exception
|
||||
|
||||
# call on_trash if required
|
||||
from webnotes.model.code import get_obj
|
||||
if doclist:
|
||||
obj = get_obj(doclist=doclist)
|
||||
else:
|
||||
obj = get_obj(doctype, name)
|
||||
|
||||
if hasattr(obj,'on_trash'):
|
||||
obj.on_trash()
|
||||
|
||||
if doctype=='DocType':
|
||||
webnotes.conn.sql("delete from `tabCustom Field` where dt = %s", name)
|
||||
webnotes.conn.sql("delete from `tabCustom Script` where dt = %s", name)
|
||||
webnotes.conn.sql("delete from `tabProperty Setter` where doc_type = %s", name)
|
||||
webnotes.conn.sql("delete from `tabSearch Criteria` where doc_type = %s", name)
|
||||
|
||||
# check if links exist
|
||||
if not force:
|
||||
check_if_doc_is_linked(doctype, name)
|
||||
|
||||
if not for_reload:
|
||||
check_permission_and_not_submitted(doctype, name)
|
||||
run_on_trash(doctype, name, doclist)
|
||||
# check if links exist
|
||||
if not force:
|
||||
check_if_doc_is_linked(doctype, name)
|
||||
|
||||
try:
|
||||
tablefields = webnotes.model.meta.get_table_fields(doctype)
|
||||
webnotes.conn.sql("delete from `tab%s` where name=%s" % (doctype, "%s"), name)
|
||||
for t in tablefields:
|
||||
webnotes.conn.sql("delete from `tab%s` where parent = %s" % (t[0], '%s'), name)
|
||||
if t[0] not in ignore_doctypes:
|
||||
webnotes.conn.sql("delete from `tab%s` where parent = %s" % (t[0], '%s'), name)
|
||||
except Exception, e:
|
||||
if e.args[0]==1451:
|
||||
webnotes.msgprint("Cannot delete %s '%s' as it is referenced in another record. You must delete the referred record first" % (doctype, name))
|
||||
|
|
@ -205,7 +181,27 @@ def delete_doc(doctype=None, name=None, doclist = None, force=0):
|
|||
raise e
|
||||
|
||||
return 'okay'
|
||||
|
||||
|
||||
def check_permission_and_not_submitted(self):
|
||||
# permission
|
||||
if webnotes.session.user!="Administrator" and not webnotes.has_permission(doctype, "cancel"):
|
||||
webnotes.msgprint(_("User not allowed to delete."), raise_exception=True)
|
||||
|
||||
# check if submitted
|
||||
if webnotes.conn.get_value(doctype, name, "docstatus") == 1:
|
||||
webnotes.msgprint(_("Submitted Record cannot be deleted")+": "+name+"("+doctype+")",
|
||||
raise_exception=True)
|
||||
|
||||
def run_on_trash(doctype, name, doclist):
|
||||
# call on_trash if required
|
||||
if doclist:
|
||||
obj = webnotes.get_obj(doclist=doclist)
|
||||
else:
|
||||
obj = webnotes.get_obj(doctype, name)
|
||||
|
||||
if hasattr(obj,'on_trash'):
|
||||
obj.on_trash()
|
||||
|
||||
class LinkExistsError(webnotes.ValidationError): pass
|
||||
|
||||
def check_if_doc_is_linked(dt, dn, method="Delete"):
|
||||
|
|
@ -229,7 +225,6 @@ def check_if_doc_is_linked(dt, dn, method="Delete"):
|
|||
item[1] and item[2] or link_dt),
|
||||
raise_exception=LinkExistsError)
|
||||
|
||||
|
||||
def round_floats_in_doc(doc, precision_map):
|
||||
from webnotes.utils import flt
|
||||
for fieldname, precision in precision_map.items():
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ def export_to_files(record_list=[], record_module=None, verbose=0):
|
|||
"""
|
||||
Export record_list to files. record_list is a list of lists ([doctype],[docname] ) ,
|
||||
"""
|
||||
from webnotes.modules.import_merge import in_transfer
|
||||
if in_transfer:
|
||||
from webnotes.modules.import_file import in_import
|
||||
if in_import:
|
||||
return
|
||||
|
||||
module_doclist =[]
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ from __future__ import unicode_literals
|
|||
import webnotes, os
|
||||
from webnotes.modules import scrub, get_module_path, scrub_dt_dn
|
||||
|
||||
in_import = False
|
||||
|
||||
def import_files(module, dt=None, dn=None, force=False):
|
||||
if type(module) is list:
|
||||
for m in module:
|
||||
|
|
@ -33,12 +35,16 @@ def import_files(module, dt=None, dn=None, force=False):
|
|||
return import_file(module, dt, dn, force)
|
||||
|
||||
def import_file(module, dt, dn, force=False):
|
||||
"""Sync a file from txt if modifed, return false if not updated"""
|
||||
"""Sync a file from txt if modifed, return false if not updated"""
|
||||
global in_import
|
||||
in_import = True
|
||||
dt, dn = scrub_dt_dn(dt, dn)
|
||||
path = os.path.join(get_module_path(module),
|
||||
os.path.join(dt, dn, dn + '.txt'))
|
||||
|
||||
return import_file_by_path(path, force)
|
||||
ret = import_file_by_path(path, force)
|
||||
in_import = False
|
||||
return ret
|
||||
|
||||
def import_file_by_path(path, force=False):
|
||||
if os.path.exists(path):
|
||||
|
|
@ -54,8 +60,7 @@ def import_file_by_path(path, force=False):
|
|||
if doc['modified']== str(webnotes.conn.get_value(doc['doctype'], doc['name'], 'modified')):
|
||||
return False
|
||||
|
||||
from webnotes.modules.import_merge import set_doc
|
||||
set_doc(doclist, 1, 1, 1)
|
||||
import_doclist(doclist)
|
||||
|
||||
# since there is a new timestamp on the file, update timestamp in
|
||||
webnotes.conn.sql("update `tab%s` set modified=%s where name=%s" % \
|
||||
|
|
@ -65,3 +70,55 @@ def import_file_by_path(path, force=False):
|
|||
else:
|
||||
raise Exception, '%s missing' % path
|
||||
|
||||
ignore_values = {
|
||||
"Report": ["disabled"],
|
||||
}
|
||||
|
||||
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 webnotes.conn.exists(doctype, name):
|
||||
old_doc = webnotes.doc(doctype, name)
|
||||
|
||||
# delete old
|
||||
webnotes.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 = webnotes.bean(doclist1)
|
||||
new_bean.ignore_children_type = ignore
|
||||
new_bean.ignore_check_links = True
|
||||
new_bean.ignore_validate = 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 webnotes.conn.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]
|
||||
|
||||
|
|
@ -1,232 +0,0 @@
|
|||
# Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com)
|
||||
#
|
||||
# MIT License (MIT)
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
from __future__ import unicode_literals
|
||||
"""
|
||||
Merges (syncs) incoming doclist into the database
|
||||
Called when:
|
||||
importing .txt files
|
||||
importing bulk records from .csv files
|
||||
|
||||
For regular types, deletes the record and recreates it
|
||||
for special types: `DocType`, `Module Def`, `DocType Mapper` there are subclasses
|
||||
|
||||
To use::
|
||||
set_doc(doclist, ovr=1, ingore=1, noupdate=1)
|
||||
"""
|
||||
|
||||
import webnotes
|
||||
from webnotes.model.doc import Document
|
||||
|
||||
# this variable is a flag that transfer process is on, to the on_update
|
||||
# method so that if there are other processes on import, it can do so
|
||||
in_transfer = 0
|
||||
|
||||
no_sync = {
|
||||
"Report": ["disabled"],
|
||||
}
|
||||
|
||||
def set_doc(doclist, ovr=0, ignore=1, onupdate=1):
|
||||
"""
|
||||
Wrapper function to sync a record
|
||||
"""
|
||||
if doclist[0].doctype == "DocType":
|
||||
from webnotes.model.sync import merge_doctype
|
||||
return merge_doctype(doclist, force=ovr)
|
||||
|
||||
global in_transfer
|
||||
dt = doclist[0]['doctype']
|
||||
|
||||
if webnotes.conn.exists(doclist[0]['doctype'], doclist[0]['name']):
|
||||
# exists, merge if possible
|
||||
|
||||
if dt == 'DocType Mapper':
|
||||
ud = UpdateDocTypeMapper(doclist)
|
||||
else:
|
||||
ud = UpdateDocument(doclist)
|
||||
else:
|
||||
ud = UpdateDocument(doclist)
|
||||
|
||||
in_transfer = 1
|
||||
ud.sync()
|
||||
in_transfer = 0
|
||||
return '\n'.join(ud.log)
|
||||
|
||||
|
||||
class UpdateDocument:
|
||||
def __init__(self, in_doclist=[]):
|
||||
self.in_doclist = in_doclist
|
||||
self.doc = Document(fielddata = in_doclist[0])
|
||||
self.old_doc = None
|
||||
self.modified = self.doc.modified # make a copy
|
||||
self.doclist = []
|
||||
|
||||
self.log = []
|
||||
self.exists = 0
|
||||
|
||||
# sync
|
||||
def sync(self):
|
||||
is_mod = self.is_modified()
|
||||
|
||||
if (not self.exists) or (is_mod):
|
||||
webnotes.conn.begin()
|
||||
if self.exists:
|
||||
self.delete_existing()
|
||||
self.save()
|
||||
self.run_on_update()
|
||||
self.update_modified()
|
||||
webnotes.conn.commit()
|
||||
|
||||
# check modified
|
||||
def is_modified(self):
|
||||
try:
|
||||
timestamp = webnotes.conn.get_value(self.doc.doctype, self.doc.name, "modified")
|
||||
except Exception ,e:
|
||||
if(e.args[0]==1146):
|
||||
return
|
||||
else:
|
||||
raise e
|
||||
|
||||
if timestamp:
|
||||
self.exists = 1
|
||||
if str(timestamp) == self.doc.modified:
|
||||
self.log.append('%s %s, No change' % (self.doc.doctype, self.doc.name))
|
||||
else: return 1
|
||||
|
||||
# delete existing
|
||||
def delete_existing(self):
|
||||
from webnotes.model import delete_doc
|
||||
self.old_doc = webnotes.doc(self.doc.doctype, self.doc.name)
|
||||
delete_doc(self.doc.doctype, self.doc.name, force=1)
|
||||
|
||||
# update modified timestamp
|
||||
def update_modified(self):
|
||||
webnotes.conn.sql("""update `tab{doctype}`
|
||||
SET modified=%s WHERE name=%s""".format(doctype=self.doc.doctype),
|
||||
(self.modified, self.doc.name))
|
||||
|
||||
def save(self):
|
||||
# parent
|
||||
self.update_no_sync(self.doc)
|
||||
self.doc.save(new = 1, check_links=0)
|
||||
self.doclist = [self.doc]
|
||||
self.save_children()
|
||||
|
||||
def save_children(self):
|
||||
for df in self.in_doclist[1:]:
|
||||
self.save_one_doc(df)
|
||||
|
||||
def update_no_sync(self, d):
|
||||
if d.doctype in no_sync and self.old_doc:
|
||||
for fieldname in no_sync[d.doctype]:
|
||||
d.fields[fieldname] = self.old_doc.fields.get(fieldname)
|
||||
|
||||
def save_one_doc(self, df, as_new=1):
|
||||
d = Document(fielddata = df)
|
||||
d.save(new = as_new, check_links=0)
|
||||
self.doclist.append(d)
|
||||
|
||||
def run_on_update(self):
|
||||
from webnotes.model.code import get_obj
|
||||
so = get_obj(doc=self.doc, doclist=self.doclist)
|
||||
if hasattr(so, 'on_update'):
|
||||
so.on_update()
|
||||
|
||||
|
||||
class UpdateDocumentMerge(UpdateDocument):
|
||||
def __init__(self, in_doclist):
|
||||
self.to_update_doctype = []
|
||||
UpdateDocument.__init__(self, in_doclist)
|
||||
|
||||
def delete_existing(self):
|
||||
pass
|
||||
|
||||
def get_id(self, d):
|
||||
pass
|
||||
|
||||
def to_update(self, d):
|
||||
return 1
|
||||
|
||||
def child_exists(self, d):
|
||||
return self.get_id(d)
|
||||
|
||||
def on_save(self):
|
||||
pass
|
||||
|
||||
def save(self):
|
||||
if self.exists:
|
||||
# save main doc
|
||||
self.keep_values(self.doc)
|
||||
self.doc.save(check_links=0)
|
||||
self.doclist.append(self.doc)
|
||||
self.save_children()
|
||||
self.on_save()
|
||||
self.log.append('Updated %s' % self.doc.name)
|
||||
else:
|
||||
UpdateDocument.save(self)
|
||||
|
||||
def save_children(self):
|
||||
for df in self.in_doclist[1:]:
|
||||
d = Document(fielddata = df)
|
||||
|
||||
# update doctype?
|
||||
if d.doctype in self.to_update_doctype:
|
||||
|
||||
# update this record?
|
||||
if self.to_update(d):
|
||||
|
||||
# is it new?
|
||||
if self.child_exists(d):
|
||||
self.keep_values(d)
|
||||
d.save(check_links=0)
|
||||
self.log.append('updated %s, %s' % (d.doctype, d.name))
|
||||
else:
|
||||
d.save(1, check_links=0)
|
||||
self.log.append('new %s' % d.doctype)
|
||||
self.doclist.append(d)
|
||||
|
||||
def keep_values(self, d):
|
||||
if hasattr(self, 'get_orignal_values'):
|
||||
ov = self.get_orignal_values(d)
|
||||
if ov:
|
||||
d.fields.update(ov)
|
||||
|
||||
|
||||
class UpdateDocTypeMapper(UpdateDocumentMerge):
|
||||
"""
|
||||
Merge `DocType Mapper`
|
||||
"""
|
||||
def __init__(self, in_doclist):
|
||||
UpdateDocumentMerge.__init__(self, in_doclist)
|
||||
self.to_update_doctype = ['Field Mapper Detail', 'Table Mapper Detail']
|
||||
|
||||
def get_id(self, d):
|
||||
if d.doctype=='Field Mapper Detail':
|
||||
return webnotes.conn.sql("select name from `tabField Mapper Detail` where from_field=%s and to_field=%s and match_id=%s and parent=%s", (d.from_field, d.to_field, d.match_id, d.parent))
|
||||
elif d.doctype=='Table Mapper Detail':
|
||||
return webnotes.conn.sql("select name from `tabTable Mapper Detail` where from_table=%s and to_table = %s and match_id=%s and validation_logic=%s and parent=%s", (d.from_table, d.to_table, d.match_id, d.validation_logic, d.parent))
|
||||
|
||||
def get_orignal_values(self, d):
|
||||
if d.doctype in ['Field Mapper Detail', 'Table Mapper Detail']:
|
||||
return {'name': self.get_id(d)[0][0]}
|
||||
|
||||
|
||||
Loading…
Add table
Reference in a new issue