Procházet zdrojové kódy

Merge branch 'live' of github.com:webnotes/wnframework into live

version-14
Nabin Hait před 14 roky
rodič
revize
4408cf2f9f
31 změnil soubory, kde provedl 790 přidání a 982 odebrání
  1. +250
    -228
      cgi-bin/core/doctype/doctype_mapper/doctype_mapper.py
  2. +9
    -0
      cgi-bin/core/doctype/event/event.js
  3. +14
    -0
      cgi-bin/core/doctype/file/file.py
  4. +103
    -423
      cgi-bin/core/doctype/profile/profile.txt
  5. +8
    -66
      cgi-bin/core/doctype/search_criteria/search_criteria.txt
  6. +3
    -1
      cgi-bin/core/doctype/system_console/system_console.js
  7. +14
    -1
      cgi-bin/webnotes/__init__.py
  8. +33
    -10
      cgi-bin/webnotes/auth.py
  9. +12
    -5
      cgi-bin/webnotes/db.py
  10. +5
    -1
      cgi-bin/webnotes/model/__init__.py
  11. +28
    -29
      cgi-bin/webnotes/model/doclist.py
  12. +59
    -40
      cgi-bin/webnotes/model/utils.py
  13. +15
    -12
      cgi-bin/webnotes/modules/__init__.py
  14. +4
    -3
      cgi-bin/webnotes/modules/patch.py
  15. +6
    -2
      cgi-bin/webnotes/utils/__init__.py
  16. +14
    -1
      cgi-bin/webnotes/utils/backups.py
  17. +9
    -3
      cgi-bin/webnotes/utils/email_lib/receive.py
  18. +1
    -1
      cgi-bin/webnotes/utils/scheduler.py
  19. +1
    -1
      cgi-bin/webnotes/widgets/page.py
  20. +48
    -48
      cgi-bin/webnotes/widgets/query_builder.py
  21. +9
    -9
      cgi-bin/webnotes/widgets/search.py
  22. +25
    -5
      cgi-bin/webnotes/widgets/tags.py
  23. +17
    -14
      js/form.compressed.js
  24. +1
    -1
      js/webpage/page.js
  25. +35
    -28
      js/webpage/search.js
  26. +5
    -0
      js/widgets/form/form.js
  27. +4
    -1
      js/widgets/form/form_fields.js
  28. +6
    -7
      js/widgets/form/form_grid.js
  29. +42
    -38
      js/widgets/form/grid.js
  30. +7
    -1
      js/widgets/report_builder/report_builder.js
  31. +3
    -3
      js/wnf.compressed.js

+ 250
- 228
cgi-bin/core/doctype/doctype_mapper/doctype_mapper.py Zobrazit soubor

@@ -2,7 +2,7 @@
import webnotes import webnotes


from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
from webnotes.model import db_exists
from webnotes.model import db_exists, default_fields
from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType
from webnotes.model.doclist import getlist, copy_doclist from webnotes.model.doclist import getlist, copy_doclist
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
@@ -18,230 +18,252 @@ convert_to_lists = webnotes.conn.convert_to_lists




class DocType: class DocType:
def __init__(self, doc, doclist=[]):
self.doc = doc
self.doclist = doclist
self.prefix = is_testing and 'test' or 'tab'
self.ref_doc = ''
# Autoname
#---------
def autoname(self):
self.doc.name = make_autoname(self.doc.from_doctype + '-' + self.doc.to_doctype)

# Map Custom Fields
# ------------------
def map_custom_fields(self, from_doctype, to_doctype, from_doc, to_doc):
fld_list = []
for d in sql("select fieldname from `tabCustom Field` where dt = %s and docstatus != 2",from_doctype):
if sql("select fieldname from `tabCustom Field` where dt = %s and fieldname = %s and docstatus != 2",(to_doctype, d[0])):
fld_list.append([d[0], d[0]])
self.set_value(fld_list, from_doc, to_doc)

# Maps the fields in 'To DocType'
#--------------------------------
def dt_map(self, from_doctype, to_doctype, from_docname, to_doc, doclist, from_to_list = '[]'):

# definition of arguments
'''
String <from_doctype> : contains the name of DocType initiating the function
String <to_doctype> : contains the name of DocType created by the function
String <from_docname> : contains ID(name) of 'from_doctype'
String <to_doc> : contains doc of 'to_doctype'
String <doclist> : contains doclist of 'to_doctype'
String <from_to_list> : contains list of tables which will be mapped
'''
# Validate reference doc docstatus
self.ref_doc = from_docname
self.check_ref_docstatus()
if not doclist:
doclist.append(to_doc)

tbl_list = sql("select from_table, to_table, from_field, to_field, match_id, validation_logic from `tabTable Mapper Detail` where parent ='%s' order by match_id" % (from_doctype + "-" + to_doctype))

for t in tbl_list:
from_table_name = t[0]
to_table_name = t[1]
from_table_fname = t[2]
to_table_fname = t[3]
match_id = t[4]
validation_logic = t[5]

from_to = [from_table_name, to_table_name]

if from_to in eval(from_to_list):
fld_list = sql("select from_field, to_field from `tabField Mapper Detail` where parent = '%s' and match_id = %s and map = 'Yes'" % (from_doctype + "-" + to_doctype, match_id))
if fld_list:
if not from_docname:
msgprint(from_doctype + " not selected for mapping")
raise Exception
# Parent to parent mapping
if from_table_name == self.doc.from_doctype and to_table_name == self.doc.to_doctype:
# Check validation
nm = sql("select name from `tab%s` where name = '%s' and %s" % (from_doctype, from_docname, validation_logic))
nm = nm and nm[0][0] or ''
# If validation failed raise exception
if not nm:
msgprint("Validation failed in doctype mapper. Please contact Administrator.")
raise Exception
from_doc = Document(from_doctype, nm)
# Maps field in parent
self.set_value(fld_list, from_doc, to_doc)
# Map custom fields
self.map_custom_fields(from_doctype, to_doctype, from_doc, to_doc)

# Parent to child OR child to child mapping
else:
dnlist = ()
if from_table_name == self.doc.from_doctype:
dnlist = ((from_docname,),)
else:
dnlist = sql("select name from `tab%s` where parent='%s' and parenttype = '%s' and %s order by idx" % (from_table_name, from_docname, self.doc.from_doctype, validation_logic))
for dn in dnlist:
# Add a row in target table in 'To DocType' and returns obj
ch = addchild(to_doc, t[3], t[1], 1, doclist)
# Creates object for 'From DocType', it can be parent or child
d = Document(t[0], dn[0])
# Map values
self.set_value(fld_list, d, ch)
# Map custom fields
self.map_custom_fields(from_table_name, t[1], d, ch)

# Required when called from server side for refreshing table
return doclist
# Assigns value to "To Doctype"
#------------------------------
def set_value(self, fld_list, obj, to_doc):
for f in fld_list:
if f[0].startswith('eval:'):
to_doc.fields[f[1]] = eval(f[0][5:])
else:
to_doc.fields[f[1]] = obj.fields.get(f[0])
# Validate
#---------
def validate(self):
for d in getlist(self.doclist, 'field_mapper_details'):
# Automatically assigns default value if not entered
if not d.match_id:
d.match_id = 0
if not d.map:
d.map = 'Yes'
for d in getlist(self.doclist, 'table_mapper_details'):
if not d.reference_doctype_key:
d.reference_doctype_key = ''
if not d.reference_key:
d.reference_key = ''
# Check wrong field name
self.check_fields_in_dt()

# Check if any wrong fieldname entered
#--------------------------------------
def check_fields_in_dt(self):
for d in getlist(self.doclist, 'field_mapper_details'):
table_name = sql("select from_table, to_table from `tabTable Mapper Detail` where parent ='%s' and match_id = '%s'" % (self.doc.name, d.match_id))
if table_name:
exists1 = sql("select name from tabDocField where parent = '%s' and fieldname = '%s'" % (table_name[0][0], d.from_field))
exists2 = sql("select name from tabDocField where parent = '%s' and fieldname = '%s'" % (table_name[0][1], d.to_field))
# Default fields like name, parent, owner does not exists in DocField
if not exists1 and d.from_field not in default_fields:
msgprint('"' + cstr(d.from_field) + '" does not exists in DocType "' + cstr(table_name[0][0]) + '"')
if not exists2 and d.to_field not in default_fields:
msgprint('"' + cstr(d.to_field) + '" does not exists in DocType "' + cstr(table_name[0][1]) + '"')
# Check consistency of value with reference document
#---------------------------------------------------
def validate_reference_value(self, obj, to_docname):
for t in getlist(self.doclist, 'table_mapper_details'):
# Reference key is the fieldname which will relate to the from_table
if t.reference_doctype_key:
for d in getlist(obj.doclist, t.to_field):
if d.fields[t.reference_doctype_key] == self.doc.from_doctype:
self.check_consistency(obj.doc, d, to_docname)
self.check_ref_docstatus()
# Make list of fields whose value will be consistent with prevdoc
#-----------------------------------------------------------------
def get_checklist(self):
checklist = []
for f in getlist(self.doclist, 'field_mapper_details'):
# Check which field's value will be compared
if f.checking_operator:
checklist.append([f.from_field, f.to_field, f.checking_operator, f.match_id])
return checklist
def check_fld_type(self, tbl, fld, cur_val):
ft = sql("select fieldtype from tabDocField where fieldname = '%s' and parent = '%s'" % (fld,tbl))
ft = ft and ft[0][0] or ''
if ft == 'Currency' or ft == 'Float':
cur_val = '%.2f' % cur_val
return cur_val, ft
# Check consistency
#-------------------
def check_consistency(self, par_obj, child_obj, to_docname):
checklist = self.get_checklist()
self.ref_doc = ''
for t in getlist(self.doclist, 'table_mapper_details'):
if t.reference_key and child_obj.fields[t.reference_key]:
for cl in checklist:
if cl[3] == t.match_id:
if t.to_field:
cur_val = child_obj.fields[cl[1]]
else:
cur_val = par_obj.fields[cl[1]]
ft = self.check_fld_type(t.to_table, cl[1], cur_val)
cur_val = ft[0]

if cl[2] == '=' and (ft[1] == 'Currency' or ft[1] == 'Float'):
consistent = sql("select name, %s from `tab%s` where name = '%s' and '%s' - %s <= 0.5" % (cl[0], t.from_table, child_obj.fields[t.reference_key], flt(cur_val), cl[0]))
else:
#consistent = sql("select name, %s from `tab%s` where name = '%s' and '%s' %s %s" % (cl[0], t.from_table, child_obj.fields[t.reference_key], cur_val, cl[2], cl[0]))
consistent = sql("select name, %s from `tab%s` where name = '%s' and '%s' %s ifnull(%s, '')" % (cl[0], t.from_table, child_obj.fields[t.reference_key], ft[1] in ('Currency', 'Float', 'Int') and flt(cur_val) or cstr(cur_val), cl[2], cl[0]))

if not self.ref_doc:
det = sql("select name, parent from `tab%s` where name = '%s'" % (t.from_table, child_obj.fields[t.reference_key]))
self.ref_doc = det[0][1] and det[0][1] or det[0][0]

if not consistent:
self.give_message(t.from_table, t.to_table, cl[0], cl[1], child_obj.fields[t.reference_key], cl[2])
# Gives message and raise exception
#-----------------------------------
def give_message(self, from_table, to_table, from_field, to_field, ref_value, operator):
# Select label of the field
to_fld_label = sql("select label from tabDocField where parent = '%s' and fieldname = '%s'" % (to_table, to_field))
from_fld_label = sql("select label from tabDocField where parent = '%s' and fieldname = '%s'" % (from_table, from_field))
op_in_words = {'=':'equal to ', '>=':'greater than equal to ', '>':'greater than ', '<=':'less than equal to ', '<':'less than '}
msgprint(to_fld_label[0][0] + " should be " + op_in_words[operator] + from_fld_label[0][0] + " of " + self.doc.from_doctype + ": " + self.ref_doc)
raise Exception, "Validation Error."
def check_ref_docstatus(self):
if self.ref_doc:
det = sql("select name, docstatus from `tab%s` where name = '%s'" % (self.doc.from_doctype, self.ref_doc))
if not det:
msgprint(self.doc.from_doctype + ": " + self.ref_doc + " does not exists in the system")
raise Exception, "Validation Error."
elif self.doc.ref_doc_submitted and det[0][1] != 1:
msgprint(self.doc.from_doctype + ": " + self.ref_doc + " is not Submitted Document.")
raise Exception, "Validation Error."

def on_update(self):
import webnotes.defs
if hasattr(webnotes.defs, 'developer_mode') and webnotes.defs.developer_mode:
from webnotes.modules.export_module import export_to_files
export_to_files(record_list=[[self.doc.doctype, self.doc.name]])
def __init__(self, doc, doclist=[]):
self.doc = doc
self.doclist = doclist
self.prefix = is_testing and 'test' or 'tab'
self.ref_doc = ''
# Autoname
#---------
def autoname(self):
self.doc.name = make_autoname(self.doc.from_doctype + '-' + self.doc.to_doctype)

def map_fields_with_same_name(self, from_doctype, to_doctype, from_doc, to_doc, fld_list):
"""
Returns field list with same name in from and to doctype
"""
exception_flds = [f[0] for f in fld_list if f[2] == 'No']
exception_flds += default_fields
exception_flds += ['amended_from', 'amendment_date', 'file_list', 'naming_series', 'status']
map_fld_list = [
[d[0], d[0], 'Yes'] for d in sql("""
select t1.fieldname
from `tabDocField` t1, `tabDocField` t2
where t1.parent = %s and t2.parent = %s
and t1.fieldname = t2.fieldname
and t1.docstatus != 2 and t2.docstatus != 2
and ifnull(t1.fieldname, '') != ''
""",(from_doctype, to_doctype)) if d[0] not in exception_flds
]

self.set_value(map_fld_list, from_doc, to_doc)
# Maps the fields in 'To DocType'
#--------------------------------
def dt_map(self, from_doctype, to_doctype, from_docname, to_doc, doclist, from_to_list = '[]'):

# definition of arguments
'''
String <from_doctype> : contains the name of DocType initiating the function
String <to_doctype> : contains the name of DocType created by the function
String <from_docname> : contains ID(name) of 'from_doctype'
String <to_doc> : contains doc of 'to_doctype'
String <doclist> : contains doclist of 'to_doctype'
String <from_to_list> : contains list of tables which will be mapped
'''
# Validate reference doc docstatus
self.ref_doc = from_docname
self.check_ref_docstatus()
if not doclist:
doclist.append(to_doc)

tbl_list = sql("select from_table, to_table, from_field, to_field, match_id, validation_logic from `tabTable Mapper Detail` where parent ='%s' order by match_id" % (from_doctype + "-" + to_doctype))

for t in tbl_list:
from_table_name = t[0]
to_table_name = t[1]
from_table_fname = t[2]
to_table_fname = t[3]
match_id = t[4]
validation_logic = t[5]

from_to = [from_table_name, to_table_name]

if from_to in eval(from_to_list):
fld_list = sql("select from_field, to_field, map from `tabField Mapper Detail` where parent = '%s' and match_id = %s" % (from_doctype + "-" + to_doctype, match_id))
if not from_docname:
msgprint(from_doctype + " not selected for mapping")
raise Exception
# Parent to parent mapping
if from_table_name == self.doc.from_doctype and to_table_name == self.doc.to_doctype:
# Check validation
nm = sql("select name from `tab%s` where name = '%s' and %s" % (from_doctype, from_docname, validation_logic))
nm = nm and nm[0][0] or ''
# If validation failed raise exception
if not nm:
msgprint("Validation failed in doctype mapper. Please contact Administrator.")
raise Exception
from_doc = Document(from_doctype, nm)

# Map fields with same name

self.map_fields_with_same_name(from_doctype, to_doctype, from_doc, to_doc, fld_list)
# Maps field in parent
if fld_list:
self.set_value(fld_list, from_doc, to_doc)


# Parent to child OR child to child mapping
else:
dnlist = ()
if from_table_name == self.doc.from_doctype:
dnlist = ((from_docname,),)
else:
dnlist = sql("select name from `tab%s` where parent='%s' and parenttype = '%s' and %s order by idx" % (from_table_name, from_docname, self.doc.from_doctype, validation_logic))
for dn in dnlist:
# Add a row in target table in 'To DocType' and returns obj
ch = addchild(to_doc, t[3], t[1], 1, doclist)
# Creates object for 'From DocType', it can be parent or child
d = Document(t[0], dn[0])
# Map fields with same name
self.map_fields_with_same_name(from_table_name, t[1], d, ch, fld_list)
# Map values
if fld_list:
self.set_value(fld_list, d, ch)



# Required when called from server side for refreshing table
return doclist
# Assigns value to "To Doctype"
#------------------------------
def set_value(self, fld_list, obj, to_doc):
for f in fld_list:
if f[2] == 'Yes':
if f[0].startswith('eval:'):
to_doc.fields[f[1]] = eval(f[0][5:])
else:
to_doc.fields[f[1]] = obj.fields.get(f[0])
# Validate
#---------
def validate(self):
for d in getlist(self.doclist, 'field_mapper_details'):
# Automatically assigns default value if not entered
if not d.match_id:
d.match_id = 0
if not d.map:
d.map = 'Yes'
for d in getlist(self.doclist, 'table_mapper_details'):
if not d.reference_doctype_key:
d.reference_doctype_key = ''
if not d.reference_key:
d.reference_key = ''
# Check wrong field name
self.check_fields_in_dt()

