Explorar el Código

added query report and cleaned up wn.ui.Dialog

version-14
Rushabh Mehta hace 12 años
padre
commit
9d2c3bee22
Se han modificado 21 ficheros con 503 adiciones y 125 borrados
  1. +2
    -2
      core/doctype/customize_form/customize_form.js
  2. +1
    -1
      core/doctype/profile/profile.js
  3. +43
    -34
      core/doctype/report/report.txt
  4. +0
    -0
      core/page/query_report/__init__.py
  5. +11
    -0
      core/page/query_report/query_report.js
  6. +28
    -0
      core/page/query_report/query_report.txt
  7. +1
    -0
      public/build.json
  8. +1
    -3
      public/js/legacy/widgets/dialog.js
  9. +0
    -1
      public/js/legacy/widgets/form/form_fields.js
  10. +1
    -1
      public/js/legacy/widgets/tags.js
  11. +1
    -1
      public/js/legacy/wn/widgets/form/assign_to.js
  12. +1
    -1
      public/js/legacy/wn/widgets/form/attachments.js
  13. +2
    -2
      public/js/lib/slickgrid/slick.grid.css
  14. +1
    -1
      public/js/wn/misc/about.js
  15. +63
    -76
      public/js/wn/ui/dialog.js
  16. +1
    -1
      public/js/wn/ui/filters.js
  17. +1
    -1
      public/js/wn/ui/toolbar/selector_dialog.js
  18. +258
    -0
      public/js/wn/views/query_report.js
  19. +9
    -0
      webnotes/__init__.py
  20. +40
    -0
      webnotes/client.py
  21. +38
    -0
      webnotes/widgets/query_report.py

+ 2
- 2
core/doctype/customize_form/customize_form.js Ver fichero

@@ -87,7 +87,7 @@ cur_frm.cscript.hide_allow_attach = function(doc, dt, dn) {
}

