Merge branch 'master' of github.com:webnotes/erpnext

This commit is contained in:
Nabin Hait
2012-09-18 11:19:59 +05:30
932 changed files with 6667 additions and 7046 deletions

View File

@@ -14,6 +14,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals
import webnotes
@webnotes.whitelist()

View File

@@ -7,6 +7,7 @@
# This script can be executed from lib/wnf.py using
# lib/wnf.py --cleanup-data
from __future__ import unicode_literals
import sys
sys.path.append("lib/py")
sys.path.append(".")

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Please edit this list and import only required elements
from __future__ import unicode_literals
import webnotes
from webnotes.model.doc import Document

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -1,99 +0,0 @@
# ERPNext - web based ERP (http://erpnext.com)
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Please edit this list and import only required elements
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.model import db_exists
from webnotes.model.doc import Document, addchild, getchildren, make_autoname
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 import session, form, is_testing, msgprint, errprint
set = webnotes.conn.set
sql = webnotes.conn.sql
get_value = webnotes.conn.get_value
in_transaction = webnotes.conn.in_transaction
convert_to_lists = webnotes.conn.convert_to_lists
# -----------------------------------------------------------------------------------------
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
# bulk rename
def do_rename(self):
import csv
data = csv.reader(self.get_csv_data().splitlines())
updated = 0
msgprint(self.doc.rename_doctype)
if self.doc.rename_doctype == 'Account':
for line in data:
if len(line)==2:
rec = sql("select tc.abbr, ta.name from `tabAccount` ta, `tabCompany` tc where ta.company = tc.name and ta.account_name = %s", line[0], as_dict=1)
if rec:
new_name = line[1] + ' - ' + rec[0]['abbr']
webnotes.conn.begin()
webnotes.model.rename(self.doc.rename_doctype, rec[0]['name'], new_name)
sql("update `tabAccount` set account_name = '%s' where name = '%s'" %(line[1],new_name))
webnotes.conn.commit()
updated += 1
else:
msgprint("[Ignored] Incorrect format: %s" % str(line))
else:
for line in data:
if len(line)==2:
webnotes.conn.begin()
obj = get_obj(self.doc.rename_doctype, line[0])
if hasattr(obj, 'on_rename'):
obj.on_rename(line[1],line[0])
webnotes.model.rename(self.doc.rename_doctype, line[0], line[1])
webnotes.conn.commit()
updated += 1
else:
msgprint("[Ignored] Incorrect format: %s" % str(line))
msgprint("<b>%s</b> items updated" % updated)
# Update CSV data
def get_csv_data(self):
if not self.doc.file_list:
msgprint("File not attached!")
raise Exception
fid = self.doc.file_list.split(',')[1]
from webnotes.utils import file_manager
fn, content = file_manager.get_file(fid)
# NOTE: Don't know why this condition exists
if not isinstance(content, basestring) and hasattr(content, 'tostring'):
content = content.tostring()
return content

View File