# Check if any wrong fieldname entered
#--------------------------------------
def check_fields_in_dt(self):
for d in getlist(self.doclist, 'field_mapper_details'):
table_name = sql("select from_table, to_table from `tabTable Mapper Detail` where parent ='%s' and match_id = '%s'" % (self.doc.name, d.match_id))
if table_name:
exists1 = sql("select name from tabDocField where parent = '%s' and fieldname = '%s'" % (table_name[0][0], d.from_field))
exists2 = sql("select name from tabDocField where parent = '%s' and fieldname = '%s'" % (table_name[0][1], d.to_field))
# Default fields like name, parent, owner does not exists in DocField
if not exists1 and d.from_field not in default_fields:
msgprint('"' + cstr(d.from_field) + '" does not exists in DocType "' + cstr(table_name[0][0]) + '"')
if not exists2 and d.to_field not in default_fields:
msgprint('"' + cstr(d.to_field) + '" does not exists in DocType "' + cstr(table_name[0][1]) + '"')
# Check consistency of value with reference document
#---------------------------------------------------
def validate_reference_value(self, obj, to_docname):
for t in getlist(self.doclist, 'table_mapper_details'):
# Reference key is the fieldname which will relate to the from_table
if t.reference_doctype_key:
for d in getlist(obj.doclist, t.to_field):
if d.fields[t.reference_doctype_key] == self.doc.from_doctype:
self.check_consistency(obj.doc, d, to_docname)
self.check_ref_docstatus()
# Make list of fields whose value will be consistent with prevdoc
#-----------------------------------------------------------------
def get_checklist(self):
checklist = []
for f in getlist(self.doclist, 'field_mapper_details'):
# Check which field's value will be compared
if f.checking_operator:
checklist.append([f.from_field, f.to_field, f.checking_operator, f.match_id])
return checklist
def check_fld_type(self, tbl, fld, cur_val):
ft = sql("select fieldtype from tabDocField where fieldname = '%s' and parent = '%s'" % (fld,tbl))
ft = ft and ft[0][0] or ''
if ft == 'Currency' or ft == 'Float':
cur_val = '%.2f' % cur_val
return cur_val, ft
# Check consistency
#-------------------
def check_consistency(self, par_obj, child_obj, to_docname):
checklist = self.get_checklist()
self.ref_doc = ''
for t in getlist(self.doclist, 'table_mapper_details'):
if t.reference_key and child_obj.fields[t.reference_key]:
for cl in checklist:
if cl[3] == t.match_id:
if t.to_field:
cur_val = child_obj.fields[cl[1]]
else:
cur_val = par_obj.fields[cl[1]]
ft = self.check_fld_type(t.to_table, cl[1], cur_val)
cur_val = ft[0]

if cl[2] == '=' and (ft[1] == 'Currency' or ft[1] == 'Float'):
consistent = sql("select name, %s from `tab%s` where name = '%s' and '%s' - %s <= 0.5" % (cl[0], t.from_table, child_obj.fields[t.reference_key], flt(cur_val), cl[0]))
else:
#consistent = sql("select name, %s from `tab%s` where name = '%s' and '%s' %s %s" % (cl[0], t.from_table, child_obj.fields[t.reference_key], cur_val, cl[2], cl[0]))
consistent = sql("select name, %s from `tab%s` where name = '%s' and '%s' %s ifnull(%s, '')" % (cl[0], t.from_table, child_obj.fields[t.reference_key], ft[1] in ('Currency', 'Float', 'Int') and flt(cur_val) or cstr(cur_val), cl[2], cl[0]))

if not self.ref_doc:
det = sql("select name, parent from `tab%s` where name = '%s'" % (t.from_table, child_obj.fields[t.reference_key]))
self.ref_doc = det[0][1] and det[0][1] or det[0][0]

if not consistent:
self.give_message(t.from_table, t.to_table, cl[0], cl[1], child_obj.fields[t.reference_key], cl[2])
# Gives message and raise exception
#-----------------------------------
def give_message(self, from_table, to_table, from_field, to_field, ref_value, operator):
# Select label of the field
to_fld_label = sql("select label from tabDocField where parent = '%s' and fieldname = '%s'" % (to_table, to_field))
from_fld_label = sql("select label from tabDocField where parent = '%s' and fieldname = '%s'" % (from_table, from_field))
op_in_words = {'=':'equal to ', '>=':'greater than equal to ', '>':'greater than ', '<=':'less than equal to ', '<':'less than '}
msgprint(to_fld_label[0][0] + " should be " + op_in_words[operator] + from_fld_label[0][0] + " of " + self.doc.from_doctype + ": " + self.ref_doc)
raise Exception, "Validation Error."
def check_ref_docstatus(self):
if self.ref_doc:
det = sql("select name, docstatus from `tab%s` where name = '%s'" % (self.doc.from_doctype, self.ref_doc))
if not det:
msgprint(self.doc.from_doctype + ": " + self.ref_doc + " does not exists in the system")
raise Exception, "Validation Error."
elif self.doc.ref_doc_submitted and det[0][1] != 1:
msgprint(self.doc.from_doctype + ": " + self.ref_doc + " is not Submitted Document.")
raise Exception, "Validation Error."

def on_update(self):
import webnotes.defs
if hasattr(webnotes.defs, 'developer_mode') and webnotes.defs.developer_mode:
from webnotes.modules.export_module import export_to_files
export_to_files(record_list=[[self.doc.doctype, self.doc.name]])

+ 9
- 0
cgi-bin/core/doctype/event/event.js Zobrazit soubor

@@ -0,0 +1,9 @@
cur_frm.cscript.onload = function(doc, cdt, cdn) {
var df = get_field('Event', 'Intro HTML', doc.name);
if(doc.ref_type) {
ref = repl(cur_frm.cstring.ref_html, {'dt': doc.ref_type, 'dn':doc.ref_name});
} else var ref = '';
df.options = repl(cur_frm.cstring.intro_html, {'ref': ref});
refresh_fields('Intro HTML');
}

+ 14
- 0
cgi-bin/core/doctype/file/file.py Zobrazit soubor

@@ -0,0 +1,14 @@
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d,dl

def validate(self):
# check for extension
if not '.' in self.doc.file_name:
msgprint("Extension required in file name")
raise Exception

# set mime type
if not self.doc.mime_type:
import mimetypes
self.doc.mime_type = mimetypes.guess_type(self.doc.file_name)[0] or 'application/unknown'

+ 103
- 423
cgi-bin/core/doctype/profile/profile.txt Zobrazit soubor

@@ -5,25 +5,22 @@
{ {
'creation': '2009-05-12 11:19:11', 'creation': '2009-05-12 11:19:11',
'docstatus': 0, 'docstatus': 0,
'modified': '2010-12-21 11:07:20',
'modified_by': 'sneha@webnotestech.com',
'modified': '2011-08-25 14:02:26',
'modified_by': 'Administrator',
'owner': 'Administrator' 'owner': 'Administrator'
}, },


# These values are common for all DocType # These values are common for all DocType
{ {
'_last_update': '1303708853',
'_last_update': '1311340897',
'allow_attach': 1, 'allow_attach': 1,
'allow_copy': 0, 'allow_copy': 0,
'allow_email': 0, 'allow_email': 0,
'allow_print': 0, 'allow_print': 0,
'client_script': 'cur_frm.cscript[\'Change Password\']= function(doc, cdt, cdn) {\n var error = false;\n if ((!doc.new_password)||(!doc.retype_new_password)){\n alert("Both fields are required!");\n error = true;\n }\n if (doc.new_password.length<4) {\n alert("Password must be atleast 4 characters long");\n error = true;\n }\n if(doc.new_password!=doc.retype_new_password) {\n alert("Passwords must match");\n error = true;\n }\n if(!/[A-Z]/.test(doc.new_password) || !/[0-9]/.test(doc.new_password) || !/[\\W_]/.test(doc.new_password)) {\n msgprint(\'New password must contain atleast 1 capital letter, 1 numeric and 1 special character.\');\n error = true;\n doc.new_password = \'\';\n refresh_field(\'new_password\');\n }\n if(!error) {\n cur_frm.runscript(\'update_password\', \'\', function(r,t) {\n\tdoc.new_password = \'\';\n\tdoc.retype_new_password = \'\';\n refresh_many([\'new_password\',\'retype_new_password\']);\n });\n }\n}\n\ncur_frm.cscript.validate = function(doc, cdt, cdn) {\n doc.new_password = \'\';\n doc.retype_new_password = \'\';\n}',
'colour': 'White:FFF', 'colour': 'White:FFF',
'doctype': 'DocType', 'doctype': 'DocType',
'hide_heading': 0, 'hide_heading': 0,
'hide_toolbar': 0, 'hide_toolbar': 0,
'idx': 0,
'in_create': 1,
'issingle': 0, 'issingle': 0,
'istable': 0, 'istable': 0,
'max_attachments': 1, 'max_attachments': 1,
@@ -31,10 +28,9 @@
'name': '__common__', 'name': '__common__',
'print_outline': 'Yes', 'print_outline': 'Yes',
'read_only': 0, 'read_only': 0,
'section_style': 'Tray',
'server_code_error': ' ',
'search_fields': 'first_name, last_name',
'show_in_menu': 0, 'show_in_menu': 0,
'version': 25
'version': 32
}, },


# These values are common for all DocField # These values are common for all DocField
@@ -69,7 +65,6 @@
'create': 1, 'create': 1,
'doctype': 'DocPerm', 'doctype': 'DocPerm',
'execute': 0, 'execute': 0,
'idx': 1,
'permlevel': 0, 'permlevel': 0,
'role': 'Administrator', 'role': 'Administrator',
'submit': 0 'submit': 0
@@ -79,7 +74,6 @@
{ {
'create': 1, 'create': 1,
'doctype': 'DocPerm', 'doctype': 'DocPerm',
'idx': 2,
'permlevel': 0, 'permlevel': 0,
'role': 'System Manager' 'role': 'System Manager'
}, },
@@ -87,7 +81,6 @@
# DocPerm # DocPerm
{ {
'doctype': 'DocPerm', 'doctype': 'DocPerm',
'idx': 3,
'permlevel': 1, 'permlevel': 1,
'role': 'Administrator' 'role': 'Administrator'
}, },
@@ -95,7 +88,6 @@
# DocPerm # DocPerm
{ {
'doctype': 'DocPerm', 'doctype': 'DocPerm',
'idx': 4,
'match': 'owner', 'match': 'owner',
'permlevel': 0, 'permlevel': 0,
'role': 'All' 'role': 'All'
@@ -103,85 +95,52 @@


# DocField # DocField
{ {
'default': '1',
'doctype': 'DocField', 'doctype': 'DocField',
'fieldtype': 'Section Break',
'hidden': 0,
'idx': 1,
'label': 'Details',
'oldfieldtype': 'Section Break',
'permlevel': 0,
'reqd': 0,
'search_index': 0
},

# DocField
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
'hidden': 0,
'idx': 2,
'label': 'Picture',
'oldfieldtype': 'Column Break',
'permlevel': 0,
'reqd': 0,
'search_index': 0,
'width': '50%'
},

# DocField
{
'doctype': 'DocField',
'fieldtype': 'Image',
'idx': 3,
'label': 'Profile Picture',
'oldfieldtype': 'Image',
'permlevel': 0
'fieldname': 'enabled',
'fieldtype': 'Check',
'label': 'Enabled',
'oldfieldname': 'enabled',
'oldfieldtype': 'Check',
'permlevel': 1
}, },


# DocField # DocField
{ {
'doctype': 'DocField', 'doctype': 'DocField',
'fieldtype': 'Column Break',
'idx': 4,
'label': 'Contact',
'oldfieldtype': 'Column Break',
'permlevel': 0,
'width': '50%'
'fieldname': 'password',
'fieldtype': 'Password',
'label': 'Password',
'permlevel': 1,
'hidden': 1
}, },
# DocField # DocField
{ {
'default': '1',
'doctype': 'DocField', 'doctype': 'DocField',
'fieldname': 'enabled',
'fieldname': 'registered',
'fieldtype': 'Check', 'fieldtype': 'Check',
'idx': 5,
'label': 'Enabled',
'oldfieldname': 'enabled',
'oldfieldtype': 'Check',
'permlevel': 1
'label': 'Registered',
'permlevel': 0,
'hidden': 1
}, },


# DocField # DocField
{ {
'default': '1',
'doctype': 'DocField', 'doctype': 'DocField',
'fieldname': 'send_email_invite',
'fieldname': 'unsubscribed',
'fieldtype': 'Check', 'fieldtype': 'Check',
'idx': 6,
'label': 'Send Email Invite',
'oldfieldname': 'send_email_invite',
'oldfieldtype': 'Check',
'permlevel': 1
'label': 'Unsubscribed',
'permlevel': 0,
'hidden': 1
}, },
# DocField # DocField
{ {
'doctype': 'DocField', 'doctype': 'DocField',
'fieldname': 'recent_documents', 'fieldname': 'recent_documents',
'fieldtype': 'Text', 'fieldtype': 'Text',
'hidden': 1, 'hidden': 1,
'idx': 8,
'label': 'Recent Documents', 'label': 'Recent Documents',
'oldfieldname': 'recent_documents', 'oldfieldname': 'recent_documents',
'oldfieldtype': 'Text', 'oldfieldtype': 'Text',
@@ -195,7 +154,6 @@
'doctype': 'DocField', 'doctype': 'DocField',
'fieldname': 'first_name', 'fieldname': 'first_name',
'fieldtype': 'Data', 'fieldtype': 'Data',
'idx': 9,
'label': 'First Name', 'label': 'First Name',
'oldfieldname': 'first_name', 'oldfieldname': 'first_name',
'oldfieldtype': 'Data', 'oldfieldtype': 'Data',
@@ -208,7 +166,6 @@
'doctype': 'DocField', 'doctype': 'DocField',
'fieldname': 'middle_name', 'fieldname': 'middle_name',
'fieldtype': 'Data', 'fieldtype': 'Data',
'idx': 10,
'label': 'Middle Name (Optional)', 'label': 'Middle Name (Optional)',
'oldfieldname': 'middle_name', 'oldfieldname': 'middle_name',
'oldfieldtype': 'Data', 'oldfieldtype': 'Data',
@@ -220,46 +177,17 @@
'doctype': 'DocField', 'doctype': 'DocField',
'fieldname': 'last_name', 'fieldname': 'last_name',
'fieldtype': 'Data', 'fieldtype': 'Data',
'idx': 11,
'label': 'Last Name', 'label': 'Last Name',
'oldfieldname': 'last_name', 'oldfieldname': 'last_name',
'oldfieldtype': 'Data', 'oldfieldtype': 'Data',
'permlevel': 0 'permlevel': 0
}, },


# DocField
{
'doctype': 'DocField',
'fieldname': 'email',
'fieldtype': 'Data',
'hidden': 0,
'idx': 12,
'label': 'Email',
'oldfieldname': 'email',
'oldfieldtype': 'Data',
'permlevel': 0,
'reqd': 1,
'search_index': 0
},

# DocField
{
'doctype': 'DocField',
'fieldname': 'birth_date',
'fieldtype': 'Date',
'idx': 13,
'label': 'Birth Date',
'oldfieldname': 'birth_date',
'oldfieldtype': 'Date',
'permlevel': 0
},

# DocField # DocField
{ {
'doctype': 'DocField', 'doctype': 'DocField',
'fieldname': 'gender', 'fieldname': 'gender',
'fieldtype': 'Select', 'fieldtype': 'Select',
'idx': 14,
'label': 'Gender', 'label': 'Gender',
'oldfieldname': 'gender', 'oldfieldname': 'gender',
'oldfieldtype': 'Select', 'oldfieldtype': 'Select',
@@ -271,51 +199,74 @@
# DocField # DocField
{ {
'doctype': 'DocField', 'doctype': 'DocField',
'fieldname': 'occupation',
'fieldtype': 'Column Break',
'oldfieldtype': 'Column Break',
'permlevel': 1,
'width': '50%'
},

# DocField
{
'doctype': 'DocField',
'fieldname': 'email',
'fieldtype': 'Data', 'fieldtype': 'Data',
'idx': 15,
'label': 'Designation',
'oldfieldname': 'occupation',
'hidden': 0,
'label': 'Email',
'oldfieldname': 'email',
'oldfieldtype': 'Data', 'oldfieldtype': 'Data',
'permlevel': 0, 'permlevel': 0,
'reqd': 1,
'search_index': 0 'search_index': 0
}, },

# DocField # DocField
{ {
'doctype': 'DocField', 'doctype': 'DocField',
'fieldname': 'bio', 'fieldname': 'bio',
'fieldtype': 'Text', 'fieldtype': 'Text',
'idx': 16,
'label': 'Bio', 'label': 'Bio',
'oldfieldname': 'bio', 'oldfieldname': 'bio',
'oldfieldtype': 'Text', 'oldfieldtype': 'Text',
'permlevel': 0, 'permlevel': 0,
'search_index': 0
'search_index': 0,
'hidden': 1
}, },



# DocField # DocField
{ {
'doctype': 'DocField', 'doctype': 'DocField',
'fieldname': 'interests', 'fieldname': 'interests',
'fieldtype': 'Text', 'fieldtype': 'Text',
'idx': 17,
'label': 'Interests', 'label': 'Interests',
'oldfieldname': 'interests', 'oldfieldname': 'interests',
'oldfieldtype': 'Text', 'oldfieldtype': 'Text',
'permlevel': 0,
'hidden': 1
},

# DocField
{
'doctype': 'DocField',
'fieldname': 'birth_date',
'fieldtype': 'Date',
'label': 'Birth Date',
'oldfieldname': 'birth_date',
'oldfieldtype': 'Date',
'permlevel': 0 'permlevel': 0
}, },



# DocField # DocField
{ {
'doctype': 'DocField', 'doctype': 'DocField',
'fieldname': 'activities', 'fieldname': 'activities',
'fieldtype': 'Text', 'fieldtype': 'Text',
'idx': 18,
'label': 'Activities', 'label': 'Activities',
'oldfieldname': 'activities', 'oldfieldname': 'activities',
'oldfieldtype': 'Text', 'oldfieldtype': 'Text',
'permlevel': 0
'permlevel': 0,
'hidden': 1
}, },


# DocField # DocField
@@ -323,7 +274,6 @@
'doctype': 'DocField', 'doctype': 'DocField',
'fieldname': 'messanger_status', 'fieldname': 'messanger_status',
'fieldtype': 'Data', 'fieldtype': 'Data',
'idx': 19,
'label': 'Messanger Status', 'label': 'Messanger Status',
'oldfieldname': 'messanger_status', 'oldfieldname': 'messanger_status',
'oldfieldtype': 'Data', 'oldfieldtype': 'Data',
@@ -331,60 +281,11 @@
'search_index': 0 'search_index': 0
}, },


# DocField
{
'doctype': 'DocField',
'fieldname': 'home_phone',
'fieldtype': 'Data',
'idx': 20,
'label': 'Home Phone',
'oldfieldname': 'home_phone',
'oldfieldtype': 'Data',
'permlevel': 0
},

# DocField
{
'doctype': 'DocField',
'fieldname': 'office_phone',
'fieldtype': 'Data',
'idx': 21,
'label': 'Office Phone',
'oldfieldname': 'office_phone',
'oldfieldtype': 'Data',
'permlevel': 0
},

# DocField
{
'doctype': 'DocField',
'fieldname': 'extension',
'fieldtype': 'Data',
'idx': 22,
'label': 'Extension',
'oldfieldname': 'extension',
'oldfieldtype': 'Data',
'permlevel': 0
},

# DocField
{
'doctype': 'DocField',
'fieldname': 'cell_no',
'fieldtype': 'Data',
'idx': 23,
'label': 'Cell No',
'oldfieldname': 'cell_no',
'oldfieldtype': 'Data',
'permlevel': 0
},

# DocField # DocField
{ {
'doctype': 'DocField', 'doctype': 'DocField',
'fieldname': 'user_type', 'fieldname': 'user_type',
'fieldtype': 'Select', 'fieldtype': 'Select',
'idx': 24,
'label': 'User Type', 'label': 'User Type',
'oldfieldname': 'user_type', 'oldfieldname': 'user_type',
'oldfieldtype': 'Select', 'oldfieldtype': 'Select',
@@ -392,150 +293,27 @@
'permlevel': 0 'permlevel': 0
}, },


# DocField
{
'doctype': 'DocField',
'fieldname': 'last_login',
'fieldtype': 'Read Only',
'hidden': 0,
'idx': 25,
'label': 'Last Login',
'oldfieldname': 'last_login',
'oldfieldtype': 'Read Only',
'permlevel': 0,
'reqd': 0,
'search_index': 0
},

# DocField
{
'doctype': 'DocField',
'fieldname': 'last_ip',
'fieldtype': 'Read Only',
'idx': 26,
'label': 'Last IP',
'oldfieldname': 'last_ip',
'oldfieldtype': 'Read Only',
'permlevel': 0
},


# DocField # DocField
{ {
'doctype': 'DocField', 'doctype': 'DocField',
'fieldtype': 'Section Break', 'fieldtype': 'Section Break',
'idx': 27,
'label': 'Address',
'oldfieldtype': 'Section Break',
'permlevel': 0
},

# DocField
{
'doctype': 'DocField',
'fieldname': 'line_1',
'fieldtype': 'Data',
'idx': 28,
'label': 'Line 1',
'oldfieldname': 'line_1',
'oldfieldtype': 'Data',
'permlevel': 0
},

# DocField
{
'doctype': 'DocField',
'fieldname': 'line_2',
'fieldtype': 'Data',
'idx': 29,
'label': 'Line 2',
'oldfieldname': 'line_2',
'oldfieldtype': 'Data',
'permlevel': 0
},

# DocField
{
'doctype': 'DocField',
'fieldname': 'city',
'fieldtype': 'Data',
'idx': 30,
'label': 'City / Town',
'oldfieldname': 'city',
'oldfieldtype': 'Data',
'permlevel': 0,
'reqd': 0
},

# DocField
{
'doctype': 'DocField',
'fieldname': 'district',
'fieldtype': 'Data',
'idx': 31,
'label': 'District',
'oldfieldname': 'district',
'oldfieldtype': 'Data',
'permlevel': 0
},

# DocField
{
'doctype': 'DocField',
'fieldname': 'state',
'fieldtype': 'Data',
'idx': 32,
'label': 'State',
'oldfieldname': 'state',
'oldfieldtype': 'Data',
'permlevel': 0
},

# DocField
{
'doctype': 'DocField',
'fieldname': 'country',
'fieldtype': 'Data',
'idx': 33,
'label': 'Country',
'oldfieldname': 'country',
'oldfieldtype': 'Data',
'permlevel': 0
},

# DocField
{
'doctype': 'DocField',
'fieldname': 'pin',
'fieldtype': 'Data',
'idx': 34,
'label': 'Pin',
'oldfieldname': 'pin',
'oldfieldtype': 'Data',
'permlevel': 0
},

# DocField
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
'idx': 35,
'label': 'User Role',
'hidden': 0,
'oldfieldtype': 'Section Break', 'oldfieldtype': 'Section Break',
'permlevel': 1
'permlevel': 1,
'reqd': 0,
'search_index': 0
}, },

