Changes in doclayer and doctype

This commit is contained in:
Anand Doshi 2011-11-22 11:09:48 +05:30
parent 1c2014d78b
commit b9d84ee39d
3 changed files with 244 additions and 19 deletions

View file

@ -1,13 +1,14 @@
cur_frm.cscript.doc_type = function(doc, dt, dn) {
//console.log(doc);
//console.log(doc_type);
$c_obj(make_doclist(dt, dn), 'get', '', function(r, rt) {
cur_frm.refresh();
//console.log(arguments);
});
}
cur_frm.cscript.onload_post_render = function(doc, dt, dn) {
cur_frm.cscript.refresh = function(doc, dt, dn) {
cur_frm.frm_head.page_head.buttons.Save.hidden=1;
cur_frm.page_layout.footer.hidden = 1;
cur_frm.add_custom_button('Update', function() {
@ -16,5 +17,5 @@ cur_frm.cscript.onload_post_render = function(doc, dt, dn) {
console.log(arguments);
});
}
});
},1);
}

View file

@ -2,6 +2,7 @@
DocLayer is a Single DocType used to mask the Property Setter
Thus providing a better UI from user perspective
"""
import webnotes
class DocType:
def __init__(self, doc, doclist=[]):
@ -20,6 +21,7 @@ class DocType:
'max_attachments'
]
self.docfield_properties = [
'idx',
'label',
'fieldtype',
'fieldname',
@ -39,18 +41,17 @@ class DocType:
'name'
]
def get(self):
"""
Gets DocFields applied with Property Setter customizations via DocLayerField
"""
from webnotes.model.doctype import get
from webnotes.model.doc import addchild
import webnotes
self.clear()
if self.doc.doc_type:
for d in get(self.doc.doc_type):
from webnotes.model.doc import addchild
for d in self.get_ref_doclist():
if d.doctype=='DocField':
new = addchild(self.doc, 'fields', 'DocLayerField', 1, self.doclist)
self.set(
@ -63,11 +64,20 @@ class DocType:
elif d.doctype=='DocType':
self.set({ 'list': self.doctype_properties, 'doc': d })
def post(self):
def get_ref_doclist(self):
"""
Save diff between DocLayer DocList and DocType DocList as property setter entries
* Gets doclist of type self.doc.doc_type
* Applies property setter properties on the doclist
* returns the modified doclist
"""
pass
from webnotes.model.doctype import _DocType
from webnotes.model.doc import get
ref_doclist = get('DocType', self.doc.doc_type)
_DocType(self.doc.doc_type)._override_field_properties(ref_doclist)
return ref_doclist
def clear(self):
@ -101,6 +111,172 @@ class DocType:
for f in args['list']:
args['doc_to_set'].fields[f] = args['doc'].fields[f]
else:
import webnotes
webnotes.msgprint("Please specify args['list'] to set", raise_exception=1)
def post(self):
"""
Save diff between DocLayer DocList and DocType DocList as property setter entries
"""
if self.doc.doc_type:
from webnotes.model import doc
from webnotes.model.doctype import get
this_doclist = [self.doc] + self.doclist
ref_doclist = self.get_ref_doclist()
dt_doclist = doc.get('DocType', self.doc.doc_type)
# get a list of property setter docs
diff_list = self.diff(this_doclist, ref_doclist, dt_doclist)
webnotes.msgprint('this doc')
webnotes.msgprint([[d.name, d.idx, 'label' in d.fields and d.label or None] for d in this_doclist])
webnotes.msgprint('ref doc')
webnotes.msgprint([[d.name, d.idx, 'label' in d.fields and d.label or None] for d in ref_doclist])
webnotes.msgprint('def doc')
webnotes.msgprint([[d.name, d.idx, 'label' in d.fields and d.label or None] for d in dt_doclist])
self.set_properties(diff_list)
webnotes.msgprint('End of Post')
webnotes.msgprint([[d.fields['property'], d.fields['value'], d.fields['doc_name'], d.fields['select_item'], 'delete' in d.fields and d.fields['delete'] or None] for d in diff_list])
def diff(self, new_dl, ref_dl, dt_dl):
"""
Get difference between new_dl doclist and ref_dl doclist
then check how it differs from dt_dl i.e. default doclist
"""
import re
self.defaults = self.get_defaults()
diff_list = []
for new_d in new_dl:
for ref_d in ref_dl:
if ref_d.doctype == 'DocField' and new_d.name == ref_d.name:
for prop in self.docfield_properties:
d = self.prepare_to_set(prop, new_d, ref_d, dt_dl)
if d: diff_list.append(d)
break
elif ref_d.doctype == 'DocType' and new_d.doctype == 'DocLayer':
for prop in self.doctype_properties:
d = self.prepare_to_set(prop, new_d, ref_d, dt_dl)
if d: diff_list.append(d)
break
return diff_list
def get_defaults(self):
"""
Get fieldtype and default value for properties of a field
"""
df_defaults = webnotes.conn.sql("""
SELECT fieldname, fieldtype, `default`, label
FROM `tabDocField`
WHERE parent='DocField' or parent='DocType'""", as_dict=1)
defaults = {}
for d in df_defaults:
fieldname = d['fieldname']
del d['fieldname']
defaults[fieldname] = d
defaults['idx'] = {'fieldtype' : 'Int', 'default' : 1, 'label' : 'idx'}
defaults['previous_field'] = {'fieldtype' : 'Data', 'default' : None, 'label' : 'Previous Field'}
return defaults
def prepare_to_set(self, prop, new_d, ref_d, dt_doclist, delete=0):
"""
Prepares docs of property setter
sets delete property if it is required to be deleted
"""
# Check if property has changed compared to when it was loaded
if new_d.fields[prop] != ref_d.fields[prop] \
and not \
( \
new_d.fields[prop] in [None, 0] \
and ref_d.fields[prop] in [None, 0] \
) and not \
( \
new_d.fields[prop] in [None, ''] \
and ref_d.fields[prop] in [None, ''] \
):
# Check if the new property is same as that in original doctype
# If yes, we need to delete the property setter entry
for dt_d in dt_doclist:
if dt_d.name == ref_d.name \
and (new_d.fields[prop] == dt_d.fields[prop] \
or \
( \
new_d.fields[prop] in [None, 0] \
and dt_d.fields[prop] in [None, 0] \
) or \
( \
new_d.fields[prop] in [None, ''] \
and dt_d.fields[prop] in [None, ''] \
)):
delete = 1
break
value = new_d.fields[prop]
if prop == 'idx':
if value > 1:
for idoc in ([self.doc] + self.doclist):
if idoc.fields[prop] == (value - 1):
prop = 'previous_field'
value = idoc.name
break
elif value == 1:
prop = 'previous_field'
value = None
# If the above conditions are fulfilled,
# create a property setter doc, but dont save it yet.
from webnotes.model.doc import Document
d = Document('Property Setter')
d.doctype_or_field = ref_d.doctype=='DocField' and 'DocField' or 'DocType'
d.doc_type = self.doc.doc_type
d.doc_name = ref_d.name
d.property = prop
d.value = value
d.property_type = self.defaults[prop]['fieldtype']
d.default_value = self.defaults[prop]['default']
d.select_doctype = self.doc.doc_type
d.select_item = ref_d.label and str(ref_d.idx) \
+ " - " + str(ref_d.label) \
+ " (" + str(ref_d.fieldtype) + ")" \
or None
d.select_property = self.defaults[prop]['label']
if delete: d.delete = 1
# return the property setter doc
return d
def set_properties(self, ps_doclist):
"""
* Delete a property setter entry
+ if it already exists
+ if marked for deletion
* Save the property setter doc in the list
"""
for d in ps_doclist:
# Check if the property setter doc already exists
res = webnotes.conn.sql("""
SELECT * FROM `tabProperty Setter`
WHERE doc_type = %(doc_type)s
AND doc_name = %(doc_name)s
AND property = %(property)s""", d.fields)
if res and res[0][0]:
webnotes.conn.sql("""
DELETE FROM `tabProperty Setter`
WHERE doc_type = %(doc_type)s
AND doc_name = %(doc_name)s
AND property = %(property)s""", d.fields)
# Save the property setter doc if not marked for deletion i.e. delete=0
if not d.delete:
d.save(1)

View file

@ -206,9 +206,10 @@ class _DocType:
dt = doclist[0].name
try:
for f in webnotes.conn.sql("select doc_name, property, property_type, value from `tabProperty Setter` where doc_type=%s", dt, as_dict=1):
if not f['doc_name'] in property_dict:
property_dict[f['doc_name']] = []
property_dict[f['doc_name']].append(f)
#if not f['doc_name'] in property_dict:
# property_dict[f['doc_name']] = []
#property_dict[f['doc_name']].append(f)
property_dict[f['doc_name']] = f
except Exception, e:
if e.args[0]==1146:
# no override table
@ -216,14 +217,20 @@ class _DocType:
else:
raise e
# loop over fields and override property
for d in doclist:
if d.doctype=='DocField' and d.name in property_dict:
for p in property_dict[d.name]:
if p['property_type']=='Check':
d.fields[p['property']] = int(p['value'])
else:
d.fields[p['property']] = p['value']
#for p in property_dict[d.name]:
p = property_dict[d.name]
if p['property_type']=='Check':
d.fields[p['property']] = int(p['value'])
elif p['property']=='previous_field':
continue
else:
d.fields[p['property']] = p['value']
self.change_doclist_idx(doclist, property_dict)
# override properties in the main doctype
if dt in property_dict:
@ -231,6 +238,47 @@ class _DocType:
doclist[0].fields[p['property']] = p['value']
def change_doclist_idx(self, doclist, property_dict):
"""
"""
docfields = []
sorted_doclist = sorted([dl for dl in doclist if dl.doctype=='DocField'], key=lambda dl: dl.idx)
old_order = [d.name for d in sorted_doclist]
property_list = []
import webnotes
for p in property_dict.values():
if p['property']=='previous_field':
property_list.append([p['value'], p['doc_name']])
nf = [p for p in property_list if p[0] is None]
while(old_order):
if nf:
property_list.remove(nf[0])
next_field = nf[0][1]
else:
for o in old_order:
if not (o in docfields):
next_field = o
old_order.remove(o)
break
else:
old_order.remove(o)
docfields.append(next_field)
nf = property_list and [p for p in property_list if p[0]==next_field] or None
webnotes.msgprint(docfields)
for d in doclist:
if d.doctype == 'DocField':
d.idx = docfields.index(d.name) + 1
for d in sorted([dl for dl in doclist if dl.doctype=='DocField'], key=lambda dl: dl.idx):
webnotes.msgprint(str(d.idx) + " | " + str(d.label))
def make_doclist(self):
"""
returns the :term:`doclist` for consumption by the client