Print Format and DocLayer Changesversion-14
@@ -396,8 +396,8 @@ return lh;},print_style:"\ | |||
}",print_std:function(no_letterhead){var docname=cur_frm.docname;var doctype=cur_frm.doctype;var data=getchildren('DocField',doctype,'fields','DocType');var layout=_p.add_layout(doctype);this.pf_list=[layout];var me=this;me.layout=layout;$.extend(this,{build_head:function(doctype,docname){var h1_style={fontSize:'22px',marginBottom:'8px'} | |||
var h1=$a(me.layout.cur_row.header,'h1','',h1_style);h1.innerHTML=cur_frm.pformat[docname]?cur_frm.pformat[docname]:get_doctype_label(doctype);var h2_style={fontSize:'16px',color:'#888',marginBottom:'8px',paddingBottom:'8px',borderBottom:(me.layout.with_border?'0px':'1px solid #000')} | |||
var h2=$a(me.layout.cur_row.header,'div','',h2_style);h2.innerHTML=docname;},build_data:function(data,doctype,docname){if(data[0]&&data[0].fieldtype!="Section Break"){me.layout.addrow();if(data[0].fieldtype!="Column Break"){me.layout.addcell();}} | |||
$.extend(this,{generate_custom_html:function(field,doctype,docname){var container=$a(me.layout.cur_cell,'div');container.innerHTML=cur_frm.pformat[field.fieldname](locals[doctype][docname]);},render_normal:function(field){switch(field.fieldtype){case'Section Break':me.layout.addrow();if(field[i+1]&&field[i+1].fieldtype!='Column Break'){me.layout.addcell();} | |||
break;case'Column Break':me.layout.addcell(field.width,field.label);break;case'Table':var table=print_table(doctype,docname,field.fieldname,field.options,null,null,null,null);me.layout=_p.print_std_add_table(table,me.layout,me.pf_list,doctype,no_letterhead);break;case'HTML':var div=$a(me.layout.cur_cell,'div');div.innerHTML=field.options;break;case'Code':var div=$a(me.layout.cur_cell,'div');var val=_f.get_value(doctype,docname,field.fieldname);div.innerHTML='<div>'+field.label+': </div><pre style="font-family: Courier, Fixed;">'+(val?val:'')+'</pre>';break;case'Text Editor':var div=$a(me.layout.cur_cell,'div');var val=_f.get_value(doctype,docname,field.fieldname);div.innerHTML=val?val:'';break;default:_p.print_std_add_field(doctype,docname,field,me.layout);break;}}});for(var i=0;i<data.length;i++){var fieldname=data[i].fieldname?data[i].fieldname:data[i].label;var field=fieldname?get_field(doctype,fieldname,docname):data[i];if(!field.print_hide){if(cur_frm.pformat[field.fieldname]){this.generate_custom_html(field,doctype,docname);}else{this.render_normal(field);}}} | |||
$.extend(this,{generate_custom_html:function(field,doctype,docname){var container=$a(me.layout.cur_cell,'div');container.innerHTML=cur_frm.pformat[field.fieldname](locals[doctype][docname]);},render_normal:function(field,data,i){switch(field.fieldtype){case'Section Break':me.layout.addrow();if(data[i+1]&&data[i+1].fieldtype!='Column Break'){me.layout.addcell();} | |||
break;case'Column Break':me.layout.addcell(field.width,field.label);break;case'Table':var table=print_table(doctype,docname,field.fieldname,field.options,null,null,null,null);me.layout=_p.print_std_add_table(table,me.layout,me.pf_list,doctype,no_letterhead);break;case'HTML':var div=$a(me.layout.cur_cell,'div');div.innerHTML=field.options;break;case'Code':var div=$a(me.layout.cur_cell,'div');var val=_f.get_value(doctype,docname,field.fieldname);div.innerHTML='<div>'+field.label+': </div><pre style="font-family: Courier, Fixed;">'+(val?val:'')+'</pre>';break;case'Text Editor':var div=$a(me.layout.cur_cell,'div');var val=_f.get_value(doctype,docname,field.fieldname);div.innerHTML=val?val:'';break;default:_p.print_std_add_field(doctype,docname,field,me.layout);break;}}});for(var i=0;i<data.length;i++){var fieldname=data[i].fieldname?data[i].fieldname:data[i].label;var field=fieldname?get_field(doctype,fieldname,docname):data[i];if(!field.print_hide){if(cur_frm.pformat[field.fieldname]){this.generate_custom_html(field,doctype,docname);}else{this.render_normal(field,data,i);}}} | |||
me.layout.close_borders();},build_html:function(){var html='';for(var i=0;i<me.pf_list.length;i++){if(me.pf_list[i].wrapper){html+=me.pf_list[i].wrapper.innerHTML;}else if(me.pf_list[i].innerHTML){html+=me.pf_list[i].innerHTML;}else{html+=me.pf_list[i];}} | |||
this.pf_list=[];return html;}});this.build_head(doctype,docname);this.build_data(data,doctype,docname);var html=this.build_html();return html;},add_layout:function(doctype){var layout=new Layout();layout.addrow();if(locals['DocType'][doctype].print_outline=='Yes'){layout.with_border=1} | |||
return layout;},print_std_add_table:function(t,layout,pf_list,dt,no_letterhead){if(t.appendChild){layout.cur_cell.appendChild(t);}else{page_break='\n\ | |||
@@ -394,13 +394,13 @@ $.extend(_p, { | |||
container.innerHTML = cur_frm.pformat[field.fieldname](locals[doctype][docname]); | |||
}, | |||
render_normal: function(field) { | |||
render_normal: function(field, data, i) { | |||
switch(field.fieldtype) { | |||
case 'Section Break': | |||
me.layout.addrow(); | |||
// Add column if no column break after this field | |||
if(field[i+1] && field[i+1].fieldtype != | |||
if(data[i+1] && data[i+1].fieldtype != | |||
'Column Break') { | |||
me.layout.addcell(); | |||
} | |||
@@ -464,7 +464,7 @@ $.extend(_p, { | |||
this.generate_custom_html(field, doctype, docname); | |||
} else { | |||
// Do the normal rendering | |||
this.render_normal(field); | |||
this.render_normal(field, data, i); | |||
} | |||
} | |||
} | |||
@@ -0,0 +1,90 @@ | |||
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 = function(doc, dt, dn) { | |||
cur_frm.grids[0].grid.tbar_div.style.width = "30%"; | |||
p = cur_frm.grids[0].grid.tbar_tab.children[0].children[0]; | |||
p.removeChild(p.children[0]) | |||
p.removeChild(p.children[0]) | |||
} | |||
cur_frm.cscript.refresh = function(doc, dt, dn) { | |||
//console.log(p) | |||
cur_frm.frm_head.timestamp_area.hidden = 1; | |||
cur_frm.frm_head.page_head.buttons.Save.hidden=1; | |||
cur_frm.page_layout.footer.hidden = 1; | |||
cur_frm.add_custom_button('Update', function() { | |||
if(cur_frm.fields_dict['doc_type'].value) { | |||
$c_obj(make_doclist(dt, dn), 'post', '', function(r, rt) { | |||
if(r.exc) { | |||
msgprint(r.exc); | |||
} else { | |||
cur_frm.frm_head.status_area.innerHTML = | |||
'<span style="padding: 2px; background-color: rgb(0, 170, 17); \ | |||
color: rgb(255, 255, 255); font-weight: bold; margin-left: 0px; \ | |||
font-size: 11px;">Saved</span>' | |||
console.log(arguments); | |||
} | |||
}); | |||
} | |||
},1); | |||
cur_frm.frm_head.page_head.buttons.Update.className = "cupid-green"; | |||
cur_frm.add_custom_button('Reload', function() { | |||
cur_frm.cscript.doc_type(doc, dt, dn); | |||
}, 1); | |||
cur_frm.add_custom_button('Reset to defaults', function() { | |||
cur_frm.confirm('This will remove the customizations defined for this form.\n\n' | |||
+ 'Are you sure you want to reset to defaults?'); | |||
}, 1); | |||
} | |||
cur_frm.confirm = function(msg) { | |||
var d = new wn.widgets.Dialog({ | |||
title: 'Reset To Defaults', | |||
width: 300, | |||
fields: [ | |||
{ | |||
fieldtype: 'HTML', | |||
label: 'Please Confirm', | |||
fieldname: 'msg' | |||
}, | |||
{ | |||
fieldtype: 'Button', | |||
label: 'Proceed', | |||
fieldname: 'btn_proceed' | |||
}, | |||
{ | |||
fieldtype: 'Button', | |||
label: 'Cancel', | |||
fieldname: 'btn_cancel' | |||
} | |||
] | |||
}); | |||
//d.set_value('msg', msg); | |||
d.fields_dict.btn_proceed.input.onclick = function() { | |||
this.set_working(); | |||
$c_obj(make_doclist(dt, dn), 'delete', '', function(r, rt) { | |||
if(r.exc) { | |||
msgprint(r.exc); | |||
} else { | |||
console.log(arguments); | |||
} | |||
}); | |||
this.done_working(); | |||
cur_frm.confirm_dialog.hide(); | |||
} | |||
d.fields_dict.btn_cancel.input.onclick = function() { | |||
cur_frm.confirm.dialog.hide(); | |||
} | |||
cur_frm.confirm.dialog = d; | |||
} |
@@ -0,0 +1,280 @@ | |||
""" | |||
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=[]): | |||
self.doc, self.doclist = doc, doclist | |||
self.doctype_properties = [ | |||
'autoname', | |||
'search_fields', | |||
'tag_fields', | |||
'default_print_format', | |||
'read_only_onload', | |||
'allow_print', | |||
'allow_email', | |||
'allow_copy', | |||
'allow_rename', | |||
'allow_attach', | |||
'max_attachments' | |||
] | |||
self.docfield_properties = [ | |||
'idx', | |||
'label', | |||
'fieldtype', | |||
'fieldname', | |||
'options', | |||
'permlevel', | |||
'width', | |||
'reqd', | |||
'in_filter', | |||
'hidden', | |||
'print_hide', | |||
'no_copy', | |||
'report_hide', | |||
'allow_on_submit', | |||
'depends_on', | |||
'description', | |||
'default', | |||
'name' | |||
] | |||
def get(self): | |||
""" | |||
Gets DocFields applied with Property Setter customizations via DocLayerField | |||
""" | |||
self.clear() | |||
if 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( | |||
{ | |||
'list': self.docfield_properties, | |||
'doc' : d, | |||
'doc_to_set': new | |||
} | |||
) | |||
elif d.doctype=='DocType': | |||
self.set({ 'list': self.doctype_properties, 'doc': d }) | |||
def get_ref_doclist(self): | |||
""" | |||
* Gets doclist of type self.doc.doc_type | |||
* Applies property setter properties on the doclist | |||
* returns the modified doclist | |||
""" | |||
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): | |||
""" | |||
Clear fields in the doc | |||
""" | |||
# Clear table before adding new doctype's fields | |||
self.doc.clear_table(self.doclist, 'fields') | |||
self.set({ 'list': self.doctype_properties, 'value': None }) | |||
def set(self, args): | |||
""" | |||
Set a list of attributes of a doc to a value | |||
or to attribute values of a doc passed | |||
args can contain: | |||
* list --> list of attributes to set | |||
* doc_to_set --> defaults to self.doc | |||
* value --> to set all attributes to one value eg. None | |||
* doc --> copy attributes from doc to doc_to_set | |||
""" | |||
if not 'doc_to_set' in args: | |||
args['doc_to_set'] = self.doc | |||
if 'list' in args: | |||
if 'value' in args: | |||
for f in args['list']: | |||
args['doc_to_set'].fields[f] = None | |||
elif 'doc' in args: | |||
for f in args['list']: | |||
args['doc_to_set'].fields[f] = args['doc'].fields[f] | |||
else: | |||
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) | |||
self.set_properties(diff_list) | |||
#webnotes.msgprint('End of Post') | |||
#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]) | |||
#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: | |||
defaults[d['fieldname']] = d | |||
defaults['idx'] = {'fieldname' : 'idx', 'fieldtype' : 'Int', 'default' : 1, 'label' : 'idx'} | |||
defaults['previous_field'] = {'fieldname' : '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) |
@@ -0,0 +1,226 @@ | |||
# DocType, DocLayer | |||
[ | |||
# These values are common in all dictionaries | |||
{ | |||
'creation': '2011-11-16 16:09:34', | |||
'docstatus': 0, | |||
'modified': '2011-11-17 16:38:45', | |||
'modified_by': 'Administrator', | |||
'owner': 'Administrator' | |||
}, | |||
# These values are common for all DocType | |||
{ | |||
'_last_update': '1321528082', | |||
'autoname': 'DL.####', | |||
'colour': 'White:FFF', | |||
'doctype': 'DocType', | |||
'hide_toolbar': 0, | |||
'issingle': 1, | |||
'module': 'Core', | |||
'name': '__common__', | |||
'search_fields': 'doc_type', | |||
'section_style': 'Simple', | |||
'show_in_menu': 1, | |||
'version': 21 | |||
}, | |||
# These values are common for all DocField | |||
{ | |||
'doctype': 'DocField', | |||
'name': '__common__', | |||
'parent': 'DocLayer', | |||
'parentfield': 'fields', | |||
'parenttype': 'DocType' | |||
}, | |||
# These values are common for all DocPerm | |||
{ | |||
'doctype': 'DocPerm', | |||
'name': '__common__', | |||
'parent': 'DocLayer', | |||
'parentfield': 'permissions', | |||
'parenttype': 'DocType', | |||
'read': 1, | |||
'role': 'System Manager' | |||
}, | |||
# DocType, DocLayer | |||
{ | |||
'doctype': 'DocType', | |||
'name': 'DocLayer' | |||
}, | |||
# DocPerm | |||
{ | |||
'create': 1, | |||
'doctype': 'DocPerm', | |||
'permlevel': 0, | |||
'write': 1 | |||
}, | |||
# DocPerm | |||
{ | |||
'create': 1, | |||
'doctype': 'DocPerm', | |||
'permlevel': 1, | |||
'write': 1 | |||
}, | |||
# DocPerm | |||
{ | |||
'doctype': 'DocPerm', | |||
'permlevel': 2 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'doc_type', | |||
'fieldtype': 'Select', | |||
'label': 'Type', | |||
'options': 'Link:DocType', | |||
'permlevel': 0 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldtype': 'Section Break', | |||
'label': 'Properties', | |||
'permlevel': 0 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldtype': 'Column Break', | |||
'permlevel': 0 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'autoname', | |||
'fieldtype': 'Data', | |||
'label': 'Auto Name', | |||
'permlevel': 0 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'search_fields', | |||
'fieldtype': 'Data', | |||
'label': 'Search Fields', | |||
'permlevel': 0 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'tag_fields', | |||
'fieldtype': 'Data', | |||
'label': 'Tag Fields', | |||
'permlevel': 0 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'default_print_format', | |||
'fieldtype': 'Link', | |||
'label': 'Default Print Format', | |||
'options': 'Print Format', | |||
'permlevel': 0 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldtype': 'Column Break', | |||
'permlevel': 0 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'read_only_onload', | |||
'fieldtype': 'Check', | |||
'label': 'Show Print First', | |||
'permlevel': 0 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'allow_print', | |||
'fieldtype': 'Check', | |||
'label': 'Hide Print', | |||
'permlevel': 0 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'allow_email', | |||
'fieldtype': 'Check', | |||
'label': 'Hide Email', | |||
'permlevel': 0 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'allow_copy', | |||
'fieldtype': 'Check', | |||
'label': 'Hide Copy', | |||
'permlevel': 0 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'allow_rename', | |||
'fieldtype': 'Check', | |||
'label': 'Allow Rename', | |||
'permlevel': 0 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'allow_attach', | |||
'fieldtype': 'Check', | |||
'label': 'Allow Attach', | |||
'permlevel': 0 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'max_attachments', | |||
'fieldtype': 'Int', | |||
'label': 'Max Attachments', | |||
'permlevel': 0 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldtype': 'Section Break', | |||
'label': 'Fields', | |||
'permlevel': 0 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'fields', | |||
'fieldtype': 'Table', | |||
'label': 'Fields', | |||
'options': 'DocLayerField', | |||
'permlevel': 1 | |||
} | |||
] |
@@ -0,0 +1,281 @@ | |||
# DocType, DocLayerField | |||
[ | |||
# These values are common in all dictionaries | |||
{ | |||
'creation': '2011-11-16 16:45:16', | |||
'docstatus': 0, | |||
'modified': '2011-11-22 16:09:21', | |||
'modified_by': 'Administrator', | |||
'owner': 'Administrator' | |||
}, | |||
# These values are common for all DocType | |||
{ | |||
'allow_copy': 0, | |||
'allow_email': 0, | |||
'allow_print': 0, | |||
'autoname': 'DLF.#####', | |||
'colour': 'White:FFF', | |||
'doctype': 'DocType', | |||
'hide_heading': 0, | |||
'hide_toolbar': 0, | |||
'issingle': 0, | |||
'istable': 1, | |||
'module': 'Core', | |||
'name': '__common__', | |||
'read_only': 0, | |||
'section_style': 'Simple', | |||
'show_in_menu': 0, | |||
'version': 3 | |||
}, | |||
# These values are common for all DocField | |||
{ | |||
'doctype': 'DocField', | |||
'hidden': 0, | |||
'name': '__common__', | |||
'parent': 'DocLayerField', | |||
'parentfield': 'fields', | |||
'parenttype': 'DocType', | |||
'print_hide': 0 | |||
}, | |||
# These values are common for all DocPerm | |||
{ | |||
'doctype': 'DocPerm', | |||
'name': '__common__', | |||
'parent': 'DocLayerField', | |||
'parentfield': 'permissions', | |||
'parenttype': 'DocType', | |||
'read': 1, | |||
'role': 'System Manager' | |||
}, | |||
# DocType, DocLayerField | |||
{ | |||
'doctype': 'DocType', | |||
'name': 'DocLayerField' | |||
}, | |||
# DocPerm | |||
{ | |||
'create': 1, | |||
'doctype': 'DocPerm', | |||
'permlevel': 0, | |||
'write': 1 | |||
}, | |||
# DocPerm | |||
{ | |||
'create': 1, | |||
'doctype': 'DocPerm', | |||
'permlevel': 1, | |||
'write': 1 | |||
}, | |||
# DocPerm | |||
{ | |||
'doctype': 'DocPerm', | |||
'permlevel': 2 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'label', | |||
'fieldtype': 'Data', | |||
'label': 'Label', | |||
'oldfieldname': 'label', | |||
'oldfieldtype': 'Data', | |||
'permlevel': 1, | |||
'reqd': 0, | |||
'search_index': 1 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'fieldtype', | |||
'fieldtype': 'Select', | |||
'label': 'Type', | |||
'oldfieldname': 'fieldtype', | |||
'oldfieldtype': 'Select', | |||
'options': 'Data\nSelect\nText\nSmall Text\nText Editor\nLink\nInt\nDate\nTime\nCurrency\nTable\nFloat\nCheck\nSection Break\nColumn Break\nButton\nRead Only\nCode\nHTML\nImage\nBlob\nPassword', | |||
'permlevel': 2, | |||
'reqd': 1, | |||
'search_index': 1 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'fieldname', | |||
'fieldtype': 'Data', | |||
'label': 'Name', | |||
'oldfieldname': 'fieldname', | |||
'oldfieldtype': 'Data', | |||
'permlevel': 2, | |||
'reqd': 0, | |||
'search_index': 1 | |||
}, | |||
# DocField | |||
{ | |||
'description': 'For Links, enter the DocType as range\nFor Select, enter list of Options separated by comma', | |||
'doctype': 'DocField', | |||
'fieldname': 'options', | |||
'fieldtype': 'Text', | |||
'label': 'Options', | |||
'oldfieldname': 'options', | |||
'oldfieldtype': 'Text', | |||
'permlevel': 1, | |||
'reqd': 0, | |||
'search_index': 0 | |||
}, | |||
# DocField | |||
{ | |||
'default': '0', | |||
'doctype': 'DocField', | |||
'fieldname': 'permlevel', | |||
'fieldtype': 'Int', | |||
'label': 'Perm Level', | |||
'oldfieldname': 'permlevel', | |||
'oldfieldtype': 'Int', | |||
'permlevel': 1, | |||
'reqd': 0, | |||
'search_index': 0 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'width', | |||
'fieldtype': 'Data', | |||
'label': 'Width', | |||
'oldfieldname': 'width', | |||
'oldfieldtype': 'Data', | |||
'permlevel': 1, | |||
'reqd': 0, | |||
'search_index': 0, | |||
'width': '50px' | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'reqd', | |||
'fieldtype': 'Check', | |||
'label': 'Reqd', | |||
'oldfieldname': 'reqd', | |||
'oldfieldtype': 'Check', | |||
'permlevel': 1, | |||
'reqd': 0, | |||
'search_index': 0, | |||
'width': '50px' | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'in_filter', | |||
'fieldtype': 'Check', | |||
'label': 'In Filter', | |||
'oldfieldname': 'in_filter', | |||
'oldfieldtype': 'Check', | |||
'permlevel': 1, | |||
'reqd': 0, | |||
'width': '50px' | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'hidden', | |||
'fieldtype': 'Check', | |||
'label': 'Hidden', | |||
'oldfieldname': 'hidden', | |||
'oldfieldtype': 'Check', | |||
'permlevel': 1, | |||
'reqd': 0, | |||
'search_index': 0, | |||
'width': '50px' | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'print_hide', | |||
'fieldtype': 'Check', | |||
'label': 'Print Hide', | |||
'oldfieldname': 'print_hide', | |||
'oldfieldtype': 'Check', | |||
'permlevel': 1, | |||
'reqd': 0, | |||
'search_index': 0 | |||
}, | |||
# DocField | |||
{ | |||
'colour': 'White:FFF', | |||
'doctype': 'DocField', | |||
'fieldname': 'report_hide', | |||
'fieldtype': 'Check', | |||
'label': 'Report Hide', | |||
'oldfieldname': 'report_hide', | |||
'oldfieldtype': 'Check', | |||
'permlevel': 1, | |||
'reqd': 0 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'allow_on_submit', | |||
'fieldtype': 'Check', | |||
'label': 'Allow on Submit', | |||
'oldfieldname': 'allow_on_submit', | |||
'oldfieldtype': 'Check', | |||
'permlevel': 0, | |||
'reqd': 0 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'depends_on', | |||
'fieldtype': 'Data', | |||
'label': 'Depends On', | |||
'oldfieldname': 'depends_on', | |||
'oldfieldtype': 'Data', | |||
'permlevel': 1, | |||
'reqd': 0 | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'description', | |||
'fieldtype': 'Text', | |||
'label': 'Description', | |||
'oldfieldname': 'description', | |||
'oldfieldtype': 'Text', | |||
'permlevel': 1, | |||
'reqd': 0, | |||
'width': '300px' | |||
}, | |||
# DocField | |||
{ | |||
'doctype': 'DocField', | |||
'fieldname': 'default', | |||
'fieldtype': 'Text', | |||
'label': 'Default', | |||
'oldfieldname': 'default', | |||
'oldfieldtype': 'Text', | |||
'permlevel': 1, | |||
'reqd': 0, | |||
'search_index': 0 | |||
} | |||
] |
@@ -63,15 +63,14 @@ class DocType: | |||
if d.fieldtype in ('HTML', 'Button', 'Section Break', 'Column Break') and d.reqd: | |||
webnotes.msgprint('%(lable)s [%(fieldtype)s] cannot be mandatory', raise_exception=1) | |||
# validate if allow attach, then file_list must be present | |||
if self.doc.allow_attach and not fieldnames.get('file_list'): | |||
webnotes.msgprint('To allow attachments, a field with fieldname "file_list" of type text must be present', raise_exception = 1) | |||
def validate(self): | |||
self.validate_series() | |||
self.scrub_field_names() | |||
self.validate_fields() | |||
self.set_version() | |||
self.make_file_list() | |||
def on_update(self): | |||
# make schma changes | |||
@@ -86,6 +85,7 @@ class DocType: | |||
if (not in_transfer) and getattr(webnotes.defs,'developer_mode', 0): | |||
self.export_doc() | |||
sql("delete from __DocTypeCache") | |||
def export_doc(self): | |||
from webnotes.modules.export_module import export_to_files | |||
@@ -94,3 +94,22 @@ class DocType: | |||
def import_doc(self): | |||
from webnotes.modules.import_module import import_from_files | |||
import_from_files(record_list=[[self.doc.module, 'doctype', self.doc.name]]) | |||
def make_file_list(self): | |||
""" | |||
if allow_attach is checked and the column file_list doesn't exist, | |||
create a new field 'file_list' | |||
""" | |||
if self.doc.allow_attach: | |||
if 'file_list' not in [d.fieldname for d in self.doclist]: | |||
new = self.doc.addchild('fields', 'DocField', 1, self.doclist) | |||
new.label = 'File List' | |||
new.fieldtype = 'Text' | |||
new.fieldname = 'file_list' | |||
new.hidden = 1 | |||
new.permlevel = 0 | |||
new.print_hide = 1 | |||
new.no_copy = 1 | |||
max_idx = max([d.idx for d in self.doclist if d.idx]) | |||
max_idx = max_idx and max_idx or 0 | |||
new.idx = max_idx + 1 |
@@ -216,14 +216,22 @@ class _DocType: | |||
else: | |||
raise e | |||
change_idx = False | |||
# 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']) | |||
elif p['property']=='previous_field': | |||
change_idx = True | |||
continue | |||
else: | |||
d.fields[p['property']] = p['value'] | |||
if change_idx: self._change_doclist_idx(doclist, property_dict) | |||
# override properties in the main doctype | |||
if dt in property_dict: | |||
@@ -231,6 +239,70 @@ class _DocType: | |||
doclist[0].fields[p['property']] = p['value'] | |||
def _change_doclist_idx(self, doclist, property_dict): | |||
""" | |||
1. Select docs in doclist of type DocField | |||
2. Sort this doclist according to idx | |||
3. Extract the name of docs in a list | |||
4. Arrange the property_dict entries of property "previous_field" | |||
and chain the set of fields according to value | |||
5. Move the docnames according to their previous field values | |||
6. Assign the new idx values to the doclist docs | |||
""" | |||
# Process doclist | |||
docfield_doclist = [d for d in doclist if d.doctype=='DocField'] | |||
sorted_docfield_doclist = sorted(docfield_doclist, key=lambda df: df.idx) | |||
docfields = [d.name for d in sorted_docfield_doclist] | |||
# Process property_dict | |||
previous_field_dict = {} | |||
for pl in property_dict.values(): | |||
for p in pl: | |||
if p['property'] == 'previous_field': | |||
previous_field_dict[str(p['value'])] = str(p['doc_name']) | |||
i = 0 | |||
if 'None' in previous_field_dict: | |||
prev_field = 'None' | |||
else: | |||
i = i + 1 | |||
prev_field = docfields[i] | |||
while previous_field_dict: | |||
get_next_docfield = 0 | |||
if prev_field in previous_field_dict: | |||
this_field = previous_field_dict[prev_field] | |||
docfields.remove(this_field) | |||
if prev_field == 'None': | |||
docfields.insert(0, this_field) | |||
else: | |||
docfields.insert(docfields.index(prev_field) + 1, this_field) | |||
del previous_field_dict[prev_field] | |||
if this_field in previous_field_dict: | |||
prev_field = this_field | |||
else: | |||
get_next_docfield = 1 | |||
else: | |||
get_next_docfield = 1 | |||
if get_next_docfield: | |||
i = i + 1 | |||
prev_field = docfields[i] | |||
vals = previous_field_dict.values() | |||
if prev_field in vals: | |||
i = i - 1 | |||
keys = previous_field_dict.keys() | |||
prev_field = keys[vals.index(prev_field)] | |||
for d in doclist: | |||
if d.doctype=='DocField': | |||
d.idx = docfields.index(d.name) + 1 | |||
def make_doclist(self): | |||
""" | |||
returns the :term:`doclist` for consumption by the client | |||