@@ -1,126 +0,0 @@
# DocType, Bulk Rename Tool
[
# These values are common in all dictionaries
{
'creation': '2012-03-27 14:36:46',
'docstatus': 0,
'modified': '2012-03-27 14:45:46',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
# These values are common for all DocType
{
'_last_update': u'1322549701',
'allow_attach': 1,
'autoname': u'field:rename_doctype',
'colour': u'White:FFF',
'default_print_format': u'Standard',
'doctype': 'DocType',
'is_submittable': 1,
'module': u'Utilities',
'name': '__common__',
'section_style': u'Simple',
'show_in_menu': 0,
'version': 8
},
# These values are common for all DocField
{
'doctype': u'DocField',
'name': '__common__',
'parent': u'Bulk Rename Tool',
'parentfield': u'fields',
'parenttype': u'DocType'
},
# These values are common for all DocPerm
{
'doctype': u'DocPerm',
'name': '__common__',
'parent': u'Bulk Rename Tool',
'parentfield': u'permissions',
'parenttype': u'DocType',
'read': 1,
'role': u'System Manager'
},
# DocType, Bulk Rename Tool
{
'doctype': 'DocType',
'name': u'Bulk Rename Tool'
},
# DocPerm
{
'create': 1,
'doctype': u'DocPerm',
'permlevel': 0,
'submit': 1,
'write': 1
},
# DocPerm
{
'doctype': u'DocPerm',
'permlevel': 1
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'rename_doctype',
'fieldtype': u'Data',
'label': u'Rename DocType',
'options': u'Suggest',
'permlevel': 0,
'reqd': 1
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'file_list',
'fieldtype': u'Text',
'hidden': 1,
'label': u'File List',
'no_copy': 1,
'permlevel': 1
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'rename',
'fieldtype': u'Button',
'label': u'Rename',
'options': u'do_rename',
'permlevel': 0
},
# DocField
{
'depends_on': u'eval:doc.amended_from',
'description': u'The date at which current entry is corrected in the system.',
'doctype': u'DocField',
'fieldname': u'amendment_date',
'fieldtype': u'Date',
'label': u'Amendment Date',
'no_copy': 1,
'permlevel': 0,
'print_hide': 1
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'amended_from',
'fieldtype': u'Link',
'label': u'Amended From',
'no_copy': 1,
'options': u'Sales Invoice',
'permlevel': 1,
'print_hide': 1
}
]

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Please edit this list and import only required elements
from __future__ import unicode_literals
import webnotes
from webnotes.model.doc import Document

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Please edit this list and import only required elements
from __future__ import unicode_literals
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

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -14,6 +14,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -14,6 +14,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals
class DocType:
def __init__(self, d, dl=[]):
self.doc, self.doclist = d, dl

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Please edit this list and import only required elements
from __future__ import unicode_literals
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

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Please edit this list and import only required elements
from __future__ import unicode_literals
import webnotes
from webnotes.utils import cint, flt, load_json, nowdate, cstr

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Please edit this list and import only required elements
from __future__ import unicode_literals
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

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -1,156 +0,0 @@
// ERPNext - web based ERP (http://erpnext.com)
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// question toolbar
// contains - voting widget / tag list and user info / timestamp
// By XXXXXX on YYYYY
KBItemToolbar = function(args, kb) {
$.extend(this, args);
var me = this;
this.make = function() {
this.wrapper = $a(this.parent, 'div', '', {});
this.line1 = $a(this.wrapper, 'div', '', {color: '#888', fontSize:'11px', margin:'7px 0px'});
this.make_timestamp();
this.make_answers();
if(this.with_tags)
this.make_tags();
this.setup_del();
}
this.make_timestamp = function() {
this.line1.innerHTML = repl('By %(name)s | %(when)s', {
name: wn.utils.full_name(this.det.first_name, this.det.last_name),
when: wn.datetime.comment_when(this.det.modified)
});
// allow system manager to delete questions / answers
if(has_common(user_roles, ['Administrator', 'System Manager'])) {
this.line1.innerHTML += ' | <a style="cursor:pointer;"\
class="del-link">delete</a>';
}
}
this.make_answers = function() {
if(this.doctype=='Question') {
if(this.det.answers==0) {
this.line1.innerHTML += ' | no answers';
} else if(this.det.answers==1) {
this.line1.innerHTML += ' | 1 answer';
} else {
this.line1.innerHTML += ' | '+this.det.answers+' answers';
}
}
}
this.make_tags = function() {
this.line1.innerHTML += ' | '
this.tags_area = $a(this.line1, 'span', 'kb-tags')
this.tags = new TagList(this.tags_area,
this.det._user_tags && (this.det._user_tags.split(',')),
this.doctype, this.det.name, 0, kb.set_tag_filter)
}
this.setup_del = function() {
$(this.line1).find('.del-link').click(function() {
console.log(1);
this.innerHTML = 'deleting...';
this.disabled = 1;
$c_page('utilities', 'questions', 'delete', {
dt: me.doctype, dn: me.det.name}, function(r,rt) {
// reload the list
kb.list.run()
});
});
}
this.make();
}
// displays an editable text,
// needs parent, text, disp_class, inp_class
// dt, dn
EditableText = function(args) {
$.extend(this, args);
var me = this;
me.$w = $(repl('<div class="ed-text">\
<div class="ed-text-display %(disp_class)s"></div>\
<a class="ed-text-edit" style="cursor: pointer; float: right; margin-top: -16px;">[edit]</a>\
<textarea class="ed-text-input %(inp_class)s hide"></textarea>\
<div class="help hide"><br>Formatted as <a href="#markdown-reference"\
target="_blank">markdown</a></div>\
<button class="btn btn-small btn-info hide ed-text-save">Save</button>\
<a class="ed-text-cancel hide" style="cursor: pointer;">Cancel</a>\
</div>', args)).appendTo(me.parent);
this.set_display = function(txt) {
me.$w.find('.ed-text-display').html(wn.markdown(txt));
me.text = txt;
}
this.set_display(me.text);
if(me.height) me.$w.find('.ed-text-input').css('height', me.height);
// edit
me.$w.find('.ed-text-edit').click(function() {
me.$w.find('.ed-text-input').val(me.text);
me.show_as_input();
})
// save button - save the new text
me.$w.find('.ed-text-save').click(
function() {
var v = me.$w.find('.ed-text-input').val();
// check if text is written
if(!v) {
msgprint('Please write something!');
return;
}
var btn = this;
$(btn).set_working();
$c_page('utilities', 'question_view', 'update_item', {
dt: me.dt, dn: me.dn, fn: me.fieldname, text: v
},
function(r) {
$(btn).done_working();
if(r.exc) {msgprint(r.exc); return; }
me.set_display(v);
me.show_as_text();
});
}
)
// cancel button
me.$w.find('.ed-text-cancel').click(function() {
me.show_as_text();
})
this.show_as_text = function() {
me.$w.find('.ed-text-display, .ed-text-edit').toggle(true);
me.$w.find('.ed-text-input, .ed-text-save, .ed-text-cancel, .help').toggle(false);
}
this.show_as_input = function() {
me.$w.find('.ed-text-display, .ed-text-edit').toggle(false);
me.$w.find('.ed-text-input, .ed-text-save, .ed-text-cancel, .help').toggle(true);
}
}

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -1 +1,2 @@
from __future__ import unicode_literals
import webnotes

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -14,6 +14,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals
import webnotes
@webnotes.whitelist()

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -14,6 +14,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals
import webnotes
from webnotes.utils import load_json, cstr, now

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -215,4 +215,4 @@ KBQuestion = function(parent, det, kb) {
this.make()
}
wn.require('js/kb_common.js');
wn.require('js/app/kb_common.js');

View File

@@ -14,6 +14,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals
import webnotes
from webnotes.utils import load_json, cint, cstr

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -23,10 +23,6 @@
float: right;
}
.todoitem .ref_link {
line-height: 18px;
}
.todoitem .description {
padding: 3px 0px;
display: inline-block;

View File

@@ -79,10 +79,10 @@ erpnext.todo.ToDoItem = Class.extend({
parent_list += " div.todo-content";
if(todo.reference_name && todo.reference_type) {
todo.link = repl('<a href="#!Form/%(reference_type)s/%(reference_name)s">\
todo.link = repl('<br><a href="#!Form/%(reference_type)s/%(reference_name)s">\
%(reference_type)s: %(reference_name)s</a>', todo);
} else if(todo.reference_type) {
todo.link = repl('<a href="#!List/%(reference_type)s">\
todo.link = repl('<br><a href="#!List/%(reference_type)s">\
%(reference_type)s</a>', todo);
} else {
todo.link = '';
@@ -95,12 +95,10 @@ erpnext.todo.ToDoItem = Class.extend({
<div class="todoitem">\
<span class="label %(labelclass)s">%(priority)s</span>\
<span class="description">\
<span class="popup-on-click">\
<span class="help" style="margin-right: 7px">%(userdate)s</span>\
%(fullname)s%(desc)s\
</span>\
<span class="ref_link"><br>\
%(link)s</span>\
<span class="popup-on-click"><a href="#"> [edit]</a></span>\
<span class="ref_link">%(link)s</span>\
</span>\
<span class="close-span"><a href="#" class="close">&times;</a></span>\
</div>\

View File

@@ -14,6 +14,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals
import webnotes
from webnotes.model.doc import Document

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -1,13 +0,0 @@
<div class="layout-wrapper">
<a class="close" onclick="window.history.back();">&times;</a>
<h1>Users</h1>
<hr>
<div class="help" style="margin-bottom: 20px">Add, disable, delete users and change their roles, passwords and security settings</div>
<div style="margin: 11px">
<button class="btn btn-small add-user" onclick="wn.pages.users.add_user()"
><i class="icon-plus"></i> Add User</button>
</div>
<div class="users-area">
</div>
<div style="clear: both"></div>
</div>

View File

@@ -16,26 +16,37 @@
$.extend(wn.pages.users, {
onload: function(wrapper) {
wn.pages.users.profiles = {};
wn.pages.users.refresh();
wn.pages.users.setup();
wn.pages.users.role_editor = new erpnext.RoleEditor();
var w = wn.pages.users;
wn.ui.make_app_page({
parent: w,
title: "Users",
single_column: true
});
w.profiles = {};
w.refresh();
w.setup();
w.role_editor = new erpnext.RoleEditor();
},
setup: function() {
wn.pages.users.appframe.add_button('+ Add User', function() {
wn.pages.users.add_user();
});
// set roles
$('.users-area').on('click', '.btn.user-roles', function() {
var w = wn.pages.users;
$(w).on('click', '.btn.user-roles', function() {
var uid = $(this).parent().parent().attr('data-name');
wn.pages.users.role_editor.show(uid);
});
// settings
$('.users-area').on('click', '.btn.user-settings', function() {
$(w).on('click', '.btn.user-settings', function() {
var uid = $(this).parent().parent().attr('data-name');
wn.pages.users.show_settings(uid);
});
// delete
$('.users-area').on('click', 'a.close', function() {
$(w).on('click', 'a.close', function() {
$card = $(this).parent();
var uid = $card.attr('data-name');
$card.css('opacity', 0.6);
@@ -55,7 +66,7 @@ $.extend(wn.pages.users, {
wn.call({
method:'utilities.page.users.users.get',
callback: function(r, rt) {
$('.users-area').empty();
$(wn.pages.users).find('.layout-main').empty();
for(var i in r.message) {
var p = r.message[i];
wn.pages.users.profiles[p.name] = p;
@@ -91,7 +102,7 @@ $.extend(wn.pages.users, {
if(!data.enabled)
data.delete_html = '<a class="close" title="delete">&times;</a>';
$('.users-area').append(repl('<div class="user-card" data-name="%(name)s">\
$(wn.pages.users).find('.layout-main').append(repl('<div class="user-card" data-name="%(name)s">\
%(delete_html)s\
<img src="%(imgsrc)s">\
<div class="user-info">\
@@ -103,7 +114,7 @@ $.extend(wn.pages.users, {
</div>', data));
if(!data.enabled) {
$('.users-area .user-card:last')
$(wn.pages.users).find('.layout-main .user-card:last')
.addClass('disabled')
.find('.user-fullname').html('Disabled');
}
@@ -225,8 +236,7 @@ $.extend(wn.pages.users, {
var me = wn.pages.users;
var active_users = $('.user-card:not(.disabled)');
if(wn.boot.max_users && (active_users.length >= wn.boot.max_users)) {
msgprint(repl("Alas! <br />\
You already have <b>%(active_users)s</b> active users, \
msgprint(repl("You already have <b>%(active_users)s</b> active users, \
which is the maximum number that you are currently allowed to add. <br /><br /> \
So, to add more users, you can:<br /> \
1. <b>Upgrade to the unlimited users plan</b>, or<br /> \

View File

@@ -14,6 +14,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals
import webnotes
import json
@@ -30,9 +31,13 @@ def get(arg=None):
@webnotes.whitelist()
def get_roles(arg=None):
"""return all roles"""
"""return all roles except standard"""
return _get_roles(webnotes.form_dict['uid'])
def _get_roles(user):
"""return all roles except standard"""
return [r[0] for r in webnotes.conn.sql("""select name from tabRole
where name not in ('Administrator', 'Guest', 'All') order by name""")]
where name not in ('Administrator', 'Guest', 'All') order by name""", user)]
@webnotes.whitelist()
def get_user_roles(arg=None):

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -14,6 +14,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals
import webnotes
from webnotes.utils import load_json, cint, cstr, flt, get_defaults
from webnotes.model.doc import Document, addchild, getchildren