# DocField # DocField
{ {
'doctype': 'DocField', 'doctype': 'DocField',
'fieldtype': 'Section Break',
'hidden': 0,
'idx': 36,
'fieldtype': 'Column Break',
'label': 'Roles', 'label': 'Roles',
'oldfieldtype': 'Section Break',
'oldfieldtype': 'Column Break',
'permlevel': 1, 'permlevel': 1,
'reqd': 0,
'search_index': 0
},
'width': '50%'
},


# DocField # DocField
{ {
@@ -545,7 +323,6 @@
'fieldname': 'userroles', 'fieldname': 'userroles',
'fieldtype': 'Table', 'fieldtype': 'Table',
'hidden': 0, 'hidden': 0,
'idx': 37,
'label': 'User Roles', 'label': 'User Roles',
'oldfieldname': 'userroles', 'oldfieldname': 'userroles',
'oldfieldtype': 'Table', 'oldfieldtype': 'Table',
@@ -558,10 +335,9 @@
# DocField # DocField
{ {
'doctype': 'DocField', 'doctype': 'DocField',
'fieldtype': 'Section Break',
'idx': 38,
'fieldtype': 'Column Break',
'label': 'System Defaults', 'label': 'System Defaults',
'oldfieldtype': 'Section Break',
'oldfieldtype': 'Column Break',
'permlevel': 1, 'permlevel': 1,
'width': '50%' 'width': '50%'
}, },
@@ -574,7 +350,6 @@
'fieldname': 'defaults', 'fieldname': 'defaults',
'fieldtype': 'Table', 'fieldtype': 'Table',
'hidden': 0, 'hidden': 0,
'idx': 39,
'label': 'Defaults', 'label': 'Defaults',
'oldfieldname': 'defaults', 'oldfieldname': 'defaults',
'oldfieldtype': 'Table', 'oldfieldtype': 'Table',
@@ -588,145 +363,69 @@
{ {
'doctype': 'DocField', 'doctype': 'DocField',
'fieldtype': 'Section Break', 'fieldtype': 'Section Break',
'idx': 40,
'label': 'Password',
'label': 'Login Details',
'oldfieldtype': 'Section Break', 'oldfieldtype': 'Section Break',
'permlevel': 0
},

# DocField
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
'idx': 41,
'label': 'Change Your Password',
'oldfieldtype': 'Column Break',
'permlevel': 1,
'width': '50%'
},

# DocField
{
'colour': 'Pink:FEF2EA',
'doctype': 'DocField',
'fieldname': 'password',
'fieldtype': 'Data',
'hidden': 1,
'idx': 42,
'label': 'Current Password',
'oldfieldname': 'password',
'oldfieldtype': 'Data',
'permlevel': 1,
'reqd': 0,
'search_index': 0
},

# DocField
{
'doctype': 'DocField',
'fieldname': 'new_password',
'fieldtype': 'Password',
'idx': 43,
'label': 'New Password',
'oldfieldname': 'new_password',
'oldfieldtype': 'Password',
'permlevel': 1
},

# DocField
{
'doctype': 'DocField',
'fieldname': 'retype_new_password',
'fieldtype': 'Password',
'idx': 44,
'label': 'Retype New Password',
'oldfieldname': 'retype_new_password',
'oldfieldtype': 'Password',
'permlevel': 1
},

# DocField
{
'doctype': 'DocField',
'fieldname': 'password_last_updated',
'fieldtype': 'Date',
'hidden': 1,
'idx': 45,
'label': 'Password Last Updated',
'oldfieldname': 'password_last_updated',
'oldfieldtype': 'Date',
'permlevel': 1,
'print_hide': 1
'permlevel': 0,
}, },


# DocField # DocField
{ {
'doctype': 'DocField', 'doctype': 'DocField',
'fieldtype': 'Button',
'idx': 46,
'label': 'Change Password',
'oldfieldtype': 'Button',
'permlevel': 1,
'trigger': 'Client',
'width': '120px'
'fieldname': 'login_before',
'fieldtype': 'Int',
'label': 'Login Before',
'permlevel': 0
}, },


# DocField # DocField
{ {
'doctype': 'DocField', 'doctype': 'DocField',
'fieldtype': 'Section Break',
'idx': 47,
'label': 'Attachment',
'oldfieldtype': 'Section Break',
'permlevel': 1
'fieldname': 'login_after',
'fieldtype': 'Int',
'label': 'Login After',
'permlevel': 0
}, },


# DocField # DocField
{ {
'default': '0',
'doctype': 'DocField', 'doctype': 'DocField',
'fieldname': 'social_points',
'fieldtype': 'Int',
'idx': 48,
'label': 'Social Points',
'oldfieldname': 'social_points',
'oldfieldtype': 'Int',
'fieldname': 'restrict_ip',
'fieldtype': 'Data',
'label': 'Restrict IP',
'permlevel': 0 'permlevel': 0
}, },


# DocField # DocField
{ {
'doctype': 'DocField', 'doctype': 'DocField',
'fieldname': 'social_badge',
'fieldtype': 'Data',
'idx': 49,
'label': 'Social Badge',
'oldfieldname': 'social_badge',
'oldfieldtype': 'Data',
'permlevel': 0
'fieldtype': 'Column Break',
'oldfieldtype': 'Column Break',
'width': '50%'
}, },


# DocField # DocField
{ {
'doctype': 'DocField', 'doctype': 'DocField',
'fieldname': 'avatar',
'fieldtype': 'Data',
'idx': 50,
'label': 'Avatar',
'oldfieldname': 'avatar',
'oldfieldtype': 'Data',
'permlevel': 0
'fieldname': 'last_login',
'fieldtype': 'Read Only',
'hidden': 0,
'label': 'Last Login',
'oldfieldname': 'last_login',
'oldfieldtype': 'Read Only',
'permlevel': 0,
'reqd': 0,
'search_index': 0
}, },


# DocField # DocField
{ {
'doctype': 'DocField', 'doctype': 'DocField',
'fieldtype': 'HTML',
'idx': 51,
'label': 'Attachment HTML',
'oldfieldtype': 'HTML',
'options': 'First attachment must be the picture',
'permlevel': 1
'fieldname': 'last_ip',
'fieldtype': 'Read Only',
'label': 'Last IP',
'oldfieldname': 'last_ip',
'oldfieldtype': 'Read Only',
'permlevel': 0
}, },


# DocField # DocField
@@ -735,28 +434,9 @@
'fieldname': 'file_list', 'fieldname': 'file_list',
'fieldtype': 'Text', 'fieldtype': 'Text',
'hidden': 1, 'hidden': 1,
'idx': 52,
'label': 'File List', 'label': 'File List',
'oldfieldname': 'file_list', 'oldfieldname': 'file_list',
'oldfieldtype': 'Text', 'oldfieldtype': 'Text',
'permlevel': 0 'permlevel': 0
},

# DocField
{
'doctype': 'DocField',
'fieldname': 'fiscal_year',
'fieldtype': 'Select',
'hidden': 1,
'idx': 53,
'in_filter': 1,
'label': 'Fiscal Year',
'no_copy': 1,
'oldfieldname': 'fiscal_year',
'oldfieldtype': 'Select',
'options': 'link:Fiscal Year',
'permlevel': 0,
'print_hide': 1,
'report_hide': 1
}
}
] ]

+ 8
- 66
cgi-bin/core/doctype/search_criteria/search_criteria.txt Zobrazit soubor

@@ -87,10 +87,13 @@
# DocField # DocField
{ {
'doctype': 'DocField', 'doctype': 'DocField',
'fieldtype': 'Section Break',
'idx': 1,
'label': 'Details',
'oldfieldtype': 'Section Break',
'fieldname': 'criteria_name',
'fieldtype': 'Data',
'hidden': 0,
'idx': 5,
'label': 'Criteria Name',
'oldfieldname': 'criteria_name',
'oldfieldtype': 'Data',
'permlevel': 0 'permlevel': 0
}, },


@@ -135,41 +138,6 @@
'search_index': 1 'search_index': 1
}, },


# DocField
{
'doctype': 'DocField',
'fieldname': 'criteria_name',
'fieldtype': 'Data',
'hidden': 0,
'idx': 5,
'label': 'Criteria Name',
'oldfieldname': 'criteria_name',
'oldfieldtype': 'Data',
'permlevel': 0
},

# DocField
{
'doctype': 'DocField',
'fieldname': 'description',
'fieldtype': 'Text',
'idx': 6,
'label': 'Description',
'oldfieldname': 'description',
'oldfieldtype': 'Text',
'permlevel': 0,
'width': '300px'
},

# DocField
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
'idx': 7,
'label': 'Query Details',
'oldfieldtype': 'Section Break',
'permlevel': 0
},


# DocField # DocField
{ {
@@ -189,7 +157,7 @@
'doctype': 'DocField', 'doctype': 'DocField',
'fieldname': 'filters', 'fieldname': 'filters',
'fieldtype': 'Text', 'fieldtype': 'Text',
'hidden': 0,
'hidden': 1,
'idx': 9, 'idx': 9,
'label': 'Filters', 'label': 'Filters',
'oldfieldname': 'filters', 'oldfieldname': 'filters',
@@ -288,32 +256,6 @@
'permlevel': 0 'permlevel': 0
}, },


# DocField
{
'doctype': 'DocField',
'fieldname': 'graph_series',
'fieldtype': 'Data',
'hidden': 0,
'idx': 17,
'label': 'Graph Series',
'oldfieldname': 'graph_series',
'oldfieldtype': 'Data',
'permlevel': 0
},

# DocField
{
'doctype': 'DocField',
'fieldname': 'graph_values',
'fieldtype': 'Data',
'hidden': 0,
'idx': 18,
'label': 'Graph Values',
'oldfieldname': 'graph_values',
'oldfieldtype': 'Data',
'permlevel': 0
},