cur_frm.confirm = function(msg, doc, dt, dn) {
var d = new wn.widgets.Dialog({
var d = new wn.ui.Dialog({
title: 'Reset To Defaults',
width: 500
});
@@ -132,7 +132,7 @@ cur_frm.add_fields_help = function() {
<a id="fields_help" class="link_type">Help</a>\
</div>');
$('#fields_help').click(function() {
var d = new wn.widgets.Dialog({
var d = new wn.ui.Dialog({
title: 'Help: Field Properties',
width: 600
});


+ 1
- 1
core/doctype/profile/profile.js Ver fichero

@@ -147,7 +147,7 @@ wn.RoleEditor = Class.extend({
},
make_perm_dialog: function() {
this.perm_dialog = new wn.widgets.Dialog({
this.perm_dialog = new wn.ui.Dialog({
title:'Role Permissions',
width: 500
});


+ 43
- 34
core/doctype/report/report.txt Ver fichero

@@ -3,28 +3,28 @@

# These values are common in all dictionaries
{
'creation': '2012-05-15 12:14:24',
'docstatus': 0,
'modified': '2012-06-13 18:50:36',
'modified_by': u'Administrator',
'owner': u'Administrator'
u'creation': '2012-06-13 19:07:26',
u'docstatus': 0,
u'modified': '2012-10-01 14:00:02',
u'modified_by': u'Administrator',
u'owner': u'Administrator'
},

# These values are common for all DocType
{
'allow_trash': 1,
'colour': u'White:FFF',
'doctype': 'DocType',
u'doctype': u'DocType',
'module': u'Core',
'name': '__common__',
u'name': u'__common__',
'section_style': u'Simple',
'version': 1
},

# These values are common for all DocField
{
'doctype': u'DocField',
'name': '__common__',
u'doctype': u'DocField',
u'name': u'__common__',
'parent': u'Report',
'parentfield': u'fields',
'parenttype': u'DocType',
@@ -33,8 +33,8 @@

# These values are common for all DocPerm
{
'doctype': u'DocPerm',
'name': '__common__',
u'doctype': u'DocPerm',
u'name': u'__common__',
'parent': u'Report',
'parentfield': u'permissions',
'parenttype': u'DocType',
@@ -44,50 +44,59 @@

# DocType, Report
{
'doctype': 'DocType',
'name': u'Report'
u'doctype': u'DocType',
u'name': u'Report'
},

# DocField
{
u'doctype': u'DocField',
'fieldname': u'query',
'fieldtype': u'Text',
'label': u'Query'
},

# DocField
{
u'doctype': u'DocField',
'fieldname': u'json',
'fieldtype': u'Text',
'label': u'JSON'
},

# DocField
{
u'doctype': u'DocField',
'fieldname': u'ref_doctype',
'fieldtype': u'Data',
'label': u'Ref DocType'
},

# DocPerm
{
'cancel': 1,
'doctype': u'DocPerm',
u'doctype': u'DocPerm',
'role': u'Administrator'
},

# DocPerm
{
'cancel': 1,
'doctype': u'DocPerm',
'role': u'System Manager'
u'doctype': u'DocPerm',
'role': u'System Manager',
'write': 1
},

# DocPerm
{
'cancel': 1,
'doctype': u'DocPerm',
u'doctype': u'DocPerm',
'role': u'Report Manager'
},

# DocPerm
{
'doctype': u'DocPerm',
u'doctype': u'DocPerm',
'role': u'All'
},

# DocField
{
'doctype': u'DocField',
'fieldname': u'json',
'fieldtype': u'Text',
'label': u'JSON'
},

# DocField
{
'doctype': u'DocField',
'fieldname': u'ref_doctype',
'fieldtype': u'Data',
'label': u'Ref DocType'
}
]

+ 0
- 0
core/page/query_report/__init__.py Ver fichero


+ 11
- 0
core/page/query_report/query_report.js Ver fichero

@@ -0,0 +1,11 @@
wn.pages['query-report'].onload = function(wrapper) {
wn.ui.make_app_page({
parent: wrapper,
title: 'Query Report',
single_column: true
});
wn.test = new wn.views.QueryReport({
parent: wrapper,
})
}

+ 28
- 0
core/page/query_report/query_report.txt Ver fichero

@@ -0,0 +1,28 @@
# Page, query-report
[

# These values are common in all dictionaries
{
u'creation': '2012-10-01 10:35:32',
u'docstatus': 0,
u'modified': '2012-10-01 10:35:32',
u'modified_by': u'Administrator',
u'owner': u'Administrator'
},

# These values are common for all Page
{
u'doctype': u'Page',
'module': u'Core',
u'name': u'__common__',
'page_name': u'query-report',
'standard': u'Yes',
'title': u'Query Report'
},

# Page, query-report
{
u'doctype': u'Page',
u'name': u'query-report'
}
]

+ 1
- 0
public/build.json Ver fichero

@@ -141,6 +141,7 @@
"lib/public/js/wn/views/formview.js",
"lib/public/js/wn/views/reportview.js",
"lib/public/js/wn/views/grid_report.js",
"lib/public/js/wn/views/query_report.js",
"lib/public/js/legacy/widgets/dialog.js",
"lib/public/js/legacy/widgets/layout.js",
"lib/public/js/legacy/widgets/tabbedpage.js",


+ 1
- 3
public/js/legacy/widgets/dialog.js Ver fichero

@@ -28,7 +28,7 @@ var cur_dialog;
var top_index=91;

function Dialog(w, h, title, content) {
this.make({width:w, title:title});
$.extend(this, new wn.ui.Dialog({width:w, title:title}));

if(content)this.make_body(content);

@@ -39,8 +39,6 @@ function Dialog(w, h, title, content) {
this.first_button = false;
}

Dialog.prototype = new wn.widgets.Dialog()

Dialog.prototype.make_body = function(content) {
this.rows = {}; this.widgets = {};
for(var i in content) this.make_row(content[i]);


+ 0
- 1
public/js/legacy/widgets/form/form_fields.js Ver fichero

@@ -357,7 +357,6 @@ _f.CodeField.prototype.make_input = function() {
//this.input = $a(this.input_area, 'div', '', {position:'relative', width: '90%', height:'300px'});

wn.require('lib/js/lib/ace/ace.js');
//wn.require('lib/js/lib/ace/theme-twilight.js');
$(this.input_area).css('border','1px solid #aaa');
this.pre = $a(this.input_area, 'pre', '', {


+ 1
- 1
public/js/legacy/widgets/tags.js Ver fichero

@@ -100,7 +100,7 @@ TagList.prototype.make_add_tag = function() {
TagList.prototype.make_tag_dialog = function() {
var me = this;
var d = new wn.widgets.Dialog({
var d = new wn.ui.Dialog({
title: 'Add a tag',
width: 400,
fields: [


+ 1
- 1
public/js/legacy/wn/widgets/form/assign_to.js Ver fichero

@@ -72,7 +72,7 @@ wn.widgets.form.sidebar.AssignTo = Class.extend({
add: function() {
var me = this;
if(!me.dialog) {
me.dialog = new wn.widgets.Dialog({
me.dialog = new wn.ui.Dialog({
title: 'Add to To Do',
width: 350,
fields: [


+ 1
- 1
public/js/legacy/wn/widgets/form/attachments.js Ver fichero

@@ -71,7 +71,7 @@ wn.widgets.form.sidebar.Attachments = function(parent, sidebar, doctype, docname
// using the file mamanger
this.add_attachment = function() {
if(!this.dialog) {
this.dialog = new wn.widgets.Dialog({
this.dialog = new wn.ui.Dialog({
title:'Add Attachment',
width: 400
})


+ 2
- 2
public/js/lib/slickgrid/slick.grid.css Ver fichero

@@ -51,11 +51,11 @@ classes should alter those!
}

.slick-sort-indicator-desc {
background: url(images/sort-desc.gif);
background: url(lib/js/lib/slickgrid/images/sort-desc.gif);
}

.slick-sort-indicator-asc {
background: url(images/sort-asc.gif);
background: url(lib/js/lib/slickgrid/images/sort-asc.gif);
}

.slick-resizable-handle {


+ 1
- 1
public/js/wn/misc/about.js Ver fichero

@@ -25,7 +25,7 @@
wn.provide('wn.ui.misc');
wn.ui.misc.about = function() {
if(!wn.ui.misc.about_dialog) {
var d = new wn.widgets.Dialog({title:'About wnframework'})
var d = new wn.ui.Dialog({title:'About wnframework'})
$(d.body).html(repl("<div style='padding: 20px'<p><b>Application Name:</b> %(name)s</p>\
<p><b>Version:</b> %(version)s</p>\


+ 63
- 76
public/js/wn/ui/dialog.js Ver fichero

@@ -22,23 +22,32 @@

// opts { width, height, title, fields (like docfields) }

wn.widgets.FieldGroup = function() {
this.first_button = false;
this.make_fields = function(body, fl) {
wn.provide('wn.ui');

wn.ui.FieldGroup = Class.extend({
init: function(opts) {
$.extend(this, opts);
this.make_fields();
this.catch_enter_as_submit();
},
first_button: false,
make_fields: function() {
if(!window.make_field) {
// called in website, load some libs
wn.require('css/fields.css');
wn.require('js/fields.js');
}
$y(this.body, {padding:'11px'});
$(this.parent).css({padding:'11px'});
this.fields_dict = {}; // reset
for(var i=0; i<fl.length; i++) {
var df = fl[i];
for(var i=0; i< this.fields.length; i++) {
var df = this.fields[i];
if(!df.fieldname && df.label) {
df.fieldname = df.label.replace(/ /g, '_').toLowerCase();
}
var div = $a(body, 'div', '', {margin:'6px 0px'})
if(!df.fieldtype) df.fieldtype="Data";
var div = $a(this.parent, 'div', '', {margin:'6px 0px'})
f = make_field(df, null, div, null);
f.not_in_form = 1;
this.fields_dict[df.fieldname] = f
@@ -50,19 +59,16 @@ wn.widgets.FieldGroup = function() {
this.first_button = true;
}
}
}
this.catch_enter_as_submit = function() {
},
catch_enter_as_submit: function() {
var me = this;
$(this.body).find(':input[type="text"], :input[type="password"]').keypress(function(e) {
$(this.parent).find(':input[type="text"], :input[type="password"]').keypress(function(e) {
if(e.which==13) {
$(me.body).find('.btn-info:first').click();
$(me.parent).find('.btn-info:first').click();
}
})
}
/* get values */
this.get_values = function() {
},
get_values: function() {
var ret = {};
var errors = [];
for(var key in this.fields_dict) {
@@ -79,27 +85,22 @@ wn.widgets.FieldGroup = function() {
return null;
}
return ret;
}
/* set field value */
this.set_value = function(key, val){
},
set_value: function(key, val){
var f = this.fields_dict[key];
if(f) {
f.set_input(val);
f.refresh_mandatory();
}
}

/* set values from a dict */
this.set_values = function(dict) {
},
set_values: function(dict) {
for(var key in dict) {
if(this.fields_dict[key]) {
this.set_value(key, dict[key]);
}
}
}
this.clear = function() {
},
clear: function() {
for(key in this.fields_dict) {
var f = this.fields_dict[key];
if(f) {
@@ -107,50 +108,48 @@ wn.widgets.FieldGroup = function() {
}
}
}
}

wn.widgets.Dialog = function(opts) {
this.display = false;
this.make = function(opts) {
if(opts) {
this.opts = opts;
$.extend(this, opts);
}
if(!this.opts.width) this.opts.width = 480;
});

wn.ui.Dialog = wn.ui.FieldGroup.extend({
init: function(opts) {
this.display = false;
if(!opts.width) opts.width = 480;

$.extend(this, opts);
this.make();
// init fields
if(this.fields) {
this.parent = this.body
this._super({});
}
},
make: function() {
if(!$('#dialog-container').length) {
$('<div id="dialog-container">').appendTo('body');
}
this.wrapper = $('<div class="dialog_wrapper">').appendTo('#dialog-container').get(0);
this.wrapper = $('<div class="dialog_wrapper">')
.appendTo('#dialog-container').get(0);

if(this.opts.width)
this.wrapper.style.width = this.opts.width + 'px';
if(this.width)
this.wrapper.style.width = this.width + 'px';

this.make_head();
this.body = $a(this.wrapper, 'div', 'dialog_body');
if(this.opts.fields) {
this.make_fields(this.body, this.opts.fields);
this.catch_enter_as_submit();
}
}
this.make_head = function() {
},
make_head: function() {
var me = this;
this.appframe = new wn.ui.AppFrame(this.wrapper);
this.appframe.$titlebar.find('.close').unbind('click').click(function() {
if(me.oncancel)me.oncancel(); me.hide();
});
this.set_title(this.opts.title);
}
this.set_title = function(t) {
this.set_title(this.title);
},
set_title: function(t) {
this.appframe.$titlebar.find('.appframe-title').html(t || '');
}
this.set_postion = function() {
},
set_postion: function() {
// place it at the center
this.wrapper.style.left = (($(window).width() - cint(this.wrapper.style.width))/2) + 'px';
this.wrapper.style.top = ($(window).scrollTop() + 60) + 'px';
@@ -158,10 +157,8 @@ wn.widgets.Dialog = function(opts) {
// place it on top
top_index++;
$y(this.wrapper,{zIndex:top_index});
}
/** show the dialog */
this.show = function() {
},
show: function() {
// already live, do nothing
if(this.display) return;

@@ -182,9 +179,8 @@ wn.widgets.Dialog = function(opts) {
// focus on first input
$(this.wrapper).find(':input:first').focus();
}

this.hide = function() {
},
hide: function() {
// call onhide
if(this.onhide) this.onhide();

@@ -195,20 +191,11 @@ wn.widgets.Dialog = function(opts) {
// flags
this.display = false;
cur_dialog = null;
}
this.no_cancel = function() {
},
no_cancel: function() {
this.appframe.$titlebar.find('.close').toggle(false);
}

if(opts) this.make(opts);

}

wn.widgets.Dialog.prototype = new wn.widgets.FieldGroup();

wn.provide('wn.ui');
wn.ui.Dialog = wn.widgets.Dialog
});

// close open dialogs on ESC
$(document).bind('keydown', function(e) {


+ 1
- 1
public/js/wn/ui/filters.js Ver fichero

@@ -185,7 +185,7 @@ wn.ui.Filter = Class.extend({
parent: me.field.df.parent,
} : {}

var df = me.fieldselect.fields_by_name[tablename][fieldname];
var df = copy_dict(me.fieldselect.fields_by_name[tablename][fieldname]);
this.set_fieldtype(df, fieldtype);
// called when condition is changed,


+ 1
- 1
public/js/wn/ui/toolbar/selector_dialog.js Ver fichero

@@ -41,7 +41,7 @@ wn.ui.toolbar.SelectorDialog = Class.extend({
this.bind_events();
},
make_dialog: function() {
this.dialog = new wn.widgets.Dialog({
this.dialog = new wn.ui.Dialog({
title: this.opts.title,
width: 300,
fields: [


+ 258
- 0
public/js/wn/views/query_report.js Ver fichero

@@ -0,0 +1,258 @@
// Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com)
//
// MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

wn.provide("wn.views");

wn.views.QueryReport = Class.extend({
init: function(opts) {
$.extend(this, opts);
// globalify for slickgrid
this.appframe = this.parent.appframe;
this.parent.query_report = this;
this.make();
},
slickgrid_options: {
enableColumnReorder: false,
showHeaderRow: true,
headerRowHeight: 30,
explicitInitialization: true,
multiColumnSort: true
},
make: function() {
this.wrapper = $("<div>").appendTo($(this.parent).find(".layout-main"));
$('<div class="query-edit" style="display: none;">\
<div class="query-form" style="width: 60%; float: left;"></div>\
<div class="help" style="width: 30%; float: left; margin-left: 15px;">\
<b>Query Rules:</b><br>\
<ol>\
<li>Define column names as JSON objects to specifiy types and links:\
<li>Labels are automatically defined from column headings.\
To define for doctype, set `{"label": "Customer", "type": "Link", "options":"Customer"}`\
<li>For DataTypes, use suffix: eg. `{"label":"Qty", "type":"Float"}`\
<li>For Links, use suffix "link": eg. `customer:float`\
</ol>\
</div>\
<hr style="clear: both;" />\
</div>\
<div class="result-area" style="height:400px; \
border: 1px solid #aaa;"></div>').appendTo(this.wrapper);

this.make_query_form();
this.make_toolbar();
this.import_slickgrid();
},
make_toolbar: function() {
var me = this;
this.appframe.add_button("Run", function() {
// Run
wn.call({
method: "webnotes.widgets.query_report.run",
args: {
query: $(me.wrapper).find("textarea").val()
},
callback: function(r) {
me.refresh(r.message.result, r.message.columns);
}
})
}).addClass("btn-success");
if(in_list(user_roles, "System Manager")) {
// Edit
this.appframe.add_button("Edit", function() {
me.wrapper.find(".query-edit").slideToggle();
});
// Save
this.appframe.add_button("Save", function() {
var doc = me.query_form.get_values();
if(!doc) return;
doc.doctype = "Report"
wn.call({
method:"webnotes.client.save",
args: {
doclist: [doc],
},
callback: function(r) {
//wn.set_route("query-form", doc.name);
}
})
});
}
},
make_query_form: function() {
this.query_form = new wn.ui.FieldGroup({
parent: $(this.wrapper).find(".query-form").get(0),
fields: [
{label:"Report Name", reqd: 1, fieldname:"name"},
{label:"Based on", fieldtype:"Link", options:"DocType",
fieldname: "ref_doctype",
reqd:1, description:"Permissions will be based on this DocType"},
{label:"Query", fieldtype: "Text", reqd: 1}
]
});
$(this.query_form.fields_dict.query.input).css({
width: "100%",
height: "300px",
"font-weight": "Normal",
"font-family": "Monaco, Courier, Fixed"
});
},
import_slickgrid: function() {
wn.require('lib/js/lib/slickgrid/slick.grid.css');
wn.require('lib/js/lib/slickgrid/slick-default-theme.css');
wn.require('lib/js/lib/slickgrid/jquery.event.drag.min.js');
wn.require('lib/js/lib/slickgrid/slick.core.js');
wn.require('lib/js/lib/slickgrid/slick.grid.js');
wn.require('lib/js/lib/slickgrid/slick.dataview.js');
wn.dom.set_style('.slick-cell { font-size: 12px; }\
.slick-headerrow-column {\
background: #87ceeb;\
text-overflow: clip;\
-moz-box-sizing: border-box;\
box-sizing: border-box;\
}\
.slick-headerrow-column input {\
margin: 0;\
padding: 0;\
width: 100%;\
height: 100%;\
-moz-box-sizing: border-box;\
box-sizing: border-box;}');
},
refresh: function(result, columns) {
this.make_data(result, columns);
this.make_columns(columns);
this.render(result, columns);
},
render: function(result, columns) {
this.columnFilters = {};
this.make_dataview();
this.id = wn.dom.set_unique_id($(this.wrapper.find(".result-area")).get(0));
this.grid = new Slick.Grid("#"+this.id, this.dataView, this.columns,
this.slickgrid_options);
this.setup_header_row();
this.grid.init();
this.setup_sort();
},
make_columns: function(columns) {
this.columns = [{id: "_id", field: "_id", name: "Sr No", width: 60}]
.concat($.map(columns, function(c) {
return {id: c, field: c, sortable: true,
name: toTitle(c.replace(/_/g, " ")) }
}));
},
make_data: function(result, columns) {
this.data = $.map(result, function(row, row_idx) {
var newrow = {};
$.each(columns, function(i, col) {
newrow[col] = row[i];
});
newrow._id = row_idx + 1;
newrow.id = newrow.name ? newrow.name : ("_" + newrow._id);
return newrow;
});
},
make_dataview: function() {
// initialize the model
this.dataView = new Slick.Data.DataView({ inlineFilters: true });
this.dataView.beginUpdate();
this.dataView.setItems(this.data);
this.dataView.setFilter(this.inline_filter);
this.dataView.endUpdate();
var me = this;
this.dataView.onRowCountChanged.subscribe(function (e, args) {
me.grid.updateRowCount();
me.grid.render();
});

this.dataView.onRowsChanged.subscribe(function (e, args) {
me.grid.invalidateRows(args.rows);
me.grid.render();
});
},
inline_filter: function (item) {
var me = wn.container.page.query_report;
for (var columnId in me.columnFilters) {
if (columnId !== undefined && me.columnFilters[columnId] !== "") {
var c = me.grid.getColumns()[me.grid.getColumnIndex(columnId)];
if (!me.compare_values(item[c.field], me.columnFilters[columnId])) {
return false;
}
}
}
return true;
},
compare_values: function(value, filter) {
value = value + "";
value = value.toLowerCase();
filter = filter.toLowerCase();
if(filter.length < value.length) {
return filter==value.substr(0, filter.length)
}
},
setup_header_row: function() {
var me = this;
$(this.grid.getHeaderRow()).delegate(":input", "change keyup", function (e) {
var columnId = $(this).data("columnId");
if (columnId != null) {
me.columnFilters[columnId] = $.trim($(this).val());
me.dataView.refresh();
}
});

this.grid.onHeaderRowCellRendered.subscribe(function(e, args) {
$(args.node).empty();
$("<input type='text'>")
.data("columnId", args.column.id)
.val(me.columnFilters[args.column.id])
.appendTo(args.node);
});
},
setup_sort: function() {
var me = this;
this.grid.onSort.subscribe(function (e, args) {
var cols = args.sortCols;

me.data.sort(function (dataRow1, dataRow2) {
for (var i = 0, l = cols.length; i < l; i++) {
var field = cols[i].sortCol.field;
var sign = cols[i].sortAsc ? 1 : -1;
var value1 = dataRow1[field], value2 = dataRow2[field];
var result = (value1 == value2 ? 0 : (value1 > value2 ? 1 : -1)) * sign;
if (result != 0) {
return result;
}
}
return 0;
});
me.dataView.beginUpdate();
me.dataView.setItems(me.data);
me.dataView.endUpdate();
me.dataView.refresh();
});
}
})

+ 9
- 0
webnotes/__init__.py Ver fichero

@@ -247,6 +247,15 @@ def get_roles(user=None, with_standard=True):
return roles

def has_permission(doctype, ptype):
"""check if user has permission"""
return conn.sql("""select name from tabDocPerm p
where p.parent = %s
and ifnull(p.`%s`,0) = 1
and ifnull(p.permlevel,0) = 0
and p.role in (select `role` from tabUserRole where `parent`=%s)
""" % ("%s", ptype, "%s"), (doctype, session.user))

def generate_hash():
"""Generates random hash for session id"""
import hashlib, time

+ 40
- 0
webnotes/client.py Ver fichero

@@ -0,0 +1,40 @@
# Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com)
#
# MIT License (MIT)
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#

from __future__ import unicode_literals
import webnotes
import json

@webnotes.whitelist()
def save():
"""insert or update from form query"""
doclist = json.loads(webnotes.form_dict.doclist)
from webnotes.model.doclist import DocList
if not webnotes.has_permission(doclist[0]["doctype"], "write"):
webnotes.msgprint("No Write Permission", raise_exception=True)
doclistobj = DocList(doclist)
doclistobj.save()

webntoes.msgprint("%s: '%s' saved" % form.doctype, form.name)

+ 38
- 0
webnotes/widgets/query_report.py Ver fichero

@@ -0,0 +1,38 @@
# Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com)
#
# MIT License (MIT)
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#

from __future__ import unicode_literals
import webnotes

@webnotes.whitelist()
def run():
query = webnotes.form_dict.query
if not query.lower().startswith("select"):
webnotes.msgprint("Query must be a SELECT", raise_exception=True)
result = [list(t) for t in webnotes.conn.sql(query)]
columns = webnotes.conn.get_description()
return {
"result": result,
"columns": [c[0] for c in columns]
}

Cargando…
Cancelar
Guardar