""" Model utilities, unclassified functions """ def expand(docs): """ Expand a doclist sent from the client side. (Internally used by the request handler) """ def xzip(a,b): d = {} for i in range(len(a)): d[a[i]] = b[i] return d from webnotes.utils import load_json docs = load_json(docs) clist = [] for d in docs['_vl']: doc = xzip(docs['_kl'][d[0]], d); clist.append(doc) return clist def compress(doclist): """ Compress a doclist before sending it to the client side. (Internally used by the request handler) """ if doclist and hasattr(doclist[0],'fields'): docs = [d.fields for d in doclist] else: docs = doclist kl, vl = {}, [] for d in docs: dt = d['doctype'] if not (dt in kl.keys()): fl = d.keys() forbidden = ['server_code_compiled'] nl = ['doctype','localname','__oldparent','__unsaved'] # add client script for doctype, doctype due to ambiguity if dt=='DocType': nl.append('__client_script') for f in fl: if not (f in nl) and not (f in forbidden): nl.append(f) kl[dt] = nl ## values fl = kl[dt] nl = [] for f in fl: v = d.get(f) if type(v)==long: v=int(v) nl.append(v) vl.append(nl) #errprint(str({'_vl':vl,'_kl':kl})) return {'_vl':vl,'_kl':kl} def getlist(doclist, field): """ Filter a list of records for a specific field from the full doclist Example:: # find all phone call details dl = getlist(self.doclist, 'contact_updates') pl = [] for d in dl: if d.type=='Phone': pl.append(d) """ from webnotes.utils import cint l = [] for d in doclist: if d.parent and (not d.parent.lower().startswith('old_parent:')) and d.parentfield == field: l.append(d) l.sort(lambda a, b: cint(a.idx) - cint(b.idx)) return l # Copy doclist # ------------ def copy_doclist(doclist, no_copy = []): """ Save & return a copy of the given doclist Pass fields that are not to be copied in `no_copy` """ from webnotes.model.doc import Document cl = [] # main doc c = Document(fielddata = doclist[0].fields.copy()) # clear no_copy fields for f in no_copy: if c.fields.has_key(f): c.fields[f] = None c.name = None c.save(1) cl.append(c) # new parent name parent = c.name # children for d in doclist[1:]: c = Document(fielddata = d.fields.copy()) c.name = None # clear no_copy fields for f in no_copy: if c.fields.has_key(f): c.fields[f] = None c.parent = parent c.save(1) cl.append(c) return cl def getvaluelist(doclist, fieldname): """ Returns a list of values of a particualr fieldname from all Document object in a doclist """ l = [] for d in doclist: l.append(d.fields[fieldname]) return l def _make_html(doc, link_list): from webnotes.utils import cstr out = '' for k in doc.fields.keys(): if k!='server_code_compiled': v = cstr(doc.fields[k]) # link field if v and (k in link_list.keys()): dt = link_list[k] if type(dt)==str and dt.startswith('link:'): dt = dt[5:] v = '%s' % (dt, v, v) out += '\t\n' % (cstr(k), v) out += '
%s%s
' return out def to_html(doclist): """ Return a simple HTML format of the doclist """ out = '' link_lists = {} for d in doclist: if not link_lists.get(d.doctype): link_lists[d.doctype] = d.make_link_list() out += _make_html(d, link_lists[d.doctype]) return out 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] = 0; 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 webnotes.utils import pprint_dict dictlist =[pprint_dict(d) for d in commonify_doclist(doclist, with_comments)] title = '# '+doclist[0]['doctype']+', '+doclist[0]['name'] return title + '\n[\n' + ',\n'.join(dictlist) + '\n]' def peval_doclist(txt): """ Restore a pretty printed doclist """ if txt.startswith('#'): return uncommonify_doclist(eval(txt)) else: return eval(txt) return uncommonify_doclist(eval(txt))