Bladeren bron

Merge pull request #51 from anandpdoshi/master

Print Format and DocLayer Changes
version-14
Anand Doshi 13 jaren geleden
bovenliggende
commit
e60e556691
11 gewijzigde bestanden met toevoegingen van 976 en 8 verwijderingen
  1. +2
    -2
      js/legacy/form.compressed.js
  2. +3
    -3
      js/legacy/widgets/form/print_format.js
  3. +0
    -0
      py/core/doctype/doclayer/__init__.py
  4. +90
    -0
      py/core/doctype/doclayer/doclayer.js
  5. +280
    -0
      py/core/doctype/doclayer/doclayer.py
  6. +226
    -0
      py/core/doctype/doclayer/doclayer.txt
  7. +0
    -0
      py/core/doctype/doclayerfield/__init__.py
  8. +0
    -0
      py/core/doctype/doclayerfield/doclayerfield.py
  9. +281
    -0
      py/core/doctype/doclayerfield/doclayerfield.txt
  10. +22
    -3
      py/core/doctype/doctype/doctype.py
  11. +72
    -0
      py/webnotes/model/doctype.py

+ 2
- 2
js/legacy/form.compressed.js Bestand weergeven

@@ -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\


+ 3
- 3
js/legacy/widgets/form/print_format.js Bestand weergeven

@@ -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
py/core/doctype/doclayer/__init__.py Bestand weergeven


+ 90
- 0
py/core/doctype/doclayer/doclayer.js Bestand weergeven

@@ -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;
}

+ 280
- 0
py/core/doctype/doclayer/doclayer.py Bestand weergeven

@@ -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)

+ 226
- 0
py/core/doctype/doclayer/doclayer.txt Bestand weergeven

@@ -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
py/core/doctype/doclayerfield/__init__.py Bestand weergeven


+ 0
- 0
py/core/doctype/doclayerfield/doclayerfield.py Bestand weergeven


+ 281
- 0
py/core/doctype/doclayerfield/doclayerfield.txt Bestand weergeven

@@ -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
}
]

+ 22
- 3
py/core/doctype/doctype/doctype.py Bestand weergeven

@@ -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

+ 72
- 0
py/webnotes/model/doctype.py Bestand weergeven

@@ -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


Laden…
Annuleren
Opslaan