# DocField # DocField
{ {
'doctype': 'DocField', 'doctype': 'DocField',


+ 3
- 1
cgi-bin/core/doctype/system_console/system_console.js Zobrazit soubor

@@ -1,10 +1,12 @@
cur_frm.cscript['Server (Python)'] = function(doc, dt, dn) { cur_frm.cscript['Server (Python)'] = function(doc, dt, dn) {
doc.response = 'Executing...'
refresh_field('response');
$c_obj([doc], 'execute_server', '', function(r, rt) { $c_obj([doc], 'execute_server', '', function(r, rt) {
doc = locals[doc.doctype][doc.name]; doc = locals[doc.doctype][doc.name];
if(r.exc) { if(r.exc) {
doc.response = r.exc; doc.response = r.exc;
} else { } else {
doc.response = 'Worked!'
doc.response = 'Worked!'.bold()
} }
refresh_field('response'); refresh_field('response');
}) })


+ 14
- 1
cgi-bin/webnotes/__init__.py Zobrazit soubor

@@ -94,10 +94,13 @@ def errprint(msg):
""" """
debug_log.append(cstr(msg or '')) debug_log.append(cstr(msg or ''))


def msgprint(msg, small=0, raise_exception=0):
def msgprint(msg, small=0, raise_exception=0, as_table=False):
""" """
Append to the :data:`message_log` Append to the :data:`message_log`
""" """
if as_table and type(msg) in (list, tuple):
msg = '<table border="1px" style="border-collapse: collapse" cellpadding="2px">' + ''.join(['<tr>'+''.join(['<td>%s</td>' % c for c in r])+'</tr>' for r in msg]) + '</table>'
message_log.append((small and '__small:' or '')+cstr(msg or '')) message_log.append((small and '__small:' or '')+cstr(msg or ''))
if raise_exception: if raise_exception:
raise ValidationError raise ValidationError
@@ -197,3 +200,13 @@ def setup_logging():
if getattr(defs, 'log_file_name', None): if getattr(defs, 'log_file_name', None):
setup_logging() setup_logging()
def get_db_password(db_name):
from webnotes import defs
if hasattr(defs, 'get_db_password'):
return defs.get_db_password(db_name)
elif hasattr(defs, 'db_password'):
return defs.db_password
else:
return db_name

+ 33
- 10
cgi-bin/webnotes/auth.py Zobrazit soubor

@@ -104,7 +104,7 @@ class HTTPRequest:
else: else:
db_name = getattr(webnotes.defs,'default_db_name','') db_name = getattr(webnotes.defs,'default_db_name','')
webnotes.conn = webnotes.db.Database(user = db_name,password = getattr(webnotes.defs,'db_password',''))
webnotes.conn = webnotes.db.Database(user = db_name,password = getattr(webnotes.defs,'db_password', ''))
webnotes.ac_name = ac_name webnotes.ac_name = ac_name


# ================================================================================= # =================================================================================
@@ -127,8 +127,9 @@ class LoginManager:
# --------------------------- # ---------------------------
def post_login(self): def post_login(self):
self.validate_ip_address()
self.run_trigger() self.run_trigger()
self.validate_ip_address()
self.validate_hour()
# check password # check password
# -------------- # --------------
@@ -186,16 +187,38 @@ class LoginManager:
# ------------- # -------------
def validate_ip_address(self): def validate_ip_address(self):
try:
ip = webnotes.conn.sql("select ip_address from tabProfile where name = '%s'" % self.user)[0][0] or ''
except: return
ip_list = webnotes.conn.get_value('Profile', self.user, 'restrict_ip', ignore=True)
if not ip_list:
return

ip_list = ip_list.replace(",", "\n").split('\n')
ip_list = [i.strip() for i in ip_list]

for ip in ip_list:
if webnotes.remote_ip.startswith(ip):
return
ip = ip.replace(",", "\n").split('\n')
ip = [i.strip() for i in ip]
webnotes.msgprint('Not allowed from this IP Address', raise_exception=1)

def validate_hour(self):
"""
check if user is logging in during restricted hours
"""
login_before = int(webnotes.conn.get_value('Profile', self.user, 'login_before', ignore=True) or 0)
login_after = int(webnotes.conn.get_value('Profile', self.user, 'login_after', ignore=True) or 0)
if not (login_before or login_after):
return
if ret and ip:
if not (webnotes.remote_ip.startswith(ip[0]) or (webnotes.remote_ip in ip)):
raise Exception, 'Not allowed from this IP Address'
from webnotes.utils import now_datetime
current_hour = int(now_datetime().strftime('%H'))
if login_before and current_hour > login_before:
webnotes.msgprint('Not allowed to login after restricted hour', raise_exception=1)

if login_after and current_hour < login_after:
webnotes.msgprint('Not allowed to login before restricted hour', raise_exception=1)


# login as guest # login as guest
# -------------- # --------------


+ 12
- 5
cgi-bin/webnotes/db.py Zobrazit soubor

@@ -26,7 +26,7 @@ class Database:
self.transaction_writes = 0 self.transaction_writes = 0
self.testing_tables = [] self.testing_tables = []


self.password = self.get_db_password(ac_name, password)
self.password = self.get_db_password(user, password)
self.connect() self.connect()
if self.user != 'root': if self.user != 'root':
@@ -57,7 +57,9 @@ class Database:
return '' return ''
def get_db_login(self, ac_name): def get_db_login(self, ac_name):
return getattr(defs,'db_name_map').get(ac_name, getattr(defs,'default_db_name'))
if hasattr(defs, 'db_name_map'):
return getattr(defs,'db_name_map').get(ac_name, getattr(defs,'default_db_name'))
else: return ac_name


def connect(self): def connect(self):
""" """
@@ -253,7 +255,7 @@ class Database:
# ====================================================================================== # ======================================================================================
# get a single value from a record # get a single value from a record


def get_value(self, doctype, docname, fieldname):
def get_value(self, doctype, docname, fieldname, ignore=None):
""" """
Get a single / multiple value from a record. Get a single / multiple value from a record.


@@ -264,8 +266,13 @@ class Database:
if docname and (docname!=doctype or docname=='DocType'): if docname and (docname!=doctype or docname=='DocType'):
if type(fieldname) in (list, tuple): if type(fieldname) in (list, tuple):
fl = '`, `'.join(fieldname) fl = '`, `'.join(fieldname)

r = self.sql("select `%s` from `tab%s` where name='%s'" % (fl, doctype, docname))
try:
r = self.sql("select `%s` from `tab%s` where name='%s'" % (fl, doctype, docname))
except Exception, e:
if e.args[0]==1054 and ignore:
return None
else:
raise e
return r and (len(r[0]) > 1 and r[0] or r[0][0]) or None return r and (len(r[0]) > 1 and r[0] or r[0][0]) or None
else: else:
if type(fieldname) in (list, tuple): if type(fieldname) in (list, tuple):


+ 5
- 1
cgi-bin/webnotes/model/__init__.py Zobrazit soubor

@@ -76,6 +76,10 @@ def delete_doc(doctype=None, name=None, doclist = None, force=0):
# check if links exist # check if links exist
if not force: if not force:
check_if_doc_is_linked(doctype, name) check_if_doc_is_linked(doctype, name)

# remove tags
from webnotes.widgets.tags import clear_tags
clear_tags(doctype, name)
try: try:
webnotes.conn.sql("delete from `tab%s` where name='%s' limit 1" % (doctype, name)) webnotes.conn.sql("delete from `tab%s` where name='%s' limit 1" % (doctype, name))
@@ -86,7 +90,7 @@ def delete_doc(doctype=None, name=None, doclist = None, force=0):
webnotes.msgprint("Cannot delete %s '%s' as it is referenced in another record. You must delete the referred record first" % (doctype, name)) webnotes.msgprint("Cannot delete %s '%s' as it is referenced in another record. You must delete the referred record first" % (doctype, name))
raise e raise e
return 'okay' return 'okay'


#================================================================================= #=================================================================================


+ 28
- 29
cgi-bin/webnotes/model/doclist.py Zobrazit soubor

@@ -18,7 +18,7 @@ class DocList:
self.to_docstatus = 0 self.to_docstatus = 0
if dt and dn: if dt and dn:
self.load_from_db(dt, dn) self.load_from_db(dt, dn)
def load_from_db(self, dt, dn): def load_from_db(self, dt, dn):
""" """
Load doclist from dt Load doclist from dt
@@ -34,15 +34,15 @@ class DocList:
doclist = [doc,] doclist = [doc,]
for t in tablefields: for t in tablefields:
doclist += getchildren(doc.name, t[0], t[1], dt, prefix=prefix) doclist += getchildren(doc.name, t[0], t[1], dt, prefix=prefix)
self.docs = docs self.docs = docs
def __iter__(self): def __iter__(self):
""" """
Make this iterable Make this iterable
""" """
return self.docs.__iter__() return self.docs.__iter__()
def from_compressed(self, data, docname): def from_compressed(self, data, docname):
""" """
Expand called from client Expand called from client
@@ -50,13 +50,13 @@ class DocList:
from webnotes.model.utils import expand from webnotes.model.utils import expand
self.docs = expand(data) self.docs = expand(data)
self.objectify(docname) self.objectify(docname)
def objectify(self, docname=None): def objectify(self, docname=None):
""" """
Converts self.docs from a list of dicts to list of Documents Converts self.docs from a list of dicts to list of Documents
""" """
from webnotes.model.doc import Document from webnotes.model.doc import Document
self.docs = [Document(fielddata=d) for d in self.docs] self.docs = [Document(fielddata=d) for d in self.docs]
if not docname: if not docname:
self.doc, self.children = self.docs[0], self.docs[1:] self.doc, self.children = self.docs[0], self.docs[1:]
@@ -69,21 +69,20 @@ class DocList:
self.doc = d self.doc = d
else: else:
self.children.append(d) self.children.append(d)
# catch all if no self.doc # catch all if no self.doc
if not self.doc: if not self.doc:
self.doc, self.children = self.docs[0], self.docs[1:] self.doc, self.children = self.docs[0], self.docs[1:]
def make_obj(self): def make_obj(self):
""" """
Create a DocType object Create a DocType object
""" """
if self.obj: return self.obj if self.obj: return self.obj
from webnotes.model.code import get_obj from webnotes.model.code import get_obj
self.obj = get_obj(doc=self.doc, doclist=self.children) self.obj = get_obj(doc=self.doc, doclist=self.children)
return self.obj return self.obj
def next(self): def next(self):
""" """
Next doc Next doc
@@ -104,13 +103,13 @@ class DocList:


if (not is_single(self.doc.doctype)) and (not cint(self.doc.fields.get('__islocal'))): if (not is_single(self.doc.doctype)) and (not cint(self.doc.fields.get('__islocal'))):
tmp = webnotes.conn.sql(""" tmp = webnotes.conn.sql("""
SELECT modified FROM `tab%s` WHERE name="%s" for update"""
SELECT modified FROM `tab%s` WHERE name="%s" for update"""
% (self.doc.doctype, self.doc.name)) % (self.doc.doctype, self.doc.name))


if tmp and str(tmp[0][0]) != str(self.doc.modified): if tmp and str(tmp[0][0]) != str(self.doc.modified):
webnotes.msgprint(""" 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.
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) Please refresh this document. [%s/%s]""" % (tmp[0][0], self.doc.modified), raise_exception=1)


def check_permission(self): def check_permission(self):
@@ -119,7 +118,7 @@ class DocList:
""" """
if not self.doc.check_perm(verbose=1): if not self.doc.check_perm(verbose=1):
webnotes.msgprint("Not enough permission to save %s" % self.doc.doctype, raise_exception=1) webnotes.msgprint("Not enough permission to save %s" % self.doc.doctype, raise_exception=1)
def check_links(self): def check_links(self):
""" """
Checks integrity of links (throws exception if links are invalid) Checks integrity of links (throws exception if links are invalid)
@@ -130,11 +129,11 @@ class DocList:
ref[d.doctype] = d.make_link_list() ref[d.doctype] = d.make_link_list()


err_list += d.validate_links(ref[d.doctype]) err_list += d.validate_links(ref[d.doctype])
if err_list: if err_list:
webnotes.msgprint("""[Link Validation] Could not find the following values: %s.
webnotes.msgprint("""[Link Validation] Could not find the following values: %s.
Please correct and resave. Document Not Saved.""" % ', '.join(err_list), raise_exception=1) Please correct and resave. Document Not Saved.""" % ', '.join(err_list), raise_exception=1)
def update_timestamps_and_docstatus(self): def update_timestamps_and_docstatus(self):
""" """
Update owner, creation, modified_by, modified, docstatus Update owner, creation, modified_by, modified, docstatus
@@ -142,17 +141,17 @@ class DocList:
from webnotes.utils import now from webnotes.utils import now
ts = now() ts = now()
user = webnotes.__dict__.get('session', {}).get('user') or 'Administrator' user = webnotes.__dict__.get('session', {}).get('user') or 'Administrator'
for d in self.docs: for d in self.docs:
if self.doc.__islocal: if self.doc.__islocal:
d.owner = user d.owner = user
d.creation = ts d.creation = ts
d.modified_by = user d.modified_by = user
d.modified = ts d.modified = ts
if d.docstatus != 2: # don't update deleted if d.docstatus != 2: # don't update deleted
d.docstatus = self.to_docstatus d.docstatus = self.to_docstatus
def prepare_for_save(self, check_links): def prepare_for_save(self, check_links):
""" """
Set owner, modified etc before saving Set owner, modified etc before saving
@@ -175,7 +174,7 @@ class DocList:


from webnotes.model.triggers import fire_event from webnotes.model.triggers import fire_event
fire_event(self.doc, method) fire_event(self.doc, method)
def save_main(self): def save_main(self):
""" """
Save the main doc Save the main doc
@@ -184,7 +183,7 @@ class DocList:
self.doc.save(cint(self.doc.__islocal)) self.doc.save(cint(self.doc.__islocal))
except NameError, e: except NameError, e:
webnotes.msgprint('%s "%s" already exists' % (self.doc.doctype, self.doc.name)) webnotes.msgprint('%s "%s" already exists' % (self.doc.doctype, self.doc.name))
# prompt if cancelled # prompt if cancelled
if webnotes.conn.get_value(self.doc.doctype, self.doc.name, 'docstatus')==2: 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.msgprint('[%s "%s" has been cancelled]' % (self.doc.doctype, self.doc.name))
@@ -197,7 +196,7 @@ class DocList:
""" """
for d in self.children: for d in self.children:
deleted, local = d.fields.get('__deleted',0), d.fields.get('__islocal',0) deleted, local = d.fields.get('__deleted',0), d.fields.get('__islocal',0)
if cint(local) and cint(deleted): if cint(local) and cint(deleted):
pass pass


@@ -206,7 +205,7 @@ class DocList:
d.parent = self.doc.name # rename if reqd d.parent = self.doc.name # rename if reqd
d.parenttype = self.doc.doctype d.parenttype = self.doc.doctype


d.save(new = cint(local))
d.save(new = cint(local))


def save(self, check_links=1): def save(self, check_links=1):
""" """
@@ -217,7 +216,7 @@ class DocList:
self.save_main() self.save_main()
self.save_children() self.save_children()
self.run_method('on_update') self.run_method('on_update')
def submit(self): def submit(self):
""" """
Save & Submit - set docstatus = 1, run "on_submit" Save & Submit - set docstatus = 1, run "on_submit"
@@ -227,7 +226,7 @@ class DocList:
self.to_docstatus = 1 self.to_docstatus = 1
self.save() self.save()
self.run_method('on_submit') self.run_method('on_submit')
def cancel(self): def cancel(self):
""" """
Cancel - set docstatus 2, run "on_cancel" Cancel - set docstatus 2, run "on_cancel"
@@ -239,7 +238,7 @@ class DocList:
self.save_main() self.save_main()
self.save_children() self.save_children()
self.run_method('on_cancel') self.run_method('on_cancel')
def update_after_submit(self): def update_after_submit(self):
""" """
Update after submit - some values changed after submit Update after submit - some values changed after submit
@@ -260,11 +259,11 @@ def getlist(doclist, parentfield):
""" """
import webnotes.model.utils import webnotes.model.utils
return webnotes.model.utils.getlist(doclist, parentfield) return webnotes.model.utils.getlist(doclist, parentfield)
def copy_doclist(doclist, no_copy = []): def copy_doclist(doclist, no_copy = []):
""" """
Make a copy of the doclist Make a copy of the doclist
""" """
import webnotes.model.utils import webnotes.model.utils
return webnotes.model.utils.copy_doclist(doclist, no_copy) return webnotes.model.utils.copy_doclist(doclist, no_copy)

+ 59
- 40
cgi-bin/webnotes/model/utils.py Zobrazit soubor

@@ -1,7 +1,7 @@
""" """
Model utilities, unclassified functions Model utilities, unclassified functions
""" """
def expand(docs): def expand(docs):
""" """
Expand a doclist sent from the client side. (Internally used by the request handler) Expand a doclist sent from the client side. (Internally used by the request handler)
@@ -25,12 +25,12 @@ def compress(doclist):
""" """
Compress a doclist before sending it to the client side. (Internally used by the request handler) Compress a doclist before sending it to the client side. (Internally used by the request handler)


"""
"""
if doclist and hasattr(doclist[0],'fields'): if doclist and hasattr(doclist[0],'fields'):
docs = [d.fields for d in doclist] docs = [d.fields for d in doclist]
else: else:
docs = doclist docs = doclist
kl, vl = {}, [] kl, vl = {}, []
for d in docs: for d in docs:
dt = d['doctype'] dt = d['doctype']
@@ -38,10 +38,10 @@ def compress(doclist):
fl = d.keys() fl = d.keys()
forbidden = ['server_code_compiled'] forbidden = ['server_code_compiled']
nl = ['doctype','localname','__oldparent','__unsaved'] nl = ['doctype','localname','__oldparent','__unsaved']
# add client script for doctype, doctype due to ambiguity # add client script for doctype, doctype due to ambiguity
if dt=='DocType': nl.append('__client_script') if dt=='DocType': nl.append('__client_script')
for f in fl: for f in fl:
if not (f in nl) and not (f in forbidden): if not (f in nl) and not (f in forbidden):
nl.append(f) nl.append(f)
@@ -64,21 +64,24 @@ def compress(doclist):
def getlist(doclist, field): def getlist(doclist, field):
""" """
Filter a list of records for a specific field from the full doclist Filter a list of records for a specific field from the full doclist
Example:: Example::
# find all phone call details
# find all phone call details
dl = getlist(self.doclist, 'contact_updates') dl = getlist(self.doclist, 'contact_updates')
pl = [] pl = []
for d in dl: for d in dl:
if d.type=='Phone': if d.type=='Phone':
pl.append(d) pl.append(d)
""" """
from webnotes.utils import cint
l = [] l = []
for d in doclist: for d in doclist:
if d.parent and (not d.parent.lower().startswith('old_parent:')) and d.parentfield == field: if d.parent and (not d.parent.lower().startswith('old_parent:')) and d.parentfield == field:
l.append(d) l.append(d)

l.sort(lambda a, b: cint(a.idx) - cint(b.idx))

return l return l


# Copy doclist # Copy doclist
@@ -90,31 +93,31 @@ def copy_doclist(doclist, no_copy = []):
Pass fields that are not to be copied in `no_copy` Pass fields that are not to be copied in `no_copy`
""" """
from webnotes.model.doc import Document from webnotes.model.doc import Document
cl = [] cl = []
# main doc # main doc
c = Document(fielddata = doclist[0].fields.copy()) c = Document(fielddata = doclist[0].fields.copy())
# clear no_copy fields # clear no_copy fields
for f in no_copy:
for f in no_copy:
if c.fields.has_key(f): if c.fields.has_key(f):
c.fields[f] = None c.fields[f] = None
c.name = None c.name = None
c.save(1) c.save(1)
cl.append(c) cl.append(c)
# new parent name # new parent name
parent = c.name parent = c.name
# children # children
for d in doclist[1:]: for d in doclist[1:]:
c = Document(fielddata = d.fields.copy()) c = Document(fielddata = d.fields.copy())
c.name = None c.name = None
# clear no_copy fields # clear no_copy fields
for f in no_copy:
for f in no_copy:
if c.fields.has_key(f): if c.fields.has_key(f):
c.fields[f] = None c.fields[f] = None


@@ -138,18 +141,18 @@ def _make_html(doc, link_list):
from webnotes.utils import cstr from webnotes.utils import cstr
out = '<table class="simpletable">' out = '<table class="simpletable">'
for k in doc.fields.keys(): for k in doc.fields.keys():
if k!='server_code_compiled':
if k!='server_code_compiled':
v = cstr(doc.fields[k]) v = cstr(doc.fields[k])
# link field # link field
if v and (k in link_list.keys()): if v and (k in link_list.keys()):
dt = link_list[k] dt = link_list[k]
if type(dt)==str and dt.startswith('link:'): if type(dt)==str and dt.startswith('link:'):
dt = dt[5:] dt = dt[5:]
v = '<a href="index.cgi?page=Form/%s/%s">%s</a>' % (dt, v, v)
v = '<a href="index.cgi?page=Form/%s/%s">%s</a>' % (dt, v, v)
out += '\t<tr><td>%s</td><td>%s</td></tr>\n' % (cstr(k), v) out += '\t<tr><td>%s</td><td>%s</td></tr>\n' % (cstr(k), v)
out += '</table>' out += '</table>'
return out return out


@@ -159,13 +162,13 @@ def to_html(doclist):
""" """
out = '' out = ''
link_lists = {} link_lists = {}
for d in doclist: for d in doclist:
if not link_lists.get(d.doctype): if not link_lists.get(d.doctype):
link_lists[d.doctype] = d.make_link_list() link_lists[d.doctype] = d.make_link_list()


out += _make_html(d, link_lists[d.doctype]) out += _make_html(d, link_lists[d.doctype])
return out return out


def commonify_doclist(doclist, with_comments=1): def commonify_doclist(doclist, with_comments=1):
@@ -183,15 +186,17 @@ def commonify_doclist(doclist, with_comments=1):
c[k] = doclist[0][k] c[k] = doclist[0][k]
return c return c


def strip_common(d):
for k in common_keys:
def strip_common_and_idx(d):
for k in common_keys:
if k in d: del d[k] if k in d: del d[k]
if 'idx' in d: del d['idx']
return d return d


def make_common_dicts(doclist): def make_common_dicts(doclist):
common_dict = {} # one per doctype common_dict = {} # one per doctype
# make common dicts for all records # make common dicts for all records
for d in doclist: for d in doclist:
if not d['doctype'] in common_dict: if not d['doctype'] in common_dict:
@@ -206,15 +211,15 @@ def commonify_doclist(doclist, with_comments=1):
common_dict = make_common_dicts(doclist) common_dict = make_common_dicts(doclist)


# make docs # make docs
final = []
final = []
for d in doclist: for d in doclist:
f = strip_common(get_diff_dict(common_dict[d['doctype']], d))
f = strip_common_and_idx(get_diff_dict(common_dict[d['doctype']], d))
f['doctype'] = d['doctype'] # keep doctype! f['doctype'] = d['doctype'] # keep doctype!
# strip name for child records (only an auto generated number!) # strip name for child records (only an auto generated number!)
if f['doctype'] != doclist[0]['doctype']: if f['doctype'] != doclist[0]['doctype']:
del f['name'] del f['name']
if with_comments: if with_comments:
f['##comment'] = d['doctype'] + ('name' in f and (', ' + f['name']) or '') f['##comment'] = d['doctype'] + ('name' in f and (', ' + f['name']) or '')
final.append(f) final.append(f)
@@ -225,37 +230,51 @@ def commonify_doclist(doclist, with_comments=1):
d['name']='__common__' d['name']='__common__'
if with_comments: if with_comments:
d['##comment'] = 'These values are common for all ' + d['doctype'] d['##comment'] = 'These values are common for all ' + d['doctype']
commons.append(strip_common(d))
commons.append(strip_common_and_idx(d))
common_values = make_common(doclist) common_values = make_common(doclist)
return [common_values]+commons+final return [common_values]+commons+final
def uncommonify_doclist(dl): def uncommonify_doclist(dl):
""" """
Expands an commonified doclist Expands an commonified doclist
""" """
# first one has common values
common_values = dl[0] common_values = dl[0]
common_dict = {} common_dict = {}
final = [] final = []
idx_dict = {}


for d in dl[1:]: for d in dl[1:]:
if 'name' in d and d['name']=='__common__': if 'name' in d and d['name']=='__common__':
# common for a doctype -
del d['name'] del d['name']
common_dict[d['doctype']] = d common_dict[d['doctype']] = d
else: else:
dt = d['doctype']
if not dt in idx_dict: idx_dict[dt] = 0;
d1 = common_values.copy() d1 = common_values.copy()
d1.update(common_dict[d['doctype']])

# update from common and global
d1.update(common_dict[dt])
d1.update(d) d1.update(d)

# idx by sequence
d1['idx'] = idx_dict[dt]
# increment idx
idx_dict[dt] += 1

final.append(d1) final.append(d1)


return final return final
def pprint_doclist(doclist, with_comments = 1): def pprint_doclist(doclist, with_comments = 1):
""" """
Pretty Prints a doclist with common keys separated and comments Pretty Prints a doclist with common keys separated and comments
""" """
from webnotes.utils import pprint_dict from webnotes.utils import pprint_dict
dictlist =[pprint_dict(d) for d in commonify_doclist(doclist, with_comments)] dictlist =[pprint_dict(d) for d in commonify_doclist(doclist, with_comments)]
title = '# '+doclist[0]['doctype']+', '+doclist[0]['name'] title = '# '+doclist[0]['doctype']+', '+doclist[0]['name']
return title + '\n[\n' + ',\n'.join(dictlist) + '\n]' return title + '\n[\n' + ',\n'.join(dictlist) + '\n]'
@@ -268,5 +287,5 @@ def peval_doclist(txt):
return uncommonify_doclist(eval(txt)) return uncommonify_doclist(eval(txt))
else: else:
return eval(txt) return eval(txt)
return uncommonify_doclist(eval(txt)) return uncommonify_doclist(eval(txt))

+ 15
- 12
cgi-bin/webnotes/modules/__init__.py Zobrazit soubor

@@ -139,8 +139,13 @@ class Module:
""" """
Sync the file to the db Sync the file to the db
""" """
import os
dt, dn = scrub_dt_dn(dt, dn) dt, dn = scrub_dt_dn(dt, dn)
self.get_file(dt, dn, dn + '.txt').sync()
path = os.path.exists(os.path.join(self.get_path(), os.path.join(dt, dn, dn + '.txt')))
if not path:
webnotes.msgprint("%s not found" % path)
else:
self.get_file(dt, dn, dn + '.txt').sync(force=1)
def sync_all_of_type(self, extn, verbose=0): def sync_all_of_type(self, extn, verbose=0):
""" """
@@ -217,15 +222,13 @@ class ModuleFile:
""" """
returns file contents returns file contents
""" """
try:
import os
if os.path.exists(self.path):
f = open(self.path,'r') f = open(self.path,'r')
self.content = f.read() self.content = f.read()
f.close() f.close()
except IOError, e:
if e.args[0]==2:
self.content = ''
else:
raise e
else:
self.content = ''


return self.content return self.content
@@ -248,21 +251,21 @@ class TxtModuleFile(ModuleFile):
def __init__(self, path): def __init__(self, path):
ModuleFile.__init__(self, path) ModuleFile.__init__(self, path)
def sync(self):
def sync(self, force=1):
""" """
import the doclist if new import the doclist if new
""" """
if self.is_new(): if self.is_new():
from webnotes.model.utils import peval_doclist from webnotes.model.utils import peval_doclist
doclist = peval_doclist(self.read()) doclist = peval_doclist(self.read())
if doclist:
if doclist:
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 # since there is a new timestamp on the file, update timestamp in
# the record # the record
webnotes.conn.sql("update `tab%s` set modified=now() where name=%s" \ webnotes.conn.sql("update `tab%s` set modified=now() where name=%s" \
% (doclist[0]['doctype'], '%s'), doclist[0]['name']) % (doclist[0]['doctype'], '%s'), doclist[0]['name'])
from webnotes.utils.transfer import set_doc
set_doc(doclist, 1, 1, 1)
self.update() self.update()


+ 4
- 3
cgi-bin/webnotes/modules/patch.py Zobrazit soubor

@@ -31,6 +31,7 @@ def write_log():
patch_log.write(('\n\nError in %s:\n' % webnotes.conn.cur_db_name) + webnotes.getTraceback()) patch_log.write(('\n\nError in %s:\n' % webnotes.conn.cur_db_name) + webnotes.getTraceback())
patch_log.close() patch_log.close()
webnotes.msgprint("There were errors in running patches, please call the Administrator")
from webnotes.utils import sendmail
subj = 'Error in running patches in %s' % webnotes.conn.cur_db_name
msg = subj + '<br><br>Login User: ' + webnotes.user.name + '<br><br>' + webnotes.getTraceback()
sendmail(['developer@erpnext.com'], sender='automail@erpnext.com', subject= subj, parts=[['text/plain', msg]])

+ 6
- 2
cgi-bin/webnotes/utils/__init__.py Zobrazit soubor

@@ -119,7 +119,7 @@ def getdate(string_date):
else: else:
return '' return ''


def add_days(date, days):
def add_days(date, days, format='string'):
""" """
Adds `days` to the given `string_date` Adds `days` to the given `string_date`
""" """
@@ -130,7 +130,11 @@ def add_days(date, days):
if type(date) not in (datetime.datetime, datetime.date): if type(date) not in (datetime.datetime, datetime.date):
date = getdate(date) date = getdate(date)


return (date + datetime.timedelta(days)).strftime('%Y-%m-%d')
dt = date + datetime.timedelta(days)
if format=='string':
return dt.strftime('%Y-%m-%d')
else:
return dt


def add_months(string_date, months): def add_months(string_date, months):
import datetime import datetime


+ 14
- 1
cgi-bin/webnotes/utils/backups.py Zobrazit soubor

@@ -123,7 +123,7 @@ def get_backup():
""" """
#if verbose: print webnotes.conn.cur_db_name + " " + webnotes.defs.db_password #if verbose: print webnotes.conn.cur_db_name + " " + webnotes.defs.db_password
odb = BackupGenerator(webnotes.conn.cur_db_name, webnotes.conn.cur_db_name,\ odb = BackupGenerator(webnotes.conn.cur_db_name, webnotes.conn.cur_db_name,\
webnotes.defs.db_password)
get_db_password(webnotes.conn.cur_db_name))
recipient_list = odb.get_backup() recipient_list = odb.get_backup()
delete_temp_backups() delete_temp_backups()
webnotes.msgprint("""A download link to your backup will be emailed \ webnotes.msgprint("""A download link to your backup will be emailed \
@@ -131,6 +131,19 @@ def get_backup():
%s""" % (', '.join(recipient_list))) %s""" % (', '.join(recipient_list)))




def get_db_password(db_name):
"""
Get db password from defs
"""
from webnotes import defs
if hasattr(defs, 'get_db_password'):
return defs.get_db_password(db_name)

if hasattr(defs, 'db_password'):
return defs.db_password



def delete_temp_backups(): def delete_temp_backups():
""" """
Cleans up the backup_link_path directory by deleting files older than 24 hours Cleans up the backup_link_path directory by deleting files older than 24 hours


+ 9
- 3
cgi-bin/webnotes/utils/email_lib/receive.py Zobrazit soubor

@@ -39,8 +39,11 @@ class IncomingMail:
""" """
get utf-8 encoded part content get utf-8 encoded part content
""" """
return unicode(part.get_payload(decode=True),str(charset),"ignore").encode('utf8','replace')
try:
return unicode(part.get_payload(decode=True),str(charset),"ignore").encode('utf8','replace')
except LookupError, e:
return part.get_payload()

def get_attachment(self, part, charset): def get_attachment(self, part, charset):
""" """
Extracts an attachment Extracts an attachment
@@ -128,7 +131,10 @@ class POP3Mailbox:
num = len(self.pop.list()[1]) num = len(self.pop.list()[1])
for m in range(num): for m in range(num):
msg = self.pop.retr(m+1) msg = self.pop.retr(m+1)
self.process_message(IncomingMail('\n'.join(msg[1])))
try:
self.process_message(IncomingMail('\n'.join(msg[1])))
except:
pass
self.pop.dele(m+1) self.pop.dele(m+1)
self.pop.quit() self.pop.quit()


+ 1
- 1
cgi-bin/webnotes/utils/scheduler.py Zobrazit soubor

@@ -89,7 +89,7 @@ class Scheduler:
import webnotes, webnotes.defs, webnotes.db import webnotes, webnotes.defs, webnotes.db


try: try:
webnotes.conn = webnotes.db.Database(user=db_name, password=webnotes.defs.db_password)
webnotes.conn = webnotes.db.Database(user=db_name, password=webnotes.get_db_password(db_name))
webnotes.session = {'user':'Administrator'} webnotes.session = {'user':'Administrator'}


module = '.'.join(event.split('.')[:-1]) module = '.'.join(event.split('.')[:-1])


+ 1
- 1
cgi-bin/webnotes/widgets/page.py Zobrazit soubor

@@ -19,7 +19,7 @@ class Page:
Loads page info from files in module Loads page info from files in module
""" """
# load js # load js
doc.fields['__script'] = module.get_doc_file('page',doc.name,'.js').read()
doc.fields['__script'] = module.get_doc_file('page',doc.name,'.js').read() or doc.script
doc.script = None doc.script = None


# load css # load css


+ 48
- 48
cgi-bin/webnotes/widgets/query_builder.py Zobrazit soubor

@@ -14,7 +14,7 @@ def get_search_criteria_list(dt):
def load_report_list(): def load_report_list():
webnotes.response['rep_list'] = get_search_criteria_list(form.getvalue('dt')) webnotes.response['rep_list'] = get_search_criteria_list(form.getvalue('dt'))


# Get, scrub metadata # Get, scrub metadata
# ==================================================================== # ====================================================================


@@ -37,20 +37,20 @@ def get_parent_dt(dt):


def get_sql_meta(tl): def get_sql_meta(tl):
std_columns = { std_columns = {
'owner':('Owner', '', '', '100'),
'creation':('Created on', 'Date', '', '100'),
'modified':('Last modified on', 'Date', '', '100'),
'owner':('Owner', '', '', '100'),
'creation':('Created on', 'Date', '', '100'),
'modified':('Last modified on', 'Date', '', '100'),
'modified_by':('Modified By', '', '', '100') 'modified_by':('Modified By', '', '', '100')
} }
meta = {} meta = {}
for dt in tl: for dt in tl:
meta[dt] = std_columns.copy() meta[dt] = std_columns.copy()


# for table doctype, the ID is the parent id # for table doctype, the ID is the parent id
pdt = get_parent_dt(dt) pdt = get_parent_dt(dt)
if pdt:
if pdt:
meta[dt]['parent'] = ('ID', 'Link', pdt, '200') meta[dt]['parent'] = ('ID', 'Link', pdt, '200')


# get the field properties from DocField # get the field properties from DocField
@@ -58,10 +58,10 @@ def get_sql_meta(tl):
for r in res: for r in res:
if r[0]: if r[0]:
meta[dt][r[0]] = (r[1], r[2], r[3], r[4]); meta[dt][r[0]] = (r[1], r[2], r[3], r[4]);
# name # name
meta[dt]['name'] = ('ID', 'Link', dt, '200') meta[dt]['name'] = ('ID', 'Link', dt, '200')
return meta return meta


# Additional conditions to fulfill match permission rules # Additional conditions to fulfill match permission rules
@@ -80,12 +80,12 @@ def getmatchcondition(dt, ud, ur):
return '' return ''


return ' OR '.join(cond) return ' OR '.join(cond)
def add_match_conditions(q, tl, ur, ud): def add_match_conditions(q, tl, ur, ud):
sl = [] sl = []
for dt in tl: for dt in tl:
s = getmatchcondition(dt, ud, ur) s = getmatchcondition(dt, ud, ur)
if s:
if s:
sl.append(s) sl.append(s)


# insert the conditions # insert the conditions
@@ -94,13 +94,13 @@ def add_match_conditions(q, tl, ur, ud):


condition_end = q.find('ORDER BY')!=-1 and 'ORDER BY' or 'LIMIT' condition_end = q.find('ORDER BY')!=-1 and 'ORDER BY' or 'LIMIT'
condition_end = q.find('GROUP BY')!=-1 and 'GROUP BY' or condition_end condition_end = q.find('GROUP BY')!=-1 and 'GROUP BY' or condition_end
if q.find('ORDER BY')!=-1 or q.find('LIMIT')!=-1 or q.find('GROUP BY')!=-1: # if query continues beyond conditions if q.find('ORDER BY')!=-1 or q.find('LIMIT')!=-1 or q.find('GROUP BY')!=-1: # if query continues beyond conditions
q = q.split(condition_end) q = q.split(condition_end)
q = q[0] + condition_st + '(' + ' OR '.join(sl) + ') ' + condition_end + q[1] q = q[0] + condition_st + '(' + ' OR '.join(sl) + ') ' + condition_end + q[1]
else: else:
q = q + condition_st + '(' + ' OR '.join(sl) + ')' q = q + condition_st + '(' + ' OR '.join(sl) + ')'
return q return q


# execute server-side script from Search Criteria # execute server-side script from Search Criteria
@@ -111,7 +111,7 @@ def exec_report(code, res, colnames=[], colwidths=[], coltypes=[], coloptions=[]
for c in colnames: for c in colnames:
col_idx[c] = i col_idx[c] = i
i+=1 i+=1
# load globals (api) # load globals (api)
from webnotes import * from webnotes import *
from webnotes.utils import * from webnotes.utils import *
@@ -127,12 +127,12 @@ def exec_report(code, res, colnames=[], colwidths=[], coltypes=[], coloptions=[]
NEWLINE = '\n' NEWLINE = '\n'


exec str(code) exec str(code)
if out!=None: if out!=None:
res = out res = out


return res, style, header_html, footer_html, page_template return res, style, header_html, footer_html, page_template
# ==================================================================== # ====================================================================


def guess_type(m): def guess_type(m):
@@ -146,7 +146,7 @@ def guess_type(m):
return 'Date' return 'Date'
else: else:
return 'Data' return 'Data'
def build_description_simple(): def build_description_simple():
colnames, coltypes, coloptions, colwidths = [], [], [], [] colnames, coltypes, coloptions, colwidths = [], [], [], []


@@ -155,7 +155,7 @@ def build_description_simple():
coltypes.append(guess_type[m[0]]) coltypes.append(guess_type[m[0]])
coloptions.append('') coloptions.append('')
colwidths.append('100') colwidths.append('100')
return colnames, coltypes, coloptions, colwidths return colnames, coltypes, coloptions, colwidths


# ==================================================================== # ====================================================================
@@ -180,27 +180,27 @@ def build_description_standard(meta, tl):


if (not dt) and merged_meta.get(fn): if (not dt) and merged_meta.get(fn):
# no "AS" given, find type from merged description # no "AS" given, find type from merged description
desc = merged_meta[fn] desc = merged_meta[fn]
colnames.append(desc[0] or fn) colnames.append(desc[0] or fn)
coltypes.append(desc[1] or '') coltypes.append(desc[1] or '')
coloptions.append(desc[2] or '') coloptions.append(desc[2] or '')
colwidths.append(desc[3] or '100') colwidths.append(desc[3] or '100')
elif meta.get(dt,{}).has_key(fn): elif meta.get(dt,{}).has_key(fn):
# type specified for a multi-table join # type specified for a multi-table join
# usually from Report Builder # usually from Report Builder
desc = meta[dt][fn] desc = meta[dt][fn]
colnames.append(desc[0] or fn) colnames.append(desc[0] or fn)
coltypes.append(desc[1] or '') coltypes.append(desc[1] or '')
coloptions.append(desc[2] or '') coloptions.append(desc[2] or '')
colwidths.append(desc[3] or '100') colwidths.append(desc[3] or '100')
else: else:
# nothing found # nothing found
# guess # guess
colnames.append(fn) colnames.append(fn)
coltypes.append(guess_type(f[1])) coltypes.append(guess_type(f[1]))
coloptions.append('') coloptions.append('')
@@ -214,21 +214,21 @@ def build_description_standard(meta, tl):
def runquery(q='', ret=0, from_export=0): def runquery(q='', ret=0, from_export=0):
import webnotes.utils import webnotes.utils


formatted = cint(form.getvalue('formatted'))
formatted = cint(form.getvalue('formatted'))
# CASE A: Simple Query # CASE A: Simple Query
# -------------------- # --------------------
if form.getvalue('simple_query') or form.getvalue('is_simple'): if form.getvalue('simple_query') or form.getvalue('is_simple'):
q = form.getvalue('simple_query') or form.getvalue('query')
if not q: q = form.getvalue('simple_query') or form.getvalue('query')
if q.split()[0].lower() != 'select': if q.split()[0].lower() != 'select':
raise Exception, 'Query must be a SELECT' raise Exception, 'Query must be a SELECT'
as_dict = cint(form.getvalue('as_dict')) as_dict = cint(form.getvalue('as_dict'))
res = sql(q, as_dict = as_dict, as_list = not as_dict, formatted=formatted) res = sql(q, as_dict = as_dict, as_list = not as_dict, formatted=formatted)
# build colnames etc from metadata # build colnames etc from metadata
colnames, coltypes, coloptions, colwidths = [], [], [], [] colnames, coltypes, coloptions, colwidths = [], [], [], []
# CASE B: Standard Query # CASE B: Standard Query
# ----------------------- # -----------------------
else: else:
@@ -236,17 +236,17 @@ def runquery(q='', ret=0, from_export=0):


tl = get_sql_tables(q) tl = get_sql_tables(q)
meta = get_sql_meta(tl) meta = get_sql_meta(tl)
q = add_match_conditions(q, tl, webnotes.user.roles, webnotes.user.get_defaults()) q = add_match_conditions(q, tl, webnotes.user.roles, webnotes.user.get_defaults())
# replace special variables # replace special variables
q = q.replace('__user', session['user']) q = q.replace('__user', session['user'])
q = q.replace('__today', webnotes.utils.nowdate()) q = q.replace('__today', webnotes.utils.nowdate())
res = sql(q, as_list=1, formatted=formatted) res = sql(q, as_list=1, formatted=formatted)


colnames, coltypes, coloptions, colwidths = build_description_standard(meta, tl) colnames, coltypes, coloptions, colwidths = build_description_standard(meta, tl)
# run server script # run server script
# ----------------- # -----------------
style, header_html, footer_html, page_template = '', '', '', '' style, header_html, footer_html, page_template = '', '', '', ''
@@ -254,15 +254,15 @@ def runquery(q='', ret=0, from_export=0):
sc_id = form.getvalue('sc_id') sc_id = form.getvalue('sc_id')
from webnotes.model.code import get_code from webnotes.model.code import get_code
sc_details = webnotes.conn.sql("select module, standard, server_script from `tabSearch Criteria` where name=%s", sc_id)[0] sc_details = webnotes.conn.sql("select module, standard, server_script from `tabSearch Criteria` where name=%s", sc_id)[0]
if sc_details[1]!='No':
if sc_details[1]!='No':
code = get_code(sc_details[0], 'Search Criteria', sc_id, 'py') code = get_code(sc_details[0], 'Search Criteria', sc_id, 'py')
else: else:
code = sc_details[2] code = sc_details[2]
if code: if code:
filter_values = form.has_key('filter_values') and eval(form.getvalue('filter_values','')) or {} filter_values = form.has_key('filter_values') and eval(form.getvalue('filter_values','')) or {}
res, style, header_html, footer_html, page_template = exec_report(code, res, colnames, colwidths, coltypes, coloptions, filter_values, q, from_export) res, style, header_html, footer_html, page_template = exec_report(code, res, colnames, colwidths, coltypes, coloptions, filter_values, q, from_export)
out['colnames'] = colnames out['colnames'] = colnames
out['coltypes'] = coltypes out['coltypes'] = coltypes
out['coloptions'] = coloptions out['coloptions'] = coloptions
@@ -270,17 +270,17 @@ def runquery(q='', ret=0, from_export=0):
out['header_html'] = header_html out['header_html'] = header_html
out['footer_html'] = footer_html out['footer_html'] = footer_html
out['page_template'] = page_template out['page_template'] = page_template
if style: if style:
out['style'] = style out['style'] = style
# just the data - return # just the data - return
if ret==1: if ret==1:
return res
return res


out['values'] = res out['values'] = res


# return num of entries
# return num of entries
qm = form.has_key('query_max') and form.getvalue('query_max') or '' qm = form.has_key('query_max') and form.getvalue('query_max') or ''
if qm and qm.strip(): if qm and qm.strip():
if qm.split()[0].lower() != 'select': if qm.split()[0].lower() != 'select':
@@ -298,31 +298,31 @@ def runquery_csv():


# run query # run query
res = runquery(from_export = 1) res = runquery(from_export = 1)
q = form.getvalue('query') q = form.getvalue('query')
rep_name = form.getvalue('report_name') rep_name = form.getvalue('report_name')
if not form.has_key('simple_query'): if not form.has_key('simple_query'):


# Report Name # Report Name
if not rep_name: if not rep_name:
rep_name = get_sql_tables(q)[0] rep_name = get_sql_tables(q)[0]
if not rep_name: rep_name = 'DataExport' if not rep_name: rep_name = 'DataExport'
# Headings # Headings
heads = [] heads = []
rows = [[rep_name], out['colnames']] + out['values'] rows = [[rep_name], out['colnames']] + out['values']
from cStringIO import StringIO from cStringIO import StringIO
import csv import csv
f = StringIO() f = StringIO()
writer = csv.writer(f) writer = csv.writer(f)
for r in rows: for r in rows:
writer.writerow(r) writer.writerow(r)
f.seek(0) f.seek(0)
out['result'] = f.read() out['result'] = f.read()
out['type'] = 'csv' out['type'] = 'csv'


+ 9
- 9
cgi-bin/webnotes/widgets/search.py Zobrazit soubor

@@ -22,16 +22,16 @@ def getsearchfields():
webnotes.response['searchfields'] = [['name', 'ID', 'Data', '']] + res webnotes.response['searchfields'] = [['name', 'ID', 'Data', '']] + res


def make_query(fields, dt, key, txt, start, length): def make_query(fields, dt, key, txt, start, length):
return """SELECT %(fields)s
FROM `tab%(dt)s`
return """SELECT %(fields)s
FROM `tab%(dt)s`
WHERE `tab%(dt)s`.`%(key)s` LIKE '%(txt)s' AND `tab%(dt)s`.docstatus != 2 WHERE `tab%(dt)s`.`%(key)s` LIKE '%(txt)s' AND `tab%(dt)s`.docstatus != 2
ORDER BY `tab%(dt)s`.`%(key)s`
ORDER BY `tab%(dt)s`.`%(key)s`
DESC LIMIT %(start)s, %(len)s """ % { DESC LIMIT %(start)s, %(len)s """ % {
'fields': fields, 'fields': fields,
'dt': dt, 'dt': dt,
'key': key, 'key': key,
'txt': txt + '%', 'txt': txt + '%',
'start': start,
'start': start,
'len': length 'len': length
} }


@@ -48,7 +48,7 @@ def get_std_fields_list(dt, key):


def build_for_autosuggest(res): def build_for_autosuggest(res):
from webnotes.utils import cstr from webnotes.utils import cstr
results = [] results = []
for r in res: for r in res:
info = '' info = ''
@@ -56,10 +56,10 @@ def build_for_autosuggest(res):
info = ','.join([cstr(t) for t in r[1:]]) info = ','.join([cstr(t) for t in r[1:]])
if len(info) > 30: if len(info) > 30:
info = info[:30] + '...' info = info[:30] + '...'
results.append({'id':r[0], 'value':r[0], 'info':info}) results.append({'id':r[0], 'value':r[0], 'info':info})
return results return results
def scrub_custom_query(query, key, txt): def scrub_custom_query(query, key, txt):
if '%(key)s' in query: if '%(key)s' in query:
query = query.replace('%(key)s', key) query = query.replace('%(key)s', key)
@@ -74,7 +74,7 @@ def search_link():
txt = webnotes.form.getvalue('txt') txt = webnotes.form.getvalue('txt')
dt = webnotes.form.getvalue('dt') dt = webnotes.form.getvalue('dt')
query = webnotes.form.getvalue('query') query = webnotes.form.getvalue('query')
if query: if query:
res = webnotes.conn.sql(scrub_custom_query(query, 'name', txt)) res = webnotes.conn.sql(scrub_custom_query(query, 'name', txt))
else: else:
@@ -97,5 +97,5 @@ def search_widget():
query = scrub_custom_query(user_query, key, txt) query = scrub_custom_query(user_query, key, txt)
else: else:
query = make_query(', '.join(get_std_fields_list(dt, key)), dt, key, txt, webnotes.form.getvalue('start') or 0, webnotes.form.getvalue('page_len') or 50) query = make_query(', '.join(get_std_fields_list(dt, key)), dt, key, txt, webnotes.form.getvalue('start') or 0, webnotes.form.getvalue('page_len') or 50)
webnotes.widgets.query_builder.runquery(query) webnotes.widgets.query_builder.runquery(query)

+ 25
- 5
cgi-bin/webnotes/widgets/tags.py Zobrazit soubor

@@ -70,7 +70,7 @@ class DocTags:
def get_tags(self, dn): def get_tags(self, dn):
"""returns tag for a particular item""" """returns tag for a particular item"""
return webnotes.conn.get_value(self.dt, dn, '_user_tags') or ''
return webnotes.conn.get_value(self.dt, dn, '_user_tags', ignore=1) or ''


def create(self, tag): def create(self, tag):
try: try:
@@ -95,16 +95,32 @@ class DocTags:
self.update(dn, filter(lambda x:x!=tag, tl)) self.update(dn, filter(lambda x:x!=tag, tl))
TagCounter(self.dt).update(tag, -1) TagCounter(self.dt).update(tag, -1)


def remove_all(self, dn):
"""remove all user tags (call before delete)"""
tl = self.get_tags(dn).split(',')
tl = filter(lambda x:x, tl)
tc = TagCounter(self.dt)
for t in tl:
tc.update(t, -1)
self.update(dn, [])

def update(self, dn, tl): def update(self, dn, tl):
"""updates the _user_tag column in the table""" """updates the _user_tag column in the table"""


tl = list(set(filter(lambda x: x, tl)))
if not tl:
tags = ''
else:
tl = list(set(filter(lambda x: x, tl)))
tags = ',' + ','.join(tl)
try: try:
webnotes.conn.sql("update `tab%s` set _user_tags=%s where name=%s" % \ webnotes.conn.sql("update `tab%s` set _user_tags=%s where name=%s" % \
(self.dt,'%s','%s'), (',' + ','.join(tl), dn))
(self.dt,'%s','%s'), (tags , dn))
except Exception, e: except Exception, e:
if e.args[0]==1054: if e.args[0]==1054:
if not tags:
# no tags, nothing to do
return
self.setup() self.setup()
self.update(dn, tl) self.update(dn, tl)
else: raise e else: raise e
@@ -141,6 +157,8 @@ class TagCounter:
# if doctype cnt does not exist # if doctype cnt does not exist
# creates it for the first time # creates it for the first time
def update(self, tag, diff): def update(self, tag, diff):
if not tag:
return
"updates tag cnt for a doctype and tag" "updates tag cnt for a doctype and tag"
cnt = webnotes.conn.sql("select cnt from `_tag_cnt` where doctype=%s and tag=%s", (self.doctype, tag)) cnt = webnotes.conn.sql("select cnt from `_tag_cnt` where doctype=%s and tag=%s", (self.doctype, tag))


@@ -255,4 +273,6 @@ def get_top_tags(args=''):
get_item('tags-' + dt).set(tl, 60*60) get_item('tags-' + dt).set(tl, 60*60)
return tl return tl

def clear_tags(dt, dn):
DocTags(dt).remove_all(dn)

+ 17
- 14
js/form.compressed.js Zobrazit soubor

@@ -121,7 +121,8 @@ if(this.docname){if(!this.check_doc_perm())return;if(!this.setup_done)this.setup
if(this.doc.__islocal) if(this.doc.__islocal)
this.is_editable[this.docname]=1;this.editable=this.is_editable[this.docname];if(!this.doc.__archived&&(this.editable||(!this.editable&&this.meta.istable))){if(this.print_wrapper){$dh(this.print_wrapper);$ds(this.page_layout.wrapper);} this.is_editable[this.docname]=1;this.editable=this.is_editable[this.docname];if(!this.doc.__archived&&(this.editable||(!this.editable&&this.meta.istable))){if(this.print_wrapper){$dh(this.print_wrapper);$ds(this.page_layout.wrapper);}
if(!this.meta.istable){this.refresh_header();this.sidebar&&this.sidebar.refresh();} if(!this.meta.istable){this.refresh_header();this.sidebar&&this.sidebar.refresh();}
this.runclientscript('refresh');this.refresh_tabs();this.refresh_fields();this.refresh_dependency();this.refresh_footer();if(this.layout)this.layout.show();if(is_onload)
this.runclientscript('refresh');$(document).trigger('form_refresh')
this.refresh_tabs();this.refresh_fields();this.refresh_dependency();this.refresh_footer();if(this.layout)this.layout.show();if(is_onload)
this.runclientscript('onload_post_render',this.doctype,this.docname);}else{this.refresh_header();if(this.print_wrapper){this.refresh_print_layout();} this.runclientscript('onload_post_render',this.doctype,this.docname);}else{this.refresh_header();if(this.print_wrapper){this.refresh_print_layout();}
this.runclientscript('edit_status_changed');} this.runclientscript('edit_status_changed');}
if(!this.display)this.show_the_frm();if(!this.meta.in_dialog)page_body.change_to('Forms');}} if(!this.display)this.show_the_frm();if(!this.meta.in_dialog)page_body.change_to('Forms');}}
@@ -252,22 +253,25 @@ this.input.onchange=function(){if(me.editor){}else{me.set(me.input.value);}
me.run_trigger();} me.run_trigger();}
this.get_value=function(){if(me.editor){return me.editor.getContent();}else{return this.input.value;}} this.get_value=function(){if(me.editor){return me.editor.getContent();}else{return this.input.value;}}
if(this.df.fieldtype=='Text Editor'){$(me.input).tinymce({script_url:'js/tiny_mce_33/tiny_mce.js',theme:"advanced",plugins:"style,inlinepopups,table",extended_valid_elements:"div[id|dir|class|align|style]",width:'100%',height:'360px',theme_advanced_buttons1:"bold,italic,underline,strikethrough,hr,|,justifyleft,justifycenter,justifyright,|,formatselect,fontselect,fontsizeselect",theme_advanced_buttons2:"bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,code,|,forecolor,backcolor,|,tablecontrols",theme_advanced_buttons3:"",theme_advanced_toolbar_location:"top",theme_advanced_toolbar_align:"left",content_css:"js/tiny_mce_33/custom_content.css",oninit:function(){me.init_editor();}});}else{$y(me.input,{fontFamily:'Courier, Fixed'});}} if(this.df.fieldtype=='Text Editor'){$(me.input).tinymce({script_url:'js/tiny_mce_33/tiny_mce.js',theme:"advanced",plugins:"style,inlinepopups,table",extended_valid_elements:"div[id|dir|class|align|style]",width:'100%',height:'360px',theme_advanced_buttons1:"bold,italic,underline,strikethrough,hr,|,justifyleft,justifycenter,justifyright,|,formatselect,fontselect,fontsizeselect",theme_advanced_buttons2:"bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,code,|,forecolor,backcolor,|,tablecontrols",theme_advanced_buttons3:"",theme_advanced_toolbar_location:"top",theme_advanced_toolbar_align:"left",content_css:"js/tiny_mce_33/custom_content.css",oninit:function(){me.init_editor();}});}else{$y(me.input,{fontFamily:'Courier, Fixed'});}}
_f.CodeField.prototype.init_editor=function(){var me=this;this.editor=tinymce.get(this.myid);this.editor.onKeyUp.add(function(ed,e){me.set(ed.getContent());});this.editor.onPaste.add(function(ed,e){me.set(ed.getContent());});this.editor.onSetContent.add(function(ed,e){me.set(ed.getContent());});if(cur_frm)this.editor.setContent(locals[cur_frm.doctype][cur_frm.docname][this.df.fieldname]);}
_f.CodeField.prototype.init_editor=function(){var me=this;this.editor=tinymce.get(this.myid);this.editor.onKeyUp.add(function(ed,e){me.set(ed.getContent());});this.editor.onPaste.add(function(ed,e){me.set(ed.getContent());});this.editor.onSetContent.add(function(ed,e){me.set(ed.getContent());});var c=locals[cur_frm.doctype][cur_frm.docname][this.df.fieldname];if(cur_frm&&c){this.editor.setContent(c);}}
_f.CodeField.prototype.set_disp=function(val){$y(this.disp_area,{width:'90%'}) _f.CodeField.prototype.set_disp=function(val){$y(this.disp_area,{width:'90%'})
if(this.df.fieldtype=='Text Editor'){this.disp_area.innerHTML=val;}else{this.disp_area.innerHTML='<textarea class="code_text" readonly=1>'+val+'</textarea>';}} if(this.df.fieldtype=='Text Editor'){this.disp_area.innerHTML=val;}else{this.disp_area.innerHTML='<textarea class="code_text" readonly=1>'+val+'</textarea>';}}
_f.cur_grid_cell=null;_f.Grid=function(parent){} _f.cur_grid_cell=null;_f.Grid=function(parent){}
_f.Grid.prototype.init=function(parent,row_height){this.alt_row_bg='#F2F2FF';this.row_height=row_height;if(!row_height)this.row_height='26px';this.make_ui(parent);this.insert_column('','','Int','Sr','50px','',[1,0,0]);this.total_width=50;if(this.oninit)this.oninit();keypress_observers.push(this)}
_f.Grid.prototype.init=function(parent,row_height){this.col_idx_by_name={}
this.alt_row_bg='#F2F2FF';this.row_height=row_height;if(!row_height)this.row_height='26px';this.make_ui(parent);this.insert_column('','','Int','Sr','50px','',[1,0,0]);if(this.oninit)this.oninit();keypress_observers.push(this);}
_f.Grid.prototype.make_ui=function(parent){var ht=make_table($a(parent,'div'),1,2,'100%',['60%','40%']);this.main_title=$td(ht,0,0);this.main_title.className='columnHeading';$td(ht,0,1).style.textAlign='right';this.tbar_div=$a($td(ht,0,1),'div','grid_tbarlinks');if(isIE)$y(this.tbar_div,{width:'200px'});this.tbar_tab=make_table(this.tbar_div,1,4,'100%',['25%','25%','25%','25%']);this.wrapper=$a(parent,'div','grid_wrapper');$h(this.wrapper,cint(screen.width*0.5)+'px');this.head_wrapper=$a(this.wrapper,'div','grid_head_wrapper');this.head_tab=$a(this.head_wrapper,'table','grid_head_table');this.head_row=this.head_tab.insertRow(0);this.tab_wrapper=$a(this.wrapper,'div','grid_tab_wrapper');this.tab=$a(this.tab_wrapper,'table','grid_table');var me=this;this.wrapper.onscroll=function(){me.head_wrapper.style.top=me.wrapper.scrollTop+'px';}} _f.Grid.prototype.make_ui=function(parent){var ht=make_table($a(parent,'div'),1,2,'100%',['60%','40%']);this.main_title=$td(ht,0,0);this.main_title.className='columnHeading';$td(ht,0,1).style.textAlign='right';this.tbar_div=$a($td(ht,0,1),'div','grid_tbarlinks');if(isIE)$y(this.tbar_div,{width:'200px'});this.tbar_tab=make_table(this.tbar_div,1,4,'100%',['25%','25%','25%','25%']);this.wrapper=$a(parent,'div','grid_wrapper');$h(this.wrapper,cint(screen.width*0.5)+'px');this.head_wrapper=$a(this.wrapper,'div','grid_head_wrapper');this.head_tab=$a(this.head_wrapper,'table','grid_head_table');this.head_row=this.head_tab.insertRow(0);this.tab_wrapper=$a(this.wrapper,'div','grid_tab_wrapper');this.tab=$a(this.tab_wrapper,'table','grid_table');var me=this;this.wrapper.onscroll=function(){me.head_wrapper.style.top=me.wrapper.scrollTop+'px';}}
_f.Grid.prototype.show=function(){if(this.can_add_rows){$ds(this.tbar_div);}else{$dh(this.tbar_div);} _f.Grid.prototype.show=function(){if(this.can_add_rows){$ds(this.tbar_div);}else{$dh(this.tbar_div);}
$ds(this.wrapper);} $ds(this.wrapper);}
_f.Grid.prototype.hide=function(){$dh(this.wrapper);$dh(this.tbar_div);} _f.Grid.prototype.hide=function(){$dh(this.wrapper);$dh(this.tbar_div);}
_f.Grid.prototype.insert_column=function(doctype,fieldname,fieldtype,label,width,options,perm,reqd){var idx=this.head_row.cells.length;if(!width)width='100px';var col=this.head_row.insertCell(idx);col.doctype=doctype;col.fieldname=fieldname;col.fieldtype=fieldtype;col.innerHTML='<div>'+label+'</div>';col.label=label;if(reqd)
col.childNodes[0].style.color="#D22";this.total_width+=cint(width);$w(col,width);col.orig_width=col.style.width;col.options=options;col.perm=perm;}
_f.Grid.prototype.set_column_disp=function(label,show){for(var i=0;i<this.head_row.cells.length;i++){var c=this.head_row.cells[i];if(label&&(c.label==label||c.cur_label==label)){if(show){var w=c.orig_width;this.head_tab.style.width=(this.total_width+cint(w))+'px';this.tab.style.width=(this.total_width+cint(w))+'px';}else{var w='0px';this.head_tab.style.width=(this.total_width-cint(c.orig_width))+'px';this.tab.style.width=(this.total_width-cint(c.orig_width))+'px';}
$w(c,w);if(this.tab){for(var j=0;j<this.tab.rows.length;j++){var cell=this.tab.rows[j].cells[i];$w(cell,w);if(show){$ds(cell.div);cell.div.style.padding='2px';}
else{$dh(cell.div);cell.div.style.padding='0px';}}}
break;}}}
_f.Grid.prototype.append_row=function(idx,docname){if(!idx)idx=this.tab.rows.length;var row=this.tab.insertRow(idx);row.docname=docname;if(idx%2)var odd=true;else var odd=false;var me=this;for(var i=0;i<this.head_row.cells.length;i++){var cell=row.insertCell(i);var hc=this.head_row.cells[i];$w(cell,hc.style.width);cell.row=row;cell.grid=this;cell.className='grid_cell';cell.div=$a(cell,'div','grid_cell_div');if(this.row_height){cell.div.style.height=this.row_height;}
_f.Grid.prototype.insert_column=function(doctype,fieldname,fieldtype,label,width,options,perm,reqd){var idx=this.head_row.cells.length;if(!width)width='140px';if((width+'').slice(-2)!='px'){width=width+'px';}
var col=this.head_row.insertCell(idx);col.doctype=doctype;col.fieldname=fieldname;col.fieldtype=fieldtype;col.innerHTML='<div>'+label+'</div>';col.label=label;if(reqd)
col.childNodes[0].style.color="#D22";col.style.width=width;col.options=options;col.perm=perm;this.col_idx_by_name[fieldname]=idx;}
_f.Grid.prototype.reset_table_width=function(){var w=0;for(var i=0,len=this.head_row.cells.length;i<len;i++){w+=cint(this.head_row.cells[i].style.width);}
this.head_tab.style.width=w+'px';this.tab.style.width=w+'px';}
_f.Grid.prototype.set_column_disp=function(fieldname,show){var cidx=this.col_idx_by_name[fieldname];if(!cidx){msgprint('Trying to hide unknown column: '+fieldname);return;}
var disp=show?'table-cell':'none';this.head_row.cells[cidx].style.display=disp;for(var i=0,len=this.tab.rows.length;i<len;i++){var cell=this.tab.rows[i].cells[cidx];cell.style.display=disp;}
this.reset_table_width();}
_f.Grid.prototype.append_row=function(idx,docname){if(!idx)idx=this.tab.rows.length;var row=this.tab.insertRow(idx);row.docname=docname;if(idx%2)var odd=true;else var odd=false;var me=this;for(var i=0;i<this.head_row.cells.length;i++){var cell=row.insertCell(i);var hc=this.head_row.cells[i];cell.style.width=hc.style.width;cell.style.display=hc.style.display;cell.row=row;cell.grid=this;cell.className='grid_cell';cell.div=$a(cell,'div','grid_cell_div');if(this.row_height){cell.div.style.height=this.row_height;}
cell.div.cell=cell;cell.div.onclick=function(e){me.cell_click(this.cell,e);} cell.div.cell=cell;cell.div.onclick=function(e){me.cell_click(this.cell,e);}
if(odd){$bg(cell,this.alt_row_bg);cell.is_odd=1;cell.div.style.border='2px solid '+this.alt_row_bg;}else $bg(cell,'#FFF');if(!hc.fieldname)cell.div.style.cursor='default';} if(odd){$bg(cell,this.alt_row_bg);cell.is_odd=1;cell.div.style.border='2px solid '+this.alt_row_bg;}else $bg(cell,'#FFF');if(!hc.fieldname)cell.div.style.cursor='default';}
this.set_ht();return row;} this.set_ht();return row;}
@@ -299,7 +303,7 @@ return;if(!_f.cur_grid_cell)return;if(_f.cur_grid_cell.grid!=this)return;var ri=
_f.Grid.prototype.make_template=function(hc){hc.template=make_field(get_field(hc.doctype,hc.fieldname),hc.doctype,'',this.field.frm,true);hc.template.grid=this;} _f.Grid.prototype.make_template=function(hc){hc.template=make_field(get_field(hc.doctype,hc.fieldname),hc.doctype,'',this.field.frm,true);hc.template.grid=this;}
_f.Grid.prototype.append_rows=function(n){for(var i=0;i<n;i++)this.append_row();} _f.Grid.prototype.append_rows=function(n){for(var i=0;i<n;i++)this.append_row();}
_f.Grid.prototype.truncate_rows=function(n){for(var i=0;i<n;i++)this.tab.deleteRow(this.tab.rows.length-1);} _f.Grid.prototype.truncate_rows=function(n){for(var i=0;i<n;i++)this.tab.deleteRow(this.tab.rows.length-1);}
_f.Grid.prototype.set_data=function(data){this.cell_deselect();this.tab.style.width=this.total_width+'px';this.head_tab.style.width=this.total_width+'px';if(data.length>this.tab.rows.length)
_f.Grid.prototype.set_data=function(data){this.cell_deselect();this.reset_table_width();if(data.length>this.tab.rows.length)
this.append_rows(data.length-this.tab.rows.length);if(data.length<this.tab.rows.length) this.append_rows(data.length-this.tab.rows.length);if(data.length<this.tab.rows.length)
this.truncate_rows(this.tab.rows.length-data.length);for(var ridx=0;ridx<data.length;ridx++){this.refresh_row(ridx,data[ridx]);} this.truncate_rows(this.tab.rows.length-data.length);for(var ridx=0;ridx<data.length;ridx++){this.refresh_row(ridx,data[ridx]);}
if(this.can_add_rows&&this.make_newrow){this.make_newrow();} if(this.can_add_rows&&this.make_newrow){this.make_newrow();}
@@ -315,8 +319,7 @@ $td(t,0,0).isactive=1;$td(t,0,1).isactive=1;l.isactive=1;div.isactive=1;img.isac
_f.FormGrid.prototype.make_buttons=function(){var me=this;this.tbar_btns={};this.tbar_btns['Del']=this.make_tbar_link($td(this.tbar_tab,0,0),'Del',function(){me.delete_row();},'ic-round_minus');this.tbar_btns['Ins']=this.make_tbar_link($td(this.tbar_tab,0,1),'Ins',function(){me.insert_row();},'ic-round_plus');this.tbar_btns['Up']=this.make_tbar_link($td(this.tbar_tab,0,2),'Up',function(){me.move_row(true);},'ic-arrow_top');this.tbar_btns['Dn']=this.make_tbar_link($td(this.tbar_tab,0,3),'Dn',function(){me.move_row(false);},'ic-arrow_bottom');for(var i in this.btns) _f.FormGrid.prototype.make_buttons=function(){var me=this;this.tbar_btns={};this.tbar_btns['Del']=this.make_tbar_link($td(this.tbar_tab,0,0),'Del',function(){me.delete_row();},'ic-round_minus');this.tbar_btns['Ins']=this.make_tbar_link($td(this.tbar_tab,0,1),'Ins',function(){me.insert_row();},'ic-round_plus');this.tbar_btns['Up']=this.make_tbar_link($td(this.tbar_tab,0,2),'Up',function(){me.move_row(true);},'ic-arrow_top');this.tbar_btns['Dn']=this.make_tbar_link($td(this.tbar_tab,0,3),'Dn',function(){me.move_row(false);},'ic-arrow_bottom');for(var i in this.btns)
this.btns[i].isactive=true;} this.btns[i].isactive=true;}
_f.FormGrid.prototype.make_columns=function(){var gl=fields_list[this.field.df.options];if(!gl){alert('Table details not found "'+this.field.df.options+'"');} _f.FormGrid.prototype.make_columns=function(){var gl=fields_list[this.field.df.options];if(!gl){alert('Table details not found "'+this.field.df.options+'"');}
gl.sort(function(a,b){return a.idx-b.idx});var p=this.field.perm;for(var i=0;i<gl.length;i++){if(p[this.field.df.permlevel]&&p[this.field.df.permlevel][READ]&&(!gl[i].hidden)){this.insert_column(this.field.df.options,gl[i].fieldname,gl[i].fieldtype,gl[i].label,gl[i].width,gl[i].options,this.field.perm,gl[i].reqd);}}
for(var i=0;i<this.head_row.cells.length;i++){var c=this.head_row.cells[i];$w(c,cint(cint(c.style.width)/this.total_width*100)+'%')}}
gl.sort(function(a,b){return a.idx-b.idx});var p=this.field.perm;for(var i=0;i<gl.length;i++){if(p[this.field.df.permlevel]&&p[this.field.df.permlevel][READ]){this.insert_column(this.field.df.options,gl[i].fieldname,gl[i].fieldtype,gl[i].label,gl[i].width,gl[i].options,this.field.perm,gl[i].reqd);if(gl[i].hidden){this.set_column_disp(gl[i].fieldname,false);}}}}
_f.FormGrid.prototype.set_column_label=function(fieldname,label){for(var i=0;i<this.head_row.cells.length;i++){var c=this.head_row.cells[i];if(c.fieldname==fieldname){c.innerHTML='<div class="grid_head_div">'+label+'</div>';c.cur_label=label;break;}}} _f.FormGrid.prototype.set_column_label=function(fieldname,label){for(var i=0;i<this.head_row.cells.length;i++){var c=this.head_row.cells[i];if(c.fieldname==fieldname){c.innerHTML='<div class="grid_head_div">'+label+'</div>';c.cur_label=label;break;}}}
_f.FormGrid.prototype.refresh=function(){var docset=getchildren(this.doctype,this.field.frm.docname,this.field.df.fieldname,this.field.frm.doctype);var data=[];for(var i=0;i<docset.length;i++){locals[this.doctype][docset[i].name].idx=i+1;data[data.length]=docset[i].name;} _f.FormGrid.prototype.refresh=function(){var docset=getchildren(this.doctype,this.field.frm.docname,this.field.df.fieldname,this.field.frm.doctype);var data=[];for(var i=0;i<docset.length;i++){locals[this.doctype][docset[i].name].idx=i+1;data[data.length]=docset[i].name;}
this.set_data(data);} this.set_data(data);}
@@ -495,4 +498,4 @@ wn.widgets.form.file_upload_done=function(doctype,docname,fileid,filename,at_id,
fl.push(filename+','+fileid) fl.push(filename+','+fileid)
doc.file_list=fl.join('\n');} doc.file_list=fl.join('\n');}
else else
doc.file_list=filename+','+fileid;doc.modified=new_timestamp;var frm=frms[doctype];frm.attachments.dialog.hide();msgprint('File Uploaded Sucessfully.');frm.refresh();}
doc.file_list=filename+','+fileid;doc.modified=new_timestamp;var frm=frms[doctype];frm.attachments.dialog.hide();msgprint('File Uploaded Sucessfully.');frm.refresh();}

