introducing model 3.0, refactored import module
This commit is contained in:
parent
4bed53b0a9
commit
4f72d3b686
27 changed files with 844 additions and 553 deletions
|
|
@ -139,7 +139,7 @@ class DocType:
|
|||
|
||||
def post(self):
|
||||
"""
|
||||
Save diff between Customize Form DocList and DocType DocList as property setter entries
|
||||
Save diff between Customize Form ModelWrapper and DocType ModelWrapper as property setter entries
|
||||
"""
|
||||
if self.doc.doc_type:
|
||||
from webnotes.model import doc
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ class DocType:
|
|||
self.change_modified_of_parent()
|
||||
|
||||
import conf
|
||||
from webnotes.utils.transfer import in_transfer
|
||||
from webnotes.modules.import_merge import in_transfer
|
||||
|
||||
if (not in_transfer) and getattr(conf,'developer_mode', 0):
|
||||
self.export_doc()
|
||||
|
|
@ -96,7 +96,7 @@ class DocType:
|
|||
|
||||
|
||||
def export_doc(self):
|
||||
from webnotes.modules.export_module import export_to_files
|
||||
from webnotes.modules.export_file import export_to_files
|
||||
export_to_files(record_list=[['DocType', self.doc.name]])
|
||||
|
||||
def import_doc(self):
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import webnotes
|
|||
from webnotes.utils import cint, cstr, default_fields, flt, formatdate, get_defaults, getdate, now, nowdate, replace_newlines, set_default
|
||||
from webnotes.model import db_exists, default_fields
|
||||
from webnotes.model.doc import Document, addchild, getchildren, make_autoname
|
||||
from webnotes.model.doclist import getlist
|
||||
from webnotes.model.wrapper import getlist
|
||||
from webnotes.model.code import get_obj
|
||||
from webnotes import session, form, msgprint, errprint
|
||||
from webnotes.model.doctype import get
|
||||
|
|
@ -308,5 +308,5 @@ class DocType:
|
|||
"""
|
||||
import conf
|
||||
if hasattr(conf, 'developer_mode') and conf.developer_mode:
|
||||
from webnotes.modules.export_module import export_to_files
|
||||
from webnotes.modules.export_file import export_to_files
|
||||
export_to_files(record_list=[[self.doc.doctype, self.doc.name]])
|
||||
|
|
|
|||
|
|
@ -67,9 +67,9 @@ class DocType:
|
|||
it will write out a .html file
|
||||
"""
|
||||
import conf
|
||||
from webnotes.utils.transfer import in_transfer
|
||||
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.export_module import export_to_files
|
||||
from webnotes.modules.export_file import export_to_files
|
||||
from webnotes.modules import get_module_path, scrub
|
||||
import os
|
||||
export_to_files(record_list=[['Page', self.doc.name]])
|
||||
|
|
|
|||
|
|
@ -12,4 +12,15 @@ class DocType:
|
|||
"""only administrator can save standard report"""
|
||||
if self.doc.is_standard == "Yes" and webnotes.session.user!="Administrator":
|
||||
webnotes.msgprint("""Only Administrator can save a standard report.
|
||||
Please rename and save.""", raise_exception=True)
|
||||
Please rename and save.""", raise_exception=True)
|
||||
|
||||
def on_update(self):
|
||||
self.export_doc()
|
||||
|
||||
def export_doc(self):
|
||||
# export
|
||||
import conf
|
||||
if self.doc.is_standard == 'Yes' and getattr(conf, 'developer_mode', 0) == 1:
|
||||
from webnotes.modules.export_file import export_to_files
|
||||
export_to_files(record_list=[['Report', self.doc.name]],
|
||||
record_module=webnotes.conn.get_value("DocType", self.doc.ref_doctype, "module"))
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
{
|
||||
u'creation': '2012-10-04 18:45:27',
|
||||
u'docstatus': 0,
|
||||
u'modified': '2012-11-12 12:53:08',
|
||||
u'modified': '2012-11-12 12:53:09',
|
||||
u'modified_by': u'Administrator',
|
||||
u'owner': u'Administrator'
|
||||
},
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ class DocType:
|
|||
# export
|
||||
import conf
|
||||
if self.doc.standard == 'Yes' and getattr(conf, 'developer_mode', 0) == 1:
|
||||
from webnotes.modules.export_module import export_to_files
|
||||
from webnotes.modules.export_file import export_to_files
|
||||
export_to_files(record_list=[['Search Criteria', self.doc.name]])
|
||||
|
||||
# patch to rename search criteria from old style numerical to
|
||||
|
|
|
|||
|
|
@ -282,20 +282,20 @@ def delete_child_rows(rows, doctype):
|
|||
|
||||
def import_doc(d, doctype, overwrite, row_idx):
|
||||
"""import main (non child) document"""
|
||||
from webnotes.model.doclist import DocList
|
||||
from webnotes.model.wrapper import ModelWrapper
|
||||
|
||||
if webnotes.conn.exists(doctype, d['name']):
|
||||
if overwrite:
|
||||
doclist = webnotes.model.doc.get(doctype, d['name'])
|
||||
doclist[0].fields.update(d)
|
||||
DocList(doclist).save()
|
||||
ModelWrapper(doclist).save()
|
||||
return 'Updated row (#%d) %s' % (row_idx, getlink(doctype, d['name']))
|
||||
else:
|
||||
return 'Ignored row (#%d) %s (exists)' % (row_idx,
|
||||
getlink(doctype, d['name']))
|
||||
else:
|
||||
d['__islocal'] = 1
|
||||
dl = DocList([webnotes.model.doc.Document(fielddata = d)])
|
||||
dl = ModelWrapper([webnotes.model.doc.Document(fielddata = d)])
|
||||
dl.save()
|
||||
return 'Inserted row (#%d) %s' % (row_idx, getlink(doctype,
|
||||
dl.doc.fields['name']))
|
||||
|
|
|
|||
|
|
@ -262,5 +262,5 @@ def generate_hash():
|
|||
return hashlib.sha224(str(time.time())).hexdigest()
|
||||
|
||||
def model_wrapper(doctype, name=None):
|
||||
from webnotes.model.doclist import DocList
|
||||
return DocList(doctype, name)
|
||||
from webnotes.model.wrapper import ModelWrapper
|
||||
return ModelWrapper(doctype, name)
|
||||
|
|
@ -29,12 +29,12 @@ def save():
|
|||
"""insert or update from form query"""
|
||||
doclist = json.loads(webnotes.form_dict.doclist)
|
||||
|
||||
from webnotes.model.doclist import DocList
|
||||
from webnotes.model.wrapper import ModelWrapper
|
||||
|
||||
if not webnotes.has_permission(doclist[0]["doctype"], "write"):
|
||||
webnotes.msgprint("No Write Permission", raise_exception=True)
|
||||
|
||||
doclistobj = DocList(doclist)
|
||||
doclistobj = ModelWrapper(doclist)
|
||||
doclistobj.save()
|
||||
|
||||
return [d.fields for d in doclist]
|
||||
|
|
@ -30,10 +30,10 @@ default_fields = ['doctype','name','owner','creation','modified','modified_by','
|
|||
#=================================================================================
|
||||
|
||||
def insert(doclist):
|
||||
from webnotes.model.doclist import DocList
|
||||
from webnotes.model.wrapper import ModelWrapper
|
||||
for d in doclist:
|
||||
d["__islocal"] = 1
|
||||
dl = DocList(doclist)
|
||||
dl = ModelWrapper(doclist)
|
||||
dl.save()
|
||||
|
||||
return dl
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ methods in following modules are imported for backward compatibility
|
|||
* webnotes.*
|
||||
* webnotes.utils.*
|
||||
* webnotes.model.doc.*
|
||||
* webnotes.model.doclist.*
|
||||
* webnotes.model.wrapper.*
|
||||
"""
|
||||
custom_class = '''
|
||||
# Please edit this list and import only required elements
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
from __future__ import unicode_literals
|
||||
"""
|
||||
Transactions are defined as collection of classes, a DocList represents collection of Document
|
||||
Transactions are defined as collection of classes, a ModelWrapper represents collection of Document
|
||||
objects for a transaction with main and children.
|
||||
|
||||
Group actions like save, etc are performed on doclists
|
||||
|
|
@ -32,7 +32,7 @@ import webnotes
|
|||
import json, os
|
||||
import webnotes.model
|
||||
import webnotes.model.doc
|
||||
import webnotes.model.doclist
|
||||
import webnotes.model.wrapper
|
||||
import webnotes.utils.cache
|
||||
|
||||
from webnotes import _
|
||||
|
|
@ -79,12 +79,12 @@ def get_controller_class(module_name, doctype, module_path):
|
|||
for attr in dir(module):
|
||||
attrobj = getattr(module, attr)
|
||||
if inspect.isclass(attrobj) and attr.startswith(doctype.replace(' ', '').replace('-', '')) \
|
||||
and issubclass(attrobj, DocListController):
|
||||
and issubclass(attrobj, ModelWrapperController):
|
||||
return attrobj
|
||||
|
||||
return DocListController
|
||||
return ModelWrapperController
|
||||
|
||||
class DocListController(object):
|
||||
class ModelWrapperController(object):
|
||||
"""
|
||||
Collection of Documents with one parent and multiple children
|
||||
"""
|
||||
|
|
@ -104,11 +104,11 @@ class DocListController(object):
|
|||
self.set_doclist(self.load_doclist(doctype, name))
|
||||
|
||||
def load_doclist(self, doctype, name):
|
||||
return webnotes.model.doclist.load(doctype, name)
|
||||
return webnotes.model.wrapper.load(doctype, name)
|
||||
|
||||
def set_doclist(self, doclist):
|
||||
if not isinstance(doclist, webnotes.model.doclist.DocList):
|
||||
self.doclist = webnotes.model.doclist.objectify(doclist)
|
||||
if not isinstance(doclist, webnotes.model.wrapper.ModelWrapper):
|
||||
self.doclist = webnotes.model.wrapper.objectify(doclist)
|
||||
else:
|
||||
self.doclist = doclist
|
||||
self.doc = self.doclist[0]
|
||||
|
|
@ -125,7 +125,7 @@ class DocListController(object):
|
|||
from webnotes.model.doctype import get_property
|
||||
if get_property(self.doc.doctype, "document_type") in ["Master", "Transaction"]\
|
||||
and not self.doc.get("__islocal"):
|
||||
from webnotes.model.doclist import load
|
||||
from webnotes.model.wrapper import load
|
||||
# get the old doclist
|
||||
try:
|
||||
oldlist = load(self.doc.doctype, self.doc.name)
|
||||
|
|
|
|||
|
|
@ -632,6 +632,7 @@ def getseries(key, digits, doctype=''):
|
|||
|
||||
def getchildren(name, childtype, field='', parenttype='', from_doctype=0, prefix='tab'):
|
||||
import webnotes
|
||||
from webnotes.model.doclist import DocList
|
||||
|
||||
tmp = ''
|
||||
|
||||
|
|
@ -640,17 +641,11 @@ def getchildren(name, childtype, field='', parenttype='', from_doctype=0, prefix
|
|||
if parenttype:
|
||||
tmp = ' and parenttype="%s" ' % parenttype
|
||||
|
||||
try:
|
||||
dataset = webnotes.conn.sql("select * from `%s%s` where parent='%s' %s order by idx" \
|
||||
% (prefix, childtype, name, tmp))
|
||||
desc = webnotes.conn.get_description()
|
||||
except Exception, e:
|
||||
if prefix=='arc' and e.args[0]==1146:
|
||||
return []
|
||||
else:
|
||||
raise e
|
||||
dataset = webnotes.conn.sql("select * from `%s%s` where parent='%s' %s order by idx" \
|
||||
% (prefix, childtype, name, tmp))
|
||||
desc = webnotes.conn.get_description()
|
||||
|
||||
l = []
|
||||
l = DocList()
|
||||
|
||||
for i in dataset:
|
||||
d = Document()
|
||||
|
|
@ -692,7 +687,8 @@ def get(dt, dn='', with_children = 1, from_get_obj = 0, prefix = 'tab'):
|
|||
"""
|
||||
import webnotes
|
||||
import webnotes.model
|
||||
|
||||
from webnotes.model.doclist import DocList
|
||||
|
||||
dn = dn or dt
|
||||
|
||||
# load the main doc
|
||||
|
|
@ -709,13 +705,13 @@ def get(dt, dn='', with_children = 1, from_get_obj = 0, prefix = 'tab'):
|
|||
|
||||
if not with_children:
|
||||
# done
|
||||
return [doc,]
|
||||
return DocList([doc,])
|
||||
|
||||
# get all children types
|
||||
tablefields = webnotes.model.meta.get_table_fields(dt)
|
||||
|
||||
# load chilren
|
||||
doclist = [doc,]
|
||||
doclist = DocList([doc,])
|
||||
for t in tablefields:
|
||||
doclist += getchildren(doc.name, t[0], t[1], dt, prefix=prefix)
|
||||
|
||||
|
|
|
|||
|
|
@ -20,324 +20,142 @@
|
|||
# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
from __future__ import unicode_literals
|
||||
"""
|
||||
Transactions are defined as collection of classes, a DocList represents collection of Document
|
||||
objects for a transaction with main and children.
|
||||
|
||||
Group actions like save, etc are performed on doclists
|
||||
"""
|
||||
|
||||
import webnotes
|
||||
from webnotes.utils import cint
|
||||
import webnotes.model
|
||||
from webnotes.model.doc import Document
|
||||
|
||||
class DocList:
|
||||
"""
|
||||
Collection of Documents with one parent and multiple children
|
||||
"""
|
||||
def __init__(self, dt=None, dn=None):
|
||||
self.docs = []
|
||||
self.obj = None
|
||||
self.to_docstatus = 0
|
||||
if dt and dn:
|
||||
self.load_from_db(dt, dn)
|
||||
if type(dt) is list:
|
||||
self.set_doclist(dt)
|
||||
|
||||
def load_from_db(self, dt=None, dn=None, prefix='tab'):
|
||||
"""
|
||||
Load doclist from dt
|
||||
"""
|
||||
from webnotes.model.doc import Document, getchildren
|
||||
if not dt: dt = self.doc.doctype
|
||||
if not dn: dn = self.doc.name
|
||||
|
||||
doc = Document(dt, dn, prefix=prefix)
|
||||
|
||||
# get all children types
|
||||
tablefields = webnotes.model.meta.get_table_fields(dt)
|
||||
|
||||
# load chilren
|
||||
doclist = [doc,]
|
||||
for t in tablefields:
|
||||
doclist += getchildren(doc.name, t[0], t[1], dt, prefix=prefix)
|
||||
|
||||
self.set_doclist(doclist)
|
||||
|
||||
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)
|
||||
|
||||
def set_doclist(self, docs):
|
||||
for i, d in enumerate(docs):
|
||||
if isinstance(d, dict):
|
||||
docs[i] = Document(fielddata=d)
|
||||
|
||||
self.docs = self.doclist = docs
|
||||
self.doc, self.children = docs[0], docs[1:]
|
||||
if self.obj:
|
||||
self.obj.doclist = self.doclist
|
||||
self.obj.doc = self.doc
|
||||
|
||||
def make_obj(self):
|
||||
"""
|
||||
Create a DocType object
|
||||
"""
|
||||
if self.obj: return self.obj
|
||||
|
||||
from webnotes.model.code import get_obj
|
||||
self.obj = get_obj(doc=self.doc, doclist=self.children)
|
||||
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):
|
||||
"""
|
||||
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'))):
|
||||
tmp = webnotes.conn.sql("""
|
||||
SELECT modified FROM `tab%s` WHERE name="%s" for update"""
|
||||
% (self.doc.doctype, self.doc.name))
|
||||
|
||||
if tmp and str(tmp[0][0]) != str(self.doc.modified):
|
||||
webnotes.msgprint("""
|
||||
Document has been modified after you have opened it.
|
||||
To maintain the integrity of the data, you will not be able to save your changes.
|
||||
Please refresh this document. [%s/%s]""" % (tmp[0][0], self.doc.modified), raise_exception=1)
|
||||
|
||||
def check_permission(self):
|
||||
"""
|
||||
Raises exception if permission is not valid
|
||||
"""
|
||||
if not self.doc.check_perm(verbose=1):
|
||||
webnotes.msgprint("Not enough permission to save %s" % self.doc.doctype, raise_exception=1)
|
||||
|
||||
def check_links(self):
|
||||
"""
|
||||
Checks integrity of links (throws exception if links are invalid)
|
||||
"""
|
||||
ref, err_list = {}, []
|
||||
for d in self.docs:
|
||||
if not ref.get(d.doctype):
|
||||
ref[d.doctype] = d.make_link_list()
|
||||
|
||||
err_list += d.validate_links(ref[d.doctype])
|
||||
|
||||
if err_list:
|
||||
webnotes.msgprint("""[Link Validation] Could not find the following values: %s.
|
||||
Please correct and resave. Document Not Saved.""" % ', '.join(err_list), raise_exception=1)
|
||||
|
||||
def update_timestamps_and_docstatus(self):
|
||||
"""
|
||||
Update owner, creation, modified_by, modified, docstatus
|
||||
"""
|
||||
from webnotes.utils import now
|
||||
ts = now()
|
||||
user = webnotes.__dict__.get('session', {}).get('user') or 'Administrator'
|
||||
|
||||
for d in self.docs:
|
||||
if self.doc.fields.get('__islocal'):
|
||||
d.owner = user
|
||||
d.creation = ts
|
||||
|
||||
d.modified_by = user
|
||||
d.modified = ts
|
||||
if d.docstatus != 2: # don't update deleted
|
||||
d.docstatus = self.to_docstatus
|
||||
|
||||
def prepare_for_save(self, check_links):
|
||||
"""
|
||||
Set owner, modified etc before saving
|
||||
"""
|
||||
self.check_if_latest()
|
||||
self.check_permission()
|
||||
if check_links:
|
||||
self.check_links()
|
||||
self.update_timestamps_and_docstatus()
|
||||
|
||||
def run_method(self, method):
|
||||
"""
|
||||
Run a method and custom_method
|
||||
"""
|
||||
self.make_obj()
|
||||
if hasattr(self.obj, method):
|
||||
getattr(self.obj, method)()
|
||||
if hasattr(self.obj, 'custom_' + method):
|
||||
getattr(self.obj, 'custom_' + method)()
|
||||
|
||||
trigger(method, self.obj.doc)
|
||||
|
||||
self.set_doclist([self.obj.doc] + self.obj.doclist)
|
||||
|
||||
def save_main(self):
|
||||
"""
|
||||
Save the main doc
|
||||
"""
|
||||
try:
|
||||
self.doc.save(cint(self.doc.fields.get('__islocal')))
|
||||
except NameError, e:
|
||||
webnotes.msgprint('%s "%s" already exists' % (self.doc.doctype, self.doc.name))
|
||||
|
||||
# prompt if cancelled
|
||||
if webnotes.conn.get_value(self.doc.doctype, self.doc.name, 'docstatus')==2:
|
||||
webnotes.msgprint('[%s "%s" has been cancelled]' % (self.doc.doctype, self.doc.name))
|
||||
webnotes.errprint(webnotes.utils.getTraceback())
|
||||
raise e
|
||||
|
||||
def save_children(self):
|
||||
"""
|
||||
Save Children, with the new parent name
|
||||
"""
|
||||
child_map = {}
|
||||
for d in self.children:
|
||||
if (d.fields.has_key('parent') and d.fields.get('parent')) or \
|
||||
(d.fields.has_key("parentfield") and d.fields.get("parentfield")):
|
||||
# if d.parent:
|
||||
d.parent = self.doc.name # rename if reqd
|
||||
d.parenttype = self.doc.doctype
|
||||
|
||||
d.save(new = cint(d.fields.get('__islocal')))
|
||||
class DocList(list):
|
||||
"""DocList object as a wrapper around a list"""
|
||||
def get(self, filters, limit=0):
|
||||
"""pass filters as:
|
||||
{"key": "val", "key": ["!=", "val"],
|
||||
"key": ["in", "val"], "key": ["not in", "val"], "key": "^val"}"""
|
||||
# map reverse operations to set add = False
|
||||
import operator
|
||||
ops_map = {
|
||||
"!=": lambda (a, b): operator.ne(a, b),
|
||||
"in": lambda (a, b): operator.contains(b, a),
|
||||
"not in": lambda (a, b): not operator.contains(b, a)
|
||||
}
|
||||
|
||||
child_map.setdefault(d.doctype, []).append(d.name)
|
||||
out = []
|
||||
|
||||
# delete all children in database that are not in the child_map
|
||||
for doc in self:
|
||||
d = isinstance(getattr(doc, "fields", None), dict) and doc.fields or doc
|
||||
add = True
|
||||
for f in filters:
|
||||
fval = filters[f]
|
||||
|
||||
if isinstance(fval, list):
|
||||
if fval[0] in ops_map and not ops_map[fval[0]]((d.get(f), fval[1])):
|
||||
add = False
|
||||
break
|
||||
elif isinstance(fval, basestring) and fval.startswith("^"):
|
||||
if not (d.get(f) or "").startswith(fval[1:]):
|
||||
add = False
|
||||
break
|
||||
elif d.get(f)!=fval:
|
||||
add = False
|
||||
break
|
||||
|
||||
if add:
|
||||
out.append(doc)
|
||||
if limit and (len(out)-1)==limit:
|
||||
break
|
||||
|
||||
# get all children types
|
||||
tablefields = webnotes.model.meta.get_table_fields(self.doc.doctype)
|
||||
return DocList(out)
|
||||
|
||||
def getone(self, filters):
|
||||
return self.get(filters, limit=1)[0]
|
||||
|
||||
def extend(self, n):
|
||||
list.extend(self, n)
|
||||
return self
|
||||
|
||||
def copy(self):
|
||||
out = []
|
||||
for d in self:
|
||||
out.append(Document(d))
|
||||
return DocList(out)
|
||||
|
||||
def filter_valid_fields(self):
|
||||
import webnotes.model
|
||||
fieldnames = {}
|
||||
for d in self:
|
||||
remove = []
|
||||
for f in d:
|
||||
if f not in fieldnames.setdefault(d.doctype,
|
||||
webnotes.model.get_fieldnames(d.doctype)):
|
||||
remove.append(f)
|
||||
for f in remove:
|
||||
del d[f]
|
||||
|
||||
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))
|
||||
def append(self, doc):
|
||||
if not isinstance(doc, Document):
|
||||
doc = Document(doc)
|
||||
|
||||
self._prepare_doc(doc)
|
||||
|
||||
def save(self, check_links=1):
|
||||
"""
|
||||
Save the list
|
||||
"""
|
||||
self.prepare_for_save(check_links)
|
||||
self.run_method('validate')
|
||||
self.save_main()
|
||||
self.save_children()
|
||||
self.run_method('on_update')
|
||||
super(DocList, self).append(doc)
|
||||
|
||||
def extend(self, doclist):
|
||||
doclist = objectify(doclist)
|
||||
for doc in doclist:
|
||||
self._prepare_doc(doc)
|
||||
|
||||
super(DocList, self).extend(doclist)
|
||||
|
||||
def _prepare_doc(self, doc):
|
||||
if not doc.name:
|
||||
doc.fields["__islocal"] = 1
|
||||
if doc.parentfield:
|
||||
if not doc.parenttype:
|
||||
doc.parenttype = self[0].doctype
|
||||
if not doc.parent:
|
||||
doc.parent = self[0].name
|
||||
|
||||
def submit(self):
|
||||
"""
|
||||
Save & Submit - set docstatus = 1, run "on_submit"
|
||||
"""
|
||||
if self.doc.docstatus != 0:
|
||||
webnotes.msgprint("Only draft can be submitted", raise_exception=1)
|
||||
self.to_docstatus = 1
|
||||
self.save()
|
||||
self.run_method('on_submit')
|
||||
def load(doctype, name):
|
||||
# load main doc
|
||||
return objectify(load_doclist(doctype, name))
|
||||
|
||||
def cancel(self):
|
||||
"""
|
||||
Cancel - set docstatus 2, run "on_cancel"
|
||||
"""
|
||||
if self.doc.docstatus != 1:
|
||||
webnotes.msgprint("Only submitted can be cancelled", raise_exception=1)
|
||||
self.to_docstatus = 2
|
||||
self.prepare_for_save(1)
|
||||
self.save_main()
|
||||
self.save_children()
|
||||
self.run_method('on_cancel')
|
||||
|
||||
def update_after_submit(self):
|
||||
"""
|
||||
Update after submit - some values changed after submit
|
||||
"""
|
||||
if self.doc.docstatus != 1:
|
||||
webnotes.msgprint("Only to called after submit", raise_exception=1)
|
||||
self.to_docstatus = 1
|
||||
self.prepare_for_save(1)
|
||||
self.save_main()
|
||||
self.save_children()
|
||||
self.run_method('on_update_after_submit')
|
||||
|
||||
# clone
|
||||
|
||||
def clone(source_doclist):
|
||||
""" Copy previous invoice and change dates"""
|
||||
from webnotes.model.doc import Document
|
||||
new_doclist = []
|
||||
new_parent = Document(fielddata = source_doclist.doc.fields.copy())
|
||||
new_parent.name = 'Temp/001'
|
||||
new_parent.fields['__islocal'] = 1
|
||||
new_parent.fields['docstatus'] = 0
|
||||
|
||||
if new_parent.fields.has_key('amended_from'):
|
||||
new_parent.fields['amended_from'] = None
|
||||
new_parent.fields['amendment_date'] = None
|
||||
|
||||
new_parent.save(1)
|
||||
|
||||
new_doclist.append(new_parent)
|
||||
|
||||
for d in source_doclist.doclist[1:]:
|
||||
newd = Document(fielddata = d.fields.copy())
|
||||
newd.name = None
|
||||
newd.fields['__islocal'] = 1
|
||||
newd.fields['docstatus'] = 0
|
||||
newd.parent = new_parent.name
|
||||
new_doclist.append(newd)
|
||||
def load_doclist(doctype, name):
|
||||
doclist = DocList([load_main(doctype, name)])
|
||||
|
||||
doclistobj = DocList()
|
||||
doclistobj.docs = new_doclist
|
||||
doclistobj.doc = new_doclist[0]
|
||||
doclistobj.doclist = new_doclist
|
||||
doclistobj.children = new_doclist[1:]
|
||||
doclistobj.save()
|
||||
return doclistobj
|
||||
# load children
|
||||
table_fields = map(lambda f: (f.options, name, f.fieldname, doctype),
|
||||
webnotes.conn.get_table_fields(doctype))
|
||||
|
||||
|
||||
def trigger(method, doc):
|
||||
"""trigger doctype events"""
|
||||
try:
|
||||
import startup.event_handlers
|
||||
except ImportError:
|
||||
return
|
||||
for args in table_fields:
|
||||
children = load_children(*args)
|
||||
if children: doclist += children
|
||||
|
||||
if hasattr(startup.event_handlers, method):
|
||||
getattr(startup.event_handlers, method)(doc)
|
||||
return doclist
|
||||
|
||||
def load_main(doctype, name):
|
||||
"""retrieves doc from database"""
|
||||
if webnotes.conn.is_single(doctype):
|
||||
doc = webnotes.conn.sql("""select field, value from `tabSingles`
|
||||
where doctype=%s""", doctype, as_list=1)
|
||||
doc = dict(doc)
|
||||
doc["name"] = doctype
|
||||
else:
|
||||
doc = webnotes.conn.sql("""select * from `tab%s` where name = %s""" % \
|
||||
(doctype, "%s"), name, as_dict=1)
|
||||
if not doc:
|
||||
raise NameError, """%s: "%s" does not exist""" % (doctype, name)
|
||||
doc = doc[0]
|
||||
|
||||
doc["doctype"] = doctype
|
||||
return doc
|
||||
|
||||
def load_children(options, parent, parentfield, parenttype):
|
||||
"""load children based on options, parentfield, parenttype and parent"""
|
||||
options = options.split("\n")[0].strip()
|
||||
|
||||
if hasattr(startup.event_handlers, 'doclist_all'):
|
||||
startup.event_handlers.doclist_all(doc, method)
|
||||
|
||||
# for bc
|
||||
def getlist(doclist, parentfield):
|
||||
"""
|
||||
Return child records of a particular type
|
||||
"""
|
||||
import webnotes.model.utils
|
||||
return webnotes.model.utils.getlist(doclist, parentfield)
|
||||
|
||||
def copy_doclist(doclist, no_copy = []):
|
||||
"""
|
||||
Make a copy of the doclist
|
||||
"""
|
||||
import webnotes.model.utils
|
||||
return webnotes.model.utils.copy_doclist(doclist, no_copy)
|
||||
|
||||
return webnotes.conn.sql("""select *, "%s" as doctype from `tab%s` where parent = %s
|
||||
and parentfield = %s and parenttype = %s order by idx""" % (options, options, "%s", "%s", "%s"),
|
||||
(parent, parentfield, parenttype), as_dict=1)
|
||||
|
||||
def objectify(doclist):
|
||||
from webnotes.model.doc import Document
|
||||
return map(lambda d: isinstance(d, Document) and d or Document(d), doclist)
|
||||
|
|
|
|||
|
|
@ -77,7 +77,8 @@ class _DocType:
|
|||
"""
|
||||
Gets a list of custom field docs masked as type DocField
|
||||
"""
|
||||
custom_doclist = []
|
||||
from webnotes.model.doclist import DocList
|
||||
custom_doclist = DocList()
|
||||
res = webnotes.conn.sql("""SELECT * FROM `tabCustom Field`
|
||||
WHERE dt = %s AND docstatus < 2""", doc_type, as_dict=1)
|
||||
for r in res:
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ def sync_all(force=0):
|
|||
|
||||
def sync_core_doctypes(force=0):
|
||||
# doctypes
|
||||
return walk_and_sync(os.path.join(os.path.dirname(conf.__file__), 'lib'), force)
|
||||
return walk_and_sync(os.path.join(os.path.dirname(os.path.abspath(conf.__file__)), 'lib'), force)
|
||||
|
||||
def sync_modules(force=0):
|
||||
return walk_and_sync(os.path.join(os.path.dirname(conf.__file__), 'app'), force)
|
||||
return walk_and_sync(os.path.join(os.path.dirname(os.path.abspath(conf.__file__)), 'app'), force)
|
||||
|
||||
def walk_and_sync(start_path, force=0):
|
||||
"""walk and sync all doctypes and pages"""
|
||||
|
|
@ -32,8 +32,9 @@ def walk_and_sync(start_path, force=0):
|
|||
|
||||
modules = []
|
||||
|
||||
document_type = ['page', 'workflow', 'module_def', 'workflow_state', 'workflow_action']
|
||||
for path, folders, files in os.walk(start_path):
|
||||
if os.path.basename(os.path.dirname(path)) in ('doctype', 'page'):
|
||||
if os.path.basename(os.path.dirname(path)) in (['doctype'] + document_type):
|
||||
for f in files:
|
||||
if f.endswith(".txt"):
|
||||
# great grand-parent folder is module_name
|
||||
|
|
@ -49,7 +50,7 @@ def walk_and_sync(start_path, force=0):
|
|||
|
||||
if doctype == 'doctype':
|
||||
sync(module_name, name, force)
|
||||
elif doctype in ['page']:#, 'search_criteria', 'Print Format', 'DocType Mapper']:
|
||||
elif doctype in document_type:
|
||||
if reload_doc(module_name, doctype, name):
|
||||
print module_name + ' | ' + doctype + ' | ' + name
|
||||
|
||||
|
|
@ -60,14 +61,18 @@ def walk_and_sync(start_path, force=0):
|
|||
def sync(module_name, docname, force=0):
|
||||
"""sync doctype from file if modified"""
|
||||
with open(get_file_path(module_name, docname), 'r') as f:
|
||||
from webnotes.model.utils import peval_doclist
|
||||
from webnotes.modules.utils import peval_doclist
|
||||
doclist = peval_doclist(f.read())
|
||||
modified = doclist[0]['modified']
|
||||
if not doclist:
|
||||
raise Exception('DocList could not be evaluated')
|
||||
if modified == str(webnotes.conn.get_value(doclist[0].get('doctype'),
|
||||
doclist[0].get('name'), 'modified')) and not force:
|
||||
raise Exception('ModelWrapper 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)
|
||||
|
|
@ -162,47 +167,3 @@ def create_doc(data):
|
|||
d.fields.update(data)
|
||||
d.save()
|
||||
print 'Created %(doctype)s %(name)s' % d.fields
|
||||
|
||||
import unittest
|
||||
class TestSync(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.test_case = {
|
||||
'module_name': 'selling',
|
||||
'docname': 'sales_order'
|
||||
}
|
||||
webnotes.conn.begin()
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
#from webnotes.utils import cstr
|
||||
#webnotes.conn.rollback()
|
||||
|
||||
def test_sync(self):
|
||||
#old_doctype, old_docfields = self.query('Profile')
|
||||
#self.parent = sync(self.test_case.get('module_name'), self.test_case.get('docname'))
|
||||
#new_doctype, new_docfields = self.query(self.parent)
|
||||
#self.assertNotEqual(old_doctype, new_doctype)
|
||||
#self.assertNotEqual(old_docfields, new_docfields)
|
||||
|
||||
#from webnotes.utils import cstr
|
||||
#print new_doctype[0]
|
||||
#print
|
||||
#print "\n".join((cstr(d) for d in new_docfields))
|
||||
#print "\n\n"
|
||||
pass
|
||||
|
||||
def test_sync_all(self):
|
||||
sync_all()
|
||||
|
||||
def query(self, parent):
|
||||
doctype = webnotes.conn.sql("SELECT name FROM `tabDocType` \
|
||||
WHERE name=%s", parent)
|
||||
docfields = webnotes.conn.sql("SELECT idx, fieldname, label, fieldtype FROM `tabDocField` \
|
||||
WHERE parent=%s order by idx", parent)
|
||||
#doctype = webnotes.conn.sql("SELECT * FROM `tabDocType` \
|
||||
# WHERE name=%s", parent)
|
||||
#docfields = webnotes.conn.sql("SELECT * FROM `tabDocField` \
|
||||
# WHERE parent=%s order by idx", parent)
|
||||
return doctype, docfields
|
||||
|
||||
|
||||
|
|
|
|||
344
webnotes/model/wrapper.py
Normal file
344
webnotes/model/wrapper.py
Normal file
|
|
@ -0,0 +1,344 @@
|
|||
# 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
|
||||
"""
|
||||
Transactions are defined as collection of classes, a ModelWrapper represents collection of Document
|
||||
objects for a transaction with main and children.
|
||||
|
||||
Group actions like save, etc are performed on doclists
|
||||
"""
|
||||
|
||||
import webnotes
|
||||
from webnotes.utils import cint
|
||||
from webnotes.model.doc import Document
|
||||
|
||||
class ModelWrapper:
|
||||
"""
|
||||
Collection of Documents with one parent and multiple children
|
||||
"""
|
||||
def __init__(self, dt=None, dn=None):
|
||||
self.docs = []
|
||||
self.obj = None
|
||||
self.to_docstatus = 0
|
||||
if dt and dn:
|
||||
self.load_from_db(dt, dn)
|
||||
if type(dt) is list:
|
||||
self.set_doclist(dt)
|
||||
|
||||
def load_from_db(self, dt=None, dn=None, prefix='tab'):
|
||||
"""
|
||||
Load doclist from dt
|
||||
"""
|
||||
from webnotes.model.doc import Document, getchildren
|
||||
from webnotes.model.doclist import DocList
|
||||
if not dt: dt = self.doc.doctype
|
||||
if not dn: dn = self.doc.name
|
||||
|
||||
doc = Document(dt, dn, prefix=prefix)
|
||||
|
||||
# get all children types
|
||||
tablefields = webnotes.model.meta.get_table_fields(dt)
|
||||
|
||||
# load chilren
|
||||
doclist = DocList([doc,])
|
||||
for t in tablefields:
|
||||
doclist += getchildren(doc.name, t[0], t[1], dt, prefix=prefix)
|
||||
|
||||
self.set_doclist(doclist)
|
||||
|
||||
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)
|
||||
|
||||
def set_doclist(self, docs):
|
||||
for i, d in enumerate(docs):
|
||||
if isinstance(d, dict):
|
||||
docs[i] = Document(fielddata=d)
|
||||
|
||||
self.docs = self.doclist = docs
|
||||
self.doc, self.children = docs[0], docs[1:]
|
||||
if self.obj:
|
||||
self.obj.doclist = self.doclist
|
||||
self.obj.doc = self.doc
|
||||
|
||||
def make_obj(self):
|
||||
"""
|
||||
Create a DocType object
|
||||
"""
|
||||
if self.obj: return self.obj
|
||||
|
||||
from webnotes.model.code import get_obj
|
||||
self.obj = get_obj(doc=self.doc, doclist=self.children)
|
||||
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):
|
||||
"""
|
||||
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'))):
|
||||
tmp = webnotes.conn.sql("""
|
||||
SELECT modified FROM `tab%s` WHERE name="%s" for update"""
|
||||
% (self.doc.doctype, self.doc.name))
|
||||
|
||||
if tmp and str(tmp[0][0]) != str(self.doc.modified):
|
||||
webnotes.msgprint("""
|
||||
Document has been modified after you have opened it.
|
||||
To maintain the integrity of the data, you will not be able to save your changes.
|
||||
Please refresh this document. [%s/%s]""" % (tmp[0][0], self.doc.modified), raise_exception=1)
|
||||
|
||||
def check_permission(self):
|
||||
"""
|
||||
Raises exception if permission is not valid
|
||||
"""
|
||||
if not self.doc.check_perm(verbose=1):
|
||||
webnotes.msgprint("Not enough permission to save %s" % self.doc.doctype, raise_exception=1)
|
||||
|
||||
def check_links(self):
|
||||
"""
|
||||
Checks integrity of links (throws exception if links are invalid)
|
||||
"""
|
||||
ref, err_list = {}, []
|
||||
for d in self.docs:
|
||||
if not ref.get(d.doctype):
|
||||
ref[d.doctype] = d.make_link_list()
|
||||
|
||||
err_list += d.validate_links(ref[d.doctype])
|
||||
|
||||
if err_list:
|
||||
webnotes.msgprint("""[Link Validation] Could not find the following values: %s.
|
||||
Please correct and resave. Document Not Saved.""" % ', '.join(err_list), raise_exception=1)
|
||||
|
||||
def update_timestamps_and_docstatus(self):
|
||||
"""
|
||||
Update owner, creation, modified_by, modified, docstatus
|
||||
"""
|
||||
from webnotes.utils import now
|
||||
ts = now()
|
||||
user = webnotes.__dict__.get('session', {}).get('user') or 'Administrator'
|
||||
|
||||
for d in self.docs:
|
||||
if self.doc.fields.get('__islocal'):
|
||||
d.owner = user
|
||||
d.creation = ts
|
||||
|
||||
d.modified_by = user
|
||||
d.modified = ts
|
||||
if d.docstatus != 2: # don't update deleted
|
||||
d.docstatus = self.to_docstatus
|
||||
|
||||
def prepare_for_save(self, check_links):
|
||||
"""
|
||||
Set owner, modified etc before saving
|
||||
"""
|
||||
self.check_if_latest()
|
||||
self.check_permission()
|
||||
if check_links:
|
||||
self.check_links()
|
||||
self.update_timestamps_and_docstatus()
|
||||
|
||||
def run_method(self, method):
|
||||
"""
|
||||
Run a method and custom_method
|
||||
"""
|
||||
self.make_obj()
|
||||
if hasattr(self.obj, method):
|
||||
getattr(self.obj, method)()
|
||||
if hasattr(self.obj, 'custom_' + method):
|
||||
getattr(self.obj, 'custom_' + method)()
|
||||
|
||||
trigger(method, self.obj.doc)
|
||||
|
||||
self.set_doclist([self.obj.doc] + self.obj.doclist)
|
||||
|
||||
def save_main(self):
|
||||
"""
|
||||
Save the main doc
|
||||
"""
|
||||
try:
|
||||
self.doc.save(cint(self.doc.fields.get('__islocal')))
|
||||
except NameError, e:
|
||||
webnotes.msgprint('%s "%s" already exists' % (self.doc.doctype, self.doc.name))
|
||||
|
||||
# prompt if cancelled
|
||||
if webnotes.conn.get_value(self.doc.doctype, self.doc.name, 'docstatus')==2:
|
||||
webnotes.msgprint('[%s "%s" has been cancelled]' % (self.doc.doctype, self.doc.name))
|
||||
webnotes.errprint(webnotes.utils.getTraceback())
|
||||
raise e
|
||||
|
||||
def save_children(self):
|
||||
"""
|
||||
Save Children, with the new parent name
|
||||
"""
|
||||
child_map = {}
|
||||
for d in self.children:
|
||||
if (d.fields.has_key('parent') and d.fields.get('parent')) or \
|
||||
(d.fields.has_key("parentfield") and d.fields.get("parentfield")):
|
||||
# if d.parent:
|
||||
d.parent = self.doc.name # rename if reqd
|
||||
d.parenttype = self.doc.doctype
|
||||
|
||||
d.save(new = cint(d.fields.get('__islocal')))
|
||||
|
||||
child_map.setdefault(d.doctype, []).append(d.name)
|
||||
|
||||
# delete all children in database that are not in the child_map
|
||||
|
||||
# get all children types
|
||||
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))
|
||||
|
||||
def save(self, check_links=1):
|
||||
"""
|
||||
Save the list
|
||||
"""
|
||||
self.prepare_for_save(check_links)
|
||||
self.run_method('validate')
|
||||
self.save_main()
|
||||
self.save_children()
|
||||
self.run_method('on_update')
|
||||
|
||||
def submit(self):
|
||||
"""
|
||||
Save & Submit - set docstatus = 1, run "on_submit"
|
||||
"""
|
||||
if self.doc.docstatus != 0:
|
||||
webnotes.msgprint("Only draft can be submitted", raise_exception=1)
|
||||
self.to_docstatus = 1
|
||||
self.save()
|
||||
self.run_method('on_submit')
|
||||
|
||||
def cancel(self):
|
||||
"""
|
||||
Cancel - set docstatus 2, run "on_cancel"
|
||||
"""
|
||||
if self.doc.docstatus != 1:
|
||||
webnotes.msgprint("Only submitted can be cancelled", raise_exception=1)
|
||||
self.to_docstatus = 2
|
||||
self.prepare_for_save(1)
|
||||
self.save_main()
|
||||
self.save_children()
|
||||
self.run_method('on_cancel')
|
||||
|
||||
def update_after_submit(self):
|
||||
"""
|
||||
Update after submit - some values changed after submit
|
||||
"""
|
||||
if self.doc.docstatus != 1:
|
||||
webnotes.msgprint("Only to called after submit", raise_exception=1)
|
||||
self.to_docstatus = 1
|
||||
self.prepare_for_save(1)
|
||||
self.save_main()
|
||||
self.save_children()
|
||||
self.run_method('on_update_after_submit')
|
||||
|
||||
# clone
|
||||
|
||||
def clone(source_doclist):
|
||||
""" Copy previous invoice and change dates"""
|
||||
from webnotes.model.doc import Document
|
||||
new_doclist = []
|
||||
new_parent = Document(fielddata = source_doclist.doc.fields.copy())
|
||||
new_parent.name = 'Temp/001'
|
||||
new_parent.fields['__islocal'] = 1
|
||||
new_parent.fields['docstatus'] = 0
|
||||
|
||||
if new_parent.fields.has_key('amended_from'):
|
||||
new_parent.fields['amended_from'] = None
|
||||
new_parent.fields['amendment_date'] = None
|
||||
|
||||
new_parent.save(1)
|
||||
|
||||
new_doclist.append(new_parent)
|
||||
|
||||
for d in source_doclist.doclist[1:]:
|
||||
newd = Document(fielddata = d.fields.copy())
|
||||
newd.name = None
|
||||
newd.fields['__islocal'] = 1
|
||||
newd.fields['docstatus'] = 0
|
||||
newd.parent = new_parent.name
|
||||
new_doclist.append(newd)
|
||||
|
||||
doclistobj = ModelWrapper()
|
||||
doclistobj.docs = new_doclist
|
||||
doclistobj.doc = new_doclist[0]
|
||||
doclistobj.doclist = new_doclist
|
||||
doclistobj.children = new_doclist[1:]
|
||||
doclistobj.save()
|
||||
return doclistobj
|
||||
|
||||
|
||||
def trigger(method, doc):
|
||||
"""trigger doctype events"""
|
||||
try:
|
||||
import startup.event_handlers
|
||||
except ImportError:
|
||||
return
|
||||
|
||||
if hasattr(startup.event_handlers, method):
|
||||
getattr(startup.event_handlers, method)(doc)
|
||||
|
||||
if hasattr(startup.event_handlers, 'doclist_all'):
|
||||
startup.event_handlers.doclist_all(doc, method)
|
||||
|
||||
# for bc
|
||||
def getlist(doclist, parentfield):
|
||||
"""
|
||||
Return child records of a particular type
|
||||
"""
|
||||
import webnotes.model.utils
|
||||
return webnotes.model.utils.getlist(doclist, parentfield)
|
||||
|
||||
def copy_doclist(doclist, no_copy = []):
|
||||
"""
|
||||
Make a copy of the doclist
|
||||
"""
|
||||
import webnotes.model.utils
|
||||
return webnotes.model.utils.copy_doclist(doclist, no_copy)
|
||||
|
||||
|
|
@ -24,9 +24,23 @@ from __future__ import unicode_literals
|
|||
"""
|
||||
Utilities for using modules
|
||||
"""
|
||||
import webnotes
|
||||
import webnotes, os, conf
|
||||
|
||||
transfer_types = ['Role', 'Print Format','DocType','Page','DocType Mapper','GL Mapper','Search Criteria', 'Patch', 'Report']
|
||||
transfer_types = ['Role', 'Print Format','DocType','Page','DocType Mapper',
|
||||
'GL Mapper','Search Criteria', 'Patch', 'Report']
|
||||
|
||||
lower_case_files_for = ['DocType', 'Page', 'Search Criteria', 'Report',
|
||||
"Workflow", 'Module Def', 'Desktop Item', 'Workflow State', 'Workflow Action']
|
||||
|
||||
code_fields_dict = {
|
||||
'Page':[('script', 'js'), ('content', 'html'), ('style', 'css'), ('static_content', 'html'), ('server_code', 'py')],
|
||||
'DocType':[('server_code_core', 'py'), ('client_script_core', 'js')],
|
||||
'Search Criteria':[('report_script', 'js'), ('server_script', 'py'), ('custom_query', 'sql')],
|
||||
'Patch':[('patch_code', 'py')],
|
||||
'Stylesheet':['stylesheet', 'css'],
|
||||
'Page Template':['template', 'html'],
|
||||
'Control Panel':[('startup_code', 'js'), ('startup_css', 'css')]
|
||||
}
|
||||
|
||||
def scrub(txt):
|
||||
return txt.replace(' ','_').replace('-', '_').replace('/', '_').lower()
|
||||
|
|
@ -34,14 +48,13 @@ def scrub(txt):
|
|||
def scrub_dt_dn(dt, dn):
|
||||
"""Returns in lowercase and code friendly names of doctype and name for certain types"""
|
||||
ndt, ndn = dt, dn
|
||||
if dt.lower() in ('doctype', 'search criteria', 'page', 'report'):
|
||||
if dt in lower_case_files_for:
|
||||
ndt, ndn = scrub(dt), scrub(dn)
|
||||
|
||||
return ndt, ndn
|
||||
|
||||
def get_module_path(module):
|
||||
"""Returns path of the given module"""
|
||||
import os, conf
|
||||
m = scrub(module)
|
||||
|
||||
app_path = os.path.dirname(conf.__file__)
|
||||
|
|
@ -50,56 +63,18 @@ def get_module_path(module):
|
|||
return os.path.join(app_path, 'lib', 'core')
|
||||
else:
|
||||
return os.path.join(app_path, 'app', m)
|
||||
|
||||
|
||||
def get_doc_path(module, doctype, name):
|
||||
dt, dn = scrub_dt_dn(doctype, name)
|
||||
return os.path.join(get_module_path(module), dt, dn)
|
||||
|
||||
def reload_doc(module, dt=None, dn=None):
|
||||
"""reload single / list of records"""
|
||||
|
||||
if type(module) is list:
|
||||
for m in module:
|
||||
reload_single_doc(m[0], m[1], m[2])
|
||||
else:
|
||||
reload_single_doc(module, dt, dn)
|
||||
|
||||
def reload_single_doc(module, dt, dn, force=False):
|
||||
"""Sync a file from txt if modifed, return false if not updated"""
|
||||
if dt.lower() == 'doctype':
|
||||
return
|
||||
|
||||
import os
|
||||
dt, dn = scrub_dt_dn(dt, dn)
|
||||
|
||||
path = os.path.join(get_module_path(module),
|
||||
os.path.join(dt, dn, dn + '.txt'))
|
||||
|
||||
if os.path.exists(path):
|
||||
from webnotes.model.utils import peval_doclist
|
||||
|
||||
with open(path, 'r') as f:
|
||||
doclist = peval_doclist(f.read())
|
||||
|
||||
if doclist:
|
||||
doc = doclist[0]
|
||||
if not force:
|
||||
# check if timestamps match
|
||||
if doc['modified']== str(webnotes.conn.get_value(doc['doctype'], doc['name'], 'modified')):
|
||||
return False
|
||||
|
||||
from webnotes.utils.transfer import set_doc
|
||||
set_doc(doclist, 1, 1, 1)
|
||||
|
||||
# since there is a new timestamp on the file, update timestamp in
|
||||
webnotes.conn.sql("update `tab%s` set modified=%s where name=%s" % \
|
||||
(doc['doctype'], '%s', '%s'),
|
||||
(doc['modified'],doc['name']))
|
||||
return True
|
||||
else:
|
||||
raise Exception, '%s missing' % path
|
||||
|
||||
from webnotes.modules.import_file import import_files
|
||||
return import_files(module, dt, dn)
|
||||
|
||||
def export_doc(doctype, name, module=None):
|
||||
"""write out a doc"""
|
||||
from webnotes.modules.export_module import write_document_file
|
||||
from webnotes.modules.export_file import write_document_file
|
||||
import webnotes.model.doc
|
||||
if not module: module = webnotes.conn.get_value(doctype, name, 'module')
|
||||
doclist = [d.fields for d in webnotes.model.doc.get(doctype, name)]
|
||||
|
|
|
|||
|
|
@ -21,28 +21,98 @@
|
|||
#
|
||||
|
||||
from __future__ import unicode_literals
|
||||
"""
|
||||
Export files to modules
|
||||
"""
|
||||
|
||||
from webnotes.modules import scrub, get_module_path
|
||||
import webnotes, os
|
||||
import webnotes.model.doc
|
||||
from webnotes.modules import scrub, get_module_path, lower_case_files_for, \
|
||||
code_fields_dict, scrub_dt_dn
|
||||
|
||||
def export_doc(doc):
|
||||
export_to_files([[doc.doctype, doc.name]])
|
||||
|
||||
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] ) ,
|
||||
"""
|
||||
import webnotes.model.doc
|
||||
from webnotes.modules.import_merge import in_transfer
|
||||
if in_transfer:
|
||||
return
|
||||
|
||||
module_doclist =[]
|
||||
if record_list:
|
||||
for record in record_list:
|
||||
doclist = [d.fields for d in webnotes.model.doc.get(record[0], record[1])]
|
||||
write_document_file(doclist, record_module)
|
||||
write_document_file(webnotes.model.doc.get(record[0], record[1]),
|
||||
record_module)
|
||||
|
||||
def write_document_file(doclist, record_module=None):
|
||||
from webnotes.modules.utils import pprint_doclist
|
||||
|
||||
doclist = [filter_fields(d.fields) for d in doclist]
|
||||
|
||||
module = record_module or get_module_name(doclist)
|
||||
code_type = doclist[0]['doctype'] in lower_case_files_for
|
||||
|
||||
# create folder
|
||||
folder = create_folder(module, doclist[0]['doctype'], doclist[0]['name'], code_type)
|
||||
|
||||
# separate code files
|
||||
clear_code_fields(doclist, folder, code_type)
|
||||
|
||||
# write the data file
|
||||
fname = (code_type and scrub(doclist[0]['name'])) or doclist[0]['name']
|
||||
with open(os.path.join(folder, fname +'.txt'),'w+') as txtfile:
|
||||
txtfile.write(pprint_doclist(doclist))
|
||||
|
||||
def filter_fields(doc):
|
||||
from webnotes.model.doctype import get
|
||||
from webnotes.model import default_fields
|
||||
|
||||
doctypelist = get(doc.doctype, False)
|
||||
valid_fields = [d.fieldname for d in doctypelist.get({"parent":doc.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':
|
||||
module = 'Core'
|
||||
elif doclist[0]['doctype']=="Workflow":
|
||||
module = webnotes.conn.get_value("DocType", doclist[0]["document_type"], "module")
|
||||
else:
|
||||
module = doclist[0]['module']
|
||||
|
||||
return module
|
||||
|
||||
def create_folder(module, dt, dn, code_type):
|
||||
# get module path by importing the module
|
||||
module_path = get_module_path(module)
|
||||
|
||||
dt, dn = scrub_dt_dn(dt, dn)
|
||||
|
||||
# create folder
|
||||
folder = os.path.join(module_path, dt, dn)
|
||||
|
||||
webnotes.create_folder(folder)
|
||||
|
||||
# create init_py_files
|
||||
if code_type:
|
||||
create_init_py(module_path, dt, dn)
|
||||
|
||||
return folder
|
||||
|
||||
def create_init_py(module_path, dt, dn):
|
||||
"""
|
||||
Creates __init__.py in the module directory structure
|
||||
"""
|
||||
import os
|
||||
|
||||
def create_if_not_exists(path):
|
||||
initpy = os.path.join(path, '__init__.py')
|
||||
if not os.path.exists(initpy):
|
||||
|
|
@ -51,83 +121,11 @@ def create_init_py(module_path, dt, dn):
|
|||
create_if_not_exists(os.path.join(module_path))
|
||||
create_if_not_exists(os.path.join(module_path, dt))
|
||||
create_if_not_exists(os.path.join(module_path, dt, dn))
|
||||
|
||||
def create_folder(module, dt, dn):
|
||||
"""
|
||||
Creates directories for module and their __init__.py
|
||||
"""
|
||||
import webnotes, os
|
||||
|
||||
# get module path by importing the module
|
||||
module_path = get_module_path(module)
|
||||
|
||||
code_type = dt in ['DocType', 'Page', 'Search Criteria', 'Report']
|
||||
|
||||
# create folder
|
||||
folder = os.path.join(module_path, code_type and scrub(dt) or dt, code_type and scrub(dn) or dn)
|
||||
|
||||
webnotes.create_folder(folder)
|
||||
|
||||
# create init_py_files
|
||||
if code_type:
|
||||
create_init_py(module_path, scrub(dt), scrub(dn))
|
||||
|
||||
return folder
|
||||
|
||||
def get_module_name(doclist, record_module=None):
|
||||
"""
|
||||
Returns the module-name of a doclist
|
||||
"""
|
||||
# module name
|
||||
if doclist[0]['doctype'] == 'Module Def':
|
||||
module = doclist[0]['name']
|
||||
elif doclist[0]['doctype']=='Control Panel':
|
||||
module = 'Core'
|
||||
elif record_module:
|
||||
module = record_module
|
||||
else:
|
||||
module = doclist[0]['module']
|
||||
|
||||
return module
|
||||
|
||||
def write_document_file(doclist, record_module=None):
|
||||
"""
|
||||
Write a doclist to file, can optionally specify module name
|
||||
"""
|
||||
import os
|
||||
from webnotes.model.utils import pprint_doclist
|
||||
|
||||
module = get_module_name(doclist, record_module)
|
||||
|
||||
# create the folder
|
||||
code_type = doclist[0]['doctype'] in ['DocType','Page','Search Criteria', 'Report']
|
||||
|
||||
# create folder
|
||||
folder = create_folder(module, doclist[0]['doctype'], doclist[0]['name'])
|
||||
|
||||
# separate code files
|
||||
clear_code_fields(doclist, folder, code_type)
|
||||
|
||||
# write the data file
|
||||
fname = (code_type and scrub(doclist[0]['name'])) or doclist[0]['name']
|
||||
txtfile = open(os.path.join(folder, fname +'.txt'),'w+')
|
||||
txtfile.write(pprint_doclist(doclist))
|
||||
#dict_list = [pprint_dict(d) for d in doclist]
|
||||
#txtfile.write('[\n' + ',\n'.join(dict_list) + '\n]')
|
||||
txtfile.close()
|
||||
|
||||
def clear_code_fields(doclist, folder, code_type):
|
||||
"""
|
||||
Removes code from the doc
|
||||
"""
|
||||
|
||||
import os
|
||||
import webnotes
|
||||
# code will be in the parent only
|
||||
code_fields = webnotes.code_fields_dict.get(doclist[0]['doctype'], [])
|
||||
|
||||
code_fields = code_fields_dict.get(doclist[0]['doctype'], [])
|
||||
for code_field in code_fields:
|
||||
if doclist[0].get(code_field[0]):
|
||||
|
||||
doclist[0][code_field[0]] = None
|
||||
|
||||
71
webnotes/modules/import_file.py
Normal file
71
webnotes/modules/import_file.py
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
# 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
|
||||
|
||||
import webnotes, os
|
||||
from webnotes.modules import scrub, get_module_path, scrub_dt_dn
|
||||
|
||||
def import_files(module, dt=None, dn=None):
|
||||
if type(module) is list:
|
||||
for m in module:
|
||||
import_file(m[0], m[1], m[2])
|
||||
else:
|
||||
import_file(module, dt, dn)
|
||||
|
||||
def import_file(module, dt, dn, force=False):
|
||||
"""Sync a file from txt if modifed, return false if not updated"""
|
||||
if dt.lower() == 'doctype':
|
||||
return
|
||||
|
||||
dt, dn = scrub_dt_dn(dt, dn)
|
||||
|
||||
path = os.path.join(get_module_path(module),
|
||||
os.path.join(dt, dn, dn + '.txt'))
|
||||
|
||||
import_file_by_path(path, force)
|
||||
|
||||
def import_file_by_path(path, force=False):
|
||||
if os.path.exists(path):
|
||||
from webnotes.modules.utils import peval_doclist
|
||||
|
||||
with open(path, 'r') as f:
|
||||
doclist = peval_doclist(f.read())
|
||||
|
||||
if doclist:
|
||||
doc = doclist[0]
|
||||
if not force:
|
||||
# check if timestamps match
|
||||
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)
|
||||
|
||||
# since there is a new timestamp on the file, update timestamp in
|
||||
webnotes.conn.sql("update `tab%s` set modified=%s where name=%s" % \
|
||||
(doc['doctype'], '%s', '%s'),
|
||||
(doc['modified'],doc['name']))
|
||||
return True
|
||||
else:
|
||||
raise Exception, '%s missing' % path
|
||||
|
||||
|
|
@ -121,7 +121,7 @@ class UpdateDocument:
|
|||
|
||||
def save(self):
|
||||
# parent
|
||||
self.doc.save(new = 1, ignore_fields = 1, check_links=0)
|
||||
self.doc.save(new = 1, check_links=0)
|
||||
self.doclist = [self.doc]
|
||||
self.save_children()
|
||||
|
||||
|
|
@ -131,12 +131,12 @@ class UpdateDocument:
|
|||
|
||||
def save_one_doc(self, df, as_new=1):
|
||||
d = Document(fielddata = df)
|
||||
d.save(new = as_new, ignore_fields = 1, check_links=0)
|
||||
d.save(new = as_new, check_links=0)
|
||||
self.doclist.append(d)
|
||||
|
||||
def run_on_update(self):
|
||||
from webnotes.model.code import get_server_obj
|
||||
so = get_server_obj(self.doc, self.doclist)
|
||||
from webnotes.model.controller import get_obj
|
||||
so = get_obj(doc=self.doc, doclist=self.doclist)
|
||||
if hasattr(so, 'on_update'):
|
||||
so.on_update()
|
||||
|
||||
|
|
@ -165,7 +165,7 @@ class UpdateDocumentMerge(UpdateDocument):
|
|||
if self.exists:
|
||||
# save main doc
|
||||
self.keep_values(self.doc)
|
||||
self.doc.save(ignore_fields = 1, check_links=0)
|
||||
self.doc.save(check_links=0)
|
||||
self.doclist.append(self.doc)
|
||||
self.save_children()
|
||||
self.on_save()
|
||||
|
|
@ -186,10 +186,10 @@ class UpdateDocumentMerge(UpdateDocument):
|
|||
# is it new?
|
||||
if self.child_exists(d):
|
||||
self.keep_values(d)
|
||||
d.save(ignore_fields = 1, check_links=0)
|
||||
d.save(check_links=0)
|
||||
self.log.append('updated %s, %s' % (d.doctype, d.name))
|
||||
else:
|
||||
d.save(1, ignore_fields = 1, check_links=0)
|
||||
d.save(1, check_links=0)
|
||||
self.log.append('new %s' % d.doctype)
|
||||
self.doclist.append(d)
|
||||
|
||||
|
|
@ -272,7 +272,7 @@ class UpdateDocType(UpdateDocumentMerge):
|
|||
tmp = Document(fielddata = d)
|
||||
tmp.fieldname = ''
|
||||
tmp.name = None
|
||||
tmp.save(1, ignore_fields = 1, check_links=0)
|
||||
tmp.save(1, check_links=0)
|
||||
else:
|
||||
webnotes.conn.sql("update tabDocField set idx=%s where %s=%s and parent=%s" % \
|
||||
('%s', d.get('fieldname') and 'fieldname' or 'label', '%s', '%s'), (d.get('idx'), d.get('fieldname') or d.get('label'), self.doc.name))
|
||||
|
|
@ -294,8 +294,8 @@ class UpdateDocType(UpdateDocumentMerge):
|
|||
('%s', e[0] and 'fieldname' or 'label', '%s', '%s'), (idx+1, e[0] or e[1], self.doc.name))
|
||||
|
||||
def run_on_update(self):
|
||||
from webnotes.model.code import get_server_obj
|
||||
so = get_server_obj(self.doc, self.doclist)
|
||||
from webnotes.model.controller import get_obj
|
||||
so = get_obj(doc=self.doc, doclist=self.doclist)
|
||||
if hasattr(so, 'on_update'):
|
||||
so.on_update()
|
||||
|
||||
|
|
@ -58,3 +58,119 @@ def switch_module(dt, dn, to, frm=None, export=None):
|
|||
|
||||
for ext in ('py','js','html','css'):
|
||||
os.system('cp %s %s')
|
||||
|
||||
def commonify_doclist(doclist, with_comments=1):
|
||||
"""
|
||||
Makes a doclist more readable by extracting common properties.
|
||||
This is used for printing Documents in files
|
||||
"""
|
||||
from webnotes.utils import get_common_dict, get_diff_dict
|
||||
|
||||
def make_common(doclist):
|
||||
c = {}
|
||||
if with_comments:
|
||||
c['##comment'] = 'These values are common in all dictionaries'
|
||||
for k in common_keys:
|
||||
c[k] = doclist[0][k]
|
||||
return c
|
||||
|
||||
def strip_common_and_idx(d):
|
||||
for k in common_keys:
|
||||
if k in d: del d[k]
|
||||
|
||||
if 'idx' in d: del d['idx']
|
||||
return d
|
||||
|
||||
def make_common_dicts(doclist):
|
||||
|
||||
common_dict = {} # one per doctype
|
||||
|
||||
# make common dicts for all records
|
||||
for d in doclist:
|
||||
if not d['doctype'] in common_dict:
|
||||
d1 = d.copy()
|
||||
del d1['name']
|
||||
common_dict[d['doctype']] = d1
|
||||
else:
|
||||
common_dict[d['doctype']] = get_common_dict(common_dict[d['doctype']], d)
|
||||
return common_dict
|
||||
|
||||
common_keys = ['owner','docstatus','creation','modified','modified_by']
|
||||
common_dict = make_common_dicts(doclist)
|
||||
|
||||
# make docs
|
||||
final = []
|
||||
for d in doclist:
|
||||
f = strip_common_and_idx(get_diff_dict(common_dict[d['doctype']], d))
|
||||
f['doctype'] = d['doctype'] # keep doctype!
|
||||
|
||||
# strip name for child records (only an auto generated number!)
|
||||
if f['doctype'] != doclist[0]['doctype']:
|
||||
del f['name']
|
||||
|
||||
if with_comments:
|
||||
f['##comment'] = d['doctype'] + ('name' in f and (', ' + f['name']) or '')
|
||||
final.append(f)
|
||||
|
||||
# add commons
|
||||
commons = []
|
||||
for d in common_dict.values():
|
||||
d['name']='__common__'
|
||||
if with_comments:
|
||||
d['##comment'] = 'These values are common for all ' + d['doctype']
|
||||
commons.append(strip_common_and_idx(d))
|
||||
|
||||
common_values = make_common(doclist)
|
||||
return [common_values]+commons+final
|
||||
|
||||
def uncommonify_doclist(dl):
|
||||
"""
|
||||
Expands an commonified doclist
|
||||
"""
|
||||
# first one has common values
|
||||
common_values = dl[0]
|
||||
common_dict = {}
|
||||
final = []
|
||||
idx_dict = {}
|
||||
|
||||
for d in dl[1:]:
|
||||
if 'name' in d and d['name']=='__common__':
|
||||
# common for a doctype -
|
||||
del d['name']
|
||||
common_dict[d['doctype']] = d
|
||||
else:
|
||||
dt = d['doctype']
|
||||
if not dt in idx_dict: idx_dict[dt] = 1;
|
||||
d1 = common_values.copy()
|
||||
|
||||
# update from common and global
|
||||
d1.update(common_dict[dt])
|
||||
d1.update(d)
|
||||
|
||||
# idx by sequence
|
||||
d1['idx'] = idx_dict[dt]
|
||||
|
||||
# increment idx
|
||||
idx_dict[dt] += 1
|
||||
|
||||
final.append(d1)
|
||||
|
||||
return final
|
||||
|
||||
def pprint_doclist(doclist, with_comments = 1):
|
||||
"""
|
||||
Pretty Prints a doclist with common keys separated and comments
|
||||
"""
|
||||
from json import dumps
|
||||
|
||||
return dumps(commonify_doclist(doclist, False), indent=1)
|
||||
|
||||
def peval_doclist(txt):
|
||||
"""
|
||||
Restore a pretty printed doclist
|
||||
"""
|
||||
from json import loads
|
||||
if txt.startswith("#"):
|
||||
return uncommonify_doclist(eval(txt))
|
||||
else:
|
||||
return uncommonify_doclist(loads(txt))
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ from __future__ import unicode_literals
|
|||
|
||||
import webnotes, unittest
|
||||
from webnotes import msgprint
|
||||
from webnotes.model.doclist import DocList
|
||||
from webnotes.model.wrapper import ModelWrapper
|
||||
from webnotes.model.doc import Document
|
||||
|
||||
class TestNSM(unittest.TestCase):
|
||||
|
|
@ -53,7 +53,7 @@ class TestNSM(unittest.TestCase):
|
|||
]
|
||||
|
||||
for d in self.data:
|
||||
self.__dict__[d[0]] = DocList([Document(fielddata = {
|
||||
self.__dict__[d[0]] = ModelWrapper([Document(fielddata = {
|
||||
"doctype": "Item Group", "item_group_name": d[0], "parent_item_group": d[1],
|
||||
"__islocal": 1
|
||||
})])
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ def runserverobj():
|
|||
Run server objects
|
||||
"""
|
||||
import webnotes.model.code
|
||||
from webnotes.model.doclist import DocList
|
||||
from webnotes.model.wrapper import ModelWrapper
|
||||
from webnotes.utils import cint
|
||||
|
||||
doclist = None
|
||||
|
|
@ -43,7 +43,7 @@ def runserverobj():
|
|||
so = webnotes.model.code.get_obj(dt, dn)
|
||||
|
||||
else:
|
||||
doclist = DocList()
|
||||
doclist = ModelWrapper()
|
||||
doclist.from_compressed(webnotes.form_dict.get('docs'), dn)
|
||||
so = doclist.make_obj()
|
||||
doclist.check_if_latest()
|
||||
|
|
|
|||
|
|
@ -27,10 +27,10 @@ import webnotes
|
|||
def savedocs():
|
||||
"""save / submit / cancel / update doclist"""
|
||||
try:
|
||||
from webnotes.model.doclist import DocList
|
||||
from webnotes.model.wrapper import ModelWrapper
|
||||
form = webnotes.form_dict
|
||||
|
||||
doclist = DocList()
|
||||
doclist = ModelWrapper()
|
||||
doclist.from_compressed(form.get('docs'), form.get('docname'))
|
||||
|
||||
# action
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ def exec_report(code, res, colnames=[], colwidths=[], coltypes=[], coloptions=[]
|
|||
from webnotes import *
|
||||
from webnotes.utils import *
|
||||
from webnotes.model.doc import *
|
||||
from webnotes.model.doclist import getlist
|
||||
from webnotes.model.wrapper import getlist
|
||||
from webnotes.model.db_schema import updatedb
|
||||
from webnotes.model.code import get_obj
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue