@@ -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]]) | |||||
@@ -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'); | |||||
} |
@@ -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' |
@@ -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 | |||||
} | |||||
} | |||||
] | ] |
@@ -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', | ||||
@@ -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'); | ||||
}) | }) | ||||
@@ -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 |
@@ -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 | ||||
# -------------- | # -------------- | ||||
@@ -255,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. | ||||
@@ -266,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): | ||||
@@ -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' | ||||
#================================================================================= | #================================================================================= | ||||
@@ -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) | ||||
@@ -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)) |
@@ -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() | ||||
@@ -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]]) |
@@ -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 | ||||
@@ -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 | ||||
@@ -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() | ||||
@@ -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' | ||||
@@ -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) |
@@ -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) |
@@ -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();} |
@@ -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 | ||||
@@ -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; | |||||
} | } |
@@ -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(); | ||||
@@ -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) { | ||||
@@ -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) { | ||||
@@ -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) | ||||
@@ -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]); | ||||
} | } | ||||
@@ -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)} | ||||