+ 1
- 1
js/webpage/page.js Zobrazit soubor

@@ -56,7 +56,7 @@ function render_page(page_name, menuitem) {
p.doc = pdoc; p.doc = pdoc;


if(script) { if(script) {
try { eval(script); } catch(e) { submit_error(e); }
eval(script);
} }


// change // change


+ 35
- 28
js/webpage/search.js Zobrazit soubor

@@ -21,8 +21,8 @@ function makeselector() {
['Button', 'Search'], ['Button', 'Search'],
['HTML', 'Help'], ['HTML', 'Help'],
['HTML', 'Result'] ['HTML', 'Result']
]);
]);
// search with // search with
var inp = d.widgets['Beginning With']; var inp = d.widgets['Beginning With'];
var field_sel = d.widgets['Search By']; var field_sel = d.widgets['Search By'];
@@ -39,7 +39,7 @@ function makeselector() {
} }
d.style = 'Link'; d.style = 'Link';
d.set_query_description() d.set_query_description()
if(!d.sel_type)d.sel_type = 'Value'; if(!d.sel_type)d.sel_type = 'Value';
d.set_title('Select a "'+ d.sel_type +'" for field "'+label+'"'); d.set_title('Select a "'+ d.sel_type +'" for field "'+label+'"');
} }
@@ -47,18 +47,18 @@ function makeselector() {
if(d.style!='Search') { if(d.style!='Search') {
d.rows['Result'].innerHTML =''; d.rows['Result'].innerHTML ='';
d.values_len = 0; d.values_len = 0;
}
}
d.style = 'Search'; d.style = 'Search';
if(d.input) { d.input = null; sel_type = null; } if(d.input) { d.input = null; sel_type = null; }
d.sel_type = get_label_doctype(dt); d.sel_type = get_label_doctype(dt);
d.set_title('Quick Search for ' + dt); d.set_title('Quick Search for ' + dt);
} }
inp.onkeydown = function(e) {
inp.onkeydown = function(e) {
if(isIE)var kc = window.event.keyCode; if(isIE)var kc = window.event.keyCode;
else var kc = e.keyCode; else var kc = e.keyCode;


if(kc==13) if(!btn.disabled)btn.onclick();
if(kc==13) if(!btn.disabled)btn.onclick();
} }


d.set_query_description = function() { d.set_query_description = function() {
@@ -68,18 +68,18 @@ function makeselector() {
d.rows['Help'].innerHTML ='' d.rows['Help'].innerHTML =''
} }
} }
d.onshow = function() {
d.onshow = function() {
if(d.set_doctype!=d.sel_type) { if(d.set_doctype!=d.sel_type) {
d.rows['Result'].innerHTML =''; d.rows['Result'].innerHTML ='';
d.values_len = 0; d.values_len = 0;
} }
inp.value = '';
inp.value = '';
if(d.input && d.input.txt.value) { if(d.input && d.input.txt.value) {
inp.value = d.input.txt.value; inp.value = d.input.txt.value;
} }
try{inp.focus();} catch(e){} try{inp.focus();} catch(e){}
if(d.input) d.input.set_get_query(); if(d.input) d.input.set_get_query();


// temp function to strip labels from search fields // temp function to strip labels from search fields
@@ -88,10 +88,10 @@ function makeselector() {
for(var i=0; i<lf.length; i++) l.push(lf[i][1]); for(var i=0; i<lf.length; i++) l.push(lf[i][1]);
return l; return l;
} }
// set fields // set fields
$ds(d.rows['Search By']); $ds(d.rows['Search By']);
if(search_fields[d.sel_type]) { if(search_fields[d.sel_type]) {
empty_select(field_sel); empty_select(field_sel);
add_sel_options(field_sel, get_sf_list(d.sel_type), 'ID'); add_sel_options(field_sel, get_sf_list(d.sel_type), 'ID');
@@ -121,8 +121,11 @@ function makeselector() {
this.set_working(); this.set_working();
d.set_doctype = d.sel_type; d.set_doctype = d.sel_type;
var q = ''; var q = '';
args = {};

if(d.input && d.input.get_query) { if(d.input && d.input.get_query) {
var doc = {}; var doc = {};
args.is_simple = 1;
if(cur_frm) doc = locals[cur_frm.doctype][cur_frm.docname]; if(cur_frm) doc = locals[cur_frm.doctype][cur_frm.docname];
var q = d.input.get_query(doc, d.input.doctype, d.input.docname); var q = d.input.get_query(doc, d.input.doctype, d.input.docname);
if(!q) { return ''; } if(!q) { return ''; }
@@ -131,21 +134,25 @@ function makeselector() {
// for field type, return field name // for field type, return field name
var get_sf_fieldname = function(v) { var get_sf_fieldname = function(v) {
var lf = search_fields[d.sel_type]; var lf = search_fields[d.sel_type];
// still loading options // still loading options
if(!lf) if(!lf)
return 'name' return 'name'
for(var i=0; i<lf.length; i++) if(lf[i][1]==v) return lf[i][0]; for(var i=0; i<lf.length; i++) if(lf[i][1]==v) return lf[i][0];
}

$c('webnotes.widgets.search.search_widget',
args = {
'txt':strip(inp.value)
,'doctype':d.sel_type
,'query':q
,'searchfield':get_sf_fieldname(sel_val(field_sel))
},
}

// build args
$.extend(args, {
'txt':strip(inp.value)
,'doctype':d.sel_type
,'query':q
,'searchfield':get_sf_fieldname(sel_val(field_sel))
});

// run the query
$c('webnotes.widgets.search.search_widget',
args,
function(r, rtxt) { function(r, rtxt) {
btn.done_working(); btn.done_working();
if(r.coltypes)r.coltypes[0]='Link'; // first column must always be selectable even if it is not a link if(r.coltypes)r.coltypes[0]='Link'; // first column must always be selectable even if it is not a link
@@ -153,7 +160,7 @@ function makeselector() {
d.set_result(r); d.set_result(r);
}, function() { btn.done_working(); }); }, function() { btn.done_working(); });
} }
d.set_result = function(r) { d.set_result = function(r) {
d.rows['Result'].innerHTML = ''; d.rows['Result'].innerHTML = '';
var c = $a(d.rows['Result'],'div','comment',{paddingBottom:'4px',marginBottom:'4px',borderBottom:'1px solid #CCC', marginLeft:'4px'}); var c = $a(d.rows['Result'],'div','comment',{paddingBottom:'4px',marginBottom:'4px',borderBottom:'1px solid #CCC', marginLeft:'4px'});
@@ -178,8 +185,8 @@ function makeselector() {
for(var j=1; j<r.values[i].length; j++) cl.push(r.values[i][j]); for(var j=1; j<r.values[i].length; j++) cl.push(r.values[i][j]);
var c = $a(div,'div','comment',{marginTop:'2px'}); c.innerHTML = cl.join(', '); var c = $a(div,'div','comment',{marginTop:'2px'}); c.innerHTML = cl.join(', ');
} }
} }
selector = d;
selector = d;
} }

+ 5
- 0
js/widgets/form/form.js Zobrazit soubor

@@ -622,6 +622,11 @@ _f.Frm.prototype.refresh = function(docname) {
// call trigger // call trigger
this.runclientscript('refresh'); this.runclientscript('refresh');
// trigger global trigger
// to use this
// $(docuemnt).bind('form_refresh', function() { })
$(document).trigger('form_refresh')
// tabs // tabs
this.refresh_tabs(); this.refresh_tabs();


+ 4
- 1
js/widgets/form/form_fields.js Zobrazit soubor

@@ -468,7 +468,10 @@ _f.CodeField.prototype.init_editor = function() {
}); });
// reset content // reset content
if(cur_frm) this.editor.setContent(locals[cur_frm.doctype][cur_frm.docname][this.df.fieldname]);
var c = locals[cur_frm.doctype][cur_frm.docname][this.df.fieldname];
if(cur_frm && c) {
this.editor.setContent(c);
}
} }


_f.CodeField.prototype.set_disp = function(val) { _f.CodeField.prototype.set_disp = function(val) {


+ 6
- 7
js/widgets/form/form_grid.js Zobrazit soubor

@@ -67,16 +67,15 @@ _f.FormGrid.prototype.make_columns = function() {


var p = this.field.perm; var p = this.field.perm;
for(var i=0;i<gl.length;i++) { for(var i=0;i<gl.length;i++) {
if(p[this.field.df.permlevel] && p[this.field.df.permlevel][READ] && (!gl[i].hidden)) { // if read
if(p[this.field.df.permlevel] && p[this.field.df.permlevel][READ]) { // if read
this.insert_column(this.field.df.options, gl[i].fieldname, gl[i].fieldtype, gl[i].label, gl[i].width, gl[i].options, this.field.perm, gl[i].reqd); this.insert_column(this.field.df.options, gl[i].fieldname, gl[i].fieldtype, gl[i].label, gl[i].width, gl[i].options, this.field.perm, gl[i].reqd);
// hide it even if it is hidden at start..
// so that it can be brought back once
if(gl[i].hidden) {
this.set_column_disp(gl[i].fieldname, false);
}
} }
} }
// set width as percent
for(var i=0;i<this.head_row.cells.length; i++) {
var c = this.head_row.cells[i];
$w(c,cint(cint(c.style.width) / this.total_width * 100)+'%')
}
} }


_f.FormGrid.prototype.set_column_label = function(fieldname, label) { _f.FormGrid.prototype.set_column_label = function(fieldname, label) {


+ 42
- 38
js/widgets/form/grid.js Zobrazit soubor

@@ -5,6 +5,7 @@ _f.Grid = function(parent) { }


_f.Grid.prototype.init = function(parent, row_height) { _f.Grid.prototype.init = function(parent, row_height) {
this.col_idx_by_name = {}
this.alt_row_bg = '#F2F2FF'; this.alt_row_bg = '#F2F2FF';
this.row_height = row_height; this.row_height = row_height;


@@ -14,11 +15,10 @@ _f.Grid.prototype.init = function(parent, row_height) {
// Sr No // Sr No
this.insert_column('', '', 'Int', 'Sr', '50px', '', [1,0,0]); this.insert_column('', '', 'Int', 'Sr', '50px', '', [1,0,0]);
this.total_width = 50;
if(this.oninit)this.oninit(); if(this.oninit)this.oninit();
keypress_observers.push(this)
keypress_observers.push(this);
} }


_f.Grid.prototype.make_ui = function(parent) { _f.Grid.prototype.make_ui = function(parent) {
@@ -62,8 +62,10 @@ _f.Grid.prototype.hide = function() {
_f.Grid.prototype.insert_column = function(doctype, fieldname, fieldtype, label, width, options, perm, reqd) { _f.Grid.prototype.insert_column = function(doctype, fieldname, fieldtype, label, width, options, perm, reqd) {
var idx = this.head_row.cells.length; var idx = this.head_row.cells.length;
if(!width)width = '100px';
if(!width)width = '140px';
if((width+'').slice(-2)!='px') {
width= width + 'px';
}
var col = this.head_row.insertCell(idx); var col = this.head_row.insertCell(idx);
col.doctype = doctype; // for report (fields may be from diff doctypes) col.doctype = doctype; // for report (fields may be from diff doctypes)
@@ -74,43 +76,42 @@ _f.Grid.prototype.insert_column = function(doctype, fieldname, fieldtype, label,
if(reqd) if(reqd)
col.childNodes[0].style.color = "#D22"; col.childNodes[0].style.color = "#D22";
this.total_width += cint(width);
$w(col, width);
col.orig_width = col.style.width;
col.style.width = width;
col.options = options; col.options = options;
col.perm = perm; col.perm = perm;


this.col_idx_by_name[fieldname] = idx;
} }


_f.Grid.prototype.set_column_disp = function(label, show) {
//alert(label);
for(var i=0; i<this.head_row.cells.length; i++) {
var c = this.head_row.cells[i];
if(label && (c.label == label || c.cur_label == label)) {
//alert(c.orig_width);
if(show) {
var w = c.orig_width;
this.head_tab.style.width = (this.total_width + cint(w)) + 'px';
this.tab.style.width = (this.total_width + cint(w)) + 'px';
} else {
var w = '0px';
this.head_tab.style.width = (this.total_width - cint(c.orig_width)) + 'px';
this.tab.style.width = (this.total_width - cint(c.orig_width)) + 'px';
}
$w(c, w);
// change width of table too
if(this.tab) {
for(var j=0; j<this.tab.rows.length; j++) {
var cell = this.tab.rows[j].cells[i];
$w(cell, w);
if(show) { $ds(cell.div); cell.div.style.padding = '2px'; }
else { $dh(cell.div); cell.div.style.padding = '0px'; }
}
}
break;
}
_f.Grid.prototype.reset_table_width = function() {
var w = 0;
for(var i=0, len=this.head_row.cells.length; i<len; i++) {
w += cint(this.head_row.cells[i].style.width);
}
this.head_tab.style.width = w + 'px';
this.tab.style.width = w + 'px';
}

_f.Grid.prototype.set_column_disp = function(fieldname, show) {
var cidx = this.col_idx_by_name[fieldname];
if(!cidx) {
msgprint('Trying to hide unknown column: ' + fieldname);
return;
} }
var disp = show ? 'table-cell' : 'none';

// head
this.head_row.cells[cidx].style.display = disp;

// body
for(var i=0, len=this.tab.rows.length; i<len; i++) {
var cell = this.tab.rows[i].cells[cidx];
cell.style.display = disp;
}
// reset table width
this.reset_table_width();
} }


_f.Grid.prototype.append_row = function(idx, docname) { _f.Grid.prototype.append_row = function(idx, docname) {
@@ -125,7 +126,11 @@ _f.Grid.prototype.append_row = function(idx, docname) {
for(var i=0; i<this.head_row.cells.length; i++){ for(var i=0; i<this.head_row.cells.length; i++){
var cell = row.insertCell(i); var cell = row.insertCell(i);
var hc = this.head_row.cells[i]; var hc = this.head_row.cells[i];
$w(cell, hc.style.width);
// ape style of head
cell.style.width = hc.style.width;
cell.style.display = hc.style.display;
cell.row = row; cell.row = row;
cell.grid = this; cell.grid = this;
cell.className = 'grid_cell'; cell.className = 'grid_cell';
@@ -394,8 +399,7 @@ _f.Grid.prototype.set_data = function(data) {
this.cell_deselect(); this.cell_deselect();


// set table widths // set table widths
this.tab.style.width = this.total_width + 'px';
this.head_tab.style.width = this.total_width + 'px';
this.reset_table_width();


// append if reqd // append if reqd
if(data.length > this.tab.rows.length) if(data.length > this.tab.rows.length)


+ 7
- 1
js/widgets/report_builder/report_builder.js Zobrazit soubor

@@ -507,7 +507,13 @@ _r.ReportBuilder.prototype.set_sort_options = function(l) {
empty_select(this.dt.sort_sel); empty_select(this.dt.sort_sel);
if(l) sl = add_lists(l, this.orig_sort_list)
if(l) sl = add_lists(l, this.orig_sort_list);
// no sorts, add one
if(!l.length) {
l.push(['ID', 'name'])
}
for(var i=0; i<sl.length; i++) { for(var i=0; i<sl.length; i++) {
this.dt.add_sort_option(sl[i][0], sl[i][1]); this.dt.add_sort_option(sl[i][0], sl[i][1]);
} }


+ 3
- 3
js/wnf.compressed.js Zobrazit soubor

@@ -1034,11 +1034,11 @@ $ds(d.rows['Search By']);if(search_fields[d.sel_type]){empty_select(field_sel);a
d.onhide=function(){if(page_body.wntoolbar) d.onhide=function(){if(page_body.wntoolbar)
page_body.wntoolbar.search_sel.disabled=0;if(d.input&&d.input.txt) page_body.wntoolbar.search_sel.disabled=0;if(d.input&&d.input.txt)
d.input.txt.onchange()} d.input.txt.onchange()}
btn.onclick=function(){if(this.disabled)return;this.set_working();d.set_doctype=d.sel_type;var q='';if(d.input&&d.input.get_query){var doc={};if(cur_frm)doc=locals[cur_frm.doctype][cur_frm.docname];var q=d.input.get_query(doc,d.input.doctype,d.input.docname);if(!q){return'';}}
btn.onclick=function(){if(this.disabled)return;this.set_working();d.set_doctype=d.sel_type;var q='';args={};if(d.input&&d.input.get_query){var doc={};args.is_simple=1;if(cur_frm)doc=locals[cur_frm.doctype][cur_frm.docname];var q=d.input.get_query(doc,d.input.doctype,d.input.docname);if(!q){return'';}}
var get_sf_fieldname=function(v){var lf=search_fields[d.sel_type];if(!lf) var get_sf_fieldname=function(v){var lf=search_fields[d.sel_type];if(!lf)
return'name' return'name'
for(var i=0;i<lf.length;i++)if(lf[i][1]==v)return lf[i][0];} for(var i=0;i<lf.length;i++)if(lf[i][1]==v)return lf[i][0];}
$c('webnotes.widgets.search.search_widget',args={'txt':strip(inp.value),'doctype':d.sel_type,'query':q,'searchfield':get_sf_fieldname(sel_val(field_sel))},function(r,rtxt){btn.done_working();if(r.coltypes)r.coltypes[0]='Link';d.values_len=r.values.length;d.set_result(r);},function(){btn.done_working();});}
$.extend(args,{'txt':strip(inp.value),'doctype':d.sel_type,'query':q,'searchfield':get_sf_fieldname(sel_val(field_sel))});$c('webnotes.widgets.search.search_widget',args,function(r,rtxt){btn.done_working();if(r.coltypes)r.coltypes[0]='Link';d.values_len=r.values.length;d.set_result(r);},function(){btn.done_working();});}
d.set_result=function(r){d.rows['Result'].innerHTML='';var c=$a(d.rows['Result'],'div','comment',{paddingBottom:'4px',marginBottom:'4px',borderBottom:'1px solid #CCC',marginLeft:'4px'});if(r.values.length==50) d.set_result=function(r){d.rows['Result'].innerHTML='';var c=$a(d.rows['Result'],'div','comment',{paddingBottom:'4px',marginBottom:'4px',borderBottom:'1px solid #CCC',marginLeft:'4px'});if(r.values.length==50)
c.innerHTML='Showing max 50 results. Use filters to narrow down your search';else c.innerHTML='Showing max 50 results. Use filters to narrow down your search';else
c.innerHTML='Showing '+r.values.length+' resuts.';var w=$a(d.rows['Result'],'div','',{height:'240px',overflow:'auto',margin:'4px'});for(var i=0;i<r.values.length;i++){var div=$a(w,'div','',{marginBottom:'4px',paddingBottom:'4px',borderBottom:'1px dashed #CCC'});var l=$a($a(div,'div'),'span','link_type');l.innerHTML=r.values[i][0];l.link_name=r.values[i][0];l.dt=r.coloptions[0];if(d.input) c.innerHTML='Showing '+r.values.length+' resuts.';var w=$a(d.rows['Result'],'div','',{height:'240px',overflow:'auto',margin:'4px'});for(var i=0;i<r.values.length;i++){var div=$a(w,'div','',{marginBottom:'4px',paddingBottom:'4px',borderBottom:'1px dashed #CCC'});var l=$a($a(div,'div'),'span','link_type');l.innerHTML=r.values[i][0];l.link_name=r.values[i][0];l.dt=r.coloptions[0];if(d.input)
@@ -1130,7 +1130,7 @@ pages['_home']=this;return this;}
function render_page(page_name,menuitem){if(!page_name)return;if((!locals['Page'])||(!locals['Page'][page_name])){loadpage('_home');return;} function render_page(page_name,menuitem){if(!page_name)return;if((!locals['Page'])||(!locals['Page'][page_name])){loadpage('_home');return;}
var pdoc=locals['Page'][page_name];if(pdoc.style)set_style(pdoc.style) var pdoc=locals['Page'][page_name];if(pdoc.style)set_style(pdoc.style)
if(pdoc.stylesheet){set_style(locals.Stylesheet[pdoc.stylesheet].stylesheet);stylesheets.push(pdoc.stylesheet);} if(pdoc.stylesheet){set_style(locals.Stylesheet[pdoc.stylesheet].stylesheet);stylesheets.push(pdoc.stylesheet);}
var p=new Page(page_name,pdoc._Page__content?pdoc._Page__content:pdoc.content);var script=pdoc.__script?pdoc.__script:pdoc.script;p.doc=pdoc;if(script){try{eval(script);}catch(e){submit_error(e);}}
var p=new Page(page_name,pdoc._Page__content?pdoc._Page__content:pdoc.content);var script=pdoc.__script?pdoc.__script:pdoc.script;p.doc=pdoc;if(script){eval(script);}
page_body.change_to(page_name);try{if(pscript['onload_'+page_name])pscript['onload_'+page_name]();}catch(e){submit_error(e);} page_body.change_to(page_name);try{if(pscript['onload_'+page_name])pscript['onload_'+page_name]();}catch(e){submit_error(e);}
return p;} return p;}
function refresh_page(page_name){var fn=function(r,rt){render_page(page_name)} function refresh_page(page_name){var fn=function(r,rt){render_page(page_name)}


Načítá se…
Zrušit
Uložit