Merge branch 'master' into dev
diff --git a/erpnext/accounts/doctype/account/account.js b/erpnext/accounts/doctype/account/account.js
index d5300c7..75cc9e5 100644
--- a/erpnext/accounts/doctype/account/account.js
+++ b/erpnext/accounts/doctype/account/account.js
@@ -14,6 +14,47 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+// Onload
+// -----------------------------------------
+cur_frm.cscript.onload = function(doc, cdt, cdn) {
+}
+
+cur_frm.cscript.set_breadcrumbs = function(barea) {
+ cur_frm.frm_head.appframe.add_breadcrumb(cur_frm.docname);
+ cur_frm.frm_head.appframe.add_breadcrumb(' in <a href="#!Accounts Browser/Account">\
+ Chart of Accounts</a>');
+ cur_frm.frm_head.appframe.add_breadcrumb(' in <a href="#!accounts-home">Accounts</a>');
+}
+
+// Refresh
+// -----------------------------------------
+cur_frm.cscript.refresh = function(doc, cdt, cdn) {
+ cur_frm.toggle_fields('account_name', doc.__islocal);
+
+ // hide fields if group
+ cur_frm.toggle_fields(['account_type', 'master_type', 'master_name', 'freeze_account',
+ 'credit_days', 'credit_limit', 'tax_rate'], doc.group_or_ledger=='Ledger')
+
+ // read-only for root accounts
+ root_acc = ['Application of Funds (Assets)','Expenses','Income','Source of Funds (Liabilities)'];
+ if(in_list(root_acc, doc.account_name)) {
+ cur_frm.perm = [[1,0,0], [1,0,0]];
+ cur_frm.set_intro("This is a root account and cannot be edited.");
+ } else {
+ // credit days and type if customer or supplier
+ cur_frm.set_intro(null);
+ cur_frm.toggle_fields(['credit_days', 'credit_limit'],
+ in_list(['Customer', 'Supplier'], doc.master_type))
+
+ // hide tax_rate
+ cur_frm.cscript.account_type(doc, cdt, cdn);
+
+ // show / hide convert buttons
+ cur_frm.cscript.hide_unhide_group_ledger(doc);
+ }
+}
+
// Fetch parent details
// -----------------------------------------
cur_frm.add_fetch('parent_account', 'debit_or_credit', 'debit_or_credit');
@@ -22,47 +63,31 @@
// Hide tax rate based on account type
// -----------------------------------------
cur_frm.cscript.account_type = function(doc, cdt, cdn) {
- if(doc.account_type == 'Tax') unhide_field(['tax_rate']);
- else hide_field(['tax_rate']);
-}
-
-// Onload
-// -----------------------------------------
-cur_frm.cscript.onload = function(doc, cdt, cdn) {
- cur_frm.cscript.account_type(doc, cdt, cdn);
- // hide India specific fields
- var cp = wn.control_panel;
- if(cp.country == 'India')
- unhide_field(['pan_number', 'tds_applicable', 'tds_details', 'tds']);
- else
- hide_field(['pan_number', 'tds_applicable', 'tds_details', 'tds']);
-}
-
-// Refresh
-// -----------------------------------------
-cur_frm.cscript.refresh = function(doc, cdt, cdn) {
- root_acc = [' Application of Funds (Assets)','Expenses','Income','Source of Funds (Liabilities)'];
- if(inList(root_acc, doc.account_name))
- cur_frm.perm = [[1,0,0], [1,0,0]];
- cur_frm.cscript.hide_unhide_group_ledger(doc);
+ if(doc.group_or_ledger=='Ledger') {
+ cur_frm.toggle_fields(['tax_rate'],
+ doc.account_type == 'Tax');
+ cur_frm.toggle_fields(['master_type', 'master_name'],
+ cstr(doc.account_type)=='');
+ }
}
// Hide/unhide group or ledger
// -----------------------------------------
cur_frm.cscript.hide_unhide_group_ledger = function(doc) {
- hide_field(['convert_to_group', 'convert_to_ledger']);
- if (cstr(doc.group_or_ledger) == 'Group') unhide_field('convert_to_ledger');
- else if (cstr(doc.group_or_ledger) == 'Ledger') unhide_field('convert_to_group');
+ if (cstr(doc.group_or_ledger) == 'Group') {
+ cur_frm.add_custom_button('Convert to Ledger',
+ function() { cur_frm.cscript.convert_to_ledger(); }, 'icon-retweet')
+ } else if (cstr(doc.group_or_ledger) == 'Ledger') {
+ cur_frm.add_custom_button('Convert to Group',
+ function() { cur_frm.cscript.convert_to_group(); }, 'icon-retweet')
+ }
}
-
// Convert group to ledger
// -----------------------------------------
cur_frm.cscript.convert_to_ledger = function(doc, cdt, cdn) {
- $c_obj(make_doclist(cdt,cdn),'convert_group_to_ledger','',function(r,rt) {
- if(r.message == 1) {
- doc.group_or_ledger = 'Ledger';
- refresh_field('group_or_ledger');
- cur_frm.cscript.hide_unhide_group_ledger(doc);
+ $c_obj(cur_frm.get_doclist(),'convert_group_to_ledger','',function(r,rt) {
+ if(r.message == 1) {
+ cur_frm.refresh();
}
});
}
@@ -70,11 +95,9 @@
// Convert ledger to group
// -----------------------------------------
cur_frm.cscript.convert_to_group = function(doc, cdt, cdn) {
- $c_obj(make_doclist(cdt,cdn),'convert_ledger_to_group','',function(r,rt) {
+ $c_obj(cur_frm.get_doclist(),'convert_ledger_to_group','',function(r,rt) {
if(r.message == 1) {
- doc.group_or_ledger = 'Group';
- refresh_field('group_or_ledger');
- cur_frm.cscript.hide_unhide_group_ledger(doc);
+ cur_frm.refresh();
}
});
}
@@ -85,11 +108,13 @@
if (doc.master_type){
return 'SELECT `tab'+doc.master_type+'`.name FROM `tab'+doc.master_type+'` WHERE `tab'+doc.master_type+'`.name LIKE "%s" and `tab'+doc.master_type+'`.docstatus != 2 ORDER BY `tab'+doc.master_type+'`.name LIMIT 50';
}
- else alert("Please select master type");
}
// parent account get query
// -----------------------------------------
cur_frm.fields_dict['parent_account'].get_query = function(doc){
- return 'SELECT DISTINCT `tabAccount`.name FROM `tabAccount` WHERE `tabAccount`.group_or_ledger="Group" AND `tabAccount`.docstatus != 2 AND `tabAccount`.company="'+ doc.company+'" AND `tabAccount`.company is not NULL AND `tabAccount`.name LIKE "%s" ORDER BY `tabAccount`.name LIMIT 50';
+ return 'SELECT DISTINCT `tabAccount`.name FROM `tabAccount` WHERE \
+ `tabAccount`.group_or_ledger="Group" AND `tabAccount`.docstatus != 2 AND \
+ `tabAccount`.company="'+ doc.company+'" AND `tabAccount`.company is not NULL AND \
+ `tabAccount`.name LIKE "%s" ORDER BY `tabAccount`.name LIMIT 50';
}
diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py
index 335d47c..d4f63f4 100644
--- a/erpnext/accounts/doctype/account/account.py
+++ b/erpnext/accounts/doctype/account/account.py
@@ -43,7 +43,6 @@
self.doc.name = self.doc.account_name.strip() + ' - ' + company_abbr
# Get customer/supplier address
- # ==================================================================
def get_address(self):
add=sql("Select address from `tab%s` where name='%s'"%(self.doc.master_type,self.doc.master_name))
ret={'address':add[0][0]}
@@ -51,20 +50,17 @@
# check whether master name entered for supplier/customer
- # ==================================================================
def validate_master_name(self):
if (self.doc.master_type == 'Customer' or self.doc.master_type == 'Supplier') and not self.doc.master_name:
msgprint("Message: Please enter Master Name once the account is created.")
# Rate is mandatory for tax account
- # ==================================================================
def validate_rate_for_tax(self):
if self.doc.account_type == 'Tax' and not self.doc.tax_rate:
msgprint("Please Enter Rate", raise_exception=1)
# Fetch Parent Details and validation for account not to be created under ledger
- # ==================================================================
def validate_parent(self):
if self.doc.parent_account:
par = sql("select name, group_or_ledger, is_pl_account, debit_or_credit from tabAccount where name =%s",self.doc.parent_account)
@@ -81,13 +77,11 @@
self.doc.debit_or_credit = par[0][3]
# Account name must be unique
- # ==================================================================
def validate_duplicate_account(self):
if (self.doc.__islocal or (not self.doc.name)) and sql("select name from tabAccount where account_name=%s and company=%s", (self.doc.account_name, self.doc.company)):
msgprint("Account Name already exists, please rename", raise_exception=1)
# validate root details
- # ==================================================================
def validate_root_details(self):
#does not exists parent
if self.doc.account_name in ['Income','Source of Funds', 'Expenses','Application of Funds'] and self.doc.parent_account:
@@ -106,7 +100,6 @@
self.doc.is_pl_account = 'No'
# Convert group to ledger
- # ==================================================================
def convert_group_to_ledger(self):
if self.check_if_child_exists():
msgprint("Account: %s has existing child. You can not convert this account to ledger" % (self.doc.name), raise_exception=1)
@@ -118,28 +111,28 @@
return 1
# Convert ledger to group
- # ==================================================================
def convert_ledger_to_group(self):
if self.check_gle_exists():
- msgprint("Account with existing transaction can not be converted to group.", raise_exception=1)
+ msgprint("Account with existing transaction can not be converted to group.",
+ raise_exception=1)
+ elif self.doc.master_type or self.doc.account_type:
+ msgprint("Cannot covert to Group because Master Type or Account Type is selected.",
+ raise_exception=1)
else:
self.doc.group_or_ledger = 'Group'
self.doc.save()
return 1
# Check if any previous balance exists
- # ==================================================================
def check_gle_exists(self):
exists = sql("select name from `tabGL Entry` where account = '%s' and ifnull(is_cancelled, 'No') = 'No'" % (self.doc.name))
return exists and exists[0][0] or ''
# check if child exists
- # ==================================================================
def check_if_child_exists(self):
return sql("select name from `tabAccount` where parent_account = %s and docstatus != 2", self.doc.name)
# Update balance
- # ==================================================================
def update_balance(self, fy, period_det, flag = 1):
# update in all parents
for p in period_det:
@@ -147,7 +140,6 @@
# change parent balance
- # ==================================================================
def change_parent_bal(self):
period_det = []
fy = sql("select name from `tabFiscal Year` where if(ifnull(is_fiscal_year_closed, 'No'),ifnull(is_fiscal_year_closed, 'No'), 'No') = 'No'")
@@ -177,7 +169,6 @@
# VALIDATE
- # ==================================================================
def validate(self):
self.validate_master_name()
self.validate_rate_for_tax()
@@ -195,7 +186,6 @@
self.change_parent_bal()
# Add current fiscal year balance
- # ==================================================================
def set_year_balance(self):
p = sql("select name, start_date, end_date, fiscal_year from `tabPeriod` where docstatus != 2 and period_type in ('Month', 'Year')")
for d in p:
@@ -213,29 +203,26 @@
ac.save(1)
# Update Node Set Model
- # ==================================================================
def update_nsm_model(self):
import webnotes
import webnotes.utils.nestedset
webnotes.utils.nestedset.update_nsm(self)
# ON UPDATE
- # ==================================================================
def on_update(self):
+
# update nsm
self.update_nsm_model()
# Add curret year balance
self.set_year_balance()
# Check user role for approval process
- # ==================================================================
def get_authorized_user(self):
# Check logged-in user is authorized
if get_value('Global Defaults', None, 'credit_controller') in webnotes.user.get_roles():
return 1
# Check Credit limit for customer
- # ==================================================================
def check_credit_limit(self, account, company, tot_outstanding):
# Get credit limit
credit_limit_from = 'Customer'
@@ -252,7 +239,6 @@
% (fmt_money(tot_outstanding), account, fmt_money(credit_limit), credit_limit_from), raise_exception=1)
# Account with balance cannot be inactive
- # ==================================================================
def check_balance_before_trash(self):
if self.check_gle_exists():
msgprint("Account with existing transaction (Sales Invoice / Purchase Invoice / Journal Voucher) can not be trashed", raise_exception=1)
@@ -261,20 +247,18 @@
# get current year balance
- # ==================================================================
def get_curr_bal(self):
bal = sql("select balance from `tabAccount Balance` where period = '%s' and parent = '%s'" % (get_defaults()['fiscal_year'], self.doc.name),debug=0)
return bal and flt(bal[0][0]) or 0
# On Trash
- # ==================================================================
def on_trash(self):
# Check balance before trash
self.check_balance_before_trash()
# rebuild tree
- set(self.doc,'old_parent', '')
- self.update_nsm_model()
+ from webnotes.utils.nestedset import update_remove_node
+ update_remove_node('Account', self.doc.name)
# delete all cancelled gl entry of this account
sql("delete from `tabGL Entry` where account = %s and ifnull(is_cancelled, 'No') = 'Yes'", self.doc.name)
@@ -283,7 +267,6 @@
sql("delete from `tabAccount Balance` where account = %s", self.doc.name)
# On restore
- # ==================================================================
def on_restore(self):
# rebuild tree
self.update_nsm_model()
@@ -291,7 +274,6 @@
self.set_year_balance()
# on rename
- # ---------
def on_rename(self,newdn,olddn):
company_abbr = sql("select tc.abbr from `tabAccount` ta, `tabCompany` tc where ta.company = tc.name and ta.name=%s", olddn)[0][0]
diff --git a/erpnext/accounts/doctype/account/account.txt b/erpnext/accounts/doctype/account/account.txt
index ec0ade9..b649c9a 100644
--- a/erpnext/accounts/doctype/account/account.txt
+++ b/erpnext/accounts/doctype/account/account.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-03-27 14:35:39',
+ 'creation': '2012-07-03 13:30:50',
'docstatus': 0,
- 'modified': '2012-03-27 14:35:39',
+ 'modified': '2012-07-11 13:58:44',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -17,6 +17,7 @@
'allow_trash': 1,
'colour': u'White:FFF',
'default_print_format': u'Standard',
+ 'description': u'An **Account** is heading under which financial and business transactions are carried on. For example, \u201cTravel Expense\u201d is an account, \u201cCustomer Zoe\u201d, \u201cSupplier Mae\u201d are accounts. \n\n**Note:** ERPNext creates accounts for Customers and Suppliers automatically.\n\n### Groups and Ledgers\n\nThere are two main kinds of Accounts in ERPNext - Group and Ledger. Groups can have sub-groups and ledgers within them, whereas ledgers are the leaf nodes of your chart and cannot be further classified.\n\nAccounting Transactions can only be made against Ledger Accounts (not Groups)\n',
'doctype': 'DocType',
'document_type': u'Master',
'in_create': 1,
@@ -26,7 +27,7 @@
'section_style': u'Tray',
'server_code_error': u' ',
'show_in_menu': 0,
- 'version': 138
+ 'version': 1
},
# These values are common for all DocField
@@ -58,11 +59,11 @@
# DocPerm
{
- 'cancel': 1,
- 'create': 1,
+ 'cancel': 0,
+ 'create': 0,
'doctype': u'DocPerm',
'permlevel': 0,
- 'role': u'Accounts User',
+ 'role': u'Auditor',
'write': 1
},
@@ -71,6 +72,26 @@
'cancel': 0,
'create': 0,
'doctype': u'DocPerm',
+ 'permlevel': 1,
+ 'role': u'Auditor',
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 2,
+ 'role': u'Auditor',
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
'permlevel': 0,
'role': u'Sales User',
'write': 0
@@ -91,6 +112,26 @@
'cancel': 0,
'create': 0,
'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'Accounts User',
+ 'write': 1
+ },
+
+ # DocPerm
+ {
+ 'cancel': 1,
+ 'create': 1,
+ 'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'Accounts Manager',
+ 'write': 1
+ },
+
+ # DocPerm
+ {
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
'permlevel': 1,
'role': u'Accounts User',
'write': 0
@@ -108,16 +149,6 @@
# DocPerm
{
- 'cancel': 1,
- 'create': 1,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Accounts Manager',
- 'write': 1
- },
-
- # DocPerm
- {
'cancel': 0,
'create': 0,
'doctype': u'DocPerm',
@@ -141,7 +172,7 @@
'doctype': u'DocField',
'fieldname': u'properties',
'fieldtype': u'Section Break',
- 'label': u'Properties',
+ 'label': u'Account Details',
'oldfieldtype': u'Section Break',
'permlevel': 0
},
@@ -173,20 +204,6 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'parent_account',
- 'fieldtype': u'Link',
- 'label': u'Parent Account',
- 'oldfieldname': u'parent_account',
- 'oldfieldtype': u'Link',
- 'options': u'Account',
- 'permlevel': 0,
- 'search_index': 1,
- 'trigger': u'Client'
- },
-
- # DocField
- {
- 'doctype': u'DocField',
'fieldname': u'level',
'fieldtype': u'Int',
'hidden': 1,
@@ -216,26 +233,6 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'convert_to_group',
- 'fieldtype': u'Button',
- 'label': u'Convert to Group',
- 'permlevel': 0,
- 'trigger': u'Client'
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'convert_to_ledger',
- 'fieldtype': u'Button',
- 'label': u'Convert to Ledger',
- 'permlevel': 0,
- 'trigger': u'Client'
- },
-
- # DocField
- {
- 'doctype': u'DocField',
'fieldname': u'debit_or_credit',
'fieldtype': u'Data',
'in_filter': 1,
@@ -263,6 +260,46 @@
# DocField
{
'doctype': u'DocField',
+ 'fieldname': u'company',
+ 'fieldtype': u'Link',
+ 'in_filter': 1,
+ 'label': u'Company',
+ 'oldfieldname': u'company',
+ 'oldfieldtype': u'Link',
+ 'options': u'Company',
+ 'permlevel': 1,
+ 'reqd': 1,
+ 'search_index': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'column_break1',
+ 'fieldtype': u'Column Break',
+ 'permlevel': 0,
+ 'width': u'50%'
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'parent_account',
+ 'fieldtype': u'Link',
+ 'label': u'Parent Account',
+ 'oldfieldname': u'parent_account',
+ 'oldfieldtype': u'Link',
+ 'options': u'Account',
+ 'permlevel': 0,
+ 'search_index': 1,
+ 'trigger': u'Client'
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'description': u'Setting Account Type helps in selecting this Account in transactions.',
+ 'doctype': u'DocField',
'fieldname': u'account_type',
'fieldtype': u'Select',
'in_filter': 1,
@@ -278,7 +315,7 @@
# DocField
{
'colour': u'White:FFF',
- 'description': u'If Account Type is "Tax" then the default rate is required.',
+ 'description': u'Rate at which this tax is applied',
'doctype': u'DocField',
'fieldname': u'tax_rate',
'fieldtype': u'Currency',
@@ -292,19 +329,12 @@
# DocField
{
- 'doctype': u'DocField',
- 'fieldname': u'column_break1',
- 'fieldtype': u'Column Break',
- 'permlevel': 0,
- 'width': u'50%'
- },
-
- # DocField
- {
+ 'colour': u'White:FFF',
+ 'description': u'If the account is frozen, entries are allowed for the "Account Manager" only.',
'doctype': u'DocField',
'fieldname': u'freeze_account',
'fieldtype': u'Select',
- 'label': u'Freeze Account',
+ 'label': u'Frozen',
'oldfieldname': u'freeze_account',
'oldfieldtype': u'Select',
'options': u'No\nYes',
@@ -313,21 +343,7 @@
# DocField
{
- 'doctype': u'DocField',
- 'fieldname': u'company',
- 'fieldtype': u'Link',
- 'in_filter': 1,
- 'label': u'Company',
- 'oldfieldname': u'company',
- 'oldfieldtype': u'Link',
- 'options': u'Company',
- 'permlevel': 1,
- 'reqd': 1,
- 'search_index': 1
- },
-
- # DocField
- {
+ 'colour': u'White:FFF',
'doctype': u'DocField',
'fieldname': u'credit_days',
'fieldtype': u'Int',
@@ -354,13 +370,15 @@
# DocField
{
+ 'colour': u'White:FFF',
+ 'description': u'If this Account represents a Customer, Supplier or Employee, set it here.',
'doctype': u'DocField',
'fieldname': u'master_type',
'fieldtype': u'Select',
'label': u'Master Type',
'oldfieldname': u'master_type',
'oldfieldtype': u'Select',
- 'options': u'\nNA\nSupplier\nCustomer\nEmployee',
+ 'options': u'\nSupplier\nCustomer\nEmployee',
'permlevel': 0
},
@@ -374,116 +392,5 @@
'oldfieldtype': u'Link',
'permlevel': 0,
'trigger': u'Client'
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'tds',
- 'fieldtype': u'Section Break',
- 'label': u'TDS',
- 'oldfieldtype': u'Section Break',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'pan_number',
- 'fieldtype': u'Data',
- 'label': u'PAN Number',
- 'oldfieldname': u'pan_number',
- 'oldfieldtype': u'Data',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'default': u'No',
- 'doctype': u'DocField',
- 'fieldname': u'tds_applicable',
- 'fieldtype': u'Select',
- 'label': u'TDS Applicable',
- 'oldfieldname': u'tds_applicable',
- 'oldfieldtype': u'Select',
- 'options': u'\nYes\nNo',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'tds_details',
- 'fieldtype': u'Table',
- 'label': u'TDS Details',
- 'oldfieldname': u'tds_details',
- 'oldfieldtype': u'Table',
- 'options': u'TDS Detail',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'description': u"Don't delete this field at any cost",
- 'doctype': u'DocField',
- 'fieldname': u'old_parent',
- 'fieldtype': u'Link',
- 'hidden': 1,
- 'label': u'Old Parent',
- 'no_copy': 1,
- 'oldfieldname': u'old_parent',
- 'oldfieldtype': u'Data',
- 'options': u'Account',
- 'permlevel': 0,
- 'report_hide': 1
- },
-
- # DocField
- {
- 'colour': u'White:FFF',
- 'description': u"Don't delete this field at any cost",
- 'doctype': u'DocField',
- 'fieldname': u'lft',
- 'fieldtype': u'Int',
- 'hidden': 1,
- 'in_filter': 1,
- 'label': u'Lft',
- 'no_copy': 1,
- 'oldfieldname': u'lft',
- 'oldfieldtype': u'Int',
- 'permlevel': 3,
- 'print_hide': 1,
- 'report_hide': 1,
- 'search_index': 1
- },
-
- # DocField
- {
- 'colour': u'White:FFF',
- 'description': u"Don't delete this field at any cost",
- 'doctype': u'DocField',
- 'fieldname': u'rgt',
- 'fieldtype': u'Int',
- 'hidden': 1,
- 'in_filter': 1,
- 'label': u'Rgt',
- 'no_copy': 1,
- 'oldfieldname': u'rgt',
- 'oldfieldtype': u'Int',
- 'permlevel': 3,
- 'print_hide': 1,
- 'report_hide': 1,
- 'search_index': 1
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'trash_reason',
- 'fieldtype': u'Small Text',
- 'label': u'Trash Reason',
- 'oldfieldname': u'trash_reason',
- 'oldfieldtype': u'Small Text',
- 'permlevel': 1
}
]
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/budget_distribution/budget_distribution.js b/erpnext/accounts/doctype/budget_distribution/budget_distribution.js
index d7deb9a..1f72c3c 100644
--- a/erpnext/accounts/doctype/budget_distribution/budget_distribution.js
+++ b/erpnext/accounts/doctype/budget_distribution/budget_distribution.js
@@ -20,6 +20,11 @@
refresh_field('budget_distribution_details');
}
- $c('runserverobj',args={'method' : 'get_months', 'docs' : compress_doclist(make_doclist(doc.doctype, doc.name))},callback1);
+ $c('runserverobj',args={'method' : 'get_months', 'docs' :
+ compress_doclist(make_doclist(doc.doctype, doc.name))},callback1);
}
+}
+
+cur_frm.cscript.refresh = function(doc,cdt,cdn){
+ cur_frm.toggle_fields('distribution_id', doc.__islocal);
}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/budget_distribution/budget_distribution.py b/erpnext/accounts/doctype/budget_distribution/budget_distribution.py
index 9468b60..090b8fb 100644
--- a/erpnext/accounts/doctype/budget_distribution/budget_distribution.py
+++ b/erpnext/accounts/doctype/budget_distribution/budget_distribution.py
@@ -14,31 +14,20 @@
# 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
-
-# -----------------------------------------------------------------------------------------
-
+from webnotes.utils import flt
+from webnotes.model.doc import addchild
+from webnotes.model.doclist import getlist
+from webnotes import msgprint
class DocType:
def __init__(self,doc,doclist=[]):
self.doc,self.doclist = doc,doclist
def get_months(self):
- month_list = ['January','February','March','April','May','June','July','August','September','October','November','December']
+ month_list = ['January','February','March','April','May','June','July','August','September',
+ 'October','November','December']
idx =1
for m in month_list:
mnth = addchild(self.doc,'budget_distribution_details','Budget Distribution Detail',1,self.doclist)
@@ -50,9 +39,5 @@
total = 0
for d in getlist(self.doclist,'budget_distribution_details'):
total = flt(total) + flt(d.percentage_allocation)
- if total > 100:
- msgprint("Percentage Allocation should not exceed 100%.")
- raise Exception
- elif total < 100:
- msgprint("Percentage Allocation should not recede 100%.")
- raise Exception
\ No newline at end of file
+ if total != 100:
+ msgprint("Percentage Allocation should be equal to 100%%. Currently it is %s%%" % total, raise_exception=1)
diff --git a/erpnext/accounts/doctype/budget_distribution/budget_distribution.txt b/erpnext/accounts/doctype/budget_distribution/budget_distribution.txt
index ca9b869..ab8a6c8 100644
--- a/erpnext/accounts/doctype/budget_distribution/budget_distribution.txt
+++ b/erpnext/accounts/doctype/budget_distribution/budget_distribution.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-03-27 14:35:41',
+ 'creation': '2012-07-03 13:30:50',
'docstatus': 0,
- 'modified': '2012-03-27 14:35:41',
+ 'modified': '2012-07-11 14:37:30',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -15,6 +15,7 @@
'allow_trash': 1,
'autoname': u'field:distribution_id',
'colour': u'White:FFF',
+ 'description': u'**Budget Distribution** helps you distribute your budget across months if you have seasonality in your business.\n\nTo distribute a budget using this distribution, set this **Budget Distribution** in the **Cost Center**',
'doctype': 'DocType',
'module': u'Accounts',
'name': '__common__',
@@ -22,7 +23,7 @@
'section_style': u'Simple',
'server_code_error': u' ',
'show_in_menu': 0,
- 'version': 24
+ 'version': 1
},
# These values are common for all DocField
@@ -108,13 +109,16 @@
# DocField
{
+ 'colour': u'White:FFF',
+ 'description': u'Name of the Budget Distribution',
'doctype': u'DocField',
'fieldname': u'distribution_id',
'fieldtype': u'Data',
- 'label': u'Distribution ID',
+ 'label': u'Distribution Name',
'oldfieldname': u'distribution_id',
'oldfieldtype': u'Data',
- 'permlevel': 0
+ 'permlevel': 0,
+ 'reqd': 1
},
# DocField
diff --git a/erpnext/accounts/doctype/budget_distribution_detail/budget_distribution_detail.txt b/erpnext/accounts/doctype/budget_distribution_detail/budget_distribution_detail.txt
index d0912be..0acfdbc 100644
--- a/erpnext/accounts/doctype/budget_distribution_detail/budget_distribution_detail.txt
+++ b/erpnext/accounts/doctype/budget_distribution_detail/budget_distribution_detail.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-03-27 14:35:41',
+ 'creation': '2012-07-03 13:30:47',
'docstatus': 0,
- 'modified': '2012-03-27 14:35:41',
+ 'modified': '2012-07-11 14:32:16',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -21,7 +21,7 @@
'section_style': u'Tray',
'server_code_error': u' ',
'show_in_menu': 0,
- 'version': 6
+ 'version': 1
},
# These values are common for all DocField
@@ -60,16 +60,5 @@
'oldfieldname': u'percentage_allocation',
'oldfieldtype': u'Currency',
'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'aggregate_percentage',
- 'fieldtype': u'Currency',
- 'label': u'Aggregate Percentage',
- 'oldfieldname': u'aggregate_percentage',
- 'oldfieldtype': u'Currency',
- 'permlevel': 2
}
]
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/cost_center/cost_center.js b/erpnext/accounts/doctype/cost_center/cost_center.js
index ade4ee8..c131081 100644
--- a/erpnext/accounts/doctype/cost_center/cost_center.js
+++ b/erpnext/accounts/doctype/cost_center/cost_center.js
@@ -15,6 +15,38 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//onload if cost center is group
+cur_frm.cscript.onload = function(doc, cdt, cdn) {
+ if(!doc.__islocal && doc.docstatus == 0){
+ get_field(doc.doctype,'group_or_ledger',doc.name).permlevel = 1;
+ refresh_field('group_or_ledger');
+ get_field(doc.doctype,'company_name',doc.name).permlevel = 1;
+ refresh_field('company_name');
+ }
+
+}
+
+cur_frm.cscript.set_breadcrumbs = function(barea) {
+ cur_frm.frm_head.appframe.add_breadcrumb(cur_frm.docname);
+ cur_frm.frm_head.appframe.add_breadcrumb(' in <a href="#!Accounts Browser/Cost Center">\
+ Chart of Cost Centers</a>');
+ cur_frm.frm_head.appframe.add_breadcrumb(' in <a href="#!accounts-home">Accounts</a>');
+}
+
+cur_frm.cscript.refresh = function(doc, cdt, cdn) {
+ var intro_txt = '';
+ cur_frm.toggle_fields('cost_center_name', doc.__islocal);
+
+ if(!doc.__islocal && doc.group_or_ledger=='Group') {
+ intro_txt += '<p><b>Note:</b> This is Cost Center is a <i>Group</i>, \
+ Accounting Entries are not allowed against groups.</p>';
+ }
+
+ cur_frm.cscript.hide_unhide_group_ledger(doc);
+
+ cur_frm.toggle_fields('sb1', doc.group_or_ledger=='Ledger')
+ cur_frm.set_intro(intro_txt);
+}
//Account filtering for cost center
cur_frm.fields_dict['budget_details'].grid.get_field('account').get_query = function(doc) {
@@ -38,39 +70,25 @@
get_server_fields('get_abbr','','',doc,cdt,cdn,1);
}
-//onload if cost center is group
-cur_frm.cscript.onload = function(doc, cdt, cdn) {
-
- if(!doc.__islocal && doc.docstatus == 0){
- get_field(doc.doctype,'group_or_ledger',doc.name).permlevel = 1;
- refresh_field('group_or_ledger');
- get_field(doc.doctype,'company_name',doc.name).permlevel = 1;
- refresh_field('company_name');
- }
-
-}
-
-cur_frm.cscript.refresh = function(doc, cdt, cdn) {
- cur_frm.cscript.hide_unhide_group_ledger(doc);
-}
-
// Hide/unhide group or ledger
// -----------------------------------------
cur_frm.cscript.hide_unhide_group_ledger = function(doc) {
- hide_field(['convert_to_group', 'convert_to_ledger']);
- if (cstr(doc.group_or_ledger) == 'Group') unhide_field('convert_to_ledger');
- else if (cstr(doc.group_or_ledger) == 'Ledger') unhide_field('convert_to_group');
+ if (cstr(doc.group_or_ledger) == 'Group') {
+ cur_frm.add_custom_button('Convert to Ledger',
+ function() { cur_frm.cscript.convert_to_ledger(); }, 'icon-retweet')
+ } else if (cstr(doc.group_or_ledger) == 'Ledger') {
+ cur_frm.add_custom_button('Convert to Group',
+ function() { cur_frm.cscript.convert_to_group(); }, 'icon-retweet')
+ }
}
// Convert group to ledger
// -----------------------------------------
cur_frm.cscript.convert_to_ledger = function(doc, cdt, cdn) {
- $c_obj(make_doclist(cdt,cdn),'convert_group_to_ledger','',function(r,rt) {
+ $c_obj(cur_frm.get_doclist(),'convert_group_to_ledger','',function(r,rt) {
if(r.message == 1) {
- doc.group_or_ledger = 'Ledger';
- refresh_field('group_or_ledger');
- cur_frm.cscript.hide_unhide_group_ledger(doc);
+ cur_frm.refresh();
}
});
}
@@ -78,11 +96,9 @@
// Convert ledger to group
// -----------------------------------------
cur_frm.cscript.convert_to_group = function(doc, cdt, cdn) {
- $c_obj(make_doclist(cdt,cdn),'convert_ledger_to_group','',function(r,rt) {
+ $c_obj(cur_frm.get_doclist(),'convert_ledger_to_group','',function(r,rt) {
if(r.message == 1) {
- doc.group_or_ledger = 'Group';
- refresh_field('group_or_ledger');
- cur_frm.cscript.hide_unhide_group_ledger(doc);
+ cur_frm.refresh();
}
});
}
diff --git a/erpnext/accounts/doctype/cost_center/cost_center.py b/erpnext/accounts/doctype/cost_center/cost_center.py
index 83ad9d2..3e64c29 100644
--- a/erpnext/accounts/doctype/cost_center/cost_center.py
+++ b/erpnext/accounts/doctype/cost_center/cost_center.py
@@ -14,26 +14,13 @@
# 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.model.doclist import getlist
+from webnotes import msgprint
-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
+from webnotes.utils.nestedset import DocTypeNestedSet
-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:
+class DocType(DocTypeNestedSet):
def __init__(self,d,dl):
self.doc, self.doclist = d,dl
self.nsm_parent_field = 'parent_cost_center'
@@ -41,9 +28,9 @@
def autoname(self):
self.doc.name = self.doc.cost_center_name + ' - ' + self.doc.company_abbr
- #-------------------------------------------------------------------------
def get_abbr(self):
- abbr = sql("select abbr from tabCompany where company_name='%s'"%(self.doc.company_name))[0][0] or ''
+ abbr = webnotes.conn.sql("select abbr from tabCompany where company_name=%s",
+ self.doc.company_name)[0][0] or ''
ret = {
'company_abbr' : abbr
}
@@ -56,7 +43,6 @@
if self.doc.cost_center_name != 'Root' and not self.doc.parent_cost_center:
msgprint("Please enter parent cost center", raise_exception=1)
- #-------------------------------------------------------------------------
def convert_group_to_ledger(self):
if self.check_if_child_exists():
msgprint("Cost Center: %s has existing child. You can not convert this cost center to ledger" % (self.doc.name), raise_exception=1)
@@ -67,7 +53,6 @@
self.doc.save()
return 1
- #-------------------------------------------------------------------------
def convert_ledger_to_group(self):
if self.check_gle_exists():
msgprint("Cost Center with existing transaction can not be converted to group.", raise_exception=1)
@@ -76,54 +61,31 @@
self.doc.save()
return 1
- #-------------------------------------------------------------------------
def check_gle_exists(self):
- return sql("select name from `tabGL Entry` where cost_center = %s and ifnull(is_cancelled, 'No') = 'No'", (self.doc.name))
+ return webnotes.conn.sql("select name from `tabGL Entry` where cost_center = %s and \
+ ifnull(is_cancelled, 'No') = 'No'", (self.doc.name))
-
- #-------------------------------------------------------------------------
def check_if_child_exists(self):
- return sql("select name from `tabCost Center` where parent_cost_center = %s and docstatus != 2", self.doc.name)
-
+ return webnotes.conn.sql("select name from `tabCost Center` where \
+ parent_cost_center = %s and docstatus != 2", self.doc.name)
def validate_budget_details(self):
check_acc_list = []
for d in getlist(self.doclist, 'budget_details'):
+ if doc.group_or_ledger=="Group":
+ msgprint("Budget cannot be set for Group Cost Centers", raise_exception=1)
+
if [d.account, d.fiscal_year] in check_acc_list:
- msgprint("Account " + cstr(d.account) + "has been entered more than once for fiscal year " + cstr(d.fiscal_year), raise_exception=1)
+ msgprint("Account " + d.account + "has been entered more than once for fiscal year " + d.fiscal_year, raise_exception=1)
else:
check_acc_list.append([d.account, d.fiscal_year])
-
- #-------------------------------------------------------------------------
def validate(self):
"""
Cost Center name must be unique
"""
- if (self.doc.__islocal or not self.doc.name) and sql("select name from `tabCost Center` where cost_center_name = %s and company_name=%s", (self.doc.cost_center_name, self.doc.company_name)):
+ if (self.doc.__islocal or not self.doc.name) and webnotes.conn.sql("select name from `tabCost Center` where cost_center_name = %s and company_name=%s", (self.doc.cost_center_name, self.doc.company_name)):
msgprint("Cost Center Name already exists, please rename", raise_exception=1)
self.validate_mandatory()
self.validate_budget_details()
-
- #-------------------------------------------------------------------------
- def update_nsm_model(self):
- """
- update Nested Set Model
- """
- import webnotes.utils.nestedset
- webnotes.utils.nestedset.update_nsm(self)
-
- #-------------------------------------------------------------------------
- def on_update(self):
- self.update_nsm_model()
-
- # On Trash
- #-------------------------------------------------------------------------
- def on_trash(self):
- if self.check_if_child_exists():
- msgprint("Child exists for this cost center. You can not trash this account.", raise_exception=1)
-
- # rebuild tree
- set(self.doc,'old_parent', '')
- self.update_nsm_model()
diff --git a/erpnext/accounts/doctype/cost_center/cost_center.txt b/erpnext/accounts/doctype/cost_center/cost_center.txt
index b02d909..df65584 100644
--- a/erpnext/accounts/doctype/cost_center/cost_center.txt
+++ b/erpnext/accounts/doctype/cost_center/cost_center.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-03-27 14:35:41',
+ 'creation': '2012-07-03 13:30:47',
'docstatus': 0,
- 'modified': '2012-03-27 14:35:41',
+ 'modified': '2012-07-11 14:41:39',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -18,6 +18,7 @@
'autoname': u'field:cost_center_name',
'colour': u'White:FFF',
'default_print_format': u'Standard',
+ 'description': u'**Chart of Accounts** is mainly for reporting information for governmental purposes and less for how business actually performs. \n\nMost businesses have multiple activities like different product lines, market segments, areas of business that share some common overheads but should ideally have their own structure to report whether they are profitable or not. For this purpose, there is an alternate structure, called the **Cost Centers**.\n\nA tree of **Cost Centers** to cab be designed to reflect the different units of an organization. Each Income / Expense entry is also tagged against a **Cost Center** and hence you can get Profit and Loss against a **Cost Center** too.\n\n### Budgeting\n\n**Cost Centers** can be used for budgeting purposes too. A budget can be set against each **Account** and the system will either stop, warn or ignore the budget based on the settings in the **Company** master.\n\nBudgets can also be distributed seasonally using **Budget Distribution**.',
'doctype': 'DocType',
'document_type': u'Master',
'in_create': 1,
@@ -27,7 +28,7 @@
'section_style': u'Simple',
'server_code_error': u' ',
'show_in_menu': 0,
- 'version': 109
+ 'version': 1
},
# These values are common for all DocField
@@ -61,6 +62,42 @@
'cancel': 0,
'create': 0,
'doctype': u'DocPerm',
+ 'permlevel': 1,
+ 'role': u'Accounts Manager',
+ 'submit': 0,
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'amend': 0,
+ 'cancel': 1,
+ 'create': 1,
+ 'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'Accounts Manager',
+ 'submit': 0,
+ 'write': 1
+ },
+
+ # DocPerm
+ {
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 1,
+ 'role': u'Accounts User',
+ 'submit': 0,
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
'permlevel': 0,
'role': u'Accounts User',
'submit': 0,
@@ -84,40 +121,13 @@
'role': u'All'
},
- # DocPerm
+ # DocField
{
- 'amend': 0,
- 'cancel': 0,
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 1,
- 'role': u'Accounts Manager',
- 'submit': 0,
- 'write': 0
- },
-
- # DocPerm
- {
- 'amend': 0,
- 'cancel': 1,
- 'create': 1,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Accounts Manager',
- 'submit': 0,
- 'write': 1
- },
-
- # DocPerm
- {
- 'amend': 0,
- 'cancel': 0,
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 1,
- 'role': u'Accounts User',
- 'submit': 0,
- 'write': 0
+ 'doctype': u'DocField',
+ 'fieldname': u'sb0',
+ 'fieldtype': u'Section Break',
+ 'label': u'Cost Center Details',
+ 'permlevel': 0
},
# DocField
@@ -148,7 +158,7 @@
# DocField
{
- 'description': u'Select company name first.',
+ 'colour': u'White:FFF',
'doctype': u'DocField',
'fieldname': u'parent_cost_center',
'fieldtype': u'Link',
@@ -178,9 +188,11 @@
# DocField
{
+ 'colour': u'White:FFF',
'doctype': u'DocField',
'fieldname': u'company_abbr',
'fieldtype': u'Data',
+ 'hidden': 1,
'label': u'Company Abbr',
'oldfieldname': u'company_abbr',
'oldfieldtype': u'Data',
@@ -189,6 +201,15 @@
# DocField
{
+ 'doctype': u'DocField',
+ 'fieldname': u'cb0',
+ 'fieldtype': u'Column Break',
+ 'permlevel': 0,
+ 'width': u'50%'
+ },
+
+ # DocField
+ {
'colour': u'White:FFF',
'doctype': u'DocField',
'fieldname': u'group_or_ledger',
@@ -209,27 +230,18 @@
# DocField
{
'colour': u'White:FFF',
+ 'description': u'Define Budget for this Cost Center. To set budget action, see <a href="#!List/Company">Company Master</a>',
'doctype': u'DocField',
- 'fieldname': u'convert_to_group',
- 'fieldtype': u'Button',
- 'label': u'Convert to Group',
- 'permlevel': 0,
- 'trigger': u'Client'
+ 'fieldname': u'sb1',
+ 'fieldtype': u'Section Break',
+ 'label': u'Budget',
+ 'permlevel': 0
},
# DocField
{
'colour': u'White:FFF',
- 'doctype': u'DocField',
- 'fieldname': u'convert_to_ledger',
- 'fieldtype': u'Button',
- 'label': u'Convert to Ledger',
- 'permlevel': 0,
- 'trigger': u'Client'
- },
-
- # DocField
- {
+ 'description': u'Select Budget Distribution, if you want to track based on seasonality.',
'doctype': u'DocField',
'fieldname': u'distribution_id',
'fieldtype': u'Link',
@@ -242,6 +254,8 @@
# DocField
{
+ 'colour': u'White:FFF',
+ 'description': u'Add rows to set annual budgets on Accounts.',
'doctype': u'DocField',
'fieldname': u'budget_details',
'fieldtype': u'Table',
diff --git a/erpnext/accounts/doctype/fiscal_year/fiscal_year.js b/erpnext/accounts/doctype/fiscal_year/fiscal_year.js
index 6a03bf7..d60e4ec 100644
--- a/erpnext/accounts/doctype/fiscal_year/fiscal_year.js
+++ b/erpnext/accounts/doctype/fiscal_year/fiscal_year.js
@@ -1,7 +1,3 @@
cur_frm.cscript.refresh = function(doc, dt, dn) {
- if (doc.__islocal) {
- hide_field(['repost_account_balances', 'repost_voucher_outstanding']);
- set_multiple(dt, dn, {'is_fiscal_year_closed': 'No'});
- }
- else unhide_field(['repost_account_balances', 'repost_voucher_outstanding']);
+ cur_frm.enable_fields('year_start_date', doc.__islocal)
}
diff --git a/erpnext/accounts/doctype/fiscal_year/fiscal_year.py b/erpnext/accounts/doctype/fiscal_year/fiscal_year.py
index a44b756..c1b4663 100644
--- a/erpnext/accounts/doctype/fiscal_year/fiscal_year.py
+++ b/erpnext/accounts/doctype/fiscal_year/fiscal_year.py
@@ -204,9 +204,6 @@
if sql("select name from `tabFiscal Year` where year_start_date < %s", self.doc.year_start_date) and not self.doc.past_year:
msgprint("Please enter Past Year", raise_exception=1)
- if not self.doc.is_fiscal_year_closed:
- self.doc.is_fiscal_year_closed = 'No'
-
# on update
def on_update(self):
diff --git a/erpnext/accounts/doctype/fiscal_year/fiscal_year.txt b/erpnext/accounts/doctype/fiscal_year/fiscal_year.txt
index ae4c5a0..68dbdb2 100644
--- a/erpnext/accounts/doctype/fiscal_year/fiscal_year.txt
+++ b/erpnext/accounts/doctype/fiscal_year/fiscal_year.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-03-27 14:35:41',
+ 'creation': '2012-07-03 13:30:47',
'docstatus': 0,
- 'modified': '2012-03-27 14:35:41',
+ 'modified': '2012-07-11 14:56:41',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -17,6 +17,7 @@
'autoname': u'field:year',
'colour': u'White:FFF',
'default_print_format': u'Standard',
+ 'description': u'**Fiscal Year** represents a Financial Year. All accounting entries and other major transactions are tracked against **Fiscal Year**.',
'doctype': 'DocType',
'document_type': u'Master',
'module': u'Accounts',
@@ -24,7 +25,7 @@
'section_style': u'Tabbed',
'server_code_error': u' ',
'show_in_menu': 0,
- 'version': 57
+ 'version': 1
},
# These values are common for all DocField
@@ -59,14 +60,14 @@
# DocPerm
{
- 'doctype': u'DocPerm'
+ 'amend': 0,
+ 'doctype': u'DocPerm',
+ 'submit': 0
},
# DocPerm
{
- 'amend': 0,
- 'doctype': u'DocPerm',
- 'submit': 0
+ 'doctype': u'DocPerm'
},
# DocField
@@ -74,7 +75,7 @@
'doctype': u'DocField',
'fieldname': u'year_details',
'fieldtype': u'Section Break',
- 'label': u'Year Details',
+ 'label': u'Fiscal Year Details',
'oldfieldtype': u'Section Break',
'permlevel': 0
},
@@ -92,6 +93,8 @@
# DocField
{
+ 'colour': u'White:FFF',
+ 'description': u'For e.g. 2012, 2012-13',
'doctype': u'DocField',
'fieldname': u'year',
'fieldtype': u'Data',
@@ -105,18 +108,6 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'abbreviation',
- 'fieldtype': u'Data',
- 'label': u'Abbreviation',
- 'oldfieldname': u'abbreviation',
- 'oldfieldtype': u'Data',
- 'permlevel': 0,
- 'reqd': 1
- },
-
- # DocField
- {
- 'doctype': u'DocField',
'fieldname': u'year_start_date',
'fieldtype': u'Date',
'label': u'Year Start Date',
@@ -128,6 +119,9 @@
# DocField
{
+ 'colour': u'White:FFF',
+ 'default': u'No',
+ 'description': u'Entries are not allowed against this Fiscal Year if the year is closed.',
'doctype': u'DocField',
'fieldname': u'is_fiscal_year_closed',
'fieldtype': u'Select',
@@ -137,65 +131,5 @@
'options': u'\nNo\nYes',
'permlevel': 0,
'reqd': 0
- },
-
- # DocField
- {
- 'colour': u'White:FFF',
- 'description': u"Click on the button below to reset balances from your previous year's closing and repost your balances. You can use this if your previous year balance sheet has been changed and you wish to update your current accounts.",
- 'doctype': u'DocField',
- 'fieldname': u'repost_accounts',
- 'fieldtype': u'Section Break',
- 'label': u'Repost Accounts',
- 'oldfieldtype': u'Section Break',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'past_year',
- 'fieldtype': u'Select',
- 'label': u'Past Year',
- 'oldfieldname': u'past_year',
- 'oldfieldtype': u'Select',
- 'options': u'link:Fiscal Year',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'company',
- 'fieldtype': u'Link',
- 'in_filter': 0,
- 'label': u'Company',
- 'oldfieldname': u'company',
- 'oldfieldtype': u'Link',
- 'options': u'Company',
- 'permlevel': 0,
- 'search_index': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'repost_account_balances',
- 'fieldtype': u'Button',
- 'label': u'Repost Account Balances',
- 'oldfieldtype': u'Button',
- 'options': u'repost',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'repost_voucher_outstanding',
- 'fieldtype': u'Button',
- 'label': u'Repost Voucher Outstanding',
- 'oldfieldtype': u'Button',
- 'options': u'update_voucher_outstanding',
- 'permlevel': 0
}
]
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/gl_control/gl_control.py b/erpnext/accounts/doctype/gl_control/gl_control.py
index bfeddb0..ef8960c 100644
--- a/erpnext/accounts/doctype/gl_control/gl_control.py
+++ b/erpnext/accounts/doctype/gl_control/gl_control.py
@@ -123,6 +123,7 @@
ac.fields[d] = arg[d]
ac.old_parent = ''
ac_obj = get_obj(doc=ac)
+ ac_obj.doc.freeze_account='No'
ac_obj.validate()
ac_obj.doc.save(1)
ac_obj.on_update()
diff --git a/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.txt b/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.txt
index 74fd697..096050d 100644
--- a/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.txt
+++ b/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-03-27 14:35:46',
+ 'creation': '2012-07-03 13:30:49',
'docstatus': 0,
- 'modified': '2012-03-27 14:35:46',
+ 'modified': '2012-07-12 14:08:27',
'modified_by': u'Administrator',
'owner': u'wasim@webnotestech.com'
},
@@ -24,7 +24,7 @@
'section_style': u'Tray',
'server_code_error': u' ',
'show_in_menu': 0,
- 'version': 13
+ 'version': 1
},
# These values are common for all DocField
@@ -45,34 +45,6 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'category',
- 'fieldtype': u'Select',
- 'label': u'Category',
- 'oldfieldname': u'category',
- 'oldfieldtype': u'Select',
- 'options': u'\nFor Total\nFor Valuation\nFor Both',
- 'permlevel': 0,
- 'reqd': 1
- },
-
- # DocField
- {
- 'default': u'Add',
- 'doctype': u'DocField',
- 'fieldname': u'add_deduct_tax',
- 'fieldtype': u'Select',
- 'label': u'Add or Deduct',
- 'oldfieldname': u'add_deduct_tax',
- 'oldfieldtype': u'Select',
- 'options': u'\nAdd\nDeduct',
- 'permlevel': 0,
- 'reqd': 1,
- 'trigger': u'Client'
- },
-
- # DocField
- {
- 'doctype': u'DocField',
'fieldname': u'charge_type',
'fieldtype': u'Select',
'label': u'Type',
@@ -87,46 +59,6 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'row_id',
- 'fieldtype': u'Data',
- 'hidden': 0,
- 'label': u'Enter Row',
- 'oldfieldname': u'row_id',
- 'oldfieldtype': u'Data',
- 'permlevel': 0,
- 'trigger': u'Client'
- },
-
- # DocField
- {
- 'colour': u'White:FFF',
- 'doctype': u'DocField',
- 'fieldname': u'item_wise_tax_detail',
- 'fieldtype': u'Small Text',
- 'hidden': 1,
- 'label': u'Item Wise Tax Detail ',
- 'oldfieldname': u'item_wise_tax_detail',
- 'oldfieldtype': u'Small Text',
- 'permlevel': 1,
- 'print_hide': 1
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'description',
- 'fieldtype': u'Small Text',
- 'label': u'Description',
- 'oldfieldname': u'description',
- 'oldfieldtype': u'Small Text',
- 'permlevel': 0,
- 'reqd': 1,
- 'width': u'300px'
- },
-
- # DocField
- {
- 'doctype': u'DocField',
'fieldname': u'account_head',
'fieldtype': u'Link',
'label': u'Account Head',
@@ -154,6 +86,19 @@
# DocField
{
'doctype': u'DocField',
+ 'fieldname': u'description',
+ 'fieldtype': u'Small Text',
+ 'label': u'Description',
+ 'oldfieldname': u'description',
+ 'oldfieldtype': u'Small Text',
+ 'permlevel': 0,
+ 'reqd': 1,
+ 'width': u'300px'
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
'fieldname': u'rate',
'fieldtype': u'Currency',
'label': u'Rate',
@@ -182,7 +127,7 @@
'doctype': u'DocField',
'fieldname': u'total',
'fieldtype': u'Currency',
- 'label': u'Aggregate Total',
+ 'label': u'Total',
'oldfieldname': u'total',
'oldfieldtype': u'Currency',
'permlevel': 1
@@ -191,6 +136,64 @@
# DocField
{
'doctype': u'DocField',
+ 'fieldname': u'row_id',
+ 'fieldtype': u'Data',
+ 'hidden': 0,
+ 'label': u'Enter Row',
+ 'oldfieldname': u'row_id',
+ 'oldfieldtype': u'Data',
+ 'permlevel': 0,
+ 'trigger': u'Client'
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'description': u'For Both',
+ 'doctype': u'DocField',
+ 'fieldname': u'category',
+ 'fieldtype': u'Select',
+ 'label': u'Consider Tax or Charge for',
+ 'oldfieldname': u'category',
+ 'oldfieldtype': u'Select',
+ 'options': u'Valuation and Total\nValuation\nTotal',
+ 'permlevel': 0,
+ 'reqd': 1
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'default': u'Add',
+ 'doctype': u'DocField',
+ 'fieldname': u'add_deduct_tax',
+ 'fieldtype': u'Select',
+ 'label': u'Add or Deduct',
+ 'oldfieldname': u'add_deduct_tax',
+ 'oldfieldtype': u'Select',
+ 'options': u'Add\nDeduct',
+ 'permlevel': 0,
+ 'reqd': 1,
+ 'trigger': u'Client'
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'doctype': u'DocField',
+ 'fieldname': u'item_wise_tax_detail',
+ 'fieldtype': u'Small Text',
+ 'hidden': 1,
+ 'label': u'Item Wise Tax Detail ',
+ 'oldfieldname': u'item_wise_tax_detail',
+ 'oldfieldtype': u'Small Text',
+ 'permlevel': 1,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
'fieldname': u'parenttype',
'fieldtype': u'Data',
'hidden': 1,
diff --git a/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js b/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js
index d3a32e9..fa2c836 100644
--- a/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js
+++ b/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js
@@ -22,7 +22,7 @@
}
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
-
+ cur_frm.set_footnote(wn.markdown(cur_frm.meta.description));
}
cur_frm.pformat.purchase_tax_details= function(doc){
@@ -74,7 +74,7 @@
alert("Please select Category first");
d.add_deduct_tax = '';
}
- else if(d.category != 'For Total' && d.add_deduct_tax == 'Deduct'){
+ else if(d.category != 'Total' && d.add_deduct_tax == 'Deduct'){
alert("You cannot Deduct when category is for valuation or for both(i.e total and valuation)");
d.add_deduct_tax = '';
}
@@ -91,8 +91,8 @@
alert("You cannot select Charge Type as 'On Previous Row Amount' or 'On Previous Row Total' for first row");
d.charge_type = '';
}
- else if((d.category == 'For Valuation' || d.category == 'For Both') && (d.charge_type == 'On Previous Row Amount' || d.charge_type == 'On Previous Row Total')){
- alert("You cannot select charge type as 'On Previous Row Amount' or 'On Previous Row Total' for valuation. You can select only 'For Total' option for previous row amount or previous row total")
+ else if((d.category == 'Valuation' || d.category == 'Valuation and Total') && (d.charge_type == 'On Previous Row Amount' || d.charge_type == 'On Previous Row Total')){
+ alert("You cannot select charge type as 'On Previous Row Amount' or 'On Previous Row Total' for valuation. You can select only 'Total' option for previous row amount or previous row total")
d.charge_type = '';
}
validated = false;
diff --git a/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.txt b/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.txt
index 1ecac40..8add7af 100644
--- a/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.txt
+++ b/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-03-27 14:35:51',
+ 'creation': '2012-07-03 13:30:50',
'docstatus': 0,
- 'modified': '2012-03-27 14:35:51',
+ 'modified': '2012-07-12 14:10:35',
'modified_by': u'Administrator',
'owner': u'wasim@webnotestech.com'
},
@@ -17,6 +17,7 @@
'autoname': u'field:title',
'colour': u'White:FFF',
'default_print_format': u'Standard',
+ 'description': u'Standard tax template that can be applied to all Purchase Transactions. This template can contain list of tax heads and also other expense heads like "Shipping", "Insurance", "Handling" etc.\n\n#### Note\n\nThe tax rate you define here will be the standard tax rate for all **Items**. If there are **Items** that have different rates, they must be added in the **Item Tax** table in the **Item** master.\n\n#### Description of Columns\n\n1. Calculation Type: \n - This can be on **Net Total** (that is the sum of basic amount).\n - **On Previous Row Total / Amount** (for cumulative taxes or charges). If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total.\n - **Actual** (as mentioned).\n2. Account Head: The Account ledger under which this tax will be booked\n3. Cost Center: If the tax / charge is an income (like shipping) or expense it needs to be booked against a Cost Center.\n4. Description: Description of the tax (that will be printed in invoices / quotes).\n5. Rate: Tax rate.\n6. Amount: Tax amount.\n7. Total: Cumulative total to this point.\n8. Enter Row: If based on "Previous Row Total" you can select the row number which will be taken as a base for this calculation (default is the previous row).\n9. Consider Tax or Charge for: In this section you can specify if the tax / charge is only for valuation (not a part of total) or only for total (does not add value to the item) or for both.\n10. Add or Deduct: Whether you want to add or deduct the tax.',
'doctype': 'DocType',
'document_type': u'Master',
'module': u'Accounts',
@@ -24,7 +25,7 @@
'section_style': u'Simple',
'server_code_error': u' ',
'show_in_menu': 0,
- 'version': 18
+ 'version': 1
},
# These values are common for all DocField
@@ -109,22 +110,22 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'company',
- 'fieldtype': u'Link',
- 'in_filter': 1,
- 'label': u'Company',
- 'options': u'Company',
- 'reqd': 1
- },
-
- # DocField
- {
- 'doctype': u'DocField',
'fieldname': u'purchase_tax_details',
'fieldtype': u'Table',
'label': u'Purchase Taxes and Charges',
'oldfieldname': u'purchase_tax_details',
'oldfieldtype': u'Table',
'options': u'Purchase Taxes and Charges'
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'company',
+ 'fieldtype': u'Link',
+ 'in_filter': 1,
+ 'label': u'Company',
+ 'options': u'Company',
+ 'reqd': 1
}
-]
+]
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 82314ca..eb869e5 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -40,18 +40,12 @@
self.fname = 'entries'
- # Autoname
- # ---------
def autoname(self):
self.doc.name = make_autoname(self.doc.naming_series+ '.#####')
-
-# ********************************* Trigger Functions ******************************
-
- #Set retail related fields from pos settings
- #-------------------------------------------------------------------------
def set_pos_fields(self):
+ """Set retail related fields from pos settings"""
pos = webnotes.conn.sql("select * from `tabPOS Setting` where ifnull(user,'') = '%s' and company = '%s'" % (session['user'], self.doc.company), as_dict=1)
if not pos:
pos = webnotes.conn.sql("select * from `tabPOS Setting` where ifnull(user,'') = '' and company = '%s'" % (self.doc.company), as_dict=1)
@@ -79,9 +73,8 @@
if self.doc.charge: self.get_other_charges()
- # Set default values related to pos for previously created sales invoice.
- # --------------------------------------------------------------------------
def set_pos_item_values(self):
+ """Set default values related to pos for previously created sales invoice."""
if cint(self.doc.is_pos) ==1:
dtl = webnotes.conn.sql("select income_account, warehouse, cost_center from `tabPOS Setting` where ifnull(user,'') = '%s' and company = '%s'" % (session['user'], self.doc.company), as_dict=1)
if not dtl:
@@ -94,10 +87,8 @@
d.warehouse = item and item[0]['default_warehouse'] or dtl and dtl[0]['warehouse'] or d.warehouse
-
- # Get Account Head to which amount needs to be Debited based on Customer
- # ----------------------------------------------------------------------
def get_customer_account(self):
+ """Get Account Head to which amount needs to be Debited based on Customer"""
if not self.doc.company:
msgprint("Please select company first and re-select the customer after doing so", raise_exception=1)
@@ -115,10 +106,8 @@
return acc_head and {'debit_to' : acc_head} or {}
-
- # Set Due Date = Posting Date + Credit Days
- # -----------------------------------------
def get_cust_and_due_date(self):
+ """Set Due Date = Posting Date + Credit Days"""
credit_days = 0
if self.doc.debit_to:
credit_days = webnotes.conn.sql("select credit_days from `tabAccount` where name='%s' and docstatus != 2" % self.doc.debit_to)
@@ -134,9 +123,8 @@
self.doc.customer = webnotes.conn.get_value('Account',self.doc.debit_to,'master_name')
- # Pull Details of Delivery Note or Sales Order Selected
- # ------------------------------------------------------
def pull_details(self):
+ """Pull Details of Delivery Note or Sales Order Selected"""
# Delivery Note
if self.doc.delivery_note_main:
self.validate_prev_docname('delivery note')
@@ -153,14 +141,14 @@
ret = self.get_debit_to()
self.doc.debit_to = ret.get('debit_to')
- # onload pull income account
- # --------------------------
+
def load_default_accounts(self):
"""
Loads default accounts from items, customer when called from mapper
"""
self.get_income_account('entries')
+
def get_income_account(self,doctype):
for d in getlist(self.doclist, doctype):
if d.item_code:
@@ -168,8 +156,7 @@
d.income_account = item and item[0]['default_income_account'] or ''
d.cost_center = item and item[0]['default_sales_cost_center'] or ''
- # Item Details
- # -------------
+
def get_item_details(self, args=None):
import json
args = args and json.loads(args) or {}
@@ -215,61 +202,49 @@
return get_obj('Sales Common').get_barcode_details(barcode)
- # Fetch ref rate from item master as per selected price list
def get_adj_percent(self, arg=''):
+ """Fetch ref rate from item master as per selected price list"""
get_obj('Sales Common').get_adj_percent(self)
- # Get tax rate if account type is tax
- # ------------------------------------
def get_rate(self,arg):
+ """Get tax rate if account type is tax"""
get_obj('Sales Common').get_rate(arg)
- # Get Commission rate of Sales Partner
- # -------------------------------------
def get_comm_rate(self, sales_partner):
+ """Get Commission rate of Sales Partner"""
return get_obj('Sales Common').get_comm_rate(sales_partner, self)
-
- # GET TERMS & CONDITIONS
- # -------------------------------------
+
def get_tc_details(self):
return get_obj('Sales Common').get_tc_details(self)
- # Load Default Charges
- # ----------------------------------------------------------
+
def load_default_taxes(self):
self.doclist = get_obj('Sales Common').load_default_taxes(self)
- # Get Sales Taxes and Charges Master Details
- # --------------------------
+
def get_other_charges(self):
self.doclist = get_obj('Sales Common').get_other_charges(self)
- # Get Advances
- # -------------
+
def get_advances(self):
self.doclist = get_obj('GL Control').get_advances(self, self.doc.debit_to, 'Sales Invoice Advance', 'advance_adjustment_details', 'credit')
- #pull project customer
- #-------------------------
+
def pull_project_customer(self):
res = webnotes.conn.sql("select customer from `tabProject` where name = '%s'"%self.doc.project_name)
if res:
get_obj('DocType Mapper', 'Project-Sales Invoice').dt_map('Project', 'Sales Invoice', self.doc.project_name, self.doc, self.doclist, "[['Project', 'Sales Invoice']]")
-# ********************************** Server Utility Functions ******************************
-
- # Get Company Abbr.
- # ------------------
+
def get_company_abbr(self):
return webnotes.conn.sql("select abbr from tabCompany where name=%s", self.doc.company)[0][0]
-
- # Check whether sales order / delivery note items already pulled
- #----------------------------------------------------------------
+
def validate_prev_docname(self,doctype):
+ """Check whether sales order / delivery note items already pulled"""
for d in getlist(self.doclist, 'entries'):
if doctype == 'delivery note' and self.doc.delivery_note_main == d.delivery_note:
msgprint(cstr(self.doc.delivery_note_main) + " delivery note details have already been pulled.")
@@ -279,7 +254,6 @@
raise Exception , "Validation Error. Sales order details have already been pulled."
- #-----------------------------------------------------------------
def update_against_document_in_jv(self):
"""
Links invoice and advance voucher:
@@ -308,11 +282,8 @@
get_obj('GL Control').reconcile_against_document(lst)
- # ------------------------------------------------------------------------
def validate_customer(self):
- """
- Validate customer name with SO and DN
- """
+ """ Validate customer name with SO and DN"""
for d in getlist(self.doclist,'entries'):
dt = d.delivery_note and 'Delivery Note' or d.sales_order and 'Sales Order' or ''
if dt:
@@ -322,9 +293,8 @@
msgprint("Customer %s does not match with customer of %s: %s." %(self.doc.customer, dt, dt_no), raise_exception=1)
- # Validates Debit To Account and Customer Matches
- # ------------------------------------------------
- def validate_debit_to_acc(self):
+ def validate_customer_account(self):
+ """Validates Debit To Account and Customer Matches"""
if self.doc.customer and self.doc.debit_to and not cint(self.doc.is_pos):
acc_head = webnotes.conn.sql("select master_name from `tabAccount` where name = %s and docstatus != 2", self.doc.debit_to)
@@ -334,11 +304,6 @@
and Master Name in account master." %(self.doc.debit_to, self.doc.customer,self.doc.company), raise_exception=1)
- # Validate Debit To Account
- # 1. Account Exists
- # 2. Is a Debit Account
- # 3. Is a PL Account
- # ---------------------------
def validate_debit_acc(self):
acc = webnotes.conn.sql("select debit_or_credit, is_pl_account from tabAccount where name = '%s' and docstatus != 2" % self.doc.debit_to)
if not acc:
@@ -352,9 +317,8 @@
raise Exception
- # Validate Fixed Asset Account and whether Income Account Entered Exists
- # -----------------------------------------------------------------------
def validate_fixed_asset_account(self):
+ """Validate Fixed Asset Account and whether Income Account Entered Exists"""
for d in getlist(self.doclist,'entries'):
item = webnotes.conn.sql("select name,is_asset_item,is_sales_item from `tabItem` where name = '%s' and (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now())"% d.item_code)
acc = webnotes.conn.sql("select account_type from `tabAccount` where name = '%s' and docstatus != 2" % d.income_account)
@@ -366,22 +330,16 @@
raise Exception
-
- # Set totals in words
- #--------------------
def set_in_words(self):
dcc = TransactionBase().get_company_currency(self.doc.company)
self.doc.in_words = get_obj('Sales Common').get_total_in_words(dcc, self.doc.rounded_total)
self.doc.in_words_export = get_obj('Sales Common').get_total_in_words(self.doc.currency, self.doc.rounded_total_export)
- # Clear Advances
- # --------------
+
def clear_advances(self):
get_obj('GL Control').clear_advances(self, 'Sales Invoice Advance','advance_adjustment_details')
- # set aging date
- #-------------------
def set_aging_date(self):
if self.doc.is_opening != 'Yes':
self.doc.aging_date = self.doc.posting_date
@@ -390,20 +348,21 @@
raise Exception
- # Set against account for debit to account
- #------------------------------------------
def set_against_income_account(self):
+ """Set against account for debit to account"""
against_acc = []
for d in getlist(self.doclist, 'entries'):
if d.income_account not in against_acc:
against_acc.append(d.income_account)
self.doc.against_income_account = ','.join(against_acc)
+
def add_remarks(self):
if not self.doc.remarks: self.doc.remarks = 'No Remarks'
- #check in manage account if sales order / delivery note required or not.
+
def so_dn_required(self):
+ """check in manage account if sales order / delivery note required or not."""
dict = {'Sales Order':'so_required','Delivery Note':'dn_required'}
for i in dict:
res = webnotes.conn.sql("select value from `tabSingles` where doctype = 'Global Defaults' and field = '%s'"%dict[i])
@@ -413,9 +372,9 @@
msgprint("%s No. required against item %s"%(i,d.item_code))
raise Exception
- #check for does customer belong to same project as entered..
- #-------------------------------------------------------------------------------------------------
+
def validate_proj_cust(self):
+ """check for does customer belong to same project as entered.."""
if self.doc.project_name and self.doc.customer:
res = webnotes.conn.sql("select name from `tabProject` where name = '%s' and (customer = '%s' or ifnull(customer,'')='')"%(self.doc.project_name, self.doc.customer))
if not res:
@@ -431,20 +390,13 @@
raise Exception
- # ********* UPDATE CURRENT STOCK *****************************
- def update_current_stock(self):
- for d in getlist(self.doclist, 'entries'):
- bin = webnotes.conn.sql("select actual_qty from `tabBin` where item_code = %s and warehouse = %s", (d.item_code, d.warehouse), as_dict = 1)
- d.actual_qty = bin and flt(bin[0]['actual_qty']) or 0
-
def validate_item_code(self):
for d in getlist(self.doclist, 'entries'):
if not d.item_code:
msgprint("Please enter Item Code at line no : %s to update stock for POS or remove check from Update Stock in Basic Info Tab." % (d.idx))
raise Exception
- # Validate Write Off Account
- # -------------------------------
+
def validate_write_off_account(self):
if flt(self.doc.write_off_amount) and not self.doc.write_off_account:
msgprint("Please enter Write Off Account", raise_exception=1)
@@ -457,12 +409,22 @@
and parent = %s""", (self.doc.amended_from, self.doc.c_form_no))
webnotes.conn.set(self.doc, 'c_form_no', '')
+
+
+ def update_current_stock(self):
+ for d in getlist(self.doclist, 'entries'):
+ if d.item_code and d.warehouse:
+ bin = webnotes.conn.sql("select actual_qty from `tabBin` where item_code = %s and warehouse = %s", (d.item_code, d.warehouse), as_dict = 1)
+ d.actual_qty = bin and flt(bin[0]['actual_qty']) or 0
+
+ for d in getlist(self.doclist, 'packing_details'):
+ bin = sql("select actual_qty, projected_qty from `tabBin` where item_code = %s and warehouse = %s", (d.item_code, d.warehouse), as_dict = 1)
+ d.actual_qty = bin and flt(bin[0]['actual_qty']) or 0
+ d.projected_qty = bin and flt(bin[0]['projected_qty']) or 0
- # VALIDATE
- # ====================================================================================
+
def validate(self):
self.so_dn_required()
- #self.dn_required()
self.validate_proj_cust()
sales_com_obj = get_obj('Sales Common')
sales_com_obj.check_stop_sales_order(self)
@@ -472,7 +434,7 @@
sales_com_obj.get_allocated_sum(self) # this is to verify that the allocated % of sales persons is 100%
sales_com_obj.validate_fiscal_year(self.doc.fiscal_year,self.doc.posting_date,'Posting Date')
self.validate_customer()
- self.validate_debit_to_acc()
+ self.validate_customer_account()
self.validate_debit_acc()
self.validate_fixed_asset_account()
self.add_remarks()
@@ -480,7 +442,9 @@
self.validate_pos()
self.validate_write_off_account()
if cint(self.doc.update_stock):
- get_obj('Stock Ledger').validate_serial_no(self, 'entries')
+ sl = get_obj('Stock Ledger')
+ sl.validate_serial_no(self, 'entries')
+ sl.validate_serial_no(self, 'packing_details')
self.validate_item_code()
self.update_current_stock()
self.set_in_words()
@@ -488,14 +452,62 @@
self.doc.is_opening = 'No'
self.set_aging_date()
self.clear_advances()
- # Set against account
self.set_against_income_account()
self.validate_c_form()
+
+ def get_warehouse(self):
+ w = webnotes.conn.sql("select warehouse from `tabPOS Setting` where ifnull(user,'') = '%s' and company = '%s'" % (session['user'], self.doc.company))
+ w = w and w[0][0] or ''
+ if not w:
+ ps = webnotes.conn.sql("select name, warehouse from `tabPOS Setting` where ifnull(user,'') = '' and company = '%s'" % self.doc.company)
+ if not ps:
+ msgprint("To make POS entry, please create POS Setting from Accounts --> POS Setting page and refresh the system.")
+ raise Exception
+ elif not ps[0][1]:
+ msgprint("Please enter warehouse in POS Setting")
+ else:
+ w = ps[0][1]
+ return w
+
+
+ def make_packing_list(self):
+ get_obj('Sales Common').make_packing_list(self,'entries')
+ sl = get_obj('Stock Ledger')
+ sl.scrub_serial_nos(self)
+ sl.scrub_serial_nos(self, 'packing_details')
+
+
+ def on_update(self):
+ # Set default warehouse from pos setting
+ if cint(self.doc.is_pos) == 1:
+ if cint(self.doc.update_stock) == 1:
+ w = self.get_warehouse()
+ if w:
+ for d in getlist(self.doclist, 'entries'):
+ if not d.warehouse:
+ d.warehouse = cstr(w)
+
+ self.make_packing_list()
+ else:
+ self.doclist = self.doc.clear_table(self.doclist, 'packing_details')
+
+ if flt(self.doc.paid_amount) == 0:
+ if self.doc.cash_bank_account:
+ webnotes.conn.set(self.doc, 'paid_amount',
+ (flt(self.doc.grand_total) - flt(self.doc.write_off_amount)))
+ else:
+ # show message that the amount is not paid
+ webnotes.conn.set(self.doc,'paid_amount',0)
+ webnotes.msgprint("Note: Payment Entry will not be created since 'Cash/Bank Account' was not specified.")
+
+ else:
+ self.doclist = self.doc.clear_table(self.doclist, 'packing_details')
+ webnotes.conn.set(self.doc,'paid_amount',0)
+
+ webnotes.conn.set(self.doc,'outstanding_amount',flt(self.doc.grand_total) - flt(self.doc.total_advance) - flt(self.doc.paid_amount) - flt(self.doc.write_off_amount))
+
-# *************************************************** ON SUBMIT **********************************************
- # Check Ref Document's docstatus
- # -------------------------------
def check_prev_docstatus(self):
for d in getlist(self.doclist,'entries'):
if d.sales_order:
@@ -511,56 +523,45 @@
raise Exception , "Validation Error."
- #Set Actual Qty based on item code and warehouse
- #------------------------------------------------------
- def set_actual_qty(self):
- for d in getlist(self.doclist, 'entries'):
- if d.item_code and d.warehouse:
- actual_qty = webnotes.conn.sql("select actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (d.item_code, d.warehouse))
- d.actual_qty = actual_qty and flt(actual_qty[0][0]) or 0
-
-
-
- # ********************** Make Stock Entry ************************************
def make_sl_entry(self, d, wh, qty, in_value, update_stock):
- st_uom = webnotes.conn.sql("select stock_uom from `tabItem` where name = '%s'"%d.item_code)
+ st_uom = webnotes.conn.sql("select stock_uom from `tabItem` where name = '%s'"%d['item_code'])
self.values.append({
- 'item_code' : d.item_code,
+ 'item_code' : d['item_code'],
'warehouse' : wh,
'transaction_date' : getdate(self.doc.modified).strftime('%Y-%m-%d'),
'posting_date' : self.doc.posting_date,
'posting_time' : self.doc.posting_time,
'voucher_type' : 'Sales Invoice',
'voucher_no' : cstr(self.doc.name),
- 'voucher_detail_no' : cstr(d.name),
+ 'voucher_detail_no' : cstr(d['name']),
'actual_qty' : qty,
'stock_uom' : st_uom and st_uom[0][0] or '',
'incoming_rate' : in_value,
'company' : self.doc.company,
'fiscal_year' : self.doc.fiscal_year,
'is_cancelled' : (update_stock==1) and 'No' or 'Yes',
- 'batch_no' : cstr(d.batch_no),
- 'serial_no' : d.serial_no
- })
+ 'batch_no' : cstr(d['batch_no']),
+ 'serial_no' : d['serial_no']
+ })
- # UPDATE STOCK LEDGER
- # ---------------------------------------------------------------------------
- def update_stock_ledger(self, update_stock, clear = 0):
+ def update_stock_ledger(self, update_stock):
self.values = []
- for d in getlist(self.doclist, 'entries'):
- stock_item = webnotes.conn.sql("SELECT is_stock_item, is_sample_item FROM tabItem where name = '%s'"%(d.item_code), as_dict = 1) # stock ledger will be updated only if it is a stock item
+ items = get_obj('Sales Common').get_item_list(self)
+ for d in items:
+ stock_item = webnotes.conn.sql("SELECT is_stock_item, is_sample_item \
+ FROM tabItem where name = '%s'"%(d['item_code']), as_dict = 1)
if stock_item[0]['is_stock_item'] == "Yes":
+ if not d['warehouse']:
+ msgprint("Message: Please enter Warehouse for item %s as it is stock item." \
+ % d['item_code'], raise_exception=1)
+
# Reduce actual qty from warehouse
- self.make_sl_entry( d, d.warehouse, - flt(d.qty) , 0, update_stock)
- get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values, self.doc.amended_from and 'Yes' or 'No')
-
-
- #-------------------POS Stock Updatation Part----------------------------------------------
- def pos_update_stock(self):
- self.update_stock_ledger(update_stock = 1)
+ self.make_sl_entry( d, d['warehouse'], - flt(d['qty']) , 0, update_stock)
+
+ get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values)
- # ********** Get Actual Qty of item in warehouse selected *************
+
def get_actual_qty(self,args):
args = eval(args)
actual_qty = webnotes.conn.sql("select actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (args['item_code'], args['warehouse']), as_dict=1)
@@ -569,23 +570,39 @@
}
return ret
- # Make GL Entries
- # -------------------------
+
def make_gl_entries(self, is_cancel=0):
mapper = self.doc.is_pos and self.doc.write_off_account and 'POS with write off' or self.doc.is_pos and not self.doc.write_off_account and 'POS' or ''
update_outstanding = self.doc.is_pos and self.doc.write_off_account and 'No' or 'Yes'
get_obj(dt='GL Control').make_gl_entries(self.doc, self.doclist,cancel = is_cancel, use_mapper = mapper, update_outstanding = update_outstanding, merge_entries = cint(self.doc.is_pos) != 1 and 1 or 0)
- # On Submit
- # ---------
+ def update_c_form(self):
+ """Update amended id in C-form"""
+ if self.doc.c_form_no and self.doc.amended_from:
+ webnotes.conn.sql("""update `tabC-Form Invoice Detail` set invoice_no = %s,
+ invoice_date = %s, territory = %s, net_total = %s,
+ grand_total = %s where invoice_no = %s and parent = %s""", (self.doc.name, self.doc.amended_from, self.doc.c_form_no))
+
+
+ def check_next_docstatus(self):
+ submit_jv = webnotes.conn.sql("select t1.name from `tabJournal Voucher` t1,`tabJournal Voucher Detail` t2 where t1.name = t2.parent and t2.against_invoice = '%s' and t1.docstatus = 1" % (self.doc.name))
+ if submit_jv:
+ msgprint("Journal Voucher : " + cstr(submit_jv[0][0]) + " has been created against " + cstr(self.doc.doctype) + ". So " + cstr(self.doc.doctype) + " cannot be Cancelled.")
+ raise Exception, "Validation Error."
+
+
def on_submit(self):
if cint(self.doc.is_pos) == 1:
if cint(self.doc.update_stock) == 1:
sl_obj = get_obj("Stock Ledger")
sl_obj.validate_serial_no_warehouse(self, 'entries')
+ sl_obj.validate_serial_no_warehouse(self, 'packing_details')
+
sl_obj.update_serial_record(self, 'entries', is_submit = 1, is_incoming = 0)
- self.pos_update_stock()
+ sl_obj.update_serial_record(self, 'packing_details', is_submit = 1, is_incoming = 0)
+
+ self.update_stock_ledger(update_stock=1)
else:
self.check_prev_docstatus()
get_obj("Sales Common").update_prevdoc_detail(1,self)
@@ -603,31 +620,13 @@
self.update_c_form()
- def update_c_form(self):
- """Update amended id in C-form"""
- if self.doc.c_form_no and self.doc.amended_from:
- webnotes.conn.sql("""update `tabC-Form Invoice Detail` set invoice_no = %s,
- invoice_date = %s, territory = %s, net_total = %s,
- grand_total = %s where invoice_no = %s and parent = %s""", (self.doc.name, self.doc.amended_from, self.doc.c_form_no))
-
-
-
-# *************************************************** ON CANCEL **********************************************
- # Check Next Document's docstatus
- # --------------------------------
- def check_next_docstatus(self):
- submit_jv = webnotes.conn.sql("select t1.name from `tabJournal Voucher` t1,`tabJournal Voucher Detail` t2 where t1.name = t2.parent and t2.against_invoice = '%s' and t1.docstatus = 1" % (self.doc.name))
- if submit_jv:
- msgprint("Journal Voucher : " + cstr(submit_jv[0][0]) + " has been created against " + cstr(self.doc.doctype) + ". So " + cstr(self.doc.doctype) + " cannot be Cancelled.")
- raise Exception, "Validation Error."
-
-
- # On Cancel
- # ----------
def on_cancel(self):
if cint(self.doc.is_pos) == 1:
if cint(self.doc.update_stock) == 1:
- get_obj('Stock Ledger').update_serial_record(self, 'entries', is_submit = 0, is_incoming = 0)
+ sl = get_obj('Stock Ledger')
+ sl.update_serial_record(self, 'entries', is_submit = 0, is_incoming = 0)
+ sl.update_serial_record(self, 'packing_details', is_submit = 0, is_incoming = 0)
+
self.update_stock_ledger(update_stock = -1)
else:
sales_com_obj = get_obj(dt = 'Sales Common')
@@ -636,51 +635,6 @@
sales_com_obj.update_prevdoc_detail(0,self)
self.make_gl_entries(is_cancel=1)
-
- # Get Warehouse
- def get_warehouse(self):
- w = webnotes.conn.sql("select warehouse from `tabPOS Setting` where ifnull(user,'') = '%s' and company = '%s'" % (session['user'], self.doc.company))
- w = w and w[0][0] or ''
- if not w:
- ps = webnotes.conn.sql("select name, warehouse from `tabPOS Setting` where ifnull(user,'') = '' and company = '%s'" % self.doc.company)
- if not ps:
- msgprint("To make POS entry, please create POS Setting from Setup --> Accounts --> POS Setting and refresh the system.")
- raise Exception
- elif not ps[0][1]:
- msgprint("Please enter warehouse in POS Setting")
- else:
- w = ps[0][1]
- return w
-
- # on update
- def on_update(self):
- # Set default warehouse from pos setting
- #----------------------------------------
- if cint(self.doc.is_pos) == 1:
- self.set_actual_qty()
- w = self.get_warehouse()
- if w:
- for d in getlist(self.doclist, 'entries'):
- if not d.warehouse:
- d.warehouse = cstr(w)
-
- if flt(self.doc.paid_amount) == 0:
- if self.doc.cash_bank_account:
- webnotes.conn.set(self.doc, 'paid_amount',
- (flt(self.doc.grand_total) - flt(self.doc.write_off_amount)))
- else:
- # show message that the amount is not paid
- webnotes.conn.set(self.doc,'paid_amount',0)
- webnotes.msgprint("Note: Payment Entry not created since 'Cash/Bank Account' was not specified.")
-
- else:
- webnotes.conn.set(self.doc,'paid_amount',0)
-
- webnotes.conn.set(self.doc,'outstanding_amount',flt(self.doc.grand_total) - flt(self.doc.total_advance) - flt(self.doc.paid_amount) - flt(self.doc.write_off_amount))
-
- #-------------------------------------------------------------------------------------
- def on_update_after_submit(self):
- self.convert_into_recurring()
def convert_into_recurring(self):
@@ -717,3 +671,7 @@
next_date = next_date.strftime("%Y-%m-%d")
webnotes.conn.set(self.doc, 'next_date', next_date)
+
+
+ def on_update_after_submit(self):
+ self.convert_into_recurring()
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.txt b/erpnext/accounts/doctype/sales_invoice/sales_invoice.txt
index 969a7dc..a2b341f 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.txt
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-06-11 12:09:54',
+ 'creation': '2012-07-05 11:04:09',
'docstatus': 0,
- 'modified': '2012-06-17 21:37:40',
+ 'modified': '2012-07-11 12:19:49',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -353,6 +353,16 @@
# DocField
{
'doctype': u'DocField',
+ 'fieldname': u'sales_bom_help',
+ 'fieldtype': u'HTML',
+ 'label': u'Sales BOM Help',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
'fieldname': u'section_break0',
'fieldtype': u'Section Break',
'options': u'Simple',
@@ -1346,6 +1356,27 @@
# DocField
{
'doctype': u'DocField',
+ 'fieldname': u'packing_list',
+ 'fieldtype': u'Section Break',
+ 'label': u'Packing List',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'packing_details',
+ 'fieldtype': u'Table',
+ 'label': u'Packing Details',
+ 'options': u'Delivery Note Packing Item',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
'fieldname': u'sales_team_section_break',
'fieldtype': u'Section Break',
'label': u'Sales Team',
diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.txt b/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.txt
index 2a25a6a..66d7aae 100644
--- a/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.txt
+++ b/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-05-15 12:14:34',
+ 'creation': '2012-07-04 16:40:13',
'docstatus': 0,
- 'modified': '2012-07-04 13:27:05',
+ 'modified': '2012-07-12 13:50:43',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -113,7 +113,7 @@
'doctype': u'DocField',
'fieldname': u'tax_amount',
'fieldtype': u'Currency',
- 'label': u'Amount*',
+ 'label': u'Amount',
'oldfieldname': u'tax_amount',
'oldfieldtype': u'Currency',
'permlevel': 0,
@@ -126,7 +126,7 @@
'doctype': u'DocField',
'fieldname': u'total',
'fieldtype': u'Currency',
- 'label': u'Total*',
+ 'label': u'Total',
'oldfieldname': u'total',
'oldfieldtype': u'Currency',
'permlevel': 1
diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js
index bae6b74..16bf1bb 100644
--- a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js
+++ b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js
@@ -19,9 +19,9 @@
//
}
-/*cur_frm.cscript.refresh = function(doc, cdt, cdn) {
-
-}*/
+cur_frm.cscript.refresh = function(doc, cdt, cdn) {
+ cur_frm.set_footnote(wn.markdown(cur_frm.meta.description));
+}
// For customizing print
cur_frm.pformat.net_total = function(doc) {
diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.py b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.py
index f5342ed..1750e51 100644
--- a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.py
+++ b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.py
@@ -8,43 +8,25 @@
#
# 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
+# 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/>.
+# 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, doc, doclist=[]):
- self.doc = doc
- self.doclist = doclist
+ def __init__(self, doc, doclist=[]):
+ self.doc = doc
+ self.doclist = doclist
- # Get Tax Rate if account type is Tax
- # ===================================================================
- def get_rate(self, arg):
- get_obj('Sales Common').get_rate(arg, self)
+ def get_rate(self, arg):
+ from webnotes.model.code import get_obj
+ return get_obj('Sales Common').get_rate(arg, self)
- def update_other_default_charges(self):
- sql("update `tabSales Taxes and Charges Master` set is_default = 0 where ifnull(is_default,0) = 1 and name != '%s' and company = '%s'" % (self.doc.name, self.doc.company))
+ def update_other_default_charges(self):
+ webnotes.conn.sql("update `tabSales Taxes and Charges Master` set is_default = 0 where ifnull(is_default,0) = 1 and name != '%s' and company = '%s'" % (self.doc.name, self.doc.company))
- def on_update(self):
- self.update_other_default_charges()
+ def on_update(self):
+ self.update_other_default_charges()
diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.txt b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.txt
index 655269c..1707bf4 100644
--- a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.txt
+++ b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-03-27 14:36:22',
+ 'creation': '2012-07-03 13:30:46',
'docstatus': 0,
- 'modified': '2012-03-27 14:36:22',
+ 'modified': '2012-07-12 13:43:32',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -17,6 +17,7 @@
'autoname': u'field:title',
'colour': u'White:FFF',
'default_print_format': u'Standard',
+ 'description': u'Standard tax template that can be applied to all Sales Transactions. This template can contain list of tax heads and also other expense / income heads like "Shipping", "Insurance", "Handling" etc.\n\n#### Note\n\nThe tax rate you define here will be the standard tax rate for all **Items**. If there are **Items** that have different rates, they must be added in the **Item Tax** table in the **Item** master.\n\n#### Description of Columns\n\n1. Calculation Type: \n - This can be on **Net Total** (that is the sum of basic amount).\n - **On Previous Row Total / Amount** (for cumulative taxes or charges). If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total.\n - **Actual** (as mentioned).\n2. Account Head: The Account ledger under which this tax will be booked\n3. Cost Center: If the tax / charge is an income (like shipping) or expense it needs to be booked against a Cost Center.\n4. Description: Description of the tax (that will be printed in invoices / quotes).\n5. Rate: Tax rate.\n6. Amount: Tax amount.\n7. Total: Cumulative total to this point.\n8. Enter Row: If based on "Previous Row Total" you can select the row number which will be taken as a base for this calculation (default is the previous row).\n9. Is this Tax included in Basic Rate?: If you check this, it means that this tax will not be shown below the item table, but will be included in the Basic Rate in your main item table. This is useful where you want give a flat price (inclusive of all taxes) price to customers.',
'doctype': 'DocType',
'document_type': u'Master',
'module': u'Accounts',
@@ -24,7 +25,7 @@
'section_style': u'Tabbed',
'server_code_error': u' ',
'show_in_menu': 0,
- 'version': 57
+ 'version': 1
},
# These values are common for all DocField
@@ -33,7 +34,8 @@
'name': '__common__',
'parent': u'Sales Taxes and Charges Master',
'parentfield': u'fields',
- 'parenttype': u'DocType'
+ 'parenttype': u'DocType',
+ 'permlevel': 0
},
# These values are common for all DocPerm
@@ -55,6 +57,42 @@
# DocPerm
{
'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 1,
+ 'role': u'Sales Master Manager',
+ 'submit': 0,
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 1,
+ 'role': u'Sales User',
+ 'submit': 0,
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'Sales User',
+ 'submit': 0,
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'amend': 0,
'cancel': 1,
'create': 1,
'doctype': u'DocPerm',
@@ -86,63 +124,6 @@
'write': 1
},
- # DocPerm
- {
- 'amend': 0,
- 'cancel': 0,
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 1,
- 'role': u'Sales Master Manager',
- 'submit': 0,
- 'write': 0
- },
-
- # DocPerm
- {
- 'amend': 0,
- 'cancel': 0,
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 1,
- 'role': u'Sales User',
- 'submit': 0,
- 'write': 0
- },
-
- # DocPerm
- {
- 'amend': 0,
- 'cancel': 0,
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Sales User',
- 'submit': 0,
- 'write': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'trash_reason',
- 'fieldtype': u'Small Text',
- 'label': u'Trash Reason',
- 'oldfieldname': u'trash_reason',
- 'oldfieldtype': u'Small Text',
- 'permlevel': 1
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'other_charges_details',
- 'fieldtype': u'Section Break',
- 'label': u'Other Charges Details',
- 'oldfieldtype': u'Section Break',
- 'permlevel': 0
- },
-
# DocField
{
'doctype': u'DocField',
@@ -152,7 +133,6 @@
'label': u'Title',
'oldfieldname': u'title',
'oldfieldtype': u'Data',
- 'permlevel': 0,
'reqd': 1,
'search_index': 0
},
@@ -162,8 +142,20 @@
'doctype': u'DocField',
'fieldname': u'is_default',
'fieldtype': u'Check',
- 'label': u'Default',
- 'permlevel': 0
+ 'label': u'Default'
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'description': u'* Will be calculated in the transaction.',
+ 'doctype': u'DocField',
+ 'fieldname': u'other_charges',
+ 'fieldtype': u'Table',
+ 'label': u'Sales Taxes and Charges Master',
+ 'oldfieldname': u'other_charges',
+ 'oldfieldtype': u'Table',
+ 'options': u'Sales Taxes and Charges'
},
# DocField
@@ -176,20 +168,7 @@
'oldfieldname': u'company',
'oldfieldtype': u'Link',
'options': u'Company',
- 'permlevel': 0,
'reqd': 1,
'search_index': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'other_charges',
- 'fieldtype': u'Table',
- 'label': u'Sales Taxes and Charges Master',
- 'oldfieldname': u'other_charges',
- 'oldfieldtype': u'Table',
- 'options': u'Sales Taxes and Charges',
- 'permlevel': 0
}
-]
+]
\ No newline at end of file
diff --git a/erpnext/accounts/page/accounts_browser/accounts_browser.js b/erpnext/accounts/page/accounts_browser/accounts_browser.js
index 734e4de..5bc2e35 100644
--- a/erpnext/accounts/page/accounts_browser/accounts_browser.js
+++ b/erpnext/accounts/page/accounts_browser/accounts_browser.js
@@ -62,7 +62,11 @@
pscript['onshow_Accounts Browser'] = function(wrapper){
// set route
var ctype = wn.get_route()[1] || 'Account';
- wrapper.appframe.title('Chart of '+ctype+'s');
+
+ wrapper.appframe.clear_breadcrumbs();
+ wrapper.appframe.add_breadcrumb('Chart of '+ctype+'s');
+ document.title = 'Chart of '+ctype+'s';
+ wrapper.appframe.add_breadcrumb(' in <a href="#!accounts-home">Accounts</a>');
if(erpnext.account_chart && erpnext.account_chart.ctype != ctype) {
wrapper.$company_select.change();
@@ -151,13 +155,12 @@
fields: [
{fieldtype:'Data', fieldname:'account_name', label:'New Account Name', reqd:true},
{fieldtype:'Select', fieldname:'group_or_ledger', label:'Group or Ledger',
- options:'Group\nLedger'},
+ options:'Group\nLedger', description:'Further accounts can be made under Groups,\
+ but entries can be made against Ledger'},
{fieldtype:'Select', fieldname:'account_type', label:'Account Type',
options: ['', 'Fixed Asset Account', 'Bank or Cash', 'Expense Account', 'Tax',
'Income Account', 'Chargeable'].join('\n') },
{fieldtype:'Float', fieldname:'tax_rate', label:'Tax Rate'},
- {fieldtype:'Select', fieldname:'master_type', label:'Master Type',
- options: ['NA', 'Supplier', 'Customer', 'Employee'].join('\n') },
{fieldtype:'Button', fieldname:'create_new', label:'Create New' }
]
})
@@ -168,11 +171,9 @@
$(fd.group_or_ledger.input).change(function() {
if($(this).val()=='Group') {
$(fd.account_type.wrapper).toggle(false);
- $(fd.master_type.wrapper).toggle(false);
$(fd.tax_rate.wrapper).toggle(false);
} else {
$(fd.account_type.wrapper).toggle(true);
- $(fd.master_type.wrapper).toggle(true);
if(fd.account_type.get_value()=='Tax') {
$(fd.tax_rate.wrapper).toggle(true);
}
@@ -197,6 +198,7 @@
var node = me.selected_node();
v.parent_account = node.data('label');
+ v.master_type = '';
v.company = me.company;
$c_obj('GL Control', 'add_ac', v,
@@ -222,10 +224,11 @@
fields: [
{fieldtype:'Data', fieldname:'cost_center_name', label:'New Cost Center Name', reqd:true},
{fieldtype:'Select', fieldname:'group_or_ledger', label:'Group or Ledger',
- options:'Group\nLedger'},
+ options:'Group\nLedger', description:'Further accounts can be made under Groups,\
+ but entries can be made against Ledger'},
{fieldtype:'Button', fieldname:'create_new', label:'Create New' }
]
- })
+ });
// create
$(d.fields_dict.create_new.input).click(function() {
diff --git a/erpnext/hr/doctype/salary_manager/salary_manager.py b/erpnext/hr/doctype/salary_manager/salary_manager.py
index 111366b..a0cbb70 100644
--- a/erpnext/hr/doctype/salary_manager/salary_manager.py
+++ b/erpnext/hr/doctype/salary_manager/salary_manager.py
@@ -24,7 +24,6 @@
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
@@ -46,14 +45,14 @@
"""
cond = self.get_filter_condition()
+ cond += self.get_joining_releiving_condition()
emp_list = sql("""
select t1.name
from `tabEmployee` t1, `tabSalary Structure` t2
where t1.docstatus!=2 and t2.docstatus != 2
- and ifnull(t1.status, 'Left') = 'Active' and ifnull(t2.is_active, 'No') = 'Yes'
and t1.name = t2.employee
- %s """% cond)
+ %s """% cond, debug=1)
return emp_list
@@ -64,9 +63,19 @@
cond = ''
for f in ['company', 'branch', 'department', 'designation', 'grade']:
if self.doc.fields.get(f):
- cond += " and t1." + f + " = '" + self.doc.fields.get(f) + "'"
-
+ cond += " and t1." + f + " = '" + self.doc.fields.get(f) + "'"
+
return cond
+
+
+ def get_joining_releiving_condition(self):
+ m = self.get_month_details(self.doc.fiscal_year, self.doc.month)
+ cond = """
+ and ifnull(t1.date_of_joining, '0000-00-00') <= '%(month_end_date)s'
+ and ifnull(t1.relieving_date, '2199-12-31') >= '%(month_start_date)s'
+ """ % m
+ return cond
+
def check_mandatory(self):
@@ -74,6 +83,26 @@
if not self.doc.fields[f]:
msgprint("Please select %s to proceed" % f, raise_exception=1)
+
+ def get_month_details(self, year, month):
+ ysd = sql("select year_start_date from `tabFiscal Year` where name ='%s'"%year)[0][0]
+ if ysd:
+ from dateutil.relativedelta import relativedelta
+ import calendar, datetime
+ diff_mnt = cint(month)-cint(ysd.month)
+ if diff_mnt<0:
+ diff_mnt = 12-int(ysd.month)+cint(month)
+ msd = ysd + relativedelta(months=diff_mnt) # month start date
+ month_days = cint(calendar.monthrange(cint(msd.year) ,cint(month))[1]) # days in month
+ med = datetime.date(msd.year, cint(month), month_days) # month end date
+ return {
+ 'year': msd.year,
+ 'month_start_date': msd,
+ 'month_end_date': med,
+ 'month_days': month_days
+ }
+
+
def create_sal_slip(self):
"""
@@ -82,12 +111,7 @@
"""
emp_list = self.get_emp_list()
- log = ""
- if emp_list:
- log = "<table><tr><td colspan = 2>Following Salary Slip has been created: </td></tr><tr><td><u>SAL SLIP ID</u></td><td><u>EMPLOYEE NAME</u></td></tr>"
- else:
- log = "<table><tr><td colspan = 2>No employee found for the above selected criteria</td></tr>"
-
+ ss_list = []
for emp in emp_list:
if not sql("""select name from `tabSalary Slip`
where docstatus!= 2 and employee = %s and month = %s and fiscal_year = %s and company = %s
@@ -111,9 +135,18 @@
for d in getlist(ss_obj.doclist, 'deduction_details'):
d.save()
- log += '<tr><td>' + ss.name + '</td><td>' + ss_obj.doc.employee_name + '</td></tr>'
- log += '</table>'
- return log
+ ss_list.append(ss.name)
+
+ return self.create_log(ss_list)
+
+
+ def create_log(self, ss_list):
+ log = "<b>No employee for the above selected criteria OR salary slip already created</b>"
+ if ss_list:
+ log = "<b>Created Salary Slip has been created: </b>\
+ <br><br>%s" % '<br>'.join(ss_list)
+ return log
+
def get_sal_slip_list(self):
"""
@@ -132,28 +165,49 @@
"""
Submit all salary slips based on selected criteria
"""
- ss_list = self.get_sal_slip_list()
- log = ""
- if ss_list:
- log = """<table>
- <tr>
- <td colspan = 2>Following Salary Slip has been submitted: </td>
- </tr>
- <tr>
- <td><u>SAL SLIP ID</u></td>
- <td><u>EMPLOYEE NAME</u></td>
- </tr>
- """
- else:
- log = "<table><tr><td colspan = 2>No salary slip found to submit for the above selected criteria</td></tr>"
-
+ ss_list = self.get_sal_slip_list()
+ not_submitted_ss = []
for ss in ss_list:
ss_obj = get_obj("Salary Slip",ss[0],with_children=1)
- set(ss_obj.doc, 'docstatus', 1)
- ss_obj.on_submit()
+ try:
+ webnotes.conn.set(ss_obj.doc, 'email_check', cint(self.doc.send_mail))
+ if cint(self.doc.send_email) == 1:
+ ss_obj.send_mail_funct()
+
+ webnotes.conn.set(ss_obj.doc, 'docstatus', 1)
+ except Exception,e:
+ not_submitted_ss.append(ss[0])
+ msgprint(e)
+ continue
+
+ return self.create_submit_log(ss_list, not_submitted_ss)
+
+
+ def create_submit_log(self, all_ss, not_submitted_ss):
+ log = ''
+ if not all_ss:
+ log = "No salary slip found to submit for the above selected criteria"
+ else:
+ all_ss = [d[0] for d in all_ss]
- log += '<tr><td>' + ss[0] + '</td><td>' + ss_obj.doc.employee_name + '</td></tr>'
- log += '</table>'
+ submitted_ss = list(set(all_ss) - set(not_submitted_ss))
+ if submitted_ss:
+ mail_sent_msg = self.doc.send_email and " (Mail has been sent to the employee)" or ""
+ log = """
+ <b>Submitted Salary Slips%s:</b>\
+ <br><br> %s <br><br>
+ """ % (mail_sent_msg, '<br>'.join(submitted_ss))
+
+ if not_submitted_ss:
+ log += """
+ <b>Not Submitted Salary Slips: </b>\
+ <br><br> %s <br><br> \
+ Reason: <br>\
+ May be company email id specified in employee master is not valid. <br> \
+ Please mention correct email id in employee master or if you don't want to \
+ send mail, uncheck 'Send Email' checkbox. <br>\
+ Then try to submit Salary Slip again.
+ """% ('<br>'.join(not_submitted_ss))
return log
@@ -168,7 +222,7 @@
""" % (self.doc.month, self.doc.fiscal_year, cond))
return flt(tot[0][0])
-
+
def get_acc_details(self):
"""
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.js b/erpnext/hr/doctype/salary_slip/salary_slip.js
index 5fe93a6..3e61665 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.js
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.js
@@ -45,9 +45,13 @@
// Calculate total if lwp exists
// ------------------------------------------------------------------------
cur_frm.cscript.leave_without_pay = function(doc,dt,dn){
- doc.payment_days = flt(doc.total_days_in_month) - flt(doc.leave_without_pay);
- refresh_field('payment_days');
- calculate_all(doc, dt, dn);
+ if (doc.employee && doc.fiscal_year && doc.month) {
+ $c_obj(make_doclist(doc.doctype,doc.name), 'get_leave_details',doc.leave_without_pay,function(r, rt) {
+ var doc = locals[dt][dn];
+ cur_frm.refresh();
+ calculate_all(doc, dt, dn);
+ });
+ }
}
// Calculate all
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py
index 3439fc8..9860eab 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -39,27 +39,22 @@
self.doclist = doclist
- # autoname
- #=======================================================
def autoname(self):
self.doc.name = make_autoname('Sal Slip/' +self.doc.employee + '/.#####')
- # Get employee details
- #=======================================================
- def get_emp_and_leave_details(self):
- # Get payment days
- if self.doc.fiscal_year and self.doc.month:
- self.get_leave_details()
- # check sal structure
+ def get_emp_and_leave_details(self):
if self.doc.employee:
+ # Get payment days
+ if self.doc.fiscal_year and self.doc.month:
+ self.get_leave_details()
+
+ # check sal structure
struct = self.check_sal_struct()
if struct:
self.pull_sal_struct(struct)
- # Check sal structure
- #=======================================================
def check_sal_struct(self):
struct = sql("select name from `tabSalary Structure` where employee ='%s' and is_active = 'Yes' "%self.doc.employee)
if not struct:
@@ -67,8 +62,7 @@
self.doc.employee = ''
return struct and struct[0][0] or ''
- # Pull struct details
- #=======================================================
+
def pull_sal_struct(self, struct):
self.doclist = self.doc.clear_table(self.doclist, 'earning_details')
self.doclist = self.doc.clear_table(self.doclist, 'deduction_details')
@@ -81,41 +75,48 @@
self.doc.esic_no = basic_info[0][2]
self.doc.pf_no = basic_info[0][3]
- # Get leave details
- #=======================================================
- def get_leave_details(self):
- m = self.get_month_details()
- lwp = self.calculate_lwp(m)
- self.doc.total_days_in_month = m[3]
+
+ def get_leave_details(self, lwp=None):
+ m = get_obj('Salary Manager').get_month_details(self.doc.fiscal_year, self.doc.month)
+
+ if not lwp:
+ lwp = self.calculate_lwp(m)
+ self.doc.total_days_in_month = m['month_days']
self.doc.leave_without_pay = lwp
- self.doc.payment_days = flt(m[3]) - flt(lwp)
+ payment_days = flt(self.get_payment_days(m)) - flt(lwp)
+ self.doc.payment_days = payment_days > 0 and payment_days or 0
+
- # Get month details
- #=======================================================
- def get_month_details(self):
- ysd = sql("select year_start_date from `tabFiscal Year` where name ='%s'"%self.doc.fiscal_year)[0][0]
- if ysd:
- from dateutil.relativedelta import relativedelta
- import calendar, datetime
- mnt = int(self.doc.month)
- diff_mnt = int(mnt)-int(ysd.month)
- if diff_mnt<0:
- diff_mnt = 12-int(ysd.month)+int(mnt)
- msd = ysd + relativedelta(months=diff_mnt) # month start date
- month_days = cint(calendar.monthrange(cint(msd.year) ,cint(self.doc.month))[1]) # days in month
- med = datetime.date(msd.year, cint(self.doc.month), month_days) # month end date
- return msd.year, msd, med, month_days
+ def get_payment_days(self, m):
+ payment_days = m['month_days']
+ emp = webnotes.conn.sql("select date_of_joining, relieving_date from `tabEmployee` \
+ where name = %s", self.doc.employee, as_dict=1)[0]
+
+ if emp['relieving_date']:
+ if getdate(emp['relieving_date']) > m['month_start_date'] and getdate(emp['relieving_date']) < m['month_end_date']:
+ payment_days = getdate(emp['relieving_date']).day
+ elif getdate(emp['relieving_date']) < m['month_start_date']:
+ payment_days = 0
+
+ if emp['date_of_joining']:
+ if getdate(emp['date_of_joining']) > m['month_start_date'] and getdate(emp['date_of_joining']) < m['month_end_date']:
+ payment_days = payment_days - getdate(emp['date_of_joining']).day + 1
+ elif getdate(emp['date_of_joining']) > m['month_end_date']:
+ payment_days = 0
- # Calculate LWP
- #=======================================================
+ return payment_days
+
+
+
+
def calculate_lwp(self, m):
- holidays = sql("select t1.holiday_date from `tabHoliday` t1, tabEmployee t2 where t1.parent = t2.holiday_list and t2.name = '%s' and t1.holiday_date between '%s' and '%s'" % (self.doc.employee, m[1], m[2]))
+ holidays = sql("select t1.holiday_date from `tabHoliday` t1, tabEmployee t2 where t1.parent = t2.holiday_list and t2.name = '%s' and t1.holiday_date between '%s' and '%s'" % (self.doc.employee, m['month_start_date'], m['month_end_date']))
if not holidays:
holidays = sql("select t1.holiday_date from `tabHoliday` t1, `tabHoliday List` t2 where t1.parent = t2.name and ifnull(t2.is_default, 0) = 1 and t2.fiscal_year = '%s'" % self.doc.fiscal_year)
holidays = [cstr(i[0]) for i in holidays]
lwp = 0
- for d in range(m[3]):
- dt = add_days(cstr(m[1]), d)
+ for d in range(m['month_days']):
+ dt = add_days(cstr(m['month_start_date']), d)
if dt not in holidays:
leave = sql("""
select t1.name, t1.half_day
@@ -130,8 +131,7 @@
lwp = cint(leave[0][1]) and lwp + 0.5 or lwp + 1
return lwp
- # Check existing
- #=======================================================
+
def check_existing(self):
ret_exist = sql("select name from `tabSalary Slip` where month = '%s' and fiscal_year = '%s' and docstatus != 2 and employee = '%s' and name !='%s'" % (self.doc.month,self.doc.fiscal_year,self.doc.employee,self.doc.name))
if ret_exist:
@@ -139,8 +139,7 @@
self.doc.employee = ''
raise Exception
- # Validate
- #=======================================================
+
def validate(self):
self.check_existing()
dcc = TransactionBase().get_company_currency(self.doc.company)
@@ -155,6 +154,8 @@
for d in getlist(self.doclist, 'earning_details'):
if cint(d.e_depends_on_lwp) == 1:
d.e_modified_amount = round(flt(d.e_amount)*flt(self.doc.payment_days)/cint(self.doc.total_days_in_month), 2)
+ elif not self.doc.payment_days:
+ d.e_modified_amount = 0
self.doc.gross_pay += d.e_modified_amount
def calculate_ded_total(self):
@@ -165,6 +166,9 @@
for d in getlist(self.doclist, 'deduction_details'):
if cint(d.d_depends_on_lwp) == 1:
d.d_modified_amount = round(flt(d.d_amount)*flt(self.doc.payment_days)/cint(self.doc.total_days_in_month), 2)
+ elif not self.doc.payment_days:
+ d.d_modified_amount = 0
+
self.doc.total_deduction += d.d_modified_amount
def calculate_net_pay(self):
@@ -176,17 +180,12 @@
self.doc.net_pay = flt(self.doc.gross_pay) - flt(self.doc.total_deduction)
self.doc.rounded_total = round(self.doc.net_pay)
- # ON SUBMIT
- #=======================================================
+
def on_submit(self):
if(self.doc.email_check == 1):
self.send_mail_funct()
-
-
- # Send mail
- #=======================================================
def send_mail_funct(self):
from webnotes.utils.email_lib import sendmail
emailid_ret=sql("select company_email from `tabEmployee` where name = '%s'"%self.doc.employee)
@@ -281,4 +280,4 @@
</table></div>'''%(cstr(letter_head[0][0]),cstr(self.doc.employee), cstr(self.doc.employee_name), cstr(self.doc.month), cstr(self.doc.fiscal_year), cstr(self.doc.department), cstr(self.doc.branch), cstr(self.doc.designation), cstr(self.doc.grade), cstr(self.doc.bank_account_no), cstr(self.doc.bank_name), cstr(self.doc.arrear_amount), cstr(self.doc.payment_days), earn_table, ded_table, cstr(flt(self.doc.gross_pay)), cstr(flt(self.doc.total_deduction)), cstr(flt(self.doc.net_pay)), cstr(self.doc.total_in_words))
sendmail([receiver], subject=subj, msg = msg)
else:
- msgprint("Company Email ID not found.")
+ msgprint("Company Email ID not found, hence mail not sent")
diff --git a/erpnext/hr/doctype/salary_structure/listview.js b/erpnext/hr/doctype/salary_structure/listview.js
new file mode 100644
index 0000000..77259b5
--- /dev/null
+++ b/erpnext/hr/doctype/salary_structure/listview.js
@@ -0,0 +1,47 @@
+// render
+wn.doclistviews['Salary Structure'] = wn.views.ListView.extend({
+ init: function(d) {
+ this._super(d)
+ this.fields = this.fields.concat([
+ "`tabSalary Structure`.employee_name",
+ "`tabSalary Structure`.designation",
+ "`tabSalary Structure`.branch",
+ "`tabSalary Structure`.net_pay",
+ "`tabSalary Structure`.from_date",
+ "`tabSalary Structure`.to_date",
+ "`tabSalary Structure`.company"
+ ]);
+ this.stats = this.stats.concat(['company']);
+ },
+
+ prepare_data: function(data) {
+ this._super(data);
+ var concat_list = [];
+ data.designation && concat_list.push(data.designation);
+ data.branch && concat_list.push(data.branch);
+ data.description = concat_list.join(", ");
+ data.period = data.from_date + (data.to_date && ' to ' + data.to_date);
+ },
+
+ columns: [
+ {width: '2%', content: 'check'},
+ {width: '2%', content: 'docstatus'},
+ {width: '13%', content: 'name'},
+ {width: '18%', content: 'employee_name'},
+ {width: '24%', content: 'description+tags', css: {'color': '#aaa'}},
+ {width: '26%', content:'period', css: {'text-align': 'right', 'color':'#aaa'}},
+ {
+ width: '15%',
+ content: function(parent, data) {
+ $(parent).html(
+ (
+ data.company
+ ? wn.boot.company[data.company].default_currency
+ : sys_defaults.currency
+ )
+ + ' ' + fmt_money(data.net_pay));
+ },
+ css: {'text-align': 'right'},
+ },
+]
+});
\ No newline at end of file
diff --git a/erpnext/patches/july_2012/default_freeze_account.py b/erpnext/patches/july_2012/default_freeze_account.py
new file mode 100644
index 0000000..c8cbd1a
--- /dev/null
+++ b/erpnext/patches/july_2012/default_freeze_account.py
@@ -0,0 +1,9 @@
+def execute():
+ import webnotes
+ webnotes.conn.sql("""update tabAccount set freeze_account='No' where freeze_account is null""")
+ webnotes.conn.sql("""update `tabPurchase Taxes and Charges`
+ set category='Valuation and Total' where category='For Both'""")
+ webnotes.conn.sql("""update `tabPurchase Taxes and Charges`
+ set category='Valuation' where category='For Valuation'""")
+ webnotes.conn.sql("""update `tabPurchase Taxes and Charges`
+ set category='Total' where category='For Total'""")
\ No newline at end of file
diff --git a/erpnext/patches/july_2012/update_purchase_tax.py b/erpnext/patches/july_2012/update_purchase_tax.py
new file mode 100644
index 0000000..7982a0c
--- /dev/null
+++ b/erpnext/patches/july_2012/update_purchase_tax.py
@@ -0,0 +1,8 @@
+def execute():
+ import webnotes
+ webnotes.conn.sql("""update `tabPurchase Taxes and Charges`
+ set category='Valuation and Total' where category='For Both'""")
+ webnotes.conn.sql("""update `tabPurchase Taxes and Charges`
+ set category='Valuation' where category='For Valuation'""")
+ webnotes.conn.sql("""update `tabPurchase Taxes and Charges`
+ set category='Total' where category='For Total'""")
\ No newline at end of file
diff --git a/erpnext/patches/patch_list.py b/erpnext/patches/patch_list.py
index 5a6748c..6f462a4 100644
--- a/erpnext/patches/patch_list.py
+++ b/erpnext/patches/patch_list.py
@@ -483,6 +483,16 @@
'description': "deprecate doctype - Import Data Control and page - Import Data"
},
{
+ 'patch_module': 'patches.july_2012',
+ 'patch_file': 'default_freeze_account',
+ 'description': "set default freeze_account as 'No' where NULL"
+ },
+ {
+ 'patch_module': 'patches.july_2012',
+ 'patch_file': 'update_purchase_tax',
+ 'description': "rename options in purchase taxes and charges"
+ },
+ {
'patch_module': 'patches.june_2012',
'patch_file': 'cms2',
'description': 'cms2 release patches'
diff --git a/erpnext/production/doctype/bom/bom.py b/erpnext/production/doctype/bom/bom.py
index 81297b4..bc166ce 100644
--- a/erpnext/production/doctype/bom/bom.py
+++ b/erpnext/production/doctype/bom/bom.py
@@ -106,7 +106,6 @@
return ret_item
-
def get_rm_rate(self, arg):
""" Get raw material rate as per selected method, if bom exists takes bom cost """
@@ -293,7 +292,6 @@
self.validate_main_item()
self.validate_operations()
self.validate_materials()
- self.validate_operations()
@@ -353,8 +351,6 @@
})
-
-
# Get Current Flat BOM Items
# -----------------------------
def get_current_flat_bom_items(self):
diff --git a/erpnext/selling/doctype/campaign/campaign.txt b/erpnext/selling/doctype/campaign/campaign.txt
index 0912fe7..41c0e77 100644
--- a/erpnext/selling/doctype/campaign/campaign.txt
+++ b/erpnext/selling/doctype/campaign/campaign.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-03-27 14:36:07',
+ 'creation': '2012-07-03 13:30:38',
'docstatus': 0,
- 'modified': '2012-03-27 14:36:07',
+ 'modified': '2012-07-12 13:21:52',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -17,6 +17,7 @@
'autoname': u'field:campaign_name',
'colour': u'White:FFF',
'default_print_format': u'Standard',
+ 'description': u'Keep Track of Sales Campaigns. Keep track of Leads, Quotations, Sales Order etc from Campaigns to gauge Return on Investment. ',
'doctype': 'DocType',
'document_type': u'Master',
'module': u'Selling',
@@ -24,7 +25,7 @@
'section_style': u'Simple',
'server_code_error': u' ',
'show_in_menu': 0,
- 'version': 7
+ 'version': 1
},
# These values are common for all DocField
@@ -56,6 +57,56 @@
# DocPerm
{
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 1,
+ 'role': u'Sales Manager',
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'Sales Manager',
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 1,
+ 'role': u'Sales Master Manager',
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 1,
+ 'role': u'Sales User',
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'Sales User',
+ 'write': 0
+ },
+
+ # DocPerm
+ {
'cancel': 1,
'create': 1,
'doctype': u'DocPerm',
@@ -64,56 +115,6 @@
'write': 1
},
- # DocPerm
- {
- 'cancel': 0,
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 1,
- 'role': u'Sales Manager',
- 'write': 0
- },
-
- # DocPerm
- {
- 'cancel': 0,
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Sales Manager',
- 'write': 0
- },
-
- # DocPerm
- {
- 'cancel': 0,
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 1,
- 'role': u'Sales Master Manager',
- 'write': 0
- },
-
- # DocPerm
- {
- 'cancel': 0,
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 1,
- 'role': u'Sales User',
- 'write': 0
- },
-
- # DocPerm
- {
- 'cancel': 0,
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Sales User',
- 'write': 0
- },
-
# DocField
{
'doctype': u'DocField',
diff --git a/erpnext/selling/doctype/sales_common/sales_common.js b/erpnext/selling/doctype/sales_common/sales_common.js
index c852230..952a55f 100644
--- a/erpnext/selling/doctype/sales_common/sales_common.js
+++ b/erpnext/selling/doctype/sales_common/sales_common.js
@@ -127,10 +127,34 @@
cur_frm.cscript.base_currency = base_curr;
set_dynamic_label_par(doc, cdt, cdn, base_curr);
set_dynamic_label_child(doc, cdt, cdn, base_curr);
+ set_sales_bom_help(doc);
if (callback) callback(doc, cdt, cdn);
}
+// Help for Sales BOM items
+var set_sales_bom_help = function(doc) {
+ if (getchildren('Delivery Note Packing Item', doc.name, 'packing_details').length) {
+ $(cur_frm.fields_dict.packing_list.row.wrapper).toggle(true);
+
+ if (inList(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
+ help_msg = "<div class='help-box'> \
+ For 'Sales BOM' items, warehouse, serial no and batch no \
+ will be considered from the 'Packing List' table. \
+ If warehouse and batch no are same for all packing items for any 'Sales BOM' item, \
+ those values can be entered in the main item table, values will be copied to 'Packing List' table. \
+ </div>";
+ get_field(doc.doctype, 'sales_bom_help', doc.name).options = help_msg;
+ }
+ } else {
+ $(cur_frm.fields_dict.packing_list.row.wrapper).toggle(false);
+ if (inList(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
+ get_field(doc.doctype, 'sales_bom_help', doc.name).options = '';
+ }
+ }
+ refresh_field('sales_bom_help');
+}
+
// hide / unhide price list currency based on availability of price list in customer's currency
//---------------------------------------------------------------------------------------------------
@@ -340,7 +364,12 @@
// ************* GET OTHER CHARGES BASED ON COMPANY *************
cur_frm.fields_dict.charge.get_query = function(doc) {
- return 'SELECT DISTINCT `tabSales Taxes and Charges Master`.name FROM `tabSales Taxes and Charges Master` WHERE `tabSales Taxes and Charges Master`.company = "'+doc.company+'" AND `tabSales Taxes and Charges Master`.company is not NULL AND `tabSales Taxes and Charges Master`.docstatus != 2 AND `tabSales Taxes and Charges Master`.%(key)s LIKE "%s" ORDER BY `tabSales Taxes and Charges Master`.name LIMIT 50';
+ return 'SELECT DISTINCT `tabSales Taxes and Charges Master`.name FROM \
+ `tabSales Taxes and Charges Master` WHERE `tabSales Taxes and Charges Master`.company = "'
+ +doc.company+'" AND `tabSales Taxes and Charges Master`.company is not NULL \
+ AND `tabSales Taxes and Charges Master`.docstatus != 2 \
+ AND `tabSales Taxes and Charges Master`.%(key)s LIKE "%s" \
+ ORDER BY `tabSales Taxes and Charges Master`.name LIMIT 50';
}
// ********************* Get Charges ****************************
diff --git a/erpnext/selling/doctype/sales_common/sales_common.py b/erpnext/selling/doctype/sales_common/sales_common.py
index 74963fb..a658209 100644
--- a/erpnext/selling/doctype/sales_common/sales_common.py
+++ b/erpnext/selling/doctype/sales_common/sales_common.py
@@ -385,7 +385,7 @@
return ret
- def get_item_list(self, obj, is_stopped):
+ def get_item_list(self, obj, is_stopped=0):
"""get item list"""
il = []
for d in getlist(obj.doclist,obj.fname):
@@ -394,7 +394,7 @@
if is_stopped:
qty = flt(d.qty) > flt(d.delivered_qty) and flt(flt(d.qty) - flt(d.delivered_qty)) or 0
- if d.prevdoc_doctype == 'Sales Order':
+ if d.prevdoc_doctype == 'Sales Order':
# used in delivery note to reduce reserved_qty
# Eg.: if SO qty is 10 and there is tolerance of 20%, then it will allow DN of 12.
# But in this case reserved qty should only be reduced by 10 and not 12.
@@ -413,7 +413,7 @@
if p.parent_detail_docname == d.name:
# the packing details table's qty is already multiplied with parent's qty
il.append({
- 'warehouse': d.warehouse,
+ 'warehouse': p.warehouse,
'reserved_warehouse': reserved_wh,
'item_code': p.item_code,
'qty': flt(p.qty),
@@ -496,23 +496,21 @@
pi.qty = flt(qty)
pi.actual_qty = bin and flt(bin['actual_qty']) or 0
pi.projected_qty = bin and flt(bin['projected_qty']) or 0
- pi.warehouse = warehouse
pi.prevdoc_doctype = line.prevdoc_doctype
- if packing_item_code == line.item_code:
- pi.serial_no = cstr(line.serial_no)
+ if not pi.warehouse:
+ pi.warehouse = warehouse
+ if not pi.batch_no:
pi.batch_no = cstr(line.batch_no)
pi.idx = self.packing_list_idx
- # has to be saved, since this function is called on_update of delivery note
+ # saved, since this function is called on_update of delivery note
pi.save()
self.packing_list_idx += 1
- # ------------------
- # make packing list from sales bom if exists or directly copy item with balance
- # ------------------
def make_packing_list(self, obj, fname):
+ """make packing list for sales bom item"""
self.packing_list_idx = 0
parent_items = []
for d in getlist(obj.doclist, fname):
@@ -520,10 +518,9 @@
if self.has_sales_bom(d.item_code):
for i in self.get_sales_bom_items(d.item_code):
self.update_packing_list_item(obj, i['item_code'], flt(i['qty'])*flt(d.qty), warehouse, d)
- else:
- self.update_packing_list_item(obj, d.item_code, d.qty, warehouse, d)
- if [d.item_code, d.name] not in parent_items:
- parent_items.append([d.item_code, d.name])
+
+ if [d.item_code, d.name] not in parent_items:
+ parent_items.append([d.item_code, d.name])
self.cleanup_packing_list(obj, parent_items)
diff --git a/erpnext/selling/page/sales_browser/sales_browser.js b/erpnext/selling/page/sales_browser/sales_browser.js
index 66e1d52..c98e0e4 100644
--- a/erpnext/selling/page/sales_browser/sales_browser.js
+++ b/erpnext/selling/page/sales_browser/sales_browser.js
@@ -31,7 +31,12 @@
pscript['onshow_Sales Browser'] = function(wrapper){
// set route
var ctype = wn.get_route()[1] || 'Territory';
- wrapper.appframe.title(ctype + ' Tree');
+
+ wrapper.appframe.clear_breadcrumbs();
+ wrapper.appframe.add_breadcrumb(ctype+' Tree')
+ document.title = ctype+' Tree';
+
+ wrapper.appframe.add_breadcrumb(' in <a href="#!selling-home">Selling</a>');
if(erpnext.sales_chart && erpnext.sales_chart.ctype != ctype) {
wrapper.make_tree();
diff --git a/erpnext/selling/page/selling_home/selling_home.html b/erpnext/selling/page/selling_home/selling_home.html
index 4857def..164d365 100644
--- a/erpnext/selling/page/selling_home/selling_home.html
+++ b/erpnext/selling/page/selling_home/selling_home.html
@@ -79,12 +79,17 @@
</div>
<div class="section-item">
<a class="section-link"
+ title = "Tree of item classification"
+ href="#!Sales Browser/Item Group">Item Group</a>
+ </div>
+ <div class="section-item">
+ <a class="section-link"
title = "Sales campaigns"
href="#!List/Campaign">Campaign</a>
</div>
<div class="section-item">
<a class="section-link"
- title = "Send mass SMS to your conatacts, leads and employees"
+ title = "Send mass SMS to your contacts, leads and employees"
href="#!Form/SMS Center/SMS Center">SMS Center</a>
</div>
</div>
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index 11ed655..195b021 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -166,6 +166,8 @@
ac.fields[d] = (d == 'parent_account' and lst[self.fld_dict[d]]) and lst[self.fld_dict[d]] +' - '+ self.doc.abbr or lst[self.fld_dict[d]]
ac.old_parent = ''
ac_obj = get_obj(doc=ac)
+ ac_obj.doc.freeze_account='No'
+ ac_obj.doc.master_type = ''
ac_obj.validate()
ac_obj.doc.save(1)
ac_obj.on_update()
diff --git a/erpnext/setup/doctype/company/company.txt b/erpnext/setup/doctype/company/company.txt
index 17bd61b..3437faf 100644
--- a/erpnext/setup/doctype/company/company.txt
+++ b/erpnext/setup/doctype/company/company.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-03-27 14:36:19',
+ 'creation': '2012-07-03 13:30:55',
'docstatus': 0,
- 'modified': '2012-03-27 14:36:19',
+ 'modified': '2012-07-11 14:43:55',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -23,7 +23,7 @@
'section_style': u'Tabbed',
'server_code_error': u' ',
'show_in_menu': 0,
- 'version': 96
+ 'version': 1
},
# These values are common for all DocField
@@ -85,11 +85,11 @@
# DocField
{
- 'description': u'Please Enter Company Name and Abbr and save the document. Once saved Accounting Settings will be populated automatically',
+ 'colour': u'White:FFF',
'doctype': u'DocField',
'fieldname': u'details',
'fieldtype': u'Section Break',
- 'label': u'Details',
+ 'label': u'Company Details',
'oldfieldtype': u'Section Break',
'permlevel': 0
},
@@ -110,6 +110,14 @@
# DocField
{
+ 'doctype': u'DocField',
+ 'fieldname': u'cb0',
+ 'fieldtype': u'Column Break',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
'colour': u'White:FFF',
'description': u'Please Enter Abbreviation or Short Name properly as it will be added as Suffix to all Account Heads.',
'doctype': u'DocField',
@@ -253,6 +261,8 @@
# DocField
{
+ 'colour': u'White:FFF',
+ 'description': u'For reference only.',
'doctype': u'DocField',
'fieldname': u'company_info',
'fieldtype': u'Section Break',
diff --git a/erpnext/setup/doctype/currency/currency.js b/erpnext/setup/doctype/currency/currency.js
new file mode 100644
index 0000000..cd42c18
--- /dev/null
+++ b/erpnext/setup/doctype/currency/currency.js
@@ -0,0 +1,3 @@
+cur_frm.cscript.refresh = function(doc) {
+ cur_frm.set_intro(doc.__islocal ? "" : "There is nothing to edit.")
+}
\ No newline at end of file
diff --git a/erpnext/setup/doctype/currency/currency.txt b/erpnext/setup/doctype/currency/currency.txt
index 5abf9c5..906e2f8 100644
--- a/erpnext/setup/doctype/currency/currency.txt
+++ b/erpnext/setup/doctype/currency/currency.txt
@@ -3,17 +3,19 @@
# These values are common in all dictionaries
{
- 'creation': '2012-03-27 14:36:19',
+ 'creation': '2012-07-03 13:30:55',
'docstatus': 0,
- 'modified': '2012-03-27 14:36:19',
+ 'modified': '2012-07-11 16:11:45',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
# These values are common for all DocType
{
+ 'allow_trash': 1,
'autoname': u'field:currency_name',
'colour': u'White:FFF',
+ 'description': u'**Currency** Master',
'doctype': 'DocType',
'in_create': 0,
'module': u'Setup',
@@ -22,7 +24,7 @@
'section_style': u'Simple',
'server_code_error': u' ',
'show_in_menu': 0,
- 'version': 3
+ 'version': 1
},
# These values are common for all DocField
@@ -62,8 +64,15 @@
# DocPerm
{
+ 'cancel': 1,
+ 'doctype': u'DocPerm',
+ 'role': u'Accounts Manager'
+ },
+
+ # DocPerm
+ {
'amend': 0,
- 'cancel': 0,
+ 'cancel': 1,
'doctype': u'DocPerm',
'role': u'Sales Master Manager',
'submit': 0
@@ -78,12 +87,6 @@
'submit': 0
},
- # DocPerm
- {
- 'doctype': u'DocPerm',
- 'role': u'Accounts Manager'
- },
-
# DocField
{
'doctype': u'DocField'
diff --git a/erpnext/setup/doctype/customer_group/customer_group.js b/erpnext/setup/doctype/customer_group/customer_group.js
index 11794cc..67bc293 100644
--- a/erpnext/setup/doctype/customer_group/customer_group.js
+++ b/erpnext/setup/doctype/customer_group/customer_group.js
@@ -14,21 +14,22 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-
-cur_frm.cscript.onload = function(){
-
- if(doc.__islocal){
- doc.parent_customer_group = 'Root';
- refresh('parent_customer_group');
- }
+cur_frm.cscript.set_breadcrumbs = function(barea) {
+ cur_frm.frm_head.appframe.add_breadcrumb(cur_frm.docname);
+ cur_frm.frm_head.appframe.add_breadcrumb(' in <a href="#!Sales Browser/Customer Group">\
+ Customer Group Tree</a>');
+ cur_frm.frm_head.appframe.add_breadcrumb(' in <a href="#!selling-home">Selling</a>');
}
+
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
}
//get query select Customer Group
cur_frm.fields_dict['parent_customer_group'].get_query = function(doc,cdt,cdn) {
- return 'SELECT `tabCustomer Group`.`name`,`tabCustomer Group`.`parent_customer_group` FROM `tabCustomer Group` WHERE `tabCustomer Group`.`is_group` = "Yes" AND `tabCustomer Group`.`docstatus`!= 2 AND `tabCustomer Group`.%(key)s LIKE "%s" ORDER BY `tabCustomer Group`.`name` ASC LIMIT 50';
+ return 'SELECT `tabCustomer Group`.`name`,`tabCustomer Group`.`parent_customer_group` \
+ FROM `tabCustomer Group` WHERE `tabCustomer Group`.`is_group` = "Yes" AND \
+ `tabCustomer Group`.`docstatus`!= 2 AND `tabCustomer Group`.%(key)s LIKE "%s" \
+ ORDER BY `tabCustomer Group`.`name` ASC LIMIT 50';
}
\ No newline at end of file
diff --git a/erpnext/setup/doctype/customer_group/customer_group.txt b/erpnext/setup/doctype/customer_group/customer_group.txt
index ceda674..5e44bef 100644
--- a/erpnext/setup/doctype/customer_group/customer_group.txt
+++ b/erpnext/setup/doctype/customer_group/customer_group.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-04-13 11:56:30',
+ 'creation': '2012-07-03 13:30:55',
'docstatus': 0,
- 'modified': '2012-04-19 17:50:43',
+ 'modified': '2012-07-12 09:47:20',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -22,6 +22,7 @@
'in_create': 1,
'module': u'Setup',
'name': '__common__',
+ 'read_only': 1,
'search_fields': u'name,parent_customer_group',
'section_style': u'Simple',
'server_code_error': u' ',
@@ -142,18 +143,6 @@
# DocField
{
- 'doctype': u'DocField',
- 'fieldname': u'description',
- 'fieldtype': u'Text',
- 'label': u'Description',
- 'oldfieldname': u'description',
- 'oldfieldtype': u'Text',
- 'permlevel': 0,
- 'width': u'300px'
- },
-
- # DocField
- {
'colour': u'White:FFF',
'doctype': u'DocField',
'fieldname': u'parent_customer_group',
@@ -185,6 +174,16 @@
# DocField
{
'doctype': u'DocField',
+ 'fieldname': u'cb0',
+ 'fieldtype': u'Column Break',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'description': u'This Price List will be selected as default for all Customers under this Group.',
+ 'doctype': u'DocField',
'fieldname': u'default_price_list',
'fieldtype': u'Link',
'label': u'Default Price List',
diff --git a/erpnext/setup/doctype/email_digest/email_digest.js b/erpnext/setup/doctype/email_digest/email_digest.js
index 1380e77..9d8d5b5 100644
--- a/erpnext/setup/doctype/email_digest/email_digest.js
+++ b/erpnext/setup/doctype/email_digest/email_digest.js
@@ -116,7 +116,7 @@
}
}
doc.recipient_list = rec_list.join('\n');
- //console.log(doc.recipient_list);
cur_frm.rec_dialog.hide();
+ cur_frm.save();
cur_frm.refresh_fields();
}
diff --git a/erpnext/setup/doctype/email_digest/email_digest.txt b/erpnext/setup/doctype/email_digest/email_digest.txt
index 0a29a8c..7aa39ca 100644
--- a/erpnext/setup/doctype/email_digest/email_digest.txt
+++ b/erpnext/setup/doctype/email_digest/email_digest.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-03-27 14:36:20',
+ 'creation': '2012-07-03 13:30:54',
'docstatus': 0,
- 'modified': '2012-03-27 14:36:20',
+ 'modified': '2012-07-12 16:29:08',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -15,13 +15,14 @@
'_last_update': u'1324556758',
'autoname': u'Prompt',
'colour': u'White:FFF',
+ 'description': u'Send regular summary reports via Email.',
'doctype': 'DocType',
'document_type': u'System',
'module': u'Setup',
'name': '__common__',
'section_style': u'Simple',
'show_in_menu': 0,
- 'version': 81
+ 'version': 1
},
# These values are common for all DocField
@@ -70,7 +71,7 @@
'doctype': u'DocField',
'fieldname': u'settings',
'fieldtype': u'Section Break',
- 'label': u'Settings',
+ 'label': u'Email Digest Settings',
'permlevel': 0
},
@@ -146,16 +147,6 @@
# DocField
{
- 'doctype': u'DocField',
- 'fieldname': u'addremove_recipients',
- 'fieldtype': u'Button',
- 'label': u'Add/Remove Recipients',
- 'permlevel': 0,
- 'trigger': u'Client'
- },
-
- # DocField
- {
'description': u'Note: Email will not be sent to disabled users',
'doctype': u'DocField',
'fieldname': u'recipient_list',
@@ -167,7 +158,19 @@
# DocField
{
+ 'doctype': u'DocField',
+ 'fieldname': u'addremove_recipients',
+ 'fieldtype': u'Button',
+ 'label': u'Add/Remove Recipients',
+ 'permlevel': 0,
+ 'trigger': u'Client'
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
'depends_on': u'eval:doc.use_standard',
+ 'description': u'Check all the items below that you want to send in this digest.',
'doctype': u'DocField',
'fieldname': u'select_digest_content',
'fieldtype': u'Section Break',
@@ -247,6 +250,14 @@
# DocField
{
+ 'doctype': u'DocField',
+ 'fieldname': u'cb1',
+ 'fieldtype': u'Column Break',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
'depends_on': u'eval:doc.use_standard',
'doctype': u'DocField',
'fieldname': u'payments',
@@ -323,35 +334,5 @@
'hidden': 1,
'label': u'Stock Items below re-order level',
'permlevel': 0
- },
-
- # DocField
- {
- 'depends_on': u'eval:!doc.use_standard',
- 'doctype': u'DocField',
- 'fieldname': u'enter_custom_code',
- 'fieldtype': u'Section Break',
- 'label': u'Enter Custom Code',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'depends_on': u'eval:!doc.use_standard',
- 'doctype': u'DocField',
- 'fieldname': u'custom_code',
- 'fieldtype': u'Code',
- 'label': u'Custom Python Code',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'depends_on': u'eval:!doc.use_standard',
- 'doctype': u'DocField',
- 'fieldname': u'email_template',
- 'fieldtype': u'Code',
- 'label': u'Email Template',
- 'permlevel': 0
}
]
\ No newline at end of file
diff --git a/erpnext/setup/doctype/email_settings/email_settings.txt b/erpnext/setup/doctype/email_settings/email_settings.txt
index 2772367..cf9d443 100644
--- a/erpnext/setup/doctype/email_settings/email_settings.txt
+++ b/erpnext/setup/doctype/email_settings/email_settings.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-05-15 12:15:01',
+ 'creation': '2012-07-03 13:30:55',
'docstatus': 0,
- 'modified': '2012-06-14 14:47:49',
+ 'modified': '2012-07-12 16:16:27',
'modified_by': u'Administrator',
'owner': u'harshada@webnotestech.com'
},
@@ -18,6 +18,7 @@
'allow_print': 1,
'colour': u'White:FFF',
'default_print_format': u'Standard',
+ 'description': u'Email Settings for Outgoing and Incoming Emails.',
'doctype': 'DocType',
'in_create': 1,
'issingle': 1,
@@ -70,6 +71,8 @@
# DocField
{
+ 'colour': u'White:FFF',
+ 'description': u'Set your outgoing mail SMTP settings here. All system generated notifications, emails will go from this mail server. If you are not sure, leave this blank to use ERPNext servers (emails will still be sent from your email id) or contact your email provider.',
'doctype': u'DocField',
'fieldname': u'outgoing_mails',
'fieldtype': u'Section Break',
@@ -78,15 +81,8 @@
# DocField
{
- 'doctype': u'DocField',
- 'fieldname': u'html1',
- 'fieldtype': u'HTML',
- 'label': u'1',
- 'options': u'<div class="help_box">Set your outgoing mail settings here. All system generated notifications, emails will go from this mail server</div>'
- },
-
- # DocField
- {
+ 'colour': u'White:FFF',
+ 'description': u'SMTP Server (e.g. smtp.gmail.com)',
'doctype': u'DocField',
'fieldname': u'outgoing_mail_server',
'fieldtype': u'Data',
@@ -96,14 +92,6 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'mail_port',
- 'fieldtype': u'Int',
- 'label': u'Mail Port'
- },
-
- # DocField
- {
- 'doctype': u'DocField',
'fieldname': u'use_ssl',
'fieldtype': u'Check',
'label': u'Use SSL'
@@ -111,6 +99,25 @@
# DocField
{
+ 'colour': u'White:FFF',
+ 'description': u'If non standard port (e.g. 587)',
+ 'doctype': u'DocField',
+ 'fieldname': u'mail_port',
+ 'fieldtype': u'Int',
+ 'label': u'Mail Port'
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'cb0',
+ 'fieldtype': u'Column Break'
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'description': u'Set Login and Password if authentication is required.',
'doctype': u'DocField',
'fieldname': u'mail_login',
'fieldtype': u'Data',
@@ -127,6 +134,8 @@
# DocField
{
+ 'colour': u'White:FFF',
+ 'description': u'System generated mails will be sent from this email id.',
'doctype': u'DocField',
'fieldname': u'auto_email_id',
'fieldtype': u'Data',
@@ -144,19 +153,12 @@
# DocField
{
- 'doctype': u'DocField',
- 'fieldname': u'html2',
- 'fieldtype': u'HTML',
- 'label': u'2',
- 'options': u'<div class="help_box">To automatically create Support Tickets from your incoming mail, set your pop3 settings here.</div>'
- },
-
- # DocField
- {
+ 'colour': u'White:FFF',
+ 'description': u'To automatically create Support Tickets from your incoming mail, set your POP3 settings here. You must ideally create a separate email id for the erp system so that all emails will be synced into the system from that mail id. If you are not sure, please contact your EMail Provider.',
'doctype': u'DocField',
'fieldname': u'section_break0',
'fieldtype': u'Section Break',
- 'options': u'Simple'
+ 'label': u'Incoming Mail Setting'
},
# DocField
@@ -216,7 +218,7 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'column_break0',
+ 'fieldname': u'cb1',
'fieldtype': u'Column Break'
},
diff --git a/erpnext/setup/doctype/item_group/item_group.js b/erpnext/setup/doctype/item_group/item_group.js
index db7582c..e5e108a 100644
--- a/erpnext/setup/doctype/item_group/item_group.js
+++ b/erpnext/setup/doctype/item_group/item_group.js
@@ -14,21 +14,14 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-
-cur_frm.cscript.onload = function(){
-
- if(doc.__islocal){
- doc.parent_item_group = 'Root';
- refresh('parent_item_group');
- }
+cur_frm.cscript.set_breadcrumbs = function(barea) {
+ cur_frm.frm_head.appframe.add_breadcrumb(cur_frm.docname);
+ cur_frm.frm_head.appframe.add_breadcrumb(' in <a href="#!Sales Browser/Item Group">\
+ Item Group Tree</a>');
+ cur_frm.frm_head.appframe.add_breadcrumb(' in <a href="#!selling-home">Selling</a>');
}
//get query select item group
cur_frm.fields_dict['parent_item_group'].get_query = function(doc,cdt,cdn) {
return 'SELECT `tabItem Group`.`name`,`tabItem Group`.`parent_item_group` FROM `tabItem Group` WHERE `tabItem Group`.`is_group` = "Yes" AND `tabItem Group`.`docstatus`!= 2 AND `tabItem Group`.`name` !="'+doc.item_group_name+'" AND `tabItem Group`.%(key)s LIKE "%s" ORDER BY `tabItem Group`.`name` ASC LIMIT 50';
-}
-
-cur_frm.cscript.refresh = function(doc, cdt, cdn) {
-
}
\ No newline at end of file
diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py
index 7e92f53..0253c8e 100644
--- a/erpnext/setup/doctype/item_group/item_group.py
+++ b/erpnext/setup/doctype/item_group/item_group.py
@@ -14,66 +14,15 @@
# 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
+from webnotes.model.doclist import getlist
+from webnotes.utils import flt
-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
-
-# -----------------------------------------------------------------------------------------
+from webnotes.utils.nestedset import DocTypeNestedSet
-
-class DocType:
- def __init__(self,d,dl):
- self.doc, self.doclist = d,dl
- self.nsm_parent_field = 'parent_item_group';
-
- # update Node Set Model
- def update_nsm_model(self):
- import webnotes
- import webnotes.utils.nestedset
- webnotes.utils.nestedset.update_nsm(self)
-
- # ON UPDATE
- #--------------------------------------
- def on_update(self):
- # update nsm
- self.update_nsm_model()
-
- def validate(self):
- if self.doc.lft and self.doc.rgt:
- res = sql("select name from `tabItem Group` where is_group = 'Yes' and docstatus!= 2 and name ='%s' and name !='%s'"%(self.doc.parent_item_group,self.doc.item_group_name))
- if not res:
- msgprint("Please enter proper parent item group.")
- raise Exception
-
- r = sql("select name from `tabItem Group` where name = '%s' and docstatus = 2"%(self.doc.item_group_name))
- if r:
- msgprint("'%s' record is trashed. To untrash please go to Setup & click on Trash."%(self.doc.item_group_name))
- raise Exception
-
- def on_trash(self):
- item = sql("select name from `tabItem` where ifnull(item_group, '') = %s", self.doc.name)
- item = [d[0] for d in item]
-
- if item:
- msgprint("""Item Group: %s can not be trashed/deleted because it is used in item: %s.
- To trash/delete this, remove/change item group in item master""" % (self.doc.name, item or ''), raise_exception=1)
-
- if sql("select name from `tabItem Group` where parent_item_group = %s and docstatus != 2", self.doc.name):
- msgprint("Child item group exists for this item group. You can not trash/cancel/delete this item group.", raise_exception=1)
-
-
- # rebuild tree
- set(self.doc,'old_parent', '')
- self.update_nsm_model()
+class DocType(DocTypeNestedSet):
+ def __init__(self, doc, doclist=[]):
+ self.doc = doc
+ self.doclist = doclist
+ self.nsm_parent_field = 'parent_item_group';
\ No newline at end of file
diff --git a/erpnext/setup/doctype/item_group/item_group.txt b/erpnext/setup/doctype/item_group/item_group.txt
index b56b8da..bd9887f 100644
--- a/erpnext/setup/doctype/item_group/item_group.txt
+++ b/erpnext/setup/doctype/item_group/item_group.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-03-27 14:36:21',
+ 'creation': '2012-07-03 13:30:53',
'docstatus': 0,
- 'modified': '2012-03-27 14:36:21',
+ 'modified': '2012-07-12 11:26:21',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -17,6 +17,7 @@
'autoname': u'field:item_group_name',
'colour': u'White:FFF',
'default_print_format': u'Standard',
+ 'description': u'Item Classification',
'doctype': 'DocType',
'document_type': u'Master',
'in_create': 1,
@@ -27,7 +28,7 @@
'section_style': u'Simple',
'server_code_error': u' ',
'show_in_menu': 0,
- 'version': 59
+ 'version': 1
},
# These values are common for all DocField
@@ -57,6 +58,54 @@
# DocPerm
{
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 1,
+ 'role': u'Material Manager',
+ 'submit': 0,
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'Material Manager',
+ 'submit': 0,
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 1,
+ 'role': u'Material User',
+ 'submit': 0,
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'Material User',
+ 'submit': 0,
+ 'write': 0
+ },
+
+ # DocPerm
+ {
'cancel': 1,
'create': 1,
'doctype': u'DocPerm',
@@ -75,54 +124,6 @@
'write': 1
},
- # DocPerm
- {
- 'amend': 0,
- 'cancel': 0,
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 1,
- 'role': u'Material Manager',
- 'submit': 0,
- 'write': 0
- },
-
- # DocPerm
- {
- 'amend': 0,
- 'cancel': 0,
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Material Manager',
- 'submit': 0,
- 'write': 0
- },
-
- # DocPerm
- {
- 'amend': 0,
- 'cancel': 0,
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 1,
- 'role': u'Material User',
- 'submit': 0,
- 'write': 0
- },
-
- # DocPerm
- {
- 'amend': 0,
- 'cancel': 0,
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Material User',
- 'submit': 0,
- 'write': 0
- },
-
# DocField
{
'doctype': u'DocField',
@@ -139,20 +140,6 @@
# DocField
{
- 'doctype': u'DocField',
- 'fieldname': u'description',
- 'fieldtype': u'Text',
- 'label': u'Description',
- 'no_copy': 0,
- 'oldfieldname': u'description',
- 'oldfieldtype': u'Text',
- 'permlevel': 0,
- 'search_index': 0,
- 'width': u'300px'
- },
-
- # DocField
- {
'colour': u'White:FFF',
'description': u'Check this if you want to show in website',
'doctype': u'DocField',
@@ -167,14 +154,9 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'show_in_catalogue',
- 'fieldtype': u'Check',
- 'label': u'Show in catalogue',
- 'no_copy': 0,
- 'oldfieldname': u'show_in_catalogue',
- 'oldfieldtype': u'Check',
- 'permlevel': 0,
- 'search_index': 0
+ 'fieldname': u'cb0',
+ 'fieldtype': u'Column Break',
+ 'permlevel': 0
},
# DocField
diff --git a/erpnext/setup/doctype/naming_series/naming_series.js b/erpnext/setup/doctype/naming_series/naming_series.js
index 7e702c4..3057e62 100644
--- a/erpnext/setup/doctype/naming_series/naming_series.js
+++ b/erpnext/setup/doctype/naming_series/naming_series.js
@@ -8,33 +8,47 @@
//
// 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
+// 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/>.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Settings
cur_frm.cscript.onload = function(doc, cdt, cdn){
- var callback = function(r, rt){
- set_field_options('select_doc_for_series', r.message);
- }
- $c_obj(make_doclist(doc.doctype, doc.name),'get_transactions','',callback);
- cur_frm.cscript.refresh();
- // add page head
- //var ph = new PageHeader(cur_frm.fields_dict['head_html'].wrapper, 'Setup Series', 'Set prefix for numbering series on your transactions');
+ cur_frm.call_server('get_transactions', '', cur_frm.cscript.update_selects);
+
+ cur_frm.cscript.select_doc_for_series(doc);
}
-cur_frm.cscript.refresh = function(doc, cdt, cdn) {
- // hide buttons
- $('.appframe-toolbar').toggle(false);
+cur_frm.cscript.update_selects = function(r) {
+ set_field_options('select_doc_for_series', r.message.transactions);
+ set_field_options('prefix', r.message.prefixes);
}
+
cur_frm.cscript.select_doc_for_series = function(doc, cdt, cdn) {
- var callback = function(r, rt){
- locals[cdt][cdn].set_options = r.message;
- refresh_field('set_options');
- }
+ cur_frm.toggle_fields(['help_html','set_options', 'user_must_always_select', 'update'],
+ doc.select_doc_for_series)
- $c_obj(make_doclist(doc.doctype, doc.name),'get_options','',callback)
+ var callback = function(r, rt){
+ locals[cdt][cdn].set_options = r.message;
+ refresh_field('set_options');
+ if(r.message && r.message.split('\n')[0]=='') {
+ cur_frm.set_value('user_must_always_select', 1)
+ }
+ }
+
+ if(doc.select_doc_for_series)
+ $c_obj(make_doclist(doc.doctype, doc.name),'get_options','',callback)
+}
+
+cur_frm.cscript.update = function() {
+ cur_frm.call_server('update_series', '', cur_frm.cscript.update_selects)
+}
+
+cur_frm.cscript.prefix = function(doc) {
+ cur_frm.call_server('get_current', '', function(r) {
+ refresh_field('current_value');
+ })
}
diff --git a/erpnext/setup/doctype/naming_series/naming_series.py b/erpnext/setup/doctype/naming_series/naming_series.py
index 5a9a265..6473459 100644
--- a/erpnext/setup/doctype/naming_series/naming_series.py
+++ b/erpnext/setup/doctype/naming_series/naming_series.py
@@ -14,7 +14,6 @@
# 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 cint, cstr
@@ -22,23 +21,37 @@
import webnotes.model.doctype
sql = webnotes.conn.sql
-
-# -----------------------------------------------------------------------------------------
-
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
- #-----------------------------------------------------------------------------------------------------------------------------------
- def get_transactions(self):
- return "\n".join([''] + [i[0] for i in sql("SELECT `tabDocField`.`parent` FROM `tabDocField`, `tabDocType` WHERE `tabDocField`.`fieldname` = 'naming_series' and `tabDocType`.name=`tabDocField`.parent order by `tabDocField`.parent")])
+ def get_transactions(self, arg=None):
+ return {
+ "transactions": "\n".join([''] + [i[0] for i in sql("""select `tabDocField`.`parent`
+ FROM `tabDocField`, `tabDocType` WHERE `tabDocField`.`fieldname` = 'naming_series'
+ and `tabDocType`.name=`tabDocField`.parent order by `tabDocField`.parent""")]),
+ "prefixes": "\n".join([''] + [i[0] for i in sql("""select name from tabSeries""")])}
def scrub_options_list(self, ol):
options = filter(lambda x: x, [cstr(n.upper()).strip() for n in ol])
return options
+
+ def update_series(self, arg=None):
+ """update series list"""
+ self.check_duplicate()
+ series_list = self.doc.set_options.split("\n")
+
+ # set in doctype
+ self.set_series_for(self.doc.select_doc_for_series, series_list)
+
+ # create series
+ map(self.insert_series, series_list)
+
+ msgprint('Series Updated')
+
+ return self.get_transactions()
- #-----------------------------------------------------------------------------------------------------------------------------------
def set_series_for(self, doctype, ol):
options = self.scrub_options_list(ol)
@@ -78,14 +91,7 @@
from webnotes.utils.cache import CacheItem
CacheItem(doctype).clear()
-
- #-----------------------------------------------------------------------------------------------------------------------------------
- def update_series(self):
- self.check_duplicate()
- self.set_series_for(self.doc.select_doc_for_series, self.doc.set_options.split("\n"))
- msgprint('Series Updated')
- #-----------------------------------------------------------------------------------------------------------------------------------
def check_duplicate(self):
from core.doctype.doctype.doctype import DocType
dt = DocType()
@@ -100,27 +106,31 @@
if series in i[0].split("\n"):
msgprint("Oops! Series name %s is already in use in %s. Please select a new one" % (series, i[1]), raise_exception=1)
- #-----------------------------------------------------------------------------------------------------------------------------------
def validate_series_name(self, n):
import re
if not re.match('[a-zA-Z0-9]+(([-/][a-zA-Z0-9])?[-/][a-zA-Z0-9]*)*',n):
msgprint('Special Characters except "-" and "/" not allowed in naming series')
raise Exception
- #-----------------------------------------------------------------------------------------------------------------------------------
def get_options(self, arg=''):
- sr = webnotes.model.doctype.get_property(self.doc.select_doc_for_series, 'options', 'naming_series')
+ sr = webnotes.model.doctype.get_property(self.doc.select_doc_for_series,
+ 'options', 'naming_series')
return sr
+ def get_current(self, arg=None):
+ """get series current"""
+ self.doc.current_value = webnotes.conn.sql("""select current from tabSeries where name=%s""",
+ self.doc.prefix)[0][0]
- #-----------------------------------------------------------------------------------------------------------------------------------
+ def insert_series(self, series):
+ """insert series if missing"""
+ if not webnotes.conn.exists('Series', series):
+ sql("insert into tabSeries (name, current) values (%s,0)", (series))
+
def update_series_start(self):
if self.doc.prefix:
- ser_det = sql("select name from `tabSeries` where name = %s", self.doc.prefix)
- if ser_det:
- sql("update `tabSeries` set current = '%s' where name = '%s'" % (self.doc.starts_from-1,self.doc.prefix))
- else:
- sql("insert into tabSeries (name, current) values (%s,%s)",(cstr(self.doc.prefix),cint(self.doc.starts_from)-1))
+ self.insert_series(self.doc.prefix)
+ sql("update `tabSeries` set current = '%s' where name = '%s'" % (self.doc.current_value,self.doc.prefix))
msgprint("Series Updated Successfully")
else:
msgprint("Please select prefix first")
diff --git a/erpnext/setup/doctype/naming_series/naming_series.txt b/erpnext/setup/doctype/naming_series/naming_series.txt
index 6cb1dab..ff83af8 100644
--- a/erpnext/setup/doctype/naming_series/naming_series.txt
+++ b/erpnext/setup/doctype/naming_series/naming_series.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-04-10 13:01:16',
+ 'creation': '2012-07-03 13:30:54',
'docstatus': 0,
- 'modified': '2012-04-10 18:45:34',
+ 'modified': '2012-07-12 15:59:52',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -16,7 +16,7 @@
'description': u'Set prefix for numbering series on your transactions',
'doctype': 'DocType',
'hide_heading': 0,
- 'hide_toolbar': 0,
+ 'hide_toolbar': 1,
'issingle': 1,
'module': u'Setup',
'name': '__common__',
@@ -24,7 +24,7 @@
'section_style': u'Tray',
'server_code_error': u' ',
'show_in_menu': 0,
- 'version': 66
+ 'version': 1
},
# These values are common for all DocField
@@ -123,7 +123,7 @@
'fieldname': u'help_html',
'fieldtype': u'HTML',
'label': u'Help HTML',
- 'options': u'<div style="padding: 8px; background-color: #FFD; margin: 8px 0px;">\nWrite the list of series options in the list below. Each on a new line<br>\nAllowed special characters are "/" and "-"<br>\nExamples:<br>\nINV-<br>\nINV-10-<br>\nINVK-<br>\n</div>'
+ 'options': u'<div class="help-box">\nEdit list of Series in the box below. Each Series Prefix on a new line.<br><br>\nAllowed special characters are "/" and "-"<br>\nExamples:<br>\nINV-<br>\nINV-10-<br>\nINVK-<br>\n</div>'
},
# DocField
@@ -131,7 +131,7 @@
'doctype': u'DocField',
'fieldname': u'set_options',
'fieldtype': u'Text',
- 'label': u'Set Series'
+ 'label': u'Series List for this Transaction'
},
# DocField
@@ -146,16 +146,17 @@
# DocField
{
+ 'colour': u'White:FFF',
'doctype': u'DocField',
'fieldname': u'update',
'fieldtype': u'Button',
- 'label': u'Update',
- 'options': u'update_series'
+ 'label': u'Update'
},
# DocField
{
- 'description': u'Set starting number for series of your transactions',
+ 'colour': u'White:FFF',
+ 'description': u'Change the starting / current sequence number of an existing series.',
'doctype': u'DocField',
'fieldname': u'update_series',
'fieldtype': u'Section Break',
@@ -166,24 +167,27 @@
{
'doctype': u'DocField',
'fieldname': u'prefix',
- 'fieldtype': u'Data',
+ 'fieldtype': u'Select',
'label': u'Prefix'
},
# DocField
{
+ 'colour': u'White:FFF',
+ 'description': u'This is the number of the last created transaction with this prefix',
'doctype': u'DocField',
- 'fieldname': u'starts_from',
+ 'fieldname': u'current_value',
'fieldtype': u'Int',
- 'label': u'Starts From'
+ 'label': u'Current Value'
},
# DocField
{
+ 'colour': u'White:FFF',
'doctype': u'DocField',
'fieldname': u'update_series_start',
'fieldtype': u'Button',
- 'label': u'Update Series Start',
+ 'label': u'Update Series Number',
'options': u'update_series_start'
}
]
\ No newline at end of file
diff --git a/erpnext/setup/doctype/notification_control/notification_control.txt b/erpnext/setup/doctype/notification_control/notification_control.txt
index 000902e..15c8eb2 100644
--- a/erpnext/setup/doctype/notification_control/notification_control.txt
+++ b/erpnext/setup/doctype/notification_control/notification_control.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-05-03 16:16:21',
+ 'creation': '2012-07-03 13:30:56',
'docstatus': 0,
- 'modified': '2012-05-03 16:23:29',
+ 'modified': '2012-07-12 16:20:36',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -16,6 +16,7 @@
'allow_email': 1,
'allow_print': 1,
'colour': u'White:FFF',
+ 'description': u'Send automatic emails to Contacts on Submitting transactions.',
'doctype': 'DocType',
'issingle': 1,
'module': u'Setup',
@@ -70,10 +71,12 @@
# DocField
{
+ 'colour': u'White:FFF',
+ 'description': u'When any of the checked transactions are "Submitted", an email is automatically sent to the associated "Contact" in that transaction, with the transaction as an attachment.',
'doctype': u'DocField',
'fieldname': u'send_autonotification_for',
'fieldtype': u'Section Break',
- 'label': u'Send Auto-notification for'
+ 'label': u'Send Email Automatically on Submission of'
},
# DocField
@@ -152,6 +155,8 @@
# DocField
{
+ 'colour': u'White:FFF',
+ 'description': u'Customize the introductory text that goes as a part of that email. Each transaction has a separate introductory text.',
'doctype': u'DocField',
'fieldname': u'customize_the_notification',
'fieldtype': u'Section Break',
diff --git a/erpnext/setup/doctype/price_list/price_list.js b/erpnext/setup/doctype/price_list/price_list.js
index a222a65..11993f8 100644
--- a/erpnext/setup/doctype/price_list/price_list.js
+++ b/erpnext/setup/doctype/price_list/price_list.js
@@ -14,24 +14,34 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-//--------- ONLOAD -------------
-cur_frm.cscript.onload = function(doc, cdt, cdn) {
-}
-
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
if(doc.__islocal) {
- set_field_options('price_help', ''); return;
+ cur_frm.set_intro("Save this list to begin.");
+ return;
}
if(!doc.file_list) {
- set_field_options('price_help', '<div class="help_box">To upload a price list, please attach a (.csv) file with 3 columns - <b>Item Code, Price and Currency</b> (no headings necessary). See attachments box in the right column</div>')
- } else {
- set_field_options('price_help', '<div class="help_box">To update prices from the attachment, please click on "Update Prices"</div>')
- }
-}
+ cur_frm.set_intro('<p>1. Click on "Download Template" \
+ to download the template of all Items.</p>'
+ +'<p>2. Update prices and Currency.</p>'
+ +'<p>3. Save it as a CSV (.csv) file.</p>'
+ +'<p>4. Upload the file.</p>');
+
+ cur_frm.add_custom_button('Download Template', function() {
+ $c_obj_csv(cur_frm.get_doclist(), 'download_template');
+ }, 'icon-download')
+
+ cur_frm.add_custom_button('Upload Price List', function() {
+ cur_frm.attachments.add_attachment();
+ }, 'icon-upload')
+
-cur_frm.cscript.clear_prices = function(doc, cdt, cdn) {
- if(confirm("This action will clear all rates for '"+ doc.name +"' from the Item Master and cannot be un-done. Are you sure you want to continue?")) {
- $c_obj(make_doclist(doc.doctype, doc.name), 'clear_prices', '', function(r, rt) { });
+ } else {
+ cur_frm.set_intro('To update prices from the attachment, click on "Update Prices". \
+ To reset prices, delete the attachment (in the sidebar) and upload again.');
+
+ // Update Prices
+ cur_frm.add_custom_button('Update Prices', function() {
+ cur_frm.call_server('update_prices');
+ }, 'icon-refresh')
}
}
diff --git a/erpnext/setup/doctype/price_list/price_list.py b/erpnext/setup/doctype/price_list/price_list.py
index be59c65..0ec7121 100644
--- a/erpnext/setup/doctype/price_list/price_list.py
+++ b/erpnext/setup/doctype/price_list/price_list.py
@@ -14,23 +14,10 @@
# 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
-
-# -----------------------------------------------------------------------------------------
+from webnotes.model.doc import Document
+from webnotes import msgprint
class DocType:
@@ -43,11 +30,24 @@
if currency in self.cl:
return 1
- if sql("select name from tabCurrency where name=%s", currency):
+ if webnotes.conn.sql("select name from tabCurrency where name=%s", currency):
self.cl.append(currency)
return 1
else:
return 0
+
+ def download_template(self, arg=None):
+ """download 3 column template with all Items"""
+ default_currency = webnotes.conn.get_default('currency')
+ item_list = webnotes.conn.sql("""select name from tabItem where
+ (ifnull(is_sales_item,'')='Yes' or ifnull(is_service_item,'')='Yes')""")
+ data = [self.get_price(i[0], default_currency) for i in item_list]
+ return [['Item', 'Rate', 'Currency']] + data
+
+ def get_price(self, item, default_currency):
+ rate = webnotes.conn.sql("""select ref_rate, ref_currency from `tabItem Price`
+ where parent=%s and price_list_name=%s""", (item, self.doc.name))
+ return [item, rate and rate[0][0] or 0, rate and rate[0][1] or default_currency]
# update prices in Price List
def update_prices(self):
@@ -57,15 +57,15 @@
updated = 0
for line in data:
- if line and len(line)==3:
+ if line and len(line)==3 and line[0]!='Item':
# if item exists
- if sql("select name from tabItem where name=%s", line[0]):
+ if webnotes.conn.sql("select name from tabItem where name=%s", line[0]):
if self.is_currency_valid(line[2]):
# if price exists
- ref_ret_detail = sql("select name from `tabItem Price` where parent=%s and price_list_name=%s and ref_currency=%s", \
+ ref_ret_detail = webnotes.conn.sql("select name from `tabItem Price` where parent=%s and price_list_name=%s and ref_currency=%s", \
(line[0], self.doc.name, line[2]))
if ref_ret_detail:
- sql("update `tabItem Price` set ref_rate=%s where name=%s", (line[1], ref_ret_detail[0][0]))
+ webnotes.conn.sql("update `tabItem Price` set ref_rate=%s where name=%s", (line[1], ref_ret_detail[0][0]))
else:
d = Document('Item Price')
d.parent = line[0]
@@ -80,17 +80,9 @@
msgprint("[Ignored] Unknown currency '%s' for Item '%s'" % (line[2], line[0]))
else:
msgprint("[Ignored] Did not find Item '%s'" % line[1])
- else:
- msgprint("[Ignored] Incorrect format: %s" % str(line))
msgprint("<b>%s</b> items updated" % updated)
- # clear prices
- def clear_prices(self):
- cnt = sql("select count(*) from `tabItem Price` where price_list_name = %s", self.doc.name)
- sql("delete from `tabItem Price` where price_list_name = %s", self.doc.name)
- msgprint("%s prices cleared" % cnt[0][0])
-
# Update CSV data
def get_csv_data(self):
if not self.doc.file_list:
@@ -99,8 +91,12 @@
fid = self.doc.file_list.split(',')[1]
- from webnotes.utils import file_manager
- fn, content = file_manager.get_file(fid)
+ try:
+ from webnotes.utils import file_manager
+ fn, content = file_manager.get_file(fid)
+ except Exception, e:
+ webnotes.msgprint("Unable to open attached file. Please try again.")
+ raise e
# NOTE: Don't know why this condition exists
if not isinstance(content, basestring) and hasattr(content, 'tostring'):
diff --git a/erpnext/setup/doctype/price_list/price_list.txt b/erpnext/setup/doctype/price_list/price_list.txt
index 2881cd7..79a7644 100644
--- a/erpnext/setup/doctype/price_list/price_list.txt
+++ b/erpnext/setup/doctype/price_list/price_list.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-05-15 12:15:02',
+ 'creation': '2012-07-03 13:30:55',
'docstatus': 0,
- 'modified': '2012-06-22 10:51:23',
+ 'modified': '2012-07-11 17:35:10',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -14,9 +14,13 @@
{
'_last_update': u'1303100817',
'allow_attach': 1,
+ 'allow_copy': 1,
+ 'allow_email': 1,
+ 'allow_print': 1,
'allow_trash': 1,
'autoname': u'field:price_list_name',
'colour': u'White:FFF',
+ 'description': u'Maintain multiple selling rates for the same **Item** using **Price Lists**. You can upload / edit multiple prices by downloading and uploading the template.',
'doctype': 'DocType',
'document_type': u'Master',
'max_attachments': 1,
@@ -34,7 +38,8 @@
'name': '__common__',
'parent': u'Price List',
'parentfield': u'fields',
- 'parenttype': u'DocType'
+ 'parenttype': u'DocType',
+ 'permlevel': 0
},
# These values are common for all DocPerm
@@ -108,71 +113,20 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'trash_reason',
- 'fieldtype': u'Small Text',
- 'label': u'Trash Reason',
- 'oldfieldname': u'trash_reason',
- 'oldfieldtype': u'Small Text',
- 'permlevel': 1
- },
-
- # DocField
- {
- 'doctype': u'DocField',
'fieldname': u'price_list_name',
'fieldtype': u'Data',
'label': u'Price List Name',
'oldfieldname': u'price_list_name',
'oldfieldtype': u'Data',
- 'permlevel': 0,
'reqd': 1
},
# DocField
{
- 'colour': u'White:FFF',
- 'depends_on': u'eval:!doc.__islocal',
- 'doctype': u'DocField',
- 'fieldname': u'price_help',
- 'fieldtype': u'HTML',
- 'label': u'Price Help',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'colour': u'White:FFF',
- 'depends_on': u'eval:!doc.__islocal',
- 'description': u'Click on this button to clear prices for this list in all items',
- 'doctype': u'DocField',
- 'fieldname': u'clear_prices',
- 'fieldtype': u'Button',
- 'label': u'Clear Prices',
- 'permlevel': 0,
- 'trigger': u'Client'
- },
-
- # DocField
- {
'doctype': u'DocField',
'fieldname': u'file_list',
'fieldtype': u'Text',
'hidden': 1,
- 'label': u'File List',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'colour': u'White:FFF',
- 'depends_on': u'eval:!doc.__islocal',
- 'description': u'Update prices from the attachment',
- 'doctype': u'DocField',
- 'fieldname': u'update_prices',
- 'fieldtype': u'Button',
- 'label': u'Update Prices',
- 'options': u'update_prices',
- 'permlevel': 0,
- 'trigger': u'Server'
+ 'label': u'File List'
}
]
\ No newline at end of file
diff --git a/erpnext/setup/doctype/sales_partner/sales_partner.js b/erpnext/setup/doctype/sales_partner/sales_partner.js
index 92c9966..4f2aba2 100644
--- a/erpnext/setup/doctype/sales_partner/sales_partner.js
+++ b/erpnext/setup/doctype/sales_partner/sales_partner.js
@@ -95,55 +95,7 @@
}
-// ******************** ITEM Group ********************************
cur_frm.fields_dict['partner_target_details'].grid.get_field("item_group").get_query = function(doc, dt, dn) {
return 'SELECT `tabItem Group`.`name`,`tabItem Group`.`parent_item_group` FROM `tabItem Group` WHERE `tabItem Group`.is_group="No" AND `tabItem Group`.docstatus != 2 AND `tabItem Group`.%(key)s LIKE "%s" LIMIT 50'
}
-// make sales order list
-cur_frm.cscript.make_so_list = function(parent, doc){
- var lst = new Listing();
- lst.colwidths = ['5%','20%','20%','15%','20%','20%'];
- lst.colnames = ['Sr.','Id','Status','SO Date','Total Commission','Grand Total'];
- lst.coltypes = ['Data','Link','Data','Data','Currency','Currency'];
- lst.coloptions = ['','Sales Order','','','','',''];
-
- cur_frm.cscript.set_list_opts(lst);
-
- var q = repl("select name,status,transaction_date, total_commission,grand_total from `tabSales Order` where sales_partner='%(sp)s'", {'sp':doc.name});
- var q_max = repl("select count(name) from `tabSales Order` where sales_partner='%(cust)s'", {'sp':doc.name});
-
- cur_frm.cscript.run_list(lst,parent,q,q_max,doc,'Sales Order','Sales Order');
-}
-
-// make delivery note list
-cur_frm.cscript.make_dn_list = function(parent,doc){
- var lst = new Listing();
- lst.colwidths = ['5%','20%','20%','15%','20%','20%'];
- lst.colnames = ['Sr.','Id','Status','Date','Total Commission','Grand Total'];
- lst.coltypes = ['Data','Link','Data','Data','Currency','Currency'];
- lst.coloptions = ['','Delivery Note','','','','',''];
-
- cur_frm.cscript.set_list_opts(lst);
-
- var q = repl("select name,status,transaction_date, total_commission,grand_total from `tabDelivery Note` where sales_partner='%(sp)s'", {'sp':doc.name});
- var q_max = repl("select count(name) from `tabDelivery Note` where sales_partner='%(cust)s'", {'sp':doc.name});
-
- cur_frm.cscript.run_list(lst,parent,q,q_max,doc,'Delivery Note','Delivery Note');
-}
-
-// make sales invoice list
-cur_frm.cscript.make_si_list = function(parent,doc){
- var lst = new Listing();
- lst.colwidths = ['5%','25%','20%','25%','25%'];
- lst.colnames = ['Sr.','Id','Invoice Date','Total Commission','Grand Total'];
- lst.coltypes = ['Data','Link','Data','Data','Currency','Currency'];
- lst.coloptions = ['','Sales Invoice','','','',''];
-
- cur_frm.cscript.set_list_opts(lst);
-
- var q = repl("select name,posting_date, total_commission,grand_total from `tabSales Invoice` where sales_partner='%(sp)s'", {'sp':doc.name});
- var q_max = repl("select count(name) from `tabSales Invoice` where sales_partner='%(cust)s'", {'sp':doc.name});
-
- cur_frm.cscript.run_list(lst,parent,q,q_max,doc,'Sales Invoice','Sales Invoice');
-}
diff --git a/erpnext/setup/doctype/sales_partner/sales_partner.txt b/erpnext/setup/doctype/sales_partner/sales_partner.txt
index 0aa2de7..4e79261 100644
--- a/erpnext/setup/doctype/sales_partner/sales_partner.txt
+++ b/erpnext/setup/doctype/sales_partner/sales_partner.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-03-27 14:36:23',
+ 'creation': '2012-07-03 13:30:54',
'docstatus': 0,
- 'modified': '2012-03-27 18:49:33',
+ 'modified': '2012-07-12 11:22:15',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -17,6 +17,7 @@
'autoname': u'field:partner_name',
'colour': u'White:FFF',
'default_print_format': u'Standard',
+ 'description': u'A **Sales Partner** is a third party distributor / dealer / commission agent / affiliate / reseller who sells the companies products for a commission. This is useful if you make the end sale to the **Customer**, involving your **Sales Partner**.\n\nIf you sell to your **Sales Partner** who in-turn sells it to the **Customer**, then you must make a **Customer** instead.',
'doctype': 'DocType',
'document_type': u'Master',
'in_create': 0,
@@ -26,7 +27,7 @@
'section_style': u'Tabbed',
'server_code_error': u' ',
'show_in_menu': 0,
- 'version': 74
+ 'version': 1
},
# These values are common for all DocField
@@ -57,49 +58,6 @@
# DocPerm
{
'amend': 0,
- 'cancel': 1,
- 'create': 1,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Sales Master Manager',
- 'submit': 0,
- 'write': 1
- },
-
- # DocPerm
- {
- 'amend': 0,
- 'cancel': 0,
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 1,
- 'role': u'Sales Master Manager',
- 'submit': 0,
- 'write': 0
- },
-
- # DocPerm
- {
- 'cancel': 1,
- 'create': 1,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'System Manager',
- 'write': 1
- },
-
- # DocPerm
- {
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 1,
- 'role': u'System Manager',
- 'write': 0
- },
-
- # DocPerm
- {
- 'amend': 0,
'cancel': 0,
'create': 0,
'doctype': u'DocPerm',
@@ -145,6 +103,49 @@
'write': 0
},
+ # DocPerm
+ {
+ 'amend': 0,
+ 'cancel': 1,
+ 'create': 1,
+ 'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'Sales Master Manager',
+ 'submit': 0,
+ 'write': 1
+ },
+
+ # DocPerm
+ {
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 1,
+ 'role': u'Sales Master Manager',
+ 'submit': 0,
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'cancel': 1,
+ 'create': 1,
+ 'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'System Manager',
+ 'write': 1
+ },
+
+ # DocPerm
+ {
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 1,
+ 'role': u'System Manager',
+ 'write': 0
+ },
+
# DocField
{
'colour': u'White:FFF',
@@ -152,7 +153,7 @@
'doctype': u'DocField',
'fieldname': u'basic_info',
'fieldtype': u'Section Break',
- 'label': u'Basic Info',
+ 'label': u'Sales Partner Details',
'oldfieldtype': u'Section Break',
'permlevel': 0
},
@@ -282,7 +283,7 @@
'doctype': u'DocField',
'fieldname': u'partner_target_details_section_break',
'fieldtype': u'Section Break',
- 'label': u'Partner Target Details',
+ 'label': u'Sales Partner Target',
'oldfieldtype': u'Section Break',
'permlevel': 0
},
@@ -290,18 +291,6 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'distribution_id',
- 'fieldtype': u'Link',
- 'label': u'Distribution Id',
- 'oldfieldname': u'distribution_id',
- 'oldfieldtype': u'Link',
- 'options': u'Budget Distribution',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
'fieldname': u'partner_target_details',
'fieldtype': u'Table',
'label': u'Partner Target Detail',
@@ -314,35 +303,15 @@
# DocField
{
- 'doctype': u'DocField',
- 'fieldname': u'manage_html',
- 'fieldtype': u'HTML',
- 'hidden': 1,
- 'label': u'Manage HTML',
- 'oldfieldtype': u'HTML',
- 'permlevel': 0,
- 'print_hide': 1
- },
-
- # DocField
- {
'colour': u'White:FFF',
- 'depends_on': u'eval:!doc.__islocal',
+ 'description': u'Select Budget Distribution to unevenly distribute targets across months.',
'doctype': u'DocField',
- 'fieldname': u'transaction_history',
- 'fieldtype': u'Section Break',
- 'label': u'Transaction History',
- 'oldfieldtype': u'Section Break',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'history_html',
- 'fieldtype': u'HTML',
- 'label': u'History HTML',
- 'oldfieldtype': u'HTML',
+ 'fieldname': u'distribution_id',
+ 'fieldtype': u'Link',
+ 'label': u'Target Distribution',
+ 'oldfieldname': u'distribution_id',
+ 'oldfieldtype': u'Link',
+ 'options': u'Budget Distribution',
'permlevel': 0
},
diff --git a/erpnext/setup/doctype/sales_person/sales_person.js b/erpnext/setup/doctype/sales_person/sales_person.js
index 453d88a..a1cac8a 100644
--- a/erpnext/setup/doctype/sales_person/sales_person.js
+++ b/erpnext/setup/doctype/sales_person/sales_person.js
@@ -14,30 +14,19 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
+cur_frm.cscript.set_breadcrumbs = function(barea) {
+ cur_frm.frm_head.appframe.add_breadcrumb(cur_frm.docname);
+ cur_frm.frm_head.appframe.add_breadcrumb(' in <a href="#!Sales Browser/Sales Person">\
+ Sales Person Tree</a>');
+ cur_frm.frm_head.appframe.add_breadcrumb(' in <a href="#!selling-home">Selling</a>');
+}
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
}
cur_frm.cscript.onload = function(){
- if(doc.__islocal){
- doc.parent_sales_person = 'Root';
- refresh('parent_sales_person');
- }
-}
-cur_frm.cscript.country = function(doc, cdt, cdn) {
- var mydoc=doc;
- $c('runserverobj', args={'method':'check_state', 'docs':compress_doclist(make_doclist(doc.doctype, doc.name))},
- function(r,rt){
- if(r.message) {
- var doc = locals[mydoc.doctype][mydoc.name];
- doc.state = '';
- get_field(doc.doctype, 'state' , doc.name).options = r.message;
- refresh_field('state');
- }
- }
- );
-}
+}
//get query select sales person
cur_frm.fields_dict['parent_sales_person'].get_query = function(doc,cdt,cdn) {
diff --git a/erpnext/setup/doctype/sales_person/sales_person.py b/erpnext/setup/doctype/sales_person/sales_person.py
index d8c6e43..3ab1847 100644
--- a/erpnext/setup/doctype/sales_person/sales_person.py
+++ b/erpnext/setup/doctype/sales_person/sales_person.py
@@ -17,79 +17,19 @@
# Please edit this list and import only required elements
import webnotes
-from webnotes.model.doc import Document
from webnotes.model.doclist import getlist
-from webnotes.model.code import get_obj
-from webnotes import session, form, is_testing, msgprint, errprint
-from webnotes.utils import flt, cstr
+from webnotes.utils import flt
-sql = webnotes.conn.sql
-convert_to_lists = webnotes.conn.convert_to_lists
-
-# -----------------------------------------------------------------------------------------
+from webnotes.utils.nestedset import DocTypeNestedSet
-class DocType:
+class DocType(DocTypeNestedSet):
def __init__(self, doc, doclist=[]):
self.doc = doc
self.doclist = doclist
self.nsm_parent_field = 'parent_sales_person';
-
- def check_state(self):
- return "\n" + "\n".join([i[0] for i in sql("select state_name from `tabState` where `tabState`.country='%s' " % self.doc.country)])
-
-
- # update Node Set Model
- def update_nsm_model(self):
- import webnotes
- import webnotes.utils.nestedset
- webnotes.utils.nestedset.update_nsm(self)
-
- # ON UPDATE
- #--------------------------------------
- def on_update(self):
- # update nsm
- self.update_nsm_model()
-
def validate(self):
for d in getlist(self.doclist, 'target_details'):
if not flt(d.target_qty) and not flt(d.target_amount):
- msgprint("Either target qty or target amount is mandatory.")
+ webnotes.msgprint("Either target qty or target amount is mandatory.")
raise Exception
-
- #self.sync_with_contact()
-
- def sync_with_contact(self):
- cid = sql("select name from tabContact where sales_person_id = %s and is_sales_person=1", self.doc.name)
- if cid:
- d = Document('Contact', cid[0][0])
- else:
- d = Document('Contact')
-
- name_split = self.doc.sales_person_name.split()
- d.contact_name = self.doc.sales_person_name
- d.first_name = name_split[0]
- d.last_name = len(name_split) > 1 and name_split[1] or ''
- d.email_id = self.doc.email_id
- d.contact_no = d.mobile_no = self.doc.mobile_no
- d.designation = self.doc.designation
- d.department = self.doc.department
- d.sales_person_id = self.doc.name
- d.is_sales_person = 1
-
- d.save(new = (not d.name))
-
-
- def on_trash(self):
- st = sql("select parent, parenttype from `tabSales Team` where ifnull(sales_person, '') = %s and docstatus != 2", self.doc.name)
- st = [(d[1] + ' : ' + d[0]) for d in st]
- if st:
- msgprint("""Sales Person: %s can not be trashed/deleted because it is used in %s.
- To trash/delete this, remove/change sales person in %s""" % (self.doc.name, st or '', st or ''), raise_exception=1)
-
- if sql("select name from `tabSales Person` where parent_sales_person = %s and docstatus != 2", self.doc.name):
- msgprint("Child sales person exists for this sales person. You can not trash/cancel this sales person.", raise_exception=1)
-
- # rebuild tree
- webnotes.conn.set(self.doc,'old_parent', '')
- self.update_nsm_model()
diff --git a/erpnext/setup/doctype/sales_person/sales_person.txt b/erpnext/setup/doctype/sales_person/sales_person.txt
index 5ff8e94..028d828 100644
--- a/erpnext/setup/doctype/sales_person/sales_person.txt
+++ b/erpnext/setup/doctype/sales_person/sales_person.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-04-13 11:56:32',
+ 'creation': '2012-07-03 13:30:54',
'docstatus': 0,
- 'modified': '2012-05-31 11:28:32',
+ 'modified': '2012-07-12 10:33:10',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -16,6 +16,7 @@
'allow_trash': 1,
'autoname': u'field:sales_person_name',
'colour': u'White:FFF',
+ 'description': u'All Sales Transactions can be tagged against multiple **Sales Persons** so that you can set and monitor targets.',
'doctype': 'DocType',
'document_type': u'Master',
'in_create': 1,
@@ -129,17 +130,6 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'general_info',
- 'fieldtype': u'Section Break',
- 'label': u'General Info',
- 'oldfieldtype': u'Section Break',
- 'options': u'Simple',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
'fieldname': u'sales_person_name',
'fieldtype': u'Data',
'in_filter': 1,
@@ -170,17 +160,6 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'sphelp',
- 'fieldtype': u'HTML',
- 'label': u'SPHelp',
- 'oldfieldtype': u'HTML',
- 'options': u'<a href="#!Sales Browser/Sales Person">To manage Sales Person, click here</a>',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
'fieldname': u'is_group',
'fieldtype': u'Select',
'label': u'Has Child Node',
@@ -194,6 +173,14 @@
# DocField
{
'doctype': u'DocField',
+ 'fieldname': u'cb0',
+ 'fieldtype': u'Column Break',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
'fieldname': u'employee',
'fieldtype': u'Link',
'label': u'Employee',
@@ -204,125 +191,6 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'department',
- 'fieldtype': u'Data',
- 'label': u'Department',
- 'oldfieldname': u'department',
- 'oldfieldtype': u'Data',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'designation',
- 'fieldtype': u'Data',
- 'label': u'Designation',
- 'oldfieldname': u'designation',
- 'oldfieldtype': u'Data',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'mobile_no',
- 'fieldtype': u'Data',
- 'label': u'Mobile No',
- 'oldfieldname': u'mobile_no',
- 'oldfieldtype': u'Data',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'column_break0',
- 'fieldtype': u'Column Break',
- 'oldfieldtype': u'Column Break',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'email_id',
- 'fieldtype': u'Data',
- 'label': u'Email Id',
- 'oldfieldname': u'email_id',
- 'oldfieldtype': u'Data',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'country',
- 'fieldtype': u'Select',
- 'in_filter': 1,
- 'label': u'Country',
- 'oldfieldname': u'country',
- 'oldfieldtype': u'Select',
- 'options': u'link:Country',
- 'permlevel': 0,
- 'search_index': 0,
- 'trigger': u'Client'
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'state',
- 'fieldtype': u'Select',
- 'in_filter': 1,
- 'label': u'State',
- 'oldfieldname': u'state',
- 'oldfieldtype': u'Select',
- 'options': u'link:State',
- 'permlevel': 0,
- 'search_index': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'city',
- 'fieldtype': u'Data',
- 'label': u'City',
- 'oldfieldname': u'city',
- 'oldfieldtype': u'Data',
- 'permlevel': 0,
- 'reqd': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'territory',
- 'fieldtype': u'Link',
- 'hidden': 0,
- 'label': u'Territory',
- 'oldfieldname': u'territory',
- 'oldfieldtype': u'Link',
- 'options': u'Territory',
- 'permlevel': 0,
- 'search_index': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'territory_help',
- 'fieldtype': u'HTML',
- 'label': u'Territory Help',
- 'oldfieldtype': u'HTML',
- 'options': u'<a href="#!Sales Browser/Territory">To manage Territories, click here</a>',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
'fieldname': u'lft',
'fieldtype': u'Int',
'hidden': 1,
@@ -368,25 +236,13 @@
# DocField
{
- 'doctype': u'DocField',
- 'fieldname': u'distribution_id',
- 'fieldtype': u'Link',
- 'label': u'Distribution Id',
- 'oldfieldname': u'distribution_id',
- 'oldfieldtype': u'Link',
- 'options': u'Budget Distribution',
- 'permlevel': 0,
- 'search_index': 0
- },
-
- # DocField
- {
+ 'colour': u'White:FFF',
+ 'description': u'Set targets Item Group-wise for this Sales Person.',
'doctype': u'DocField',
'fieldname': u'target_details_section_break',
'fieldtype': u'Section Break',
- 'label': u'Target Details',
+ 'label': u'Sales Person Targets',
'oldfieldtype': u'Section Break',
- 'options': u'Simple',
'permlevel': 0
},
@@ -400,5 +256,20 @@
'oldfieldtype': u'Table',
'options': u'Target Detail',
'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'description': u'Select Budget Distribution to unevenly distribute targets across months.',
+ 'doctype': u'DocField',
+ 'fieldname': u'distribution_id',
+ 'fieldtype': u'Link',
+ 'label': u'Target Distribution',
+ 'oldfieldname': u'distribution_id',
+ 'oldfieldtype': u'Link',
+ 'options': u'Budget Distribution',
+ 'permlevel': 0,
+ 'search_index': 0
}
]
\ No newline at end of file
diff --git a/erpnext/setup/doctype/setup_control/setup_control.py b/erpnext/setup/doctype/setup_control/setup_control.py
index 444b796..ee1cb7e 100644
--- a/erpnext/setup/doctype/setup_control/setup_control.py
+++ b/erpnext/setup/doctype/setup_control/setup_control.py
@@ -49,9 +49,7 @@
master_dict = {'Fiscal Year':{
'year': curr_fiscal_year,
'year_start_date': fy_start_date,
- 'abbreviation': fy_abbr,
- 'company': args.get('company_name'),
- 'is_fiscal_year_closed': 'No'}}
+ 'company': args.get('company_name')}}
self.create_records(master_dict)
# Company
diff --git a/erpnext/setup/doctype/supplier_type/supplier_type.js b/erpnext/setup/doctype/supplier_type/supplier_type.js
index 306ead0..945dec0 100644
--- a/erpnext/setup/doctype/supplier_type/supplier_type.js
+++ b/erpnext/setup/doctype/supplier_type/supplier_type.js
@@ -14,14 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-
-// ONLOAD
-// ===================================================================================
-cur_frm.cscript.onload = function(doc, cdt, cdn) {
-
-}
-
-cur_frm.cscript.refresh = function(doc, cdt, cdn) {
-
+cur_frm.cscript.refresh = function(doc) {
+ cur_frm.set_intro(doc.__islocal ? "" : "There is nothing to edit.")
}
\ No newline at end of file
diff --git a/erpnext/setup/doctype/terms_and_conditions/terms_and_conditions.txt b/erpnext/setup/doctype/terms_and_conditions/terms_and_conditions.txt
index 09d71f4..c120b2c 100644
--- a/erpnext/setup/doctype/terms_and_conditions/terms_and_conditions.txt
+++ b/erpnext/setup/doctype/terms_and_conditions/terms_and_conditions.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-03-27 14:36:25',
+ 'creation': '2012-07-03 13:30:54',
'docstatus': 0,
- 'modified': '2012-03-27 14:36:25',
+ 'modified': '2012-07-12 11:37:56',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -17,6 +17,7 @@
'autoname': u'field:title',
'colour': u'White:FFF',
'default_print_format': u'Standard',
+ 'description': u'Standard Terms and Conditions that can be added to Sales and Purchases.\n\nExamples:\n\n1. Validity of the offer.\n1. Payment Terms (In Advance, On Credit, part advance etc).\n1. What is extra (or payable by the Customer).\n1. Safety / usage warning.\n1. Warranty if any.\n1. Returns Policy.\n1. Terms of shipping, if applicable.\n1. Ways of addressing disputes, indemnity, liability, etc.\n1. Address and Contact of your Company.',
'doctype': 'DocType',
'document_type': u'Master',
'module': u'Setup',
@@ -24,7 +25,7 @@
'section_style': u'Simple',
'server_code_error': u' ',
'show_in_menu': 0,
- 'version': 11
+ 'version': 1
},
# These values are common for all DocField
@@ -58,6 +59,42 @@
'cancel': 0,
'create': 0,
'doctype': u'DocPerm',
+ 'permlevel': 1,
+ 'role': u'Sales Master Manager',
+ 'submit': 0,
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'amend': 0,
+ 'cancel': 1,
+ 'create': 1,
+ 'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'Sales Master Manager',
+ 'submit': 0,
+ 'write': 1
+ },
+
+ # DocPerm
+ {
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 1,
+ 'role': u'Sales User',
+ 'submit': 0,
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
'permlevel': 0,
'role': u'Sales User',
'submit': 0,
@@ -91,42 +128,6 @@
'write': 1
},
- # DocPerm
- {
- 'amend': 0,
- 'cancel': 0,
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 1,
- 'role': u'Sales Master Manager',
- 'submit': 0,
- 'write': 0
- },
-
- # DocPerm
- {
- 'amend': 0,
- 'cancel': 1,
- 'create': 1,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Sales Master Manager',
- 'submit': 0,
- 'write': 1
- },
-
- # DocPerm
- {
- 'amend': 0,
- 'cancel': 0,
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 1,
- 'role': u'Sales User',
- 'submit': 0,
- 'write': 0
- },
-
# DocField
{
'doctype': u'DocField',
diff --git a/erpnext/setup/doctype/territory/territory.js b/erpnext/setup/doctype/territory/territory.js
index 46312c4..9b36d0c 100644
--- a/erpnext/setup/doctype/territory/territory.js
+++ b/erpnext/setup/doctype/territory/territory.js
@@ -15,17 +15,19 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
+cur_frm.cscript.set_breadcrumbs = function(barea) {
+ cur_frm.frm_head.appframe.add_breadcrumb(cur_frm.docname);
+ cur_frm.frm_head.appframe.add_breadcrumb(' in <a href="#!Sales Browser/Territory">\
+ Territory Tree</a>');
+ cur_frm.frm_head.appframe.add_breadcrumb(' in <a href="#!selling-home">Selling</a>');
+}
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
}
cur_frm.cscript.onload = function(){
-
- if(doc.__islocal){
- doc.parent_territory = 'All Territories';
- refresh('parent_territory');
- }
+
}
diff --git a/erpnext/setup/doctype/territory/territory.py b/erpnext/setup/doctype/territory/territory.py
index 606efa8..fae33ec 100644
--- a/erpnext/setup/doctype/territory/territory.py
+++ b/erpnext/setup/doctype/territory/territory.py
@@ -8,87 +8,28 @@
#
# 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
+# 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/>.
+# 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
+from webnotes.model.doclist import getlist
+from webnotes.utils import flt
-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
+from webnotes.utils.nestedset import DocTypeNestedSet
-# -----------------------------------------------------------------------------------------
+class DocType(DocTypeNestedSet):
+ def __init__(self, doc, doclist=[]):
+ self.doc = doc
+ self.doclist = doclist
+ self.nsm_parent_field = 'parent_territory'
-
-class DocType:
- def __init__(self, doc, doclist=[]):
- self.doc = doc
- self.doclist = doclist
- self.nsm_parent_field = 'parent_territory'
-
- def check_state(self):
- return "\n" + "\n".join([i[0] for i in sql("select state_name from `tabState` where `tabState`.country='%s' " % self.doc.country)])
-
-
-
- # update Node Set Model
- def update_nsm_model(self):
- import webnotes
- import webnotes.utils.nestedset
- webnotes.utils.nestedset.update_nsm(self)
-
- # ON UPDATE
- #--------------------------------------
- def on_update(self):
-
- # update nsm
- self.update_nsm_model()
-
-
-
- def validate(self):
- if self.doc.lft and self.doc.rgt:
- res = sql("select name from `tabTerritory` where is_group = 'Yes' and docstatus!= 2 and name ='%s' and name !='%s'"%(self.doc.parent_territory,self.doc.territory_name))
- if not res:
- msgprint("Please enter proper parent territory.")
- raise Exception
-
- r = sql("select name from `tabTerritory` where name = '%s' and docstatus = 2"%(self.doc.territory_name))
- if r:
- msgprint("%s record is trashed. To untrash please go to Setup & click on Trash."%(self.doc.territory_name))
- raise Exception
-
- for d in getlist(self.doclist, 'target_details'):
- if not flt(d.target_qty) and not flt(d.target_amount):
- msgprint("Either target qty or target amount is mandatory.")
- raise Exception
-
-
- def on_trash(self):
- cust = sql("select name from `tabCustomer` where ifnull(territory, '') = %s", self.doc.name)
- cust = [d[0] for d in cust]
-
- if cust:
- msgprint("""Territory: %s can not be trashed/deleted because it is used in customer: %s.
- To trash/delete this, remove/change territory in customer master""" % (self.doc.name, cust or ''), raise_exception=1)
-
-
- if sql("select name from `tabTerritory` where parent_territory = %s and docstatus != 2", self.doc.name):
- msgprint("Child territory exists for this territory. You can not trash/cancel/delete this territory.", raise_exception=1)
-
- # rebuild tree
- set(self.doc,'old_parent', '')
- self.update_nsm_model()
+ def validate(self):
+ for d in getlist(self.doclist, 'target_details'):
+ if not flt(d.target_qty) and not flt(d.target_amount):
+ msgprint("Either target qty or target amount is mandatory.")
+ raise Exception
diff --git a/erpnext/setup/doctype/territory/territory.txt b/erpnext/setup/doctype/territory/territory.txt
index 3632801..a9cdf05 100644
--- a/erpnext/setup/doctype/territory/territory.txt
+++ b/erpnext/setup/doctype/territory/territory.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-04-13 11:56:32',
+ 'creation': '2012-07-03 13:30:55',
'docstatus': 0,
- 'modified': '2012-05-31 11:39:33',
+ 'modified': '2012-07-12 10:01:47',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -17,12 +17,14 @@
'autoname': u'field:territory_name',
'colour': u'White:FFF',
'default_print_format': u'Standard',
+ 'description': u'You can create **Territories** If your organization operates in multiple regions (could be countries, states or cities). Once you group **Customers** by **Territories**, you can set annual targets for each **Item Group** and get reports that will show your actual performance in the territory v/s what you had planned.',
'doctype': 'DocType',
'document_type': u'Master',
'in_create': 1,
'module': u'Setup',
'name': '__common__',
'name_case': u'Title Case',
+ 'read_only': 1,
'search_fields': u'name,parent_territory,territory_manager',
'section_style': u'Simple',
'server_code_error': u' ',
@@ -144,20 +146,6 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'territory_manager',
- 'fieldtype': u'Link',
- 'in_filter': 1,
- 'label': u'Territory Manager',
- 'oldfieldname': u'territory_manager',
- 'oldfieldtype': u'Link',
- 'options': u'Sales Person',
- 'permlevel': 0,
- 'search_index': 1
- },
-
- # DocField
- {
- 'doctype': u'DocField',
'fieldname': u'parent_territory',
'fieldtype': u'Link',
'label': u'Parent Territory',
@@ -171,17 +159,6 @@
# DocField
{
- 'doctype': u'DocField',
- 'fieldname': u'territoryhelp',
- 'fieldtype': u'HTML',
- 'label': u'TerritoryHelp',
- 'oldfieldtype': u'HTML',
- 'options': u'<a href="#!Sales Browser/Territory">To manage Territories, click here</a>',
- 'permlevel': 0
- },
-
- # DocField
- {
'colour': u'White:FFF',
'description': u'Only leaf nodes are allowed in transaction',
'doctype': u'DocField',
@@ -198,6 +175,30 @@
# DocField
{
'doctype': u'DocField',
+ 'fieldname': u'cb0',
+ 'fieldtype': u'Column Break',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'description': u'For reference',
+ 'doctype': u'DocField',
+ 'fieldname': u'territory_manager',
+ 'fieldtype': u'Link',
+ 'in_filter': 1,
+ 'label': u'Territory Manager',
+ 'oldfieldname': u'territory_manager',
+ 'oldfieldtype': u'Link',
+ 'options': u'Sales Person',
+ 'permlevel': 0,
+ 'search_index': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
'fieldname': u'lft',
'fieldtype': u'Int',
'hidden': 1,
@@ -247,22 +248,12 @@
# DocField
{
- 'doctype': u'DocField',
- 'fieldname': u'distribution_id',
- 'fieldtype': u'Link',
- 'label': u'Distribution Id',
- 'oldfieldname': u'distribution_id',
- 'oldfieldtype': u'Link',
- 'options': u'Budget Distribution',
- 'permlevel': 0
- },
-
- # DocField
- {
+ 'colour': u'White:FFF',
+ 'description': u'Set Item Group-wise budgets on this Territory. You can also include seasonality by setting the Distribution.',
'doctype': u'DocField',
'fieldname': u'target_details_section_break',
'fieldtype': u'Section Break',
- 'label': u'Target Details',
+ 'label': u'Territory Targets',
'oldfieldtype': u'Section Break',
'permlevel': 0
},
@@ -272,10 +263,24 @@
'doctype': u'DocField',
'fieldname': u'target_details',
'fieldtype': u'Table',
- 'label': u'Target Details1',
+ 'label': u'Target Details',
'oldfieldname': u'target_details',
'oldfieldtype': u'Table',
'options': u'Target Detail',
'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'description': u'Select Budget Distribution to unevenly distribute targets across months.',
+ 'doctype': u'DocField',
+ 'fieldname': u'distribution_id',
+ 'fieldtype': u'Link',
+ 'label': u'Target Distribution',
+ 'oldfieldname': u'distribution_id',
+ 'oldfieldtype': u'Link',
+ 'options': u'Budget Distribution',
+ 'permlevel': 0
}
]
\ No newline at end of file
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index ad95cf1..490051b 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -197,51 +197,6 @@
get_obj('DocType Mapper', 'Sales Order-Delivery Note', with_children = 1).validate_reference_value(self, self.doc.name)
- def validate_prevdoc_details(self):
- for d in getlist(self.doclist,'delivery_note_details'):
- prevdoc = d.prevdoc_doctype
- prevdoc_docname = d.prevdoc_docname
-
- if prevdoc_docname and prevdoc:
- # Validates Transaction Date of DN and previous doc (i.e. SO , PO, PR)
- trans_date = sql("select posting_date from `tab%s` where name = '%s'" %(prevdoc,prevdoc_docname))[0][0]
- if trans_date and getdate(self.doc.posting_date) < (trans_date):
- msgprint("Your Posting Date cannot be before "+cstr(prevdoc)+" Date.")
- raise Exception
- # Validates DN and previous doc details
- get_name = sql("select name from `tab%s` where name = '%s'" % (prevdoc, prevdoc_docname))
- name = get_name and get_name[0][0] or ''
- if name: #check for incorrect docname
- if prevdoc == 'Sales Order':
- dt = sql("select company, docstatus, customer, currency, sales_partner from `tab%s` where name = '%s'" % (prevdoc, name))
- cust_name = dt and dt[0][2] or ''
- if cust_name != self.doc.customer:
- msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " customer :" + cstr(cust_name) + " does not match with customer : " + cstr(self.doc.customer) + " of current document.")
- raise Exception, "Validation Error. "
- sal_partner = dt and dt[0][4] or ''
- if sal_partner != self.doc.sales_partner:
- msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " sales partner name :" + cstr(sal_partner) + " does not match with sales partner name : " + cstr(self.doc.sales_partner_name) + " of current document.")
- raise Exception, "Validation Error. "
- else:
- dt = sql("select company, docstatus, supplier, currency from `tab%s` where name = '%s'" % (prevdoc, name))
- supp_name = dt and dt[0][2] or ''
- company_name = dt and dt[0][0] or ''
- docstatus = dt and dt[0][1] or 0
- currency = dt and dt[0][3] or ''
- if (currency != self.doc.currency):
- msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " currency : "+ cstr(currency) + "does not match with Currency: " + cstr(self.doc.currency) + "of current document")
- raise Exception, "Validation Error."
- if (company_name != self.doc.company):
- msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " does not belong to the Company: " + cstr(self.doc.company_name))
- raise Exception, "Validation Error."
- if (docstatus != 1):
- msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " is not Submitted Document.")
- raise Exception, "Validation Error."
- else:
- msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " is not a valid " + cstr(prevdoc))
- raise Exception, "Validation Error."
-
-
def validate_for_items(self):
check_list, chk_dupl_itm = [], []
for d in getlist(self.doclist,'delivery_note_details'):
@@ -292,11 +247,22 @@
set(self.doc, 'message', 'Items against your Order #%s have been delivered. Delivery #%s: ' % (self.doc.po_no, self.doc.name))
# Check for Approving Authority
get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.company, self.doc.grand_total, self)
+
+ # validate serial no for item table (non-sales-bom item) and packing list (sales-bom item)
sl_obj = get_obj("Stock Ledger")
+ sl_obj.validate_serial_no(self, 'delivery_note_details')
+ sl_obj.validate_serial_no_warehouse(self, 'delivery_note_details')
sl_obj.validate_serial_no(self, 'packing_details')
sl_obj.validate_serial_no_warehouse(self, 'packing_details')
+
+ # update delivery details in serial no
+ sl_obj.update_serial_record(self, 'delivery_note_details', is_submit = 1, is_incoming = 0)
sl_obj.update_serial_record(self, 'packing_details', is_submit = 1, is_incoming = 0)
+
+ # update delivered qty in sales order
get_obj("Sales Common").update_prevdoc_detail(1,self)
+
+ # create stock ledger entry
self.update_stock_ledger(update_stock = 1)
self.credit_limit()
@@ -332,10 +298,14 @@
sales_com_obj = get_obj(dt = 'Sales Common')
sales_com_obj.check_stop_sales_order(self)
self.check_next_docstatus()
- get_obj('Stock Ledger').update_serial_record(self, 'packing_details', is_submit = 0, is_incoming = 0)
+
+ # remove delivery details from serial no
+ sl = get_obj('Stock Ledger')
+ sl.update_serial_record(self, 'delivery_note_details', is_submit = 0, is_incoming = 0)
+ sl.update_serial_record(self, 'packing_details', is_submit = 0, is_incoming = 0)
+
sales_com_obj.update_prevdoc_detail(0,self)
self.update_stock_ledger(update_stock = -1)
- # :::::: set DN status :::::::
set(self.doc, 'status', 'Cancelled')
self.cancel_packing_slips()
@@ -435,7 +405,8 @@
def on_update(self):
get_obj('Sales Common').make_packing_list(self,'delivery_note_details')
- self.set_actual_qty()
- get_obj('Stock Ledger').scrub_serial_nos(self)
+ sl = get_obj('Stock Ledger')
+ sl.scrub_serial_nos(self)
+ sl.scrub_serial_nos(self, 'packing_details')
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.txt b/erpnext/stock/doctype/delivery_note/delivery_note.txt
index 7db9513..a0c2df0 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.txt
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-05-15 12:15:05',
+ 'creation': '2012-06-11 12:10:09',
'docstatus': 0,
- 'modified': '2012-05-18 18:06:26',
+ 'modified': '2012-07-11 11:56:53',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -72,26 +72,14 @@
# DocPerm
{
- 'amend': 1,
- 'cancel': 1,
- 'create': 1,
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Sales User',
- 'submit': 1,
- 'write': 1
- },
-
- # DocPerm
- {
- 'amend': 1,
- 'cancel': 1,
- 'create': 1,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Material Master Manager',
- 'submit': 1,
- 'write': 1
+ 'permlevel': 1,
+ 'role': u'Material User',
+ 'submit': 0,
+ 'write': 0
},
# DocPerm
@@ -108,16 +96,72 @@
# DocPerm
{
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
'doctype': u'DocPerm',
'permlevel': 1,
- 'role': u'All'
+ 'role': u'Material Manager',
+ 'submit': 0,
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'amend': 1,
+ 'cancel': 1,
+ 'create': 1,
+ 'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'Sales User',
+ 'submit': 1,
+ 'write': 1
+ },
+
+ # DocPerm
+ {
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 1,
+ 'role': u'Sales User',
+ 'submit': 0,
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'Accounts User',
+ 'submit': 0,
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'doctype': u'DocPerm',
+ 'permlevel': 1,
+ 'role': u'Accounts User'
+ },
+
+ # DocPerm
+ {
+ 'doctype': u'DocPerm',
+ 'match': u'customer_name',
+ 'permlevel': 0,
+ 'role': u'Customer'
},
# DocPerm
{
'doctype': u'DocPerm',
'permlevel': 2,
- 'role': u'All'
+ 'role': u'All',
+ 'write': 1
},
# DocField
@@ -340,6 +384,7 @@
# DocField
{
'allow_on_submit': 1,
+ 'colour': u'White:FFF',
'doctype': u'DocField',
'fieldname': u'delivery_note_details',
'fieldtype': u'Table',
@@ -355,6 +400,16 @@
# DocField
{
'doctype': u'DocField',
+ 'fieldname': u'sales_bom_help',
+ 'fieldtype': u'HTML',
+ 'label': u'Sales BOM Help',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
'fieldname': u'section_break0',
'fieldtype': u'Section Break',
'options': u'Simple',
diff --git a/erpnext/stock/doctype/delivery_note_packing_item/delivery_note_packing_item.txt b/erpnext/stock/doctype/delivery_note_packing_item/delivery_note_packing_item.txt
index 51001fc..db512c6 100644
--- a/erpnext/stock/doctype/delivery_note_packing_item/delivery_note_packing_item.txt
+++ b/erpnext/stock/doctype/delivery_note_packing_item/delivery_note_packing_item.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-04-13 11:56:35',
+ 'creation': '2012-06-11 12:10:10',
'docstatus': 0,
- 'modified': '2012-05-09 12:55:23',
+ 'modified': '2012-07-10 12:05:31',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -111,7 +111,7 @@
'oldfieldname': u'warehouse',
'oldfieldtype': u'Link',
'options': u'Warehouse',
- 'permlevel': 1
+ 'permlevel': 0
},
# DocField
diff --git a/erpnext/stock/doctype/item/item.txt b/erpnext/stock/doctype/item/item.txt
index 06806ba..c624fc1 100644
--- a/erpnext/stock/doctype/item/item.txt
+++ b/erpnext/stock/doctype/item/item.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-06-08 12:54:51',
+ 'creation': '2012-07-03 13:30:46',
'docstatus': 0,
- 'modified': '2012-07-04 11:10:29',
+ 'modified': '2012-07-11 09:57:42',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -196,7 +196,7 @@
# DocField
{
'colour': u'White:FFF',
- 'description': u'Classify your item in any one item group by clicking on the magnifying glass',
+ 'description': u'<a href="#!Sales Browser/Item Group">Manage Item Groups</a>',
'doctype': u'DocField',
'fieldname': u'item_group',
'fieldtype': u'Link',
@@ -212,17 +212,6 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'ighelp',
- 'fieldtype': u'HTML',
- 'label': u'IGHelp',
- 'oldfieldtype': u'HTML',
- 'options': u'<a href="#!Sales Browser/Item Group">To manage Item Groups, click here</a>',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
'fieldname': u'brand',
'fieldtype': u'Link',
'hidden': 0,
diff --git a/erpnext/stock/doctype/sales_bom/sales_bom.js b/erpnext/stock/doctype/sales_bom/sales_bom.js
index 275af6a..68b9013 100644
--- a/erpnext/stock/doctype/sales_bom/sales_bom.js
+++ b/erpnext/stock/doctype/sales_bom/sales_bom.js
@@ -14,35 +14,26 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-
-cur_frm.cscript.onload = function(doc, cdt, cdn) {
-
- if(!doc.price_list) set_multiple(cdt,cdn,{price_list:sys_defaults.price_list_name});
-}
-
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
+ cur_frm.enable_fields('new_item_code', doc.__islocal);
if(!doc.__islocal) {
- get_field(doc.doctype, 'new_item_code', doc.name).permlevel = 1;
+ cur_frm.add_custom_button("Check for Duplicates", function() {
+ cur_frm.call_server('check_duplicate', 1)
+ }, 'icon-search')
}
}
-/* Get Item Code */
+cur_frm.fields_dict.new_item_code.get_query = function() {
+ return 'select name, description from tabItem where is_stock_item="No" and is_sales_item="Yes"\
+ and name not in (select name from `tabSales BOM`)\
+ and `%(key)s` like "%s"'
+}
+cur_frm.fields_dict.new_item_code.query_description = 'Select Item where "Is Stock Item" is "No" \
+ and "Is Sales Item" is "Yes" and there is no other Sales BOM';
+
cur_frm.cscript.item_code = function(doc, dt, dn) {
- var d = locals[dt][dn];
- if (d.item_code){
- get_server_fields('get_item_details', d.item_code, 'sales_bom_items', doc ,dt, dn, 1);
- }
-}
-
-cur_frm.cscript.price_list = function(doc, cdt, cdn) {
- $c_obj(make_doclist(cdt,cdn), 'get_rates', '', function(r,rt){refresh_field('sales_bom_items');});
-}
-
-cur_frm.cscript.currency = function(doc, cdt, cdn) {
- $c_obj(make_doclist(cdt,cdn), 'get_rates', '', function(r,rt){refresh_field('sales_bom_items');});
-}
-
-cur_frm.cscript.find_sales_bom = function(doc, dt, dn) {
- $c_obj(make_doclist(dt,dn), 'check_duplicate', 1, '');
-}
+ var d = locals[dt][dn];
+ if (d.item_code){
+ get_server_fields('get_item_details', d.item_code, 'sales_bom_items', doc ,dt, dn, 1);
+ }
+}
\ No newline at end of file
diff --git a/erpnext/stock/doctype/sales_bom/sales_bom.py b/erpnext/stock/doctype/sales_bom/sales_bom.py
index 03e1bd0..1cf9198 100644
--- a/erpnext/stock/doctype/sales_bom/sales_bom.py
+++ b/erpnext/stock/doctype/sales_bom/sales_bom.py
@@ -14,24 +14,9 @@
# 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
-
-# -----------------------------------------------------------------------------------------
-
+from webnotes.utils import flt
+from webnotes.model.utils import getlist
class DocType:
def __init__(self,d,dl):
@@ -40,139 +25,53 @@
def autoname(self):
self.doc.name = self.doc.new_item_code
- # Get Ref Rates
- # --------------
- def get_rates(self):
- for d in getlist(self.doclist, "sales_bom_items"):
- r = sql("select ref_rate from `tabItem Price` where price_list_name=%s and parent=%s and ref_currency = %s", (self.doc.price_list, d.item_code, self.doc.currency))
- d.rate = r and flt(r[0][0]) or 0.00
-
-
- # Get Item Details
- # -----------------
- def get_item_details(self, name):
- det = sql("select description, stock_uom from `tabItem` where name = '%s' " % cstr(name))
- rate = sql("select ref_rate from `tabItem Price` where price_list_name = %s and parent = %s and ref_currency = %s", (self.doc.price_list, name, self.doc.currency))
- return {'description' : det and det[0][0] or '', 'uom': det and det[0][1] or '', 'rate': rate and flt(rate[0][0]) or 0.00}
-
-
- def get_main_item(self):
- is_main_item = []
- for d in getlist(self.doclist,'sales_bom_items'):
- if d.is_main_item == 'Yes':
- is_main_item.append(d.item_code)
- # Check that Sales Bom Item cannot be child of Sales Bom.
- if d.item_code == self.doc.new_item_code:
- msgprint("Sales Bom Item " + d.new_item_code +" cannot be child item.")
- raise Exception
- if len(is_main_item) > 1:
- msgprint('Main item cannot be more than one.')
- raise Exception , " Validation Error."
- if len(is_main_item) == 0:
- msgprint("At least one item should be main item.")
- raise Exception , " Validation Error."
- return is_main_item[0]
-
-
- # Make Item
- # ---------
- def create_new_item(self):
- i = Document("Item")
- i.item_code = self.doc.new_item_code
- i.item_name = self.doc.new_item_name
- i.name = i.item_code
- i.is_sales_item = 'Yes'
- i.is_stock_item = 'No'
- i.save(1)
-
- # Update Rate
- def update_ref_rate(self, i):
- ref_rate = 0
- if self.doc.price_list:
- if not cstr(self.doc.currency):
- msgprint("Please enter Currency.")
- raise Exception
- for d in getlist(self.doclist, "sales_bom_items"):
- item_rate = sql("select ref_rate,ref_currency from `tabItem Price` where price_list_name=%s and parent=%s", (self.doc.price_list, d.item_code))
- ref_rate += flt(d.qty) * (item_rate and flt(item_rate[0][0]) or 0)
-
- if ref_rate:
- # clear old rates
- sql("delete from `tabItem Price` where parent=%s and price_list_name = %s", (i.name, self.doc.price_list))
-
- pld = addchild(i,"ref_rate_details", "Item Price")
- pld.price_list_name = self.doc.price_list
- pld.ref_rate = flt(ref_rate)
- pld.ref_currency = self.doc.currency
- pld.save()
-
- # Update Items
- # ------------
- def update_item(self):
- i = Document("Item", self.doc.new_item_code)
-
- # update fields
- i.brand = self.doc.new_item_brand
- i.stock_uom = self.doc.stock_uom
- i.item_group = self.doc.item_group
-
-
- i.item_name = self.doc.new_item_name
- i.description = self.doc.description
-
- # set default as 'No' or 0
- i.is_sample_item = 'No'
- i.is_asset_item = 'No'
- i.is_purchase_item = 'No'
- i.is_manufactured_item = 'No'
- i.is_sub_contracted_item = 'No'
- i.is_service_item = 'No'
- i.inspection_required = 'No'
- i.has_serial_no = 'No'
- i.lead_time_days = flt(0)
- # update rates
- self.update_ref_rate(i)
- i.save()
- msgprint("Items: %s updated successfully. To update more details open and edit item master" % self.doc.new_item_code)
-
-
def validate(self):
# check for duplicate
self.check_duplicate()
- item_code = self.get_main_item()
- if not self.doc.new_item_code:
- self.doc.new_item_code = make_autoname(item_code +'.###')
+ self.validate_main_item()
-
- def on_update(self):
- # if no item code, create new item code
- if not sql("select name from tabItem where name=%s", self.doc.new_item_code):
- self.create_new_item()
- self.update_item()
+ def validate_main_item(self):
+ """main item must have Is Stock Item as No and Is Sales Item as Yes"""
+ if not webnotes.conn.sql("""select name from tabItem where name=%s and
+ ifnull(is_stock_item,'')='No' and ifnull(is_sales_item,'')='Yes'""", self.doc.new_item_code):
+ webnotes.msgprint("""Parent Item %s is either a Stock Item or a not a Sales Item""",
+ raise_exception=1)
+ def get_item_details(self, name):
+ det = webnotes.conn.sql("""select description, stock_uom from `tabItem`
+ where name = %s""", name)
+ rate = webnotes.conn.sql("""select ref_rate from `tabItem Price`
+ where price_list_name = %s and parent = %s
+ and ref_currency = %s""", (self.doc.price_list, name, self.doc.currency))
+ return {
+ 'description' : det and det[0][0] or '',
+ 'uom': det and det[0][1] or '',
+ 'rate': rate and flt(rate[0][0]) or 0.00
+ }
def check_duplicate(self, finder=0):
il = getlist(self.doclist, "sales_bom_items")
if not il:
- msgprint("Add atleast one item")
+ webnotes.msgprint("Add atleast one item")
return
# get all Sales BOM that have the first item
- sbl = sql("select distinct parent from `tabSales BOM Item` where item_code=%s and parent != %s and docstatus != 2", (il[0].item_code, self.doc.name))
+ sbl = webnotes.conn.sql("""select distinct parent from `tabSales BOM Item` where item_code=%s
+ and parent != %s and docstatus != 2""", (il[0].item_code, self.doc.name))
# check all siblings
sub_items = [[d.item_code, flt(d.qty)] for d in il]
for s in sbl:
- t = sql("select item_code, qty from `tabSales BOM Item` where parent=%s and docstatus != 2", s[0])
+ t = webnotes.conn.sql("""select item_code, qty from `tabSales BOM Item` where parent=%s and
+ docstatus != 2""", s[0])
t = [[d[0], flt(d[1])] for d in t]
if self.has_same_items(sub_items, t):
- msgprint("%s has the same Sales BOM details" % s[0])
+ webnotes.msgprint("%s has the same Sales BOM details" % s[0])
raise Exception
if finder:
- msgprint("There is no Sales BOM present with the following Combination.")
-
+ webnotes.msgprint("There is no Sales BOM present with the following Combination.")
def has_same_items(self, l1, l2):
if len(l1)!=len(l2): return 0
diff --git a/erpnext/stock/doctype/sales_bom/sales_bom.txt b/erpnext/stock/doctype/sales_bom/sales_bom.txt
index 29fcd31..7426821 100644
--- a/erpnext/stock/doctype/sales_bom/sales_bom.txt
+++ b/erpnext/stock/doctype/sales_bom/sales_bom.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-04-30 12:08:49',
+ 'creation': '2012-07-03 13:30:44',
'docstatus': 0,
- 'modified': '2012-05-04 09:53:08',
+ 'modified': '2012-07-12 18:00:16',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -15,10 +15,10 @@
'_last_update': u'1322549701',
'allow_trash': 1,
'colour': u'White:FFF',
- 'description': u'Aggregate item and accessories to form a Sales Item. There is no inventory of the new item but of the sub-components.',
+ 'description': u'Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**. \n\nThe package **Item** will have "Is Stock Item" as "No" and "Is Sales Item" as "Yes".\n\nFor Example: If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Sales BOM Item.\n\nNote: BOM = Bill of Materials',
'doctype': 'DocType',
'document_type': u'Master',
- 'is_submittable': 1,
+ 'is_submittable': 0,
'module': u'Stock',
'name': '__common__',
'section_style': u'Simple',
@@ -33,17 +33,20 @@
'name': '__common__',
'parent': u'Sales BOM',
'parentfield': u'fields',
- 'parenttype': u'DocType'
+ 'parenttype': u'DocType',
+ 'permlevel': 0
},
# These values are common for all DocPerm
{
+ 'amend': 0,
'doctype': u'DocPerm',
'name': '__common__',
'parent': u'Sales BOM',
'parentfield': u'permissions',
'parenttype': u'DocType',
- 'read': 1
+ 'read': 1,
+ 'submit': 0
},
# DocType, Sales BOM
@@ -54,73 +57,61 @@
# DocPerm
{
- 'amend': 0,
'cancel': 0,
- 'create': 0,
+ 'create': 1,
'doctype': u'DocPerm',
'permlevel': 1,
'role': u'Material Manager',
- 'submit': 0,
- 'write': 0
- },
-
- # DocPerm
- {
- 'amend': 1,
- 'cancel': 1,
- 'create': 1,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Material Manager',
- 'submit': 1,
'write': 1
},
# DocPerm
{
- 'amend': 0,
- 'cancel': 0,
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 1,
- 'role': u'Material User',
- 'submit': 0,
- 'write': 0
- },
-
- # DocPerm
- {
- 'amend': 0,
- 'cancel': 0,
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Material User',
- 'submit': 0,
- 'write': 0
- },
-
- # DocPerm
- {
- 'amend': 0,
'cancel': 1,
'create': 1,
'doctype': u'DocPerm',
'permlevel': 0,
- 'role': u'Sales User',
- 'submit': 0,
+ 'role': u'Material Manager',
'write': 1
},
# DocPerm
{
- 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 1,
+ 'role': u'Material User',
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'Material User',
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'cancel': 1,
+ 'create': 1,
+ 'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'Sales User',
+ 'write': 1
+ },
+
+ # DocPerm
+ {
'cancel': 0,
'create': 0,
'doctype': u'DocPerm',
'permlevel': 1,
'role': u'Sales User',
- 'submit': 0,
'write': 0
},
@@ -129,167 +120,32 @@
'doctype': u'DocField',
'fieldname': u'basic_section',
'fieldtype': u'Section Break',
- 'label': u'Basic Section',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'col1',
- 'fieldtype': u'Column Break',
- 'permlevel': 0,
- 'width': u'50%'
+ 'label': u'Sales BOM Item'
},
# DocField
{
'colour': u'White:FFF',
- 'description': u'Item code of the new aggregate item.',
+ 'description': u'The Item that represents the Package. This Item must have "Is Stock Item" as "No" and "Is Sales Item" as "Yes"',
'doctype': u'DocField',
'fieldname': u'new_item_code',
- 'fieldtype': u'Data',
- 'label': u'New Item Code',
+ 'fieldtype': u'Link',
+ 'label': u'Parent Item',
'no_copy': 1,
'oldfieldname': u'new_item_code',
'oldfieldtype': u'Data',
+ 'options': u'Item',
'reqd': 1
},
# DocField
{
'colour': u'White:FFF',
- 'doctype': u'DocField',
- 'fieldname': u'new_item_name',
- 'fieldtype': u'Data',
- 'label': u'New Item Name',
- 'oldfieldname': u'new_item_name',
- 'oldfieldtype': u'Data',
- 'permlevel': 0,
- 'reqd': 1
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'new_item_brand',
- 'fieldtype': u'Data',
- 'label': u'New Item Brand',
- 'oldfieldname': u'new_item_brand',
- 'oldfieldtype': u'Data',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'description',
- 'fieldtype': u'Text',
- 'label': u'New Description',
- 'oldfieldname': u'description',
- 'oldfieldtype': u'Text',
- 'permlevel': 0,
- 'reqd': 1,
- 'width': u'300px'
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'col2',
- 'fieldtype': u'Column Break',
- 'permlevel': 0,
- 'width': u'50%'
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'item_group',
- 'fieldtype': u'Link',
- 'label': u'Item Group',
- 'oldfieldname': u'item_group',
- 'oldfieldtype': u'Link',
- 'options': u'Item Group',
- 'permlevel': 0,
- 'reqd': 1
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'stock_uom',
- 'fieldtype': u'Link',
- 'label': u'Stock UOM',
- 'oldfieldname': u'stock_uom',
- 'oldfieldtype': u'Link',
- 'options': u'UOM',
- 'permlevel': 0,
- 'reqd': 1
- },
-
- # DocField
- {
- 'colour': u'White:FFF',
- 'doctype': u'DocField',
- 'fieldname': u'price_list',
- 'fieldtype': u'Select',
- 'label': u'Price List',
- 'oldfieldname': u'price_list',
- 'oldfieldtype': u'Select',
- 'options': u'link:Price List',
- 'permlevel': 0,
- 'trigger': u'Client'
- },
-
- # DocField
- {
- 'colour': u'White:FFF',
- 'doctype': u'DocField',
- 'fieldname': u'currency',
- 'fieldtype': u'Select',
- 'label': u'Currency',
- 'oldfieldname': u'currency',
- 'oldfieldtype': u'Select',
- 'options': u'link:Currency',
- 'permlevel': 0,
- 'trigger': u'Client'
- },
-
- # 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': 1,
- 'print_hide': 1
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'amended_from',
- 'fieldtype': u'Link',
- 'label': u'Amended From',
- 'no_copy': 1,
- 'options': u'Sales BOM',
- 'permlevel': 1,
- 'print_hide': 1
- },
-
- # DocField
- {
- 'colour': u'White:FFF',
- 'description': u'List items that form a package. One of the items has to be a "main item".',
+ 'description': u'List items that form the package.',
'doctype': u'DocField',
'fieldname': u'item_section',
'fieldtype': u'Section Break',
- 'label': u'Items',
- 'permlevel': 0
+ 'label': u'Package Items'
},
# DocField
@@ -301,30 +157,6 @@
'oldfieldname': u'sales_bom_items',
'oldfieldtype': u'Table',
'options': u'Sales BOM Item',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'colour': u'White:FFF',
- 'description': u'Add a few items and find if there are any Sales BOM created with the same combination to help you identify duplication.',
- 'doctype': u'DocField',
- 'fieldname': u'find_sales_bom',
- 'fieldtype': u'Button',
- 'label': u'Find Sales BOM',
- 'oldfieldtype': u'Button',
- 'permlevel': 0,
- 'trigger': u'Client'
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'trash_reason',
- 'fieldtype': u'Small Text',
- 'label': u'Trash Reason',
- 'oldfieldname': u'trash_reason',
- 'oldfieldtype': u'Small Text',
- 'permlevel': 1
+ 'reqd': 1
}
]
\ No newline at end of file
diff --git a/erpnext/stock/doctype/sales_bom_item/sales_bom_item.txt b/erpnext/stock/doctype/sales_bom_item/sales_bom_item.txt
index 8cf93f5..76e3f26 100644
--- a/erpnext/stock/doctype/sales_bom_item/sales_bom_item.txt
+++ b/erpnext/stock/doctype/sales_bom_item/sales_bom_item.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-03-27 14:36:37',
+ 'creation': '2012-07-03 13:30:46',
'docstatus': 0,
- 'modified': '2012-03-27 14:36:37',
+ 'modified': '2012-07-11 18:56:27',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -20,7 +20,7 @@
'section_style': u'Tray',
'server_code_error': u' ',
'show_in_menu': 0,
- 'version': 3
+ 'version': 1
},
# These values are common for all DocField
@@ -41,18 +41,6 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'is_main_item',
- 'fieldtype': u'Select',
- 'label': u'Is Main Item',
- 'oldfieldname': u'is_main_item',
- 'oldfieldtype': u'Select',
- 'options': u'\nYes\nNo',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
'fieldname': u'item_code',
'fieldtype': u'Link',
'label': u'Item',
@@ -67,6 +55,18 @@
# DocField
{
'doctype': u'DocField',
+ 'fieldname': u'qty',
+ 'fieldtype': u'Currency',
+ 'label': u'Qty',
+ 'oldfieldname': u'qty',
+ 'oldfieldtype': u'Currency',
+ 'permlevel': 0,
+ 'reqd': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
'fieldname': u'description',
'fieldtype': u'Text',
'label': u'Description',
@@ -90,18 +90,6 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'qty',
- 'fieldtype': u'Currency',
- 'label': u'Qty',
- 'oldfieldname': u'qty',
- 'oldfieldtype': u'Currency',
- 'permlevel': 0,
- 'reqd': 1
- },
-
- # DocField
- {
- 'doctype': u'DocField',
'fieldname': u'uom',
'fieldtype': u'Link',
'label': u'UOM',
diff --git a/erpnext/stock/doctype/stock_ledger/stock_ledger.py b/erpnext/stock/doctype/stock_ledger/stock_ledger.py
index 0cb4b96..42ad6f6 100644
--- a/erpnext/stock/doctype/stock_ledger/stock_ledger.py
+++ b/erpnext/stock/doctype/stock_ledger/stock_ledger.py
@@ -51,19 +51,16 @@
self.doclist = doclist
- # -----------------
- # scrub serial nos
- # -----------------
- def scrub_serial_nos(self, obj):
- for d in getlist(obj.doclist, obj.fname):
+ def scrub_serial_nos(self, obj, table_name = ''):
+ if not table_name:
+ table_name = obj.fname
+
+ for d in getlist(obj.doclist, table_name):
if d.serial_no:
d.serial_no = d.serial_no.replace(',', '\n')
d.save()
- # -----------------------------
- # validate serial no warehouse
- # -----------------------------
def validate_serial_no_warehouse(self, obj, fname):
for d in getlist(obj.doclist, fname):
wh = d.warehouse or d.s_warehouse
@@ -80,10 +77,8 @@
msgprint("Serial No : %s for Item : %s doesn't exists in Warehouse : %s" % (s, d.item_code, wh), raise_exception = 1)
- # ------------------------------------
- # check whether serial no is required
- # ------------------------------------
def validate_serial_no(self, obj, fname):
+ """check whether serial no is required"""
for d in getlist(obj.doclist, fname):
is_stock_item = get_value('Item', d.item_code, 'is_stock_item')
ar_required = get_value('Item', d.item_code, 'has_serial_no')
@@ -101,18 +96,10 @@
msgprint("Rejected serial no is mandatory for rejected qty of item: "+ d.item_code, raise_exception = 1)
-
-
-
- # -------------------
- # get serial no list
- # -------------------
def get_sr_no_list(self, sr_nos, qty = 0, item_code = ''):
return get_sr_no_list(sr_nos, qty, item_code)
- # ---------------------
- # set serial no values
- # ---------------------
+
def set_pur_serial_no_values(self, obj, serial_no, d, s, new_rec):
item_details = sql("select item_group, warranty_period from `tabItem` where name = '%s' and \
(ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now()) " %(d.item_code), as_dict=1)
@@ -143,9 +130,6 @@
s.save(new_rec)
- # ----------------------------------
- # update serial no purchase details
- # ----------------------------------
def update_serial_purchase_details(self, obj, d, serial_no, is_submit, purpose = ''):
exists = sql("select name, status, docstatus from `tabSerial No` where name = '%s'" % (serial_no))
if is_submit:
@@ -168,9 +152,6 @@
sql("update `tabSerial No` set docstatus = 2, status = 'Not in Use', purchase_document_type = '', purchase_document_no = '', purchase_date = null, purchase_rate = 0, supplier = null, supplier_name = '', supplier_address = '', warehouse = '' where name = '%s'" % serial_no)
- # -------------------------------
- # check whether serial no exists
- # -------------------------------
def check_serial_no_exists(self, serial_no, item_code):
chk = sql("select name, status, docstatus, item_code from `tabSerial No` where name = %s", (serial_no), as_dict=1)
if not chk:
@@ -182,9 +163,7 @@
elif chk and chk[0]['status'] == 'Delivered':
msgprint("Serial No: %s of Item : %s is already delivered." % (serial_no, item_code), raise_exception = 1)
- # ---------------------
- # set serial no values
- # ---------------------
+
def set_delivery_serial_no_values(self, obj, serial_no):
s = Document('Serial No', serial_no)
s.delivery_document_type = obj.doc.doctype
@@ -203,9 +182,6 @@
s.save()
- # ----------------------------------
- # update serial no delivery details
- # ----------------------------------
def update_serial_delivery_details(self, obj, d, serial_no, is_submit):
if is_submit:
self.check_serial_no_exists(serial_no, d.item_code)
@@ -214,9 +190,6 @@
sql("update `tabSerial No` set docstatus = 0, status = 'In Store', delivery_document_type = '', delivery_document_no = '', delivery_date = null, customer = null, customer_name = '', delivery_address = '', territory = null where name = '%s'" % (serial_no))
- # ---------------------
- # update serial record
- # ---------------------
def update_serial_record(self, obj, fname, is_submit = 1, is_incoming = 0):
import datetime
for d in getlist(obj.doclist, fname):
@@ -235,11 +208,6 @@
self.update_serial_purchase_details(obj, d, a, is_submit)
-
-
- # -------------
- # update stock
- # -------------
def update_stock(self, values, is_amended = 'No'):
for v in values:
sle_id, serial_nos = '', ''
@@ -261,9 +229,6 @@
v["posting_date"], sle_id, v["posting_time"], '', v["is_cancelled"],v["voucher_type"],v["voucher_no"], is_amended)
- # -----------
- # make entry
- # -----------
def make_entry(self, args):
sle = Document(doctype = 'Stock Ledger Entry')
for k in args.keys():
diff --git a/erpnext/stock/doctype/warehouse/warehouse.js b/erpnext/stock/doctype/warehouse/warehouse.js
index b218063..4ad95f4 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.js
+++ b/erpnext/stock/doctype/warehouse/warehouse.js
@@ -14,6 +14,10 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
+cur_frm.cscript.refresh = function(doc) {
+ cur_frm.toggle_fields('warehouse_name', doc.__islocal);
+}
+
cur_frm.cscript.country = function(doc, cdt, cdn) {
var mydoc=doc;
$c('runserverobj', args={'method':'check_state', 'docs':compress_doclist(make_doclist(doc.doctype, doc.name))},
diff --git a/erpnext/stock/doctype/warehouse/warehouse.txt b/erpnext/stock/doctype/warehouse/warehouse.txt
index 16bf59d..844e3f3 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.txt
+++ b/erpnext/stock/doctype/warehouse/warehouse.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-05-15 12:15:13',
+ 'creation': '2012-07-03 13:30:45',
'docstatus': 0,
- 'modified': '2012-05-21 18:02:46',
+ 'modified': '2012-07-11 10:18:07',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -17,6 +17,7 @@
'autoname': u'field:warehouse_name',
'colour': u'White:FFF',
'default_print_format': u'Standard',
+ 'description': u'A logical Warehouse against which stock entries are made.\n\nThere are two main Warehouse Types that are significant in ERPNext.\n\n1. **Stores:** These are where your incoming **Items** are kept before they are consumed or sold. You can have as many \u201cStores\u201d type **Warehouses** as you wish. Stores type warehouses are significant because if you set an Item for automatic re-order, ERPNext will check its quantities in all \u201cStores\u201d type **Warehouses** when deciding whether to re-order or not.\n\n2. **Asset**: **Items** marked as type \u201cFixed Asset\u201d are maintained in Asset Type **Warehouses**. This helps you separate them for the **Items** that are consumed as a part of your regular operations or \u201cCost of Goods Sold\u201d.\n',
'doctype': 'DocType',
'document_type': u'Master',
'module': u'Stock',
@@ -173,17 +174,6 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'trash_reason',
- 'fieldtype': u'Small Text',
- 'label': u'Trash Reason',
- 'oldfieldname': u'trash_reason',
- 'oldfieldtype': u'Small Text',
- 'permlevel': 1
- },
-
- # DocField
- {
- 'doctype': u'DocField',
'fieldname': u'warehouse_detail',
'fieldtype': u'Section Break',
'label': u'Warehouse Detail',
@@ -220,7 +210,6 @@
# DocField
{
'colour': u'White:FFF',
- 'description': u'The valuation of items in this warehouse will be considered for the company that is specified',
'doctype': u'DocField',
'fieldname': u'company',
'fieldtype': u'Link',
@@ -235,6 +224,17 @@
# DocField
{
+ 'colour': u'White:FFF',
+ 'description': u'For Reference Only.',
+ 'doctype': u'DocField',
+ 'fieldname': u'warehouse_contact_info',
+ 'fieldtype': u'Section Break',
+ 'label': u'Warehouse Contact Info',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
'doctype': u'DocField',
'fieldname': u'email_id',
'fieldtype': u'Data',
@@ -249,24 +249,6 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'auto_indent_mail',
- 'fieldtype': u'Select',
- 'hidden': 1,
- 'label': u'Send Reorder Alert Mail ',
- 'no_copy': 1,
- 'oldfieldname': u'auto_indent_mail',
- 'oldfieldtype': u'Select',
- 'options': u'No\nYes',
- 'permlevel': 0,
- 'print_hide': 1,
- 'report_hide': 1,
- 'reqd': 0,
- 'trigger': u'Client'
- },
-
- # DocField
- {
- 'doctype': u'DocField',
'fieldname': u'phone_no',
'fieldtype': u'Data',
'label': u'Phone No',
@@ -357,6 +339,8 @@
# DocField
{
+ 'colour': u'White:FFF',
+ 'description': u'For Admin use only. Please report errors to support@erpnext.com',
'doctype': u'DocField',
'fieldname': u'repost_stock',
'fieldtype': u'Section Break',
diff --git a/erpnext/stock/page/stock_home/stock_home.html b/erpnext/stock/page/stock_home/stock_home.html
index ef941ab..0939a77 100644
--- a/erpnext/stock/page/stock_home/stock_home.html
+++ b/erpnext/stock/page/stock_home/stock_home.html
@@ -51,8 +51,13 @@
</div>
<div class="section-item">
<a class="section-link"
+ title = "Multiple prices lists for items"
+ href="#!List/Price List">Price List</a>
+ </div>
+ <div class="section-item">
+ <a class="section-link"
title = "Readings of incoming quality inspections"
- href="#!List/Quality Inspection">Incoming Inspection</a>
+ href="#!List/Quality Inspection">Quality Inspection</a>
</div>
<div class="section-item">
<a class="section-link"
diff --git a/erpnext/utilities/page/todo/todo.css b/erpnext/utilities/page/todo/todo.css
index 7c7dcaf..9fe5955 100644
--- a/erpnext/utilities/page/todo/todo.css
+++ b/erpnext/utilities/page/todo/todo.css
@@ -49,7 +49,7 @@
padding-right: 15px;
}
-.layout-main {
+.todo-layout {
background-color: #FFFDC9;
min-height: 300px;
}
\ No newline at end of file
diff --git a/erpnext/utilities/page/todo/todo.html b/erpnext/utilities/page/todo/todo.html
index 88dcbf3..37b07a8 100644
--- a/erpnext/utilities/page/todo/todo.html
+++ b/erpnext/utilities/page/todo/todo.html
@@ -1,6 +1,6 @@
<div class="layout-wrapper layout-wrapper-background">
<div class="appframe-area"></div>
- <div class="layout-main">
+ <div class="layout-main todo-layout">
<div>
<div id="todo-list">
<h4>My List</h4><br>
diff --git a/public/css/all-app.css b/public/css/all-app.css
index 84ac275..9c5ae1c 100644
--- a/public/css/all-app.css
+++ b/public/css/all-app.css
@@ -2059,7 +2059,7 @@
div.comment { color: #444; }
.small {
- font-size: 11px;
+ font-size: 12px;
}
.help {
@@ -2244,11 +2244,27 @@
position: fixed;
bottom: 5px;
left: 5px;
- height: 40px;
- width: 40px;
+ height: 30px;
+ width: 30px;
background: url('../images/erpnext-fade.png') no-repeat top left;
}
+.markdown p {
+ font-size: 13px;
+}
+
+.markdown h1 {
+ margin-bottom: 9px;
+}
+
+.markdown h2 {
+ margin-bottom: 7px;
+}
+
+.markdown h3, .markdown h4 {
+ margin-bottom: 5px;
+}
+
/*
* lib/css/legacy/messages.css
*/
@@ -2259,6 +2275,14 @@
div.fetching { color: #888; text-align:right; }
+.msgprint {
+ min-height: 60px;
+ max-height: 500px;
+ padding: 9px;
+ color: #333;
+ overflow: auto;
+}
+
div.notice {
postion: absolute;
background-color: #000;
@@ -2284,24 +2308,17 @@
}
.help_box, .help-box {
- background-color:#FFC;
- font-size: 13px;
- color: #864;
- padding: 7px;
+ background-color: #ffe;
+ padding: 9px 9px 9px 9px;
+ border: 1px dashed #fc7;
margin: 11px 0px;
- border: 1px solid #EEB;
}
-.help_box_big {
- background-color:#FFC;
- color: #864;
- padding: 7px;
- margin: 7px 0px;
- border: 1px solid #EEB;
- text-align: center;
- font-size: 14px;
+.help-box, .help-box p, .help-box h1, .help-box h2, .help-box h3, .help-box h4 {
+ color: #643;
}
+
/*
* lib/css/legacy/forms.css
*/
@@ -2314,6 +2331,16 @@
border-bottom: 1px solid #eee;
}
+.appframe-titlebar .label {
+ vertical-align: middle;
+ margin-right: 7px;
+}
+
+div.form-intro-area {
+ padding: 9px 9px 0px 9px;
+ margin: 0px 0px 15px 0px;
+}
+
div.form-section-head {
margin: 11px -15px 3px -15px;
border-top: 1px solid #ccc;
@@ -2323,7 +2350,7 @@
div.form-layout-row:first-child .form-section-head {
border-top: 0px solid #ccc !important;
margin-top: 0px;
- padding-top: 15px;
+ padding-top: 0px;
}
div.form-section-head h3 {
@@ -2350,18 +2377,6 @@
border-top: 1px dashed #888;
}
-div.grid_tbarlinks {
- border-bottom: 0px;
- background-color: #CCC;
- padding: 4px 4px 2px 4px;
- width: 190px;
- float: right;
-
- -moz-border-radius-topleft: 5px; -moz-border-radius-topright: 5px;
- -webkit-border-top-left-radius: 5px; -webkit-border-top-right-radius: 5px;
-}
-
-
div.dialog_frm {
position: relative;
margin: 10px;
@@ -2492,6 +2507,10 @@
.input_area input, select, textarea {
font-size: 14px;
padding: 2px;
+
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
}
.input_area input {
@@ -2509,9 +2528,16 @@
width: 80%;
padding: 2px 0px;
font-size: 12px;
+ background-color: #eee;
+ padding: 2px;
+ border: 1px solid #ddd;
+
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
}
.disp_area_no_val {
- height: 14px;
+ min-height: 14px;
}
.no_img {
@@ -2536,48 +2562,38 @@
* lib/css/legacy/grid.css
*/
-
-/* Grid */
-
-
-/* --- Simple --- */
-.grid_wrapper_simple {
- width: 100%;
- margin-bottom: 8px;
- border: 1px solid #AA9;
-}
-
-.grid_head_wrapper_simple {
- padding: 0px;
- border-bottom: 2px solid #AAA;
-}
-
-.grid_head_wrapper_simple td {
- border-right: 1px solid #AA9;
-}
-
-.grid_head_wrapper_simple td div {
- padding: 2px;
-}
-
-.grid_tab_wrapper_simple {
-}
-
-.grid_cell_simple {
- padding: 2px;
- background-color: #fff;
- border-right: 1px solid #AA9;
-}
-
-
-/* --- Normal --- */
.grid_wrapper {
position: relative;
overflow: auto;
border: 1px solid #AAA;
width: 100%;
margin-bottom: 8px;
- background-color: #fff;
+ background-color: #f8f8f8;
+}
+
+div.grid_tbarlinks {
+ border-bottom: 0px;
+ padding: 4px 4px 2px 4px;
+ width: 190px;
+ float: right;
+ margin-right: 12px;
+
+ -webkit-border-top-left-radius: 5px;
+ -webkit-border-top-right-radius: 5px;
+ -moz-border-radius-topleft: 5px;
+ -moz-border-radius-topright: 5px;
+ border-top-left-radius: 5px;
+ border-top-right-radius: 5px;
+
+ background: #dddddd; /* Old browsers */
+ background: -moz-linear-gradient(top, #dddddd 0%, #bbbbbb 100%); /* FF3.6+ */
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#dddddd), color-stop(100%,#bbbbbb)); /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, #dddddd 0%,#bbbbbb 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #dddddd 0%,#bbbbbb 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #dddddd 0%,#bbbbbb 100%); /* IE10+ */
+ background: linear-gradient(to bottom, #dddddd 0%,#bbbbbb 100%); /* W3C */
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#dddddd', endColorstr='#bbbbbb',GradientType=0 ); /* IE6-9 */
+
}
.grid_tab_wrapper {
@@ -2608,11 +2624,19 @@
}
.grid_head_table td {
- background-color: #EEE;
border-right: 1px solid #AAA;
border-bottom: 1px solid #AAA;
height: 40px;
padding: 0px;
+
+ background: #eeeeee; /* Old browsers */
+ background: -moz-linear-gradient(top, #eeeeee 0%, #cccccc 100%); /* FF3.6+ */
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#eeeeee), color-stop(100%,#cccccc)); /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, #eeeeee 0%,#cccccc 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #eeeeee 0%,#cccccc 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #eeeeee 0%,#cccccc 100%); /* IE10+ */
+ background: linear-gradient(to bottom, #eeeeee 0%,#cccccc 100%); /* W3C */
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#cccccc',GradientType=0 ); /* IE6-9 */
}
.grid_head_table td div {
@@ -3214,6 +3238,8 @@
height: 18px;
border: 1px solid #aaa;
border-radius: 9px;
+ -webkit-border-radius: 9px;
+ -moz-border-radius: 9px;
overflow: hidden;
}
@@ -3222,6 +3248,10 @@
left: 0px;
height: 100%;
z-index: 0;
+ /* So that this div is also curved like the enclosing one */
+ border-radius: 9px;
+ -webkit-border-radius: 9px;
+ -moz-border-radius: 9px;
background: #e0ff84; /* Old browsers */
background: -moz-linear-gradient(top, #e0ff84 0%, #a4e567 100%); /* FF3.6+ */
@@ -3237,12 +3267,8 @@
* lib/css/ui/views.css
*/
-.breadcrumbs {
- color: #000000;
-}
-
-.breadcrumbs a {
- color: #000000;
+.breadcrumb-area, .breadcrumb-area span {
+ vertical-align: middle;
}
div.appframe-titlebar {
@@ -3260,6 +3286,14 @@
border-radius: 5px 5px 0px 0px;
-webkit-border-radius: 5px 5px 0px 0px;
-moz-border-radius: 5px 5px 0px 0px;
+
+ text-shadow: 0px 1px 1px #fff;
+ color: #555;
+}
+
+span.appframe-title {
+ font-size: 160%;
+ font-weight: bold;
}
div.appframe-toolbar {
@@ -3269,6 +3303,8 @@
border-bottom: 1px solid #ccc;
}
+
+
/*
* lib/css/ui/fonts.css
*/
diff --git a/public/css/all-web.css b/public/css/all-web.css
index ec2fbcd..322cb25 100644
--- a/public/css/all-web.css
+++ b/public/css/all-web.css
@@ -1920,7 +1920,7 @@
div.comment { color: #444; }
.small {
- font-size: 11px;
+ font-size: 12px;
}
.help {
@@ -2105,11 +2105,27 @@
position: fixed;
bottom: 5px;
left: 5px;
- height: 40px;
- width: 40px;
+ height: 30px;
+ width: 30px;
background: url('../images/erpnext-fade.png') no-repeat top left;
}
+.markdown p {
+ font-size: 13px;
+}
+
+.markdown h1 {
+ margin-bottom: 9px;
+}
+
+.markdown h2 {
+ margin-bottom: 7px;
+}
+
+.markdown h3, .markdown h4 {
+ margin-bottom: 5px;
+}
+
/*
* lib/css/legacy/messages.css
*/
@@ -2120,6 +2136,14 @@
div.fetching { color: #888; text-align:right; }
+.msgprint {
+ min-height: 60px;
+ max-height: 500px;
+ padding: 9px;
+ color: #333;
+ overflow: auto;
+}
+
div.notice {
postion: absolute;
background-color: #000;
@@ -2145,24 +2169,17 @@
}
.help_box, .help-box {
- background-color:#FFC;
- font-size: 13px;
- color: #864;
- padding: 7px;
+ background-color: #ffe;
+ padding: 9px 9px 9px 9px;
+ border: 1px dashed #fc7;
margin: 11px 0px;
- border: 1px solid #EEB;
}
-.help_box_big {
- background-color:#FFC;
- color: #864;
- padding: 7px;
- margin: 7px 0px;
- border: 1px solid #EEB;
- text-align: center;
- font-size: 14px;
+.help-box, .help-box p, .help-box h1, .help-box h2, .help-box h3, .help-box h4 {
+ color: #643;
}
+
/*
* lib/css/legacy/dialog.css
*/
@@ -2470,6 +2487,8 @@
height: 18px;
border: 1px solid #aaa;
border-radius: 9px;
+ -webkit-border-radius: 9px;
+ -moz-border-radius: 9px;
overflow: hidden;
}
@@ -2478,6 +2497,10 @@
left: 0px;
height: 100%;
z-index: 0;
+ /* So that this div is also curved like the enclosing one */
+ border-radius: 9px;
+ -webkit-border-radius: 9px;
+ -moz-border-radius: 9px;
background: #e0ff84; /* Old browsers */
background: -moz-linear-gradient(top, #e0ff84 0%, #a4e567 100%); /* FF3.6+ */
@@ -2493,12 +2516,8 @@
* lib/css/ui/views.css
*/
-.breadcrumbs {
- color: #000000;
-}
-
-.breadcrumbs a {
- color: #000000;
+.breadcrumb-area, .breadcrumb-area span {
+ vertical-align: middle;
}
div.appframe-titlebar {
@@ -2516,6 +2535,14 @@
border-radius: 5px 5px 0px 0px;
-webkit-border-radius: 5px 5px 0px 0px;
-moz-border-radius: 5px 5px 0px 0px;
+
+ text-shadow: 0px 1px 1px #fff;
+ color: #555;
+}
+
+span.appframe-title {
+ font-size: 160%;
+ font-weight: bold;
}
div.appframe-toolbar {
@@ -2525,6 +2552,8 @@
border-bottom: 1px solid #ccc;
}
+
+
/*
* erpnext/startup/startup.css
*/
diff --git a/public/css/fields.css b/public/css/fields.css
index 3f8aaf3..61892ee 100644
--- a/public/css/fields.css
+++ b/public/css/fields.css
@@ -28,6 +28,10 @@
.input_area input, select, textarea {
font-size: 14px;
padding: 2px;
+
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
}
.input_area input {
@@ -45,9 +49,16 @@
width: 80%;
padding: 2px 0px;
font-size: 12px;
+ background-color: #eee;
+ padding: 2px;
+ border: 1px solid #ddd;
+
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
}
.disp_area_no_val {
- height: 14px;
+ min-height: 14px;
}
.no_img {
diff --git a/public/js/all-app.js b/public/js/all-app.js
index a9d1967..a86eba9 100644
--- a/public/js/all-app.js
+++ b/public/js/all-app.js
@@ -202,7 +202,7 @@
* lib/js/wn/misc/tools.js
*/
wn.markdown=function(txt){if(!wn.md2html){wn.require('js/lib/showdown.js');wn.md2html=new Showdown.converter();}
-return wn.md2html.makeHtml(txt);}
+return'<div class="markdown">'+wn.md2html.makeHtml(txt)+'</div>';}
/*
* lib/js/wn/misc/user.js
*/
@@ -249,7 +249,7 @@
* lib/js/wn/router.js
*/
wn.re_route={}
-wn.route=function(){if(wn.re_route[window.location.hash]){window.location.hash=wn.re_route[window.location.hash];}
+wn.route=function(){if(wn.re_route[window.location.hash]){var re_route_val=wn.get_route_str(wn.re_route[window.location.hash]);var cur_route_val=wn.get_route_str(wn._cur_route);if(decodeURIComponent(re_route_val)===decodeURIComponent(cur_route_val)){window.history.back();return;}else{window.location.hash=wn.re_route[window.location.hash];}}
wn._cur_route=window.location.hash;route=wn.get_route();switch(route[0]){case"List":wn.views.doclistview.show(route[1]);break;case"Form":if(route.length>3){route[2]=route.splice(2).join('/');}
wn.views.formview.show(route[1],route[2]);break;case"Report":wn.views.reportview.show(route[1],route[2]);break;case"Report2":wn.views.reportview2.show();break;default:wn.views.pageview.show(route[0]);}}
wn.get_route=function(route){return $.map(wn.get_route_str(route).split('/'),function(r){return decodeURIComponent(r);});}
@@ -349,7 +349,8 @@
if(df.fieldtype=='Check'){df.fieldtype='Select';df.options='No\nYes';}else if(['Text','Text Editor','Code','Link'].indexOf(df.fieldtype)!=-1){df.fieldtype='Data';}},set_default_condition:function(df,fieldtype){if(!fieldtype){if(df.fieldtype=='Data'){this.$w.find('.condition').val('like');}else{this.$w.find('.condition').val('=');}}},get_value:function(){var me=this;var val=me.field.get_value();var cond=me.$w.find('.condition').val();if(me.field.df.original_type=='Check'){val=(val=='Yes'?1:0);}
if(cond=='like'){val=val+'%';}
return[me.fieldselect.$select.find('option:selected').attr('table'),me.field.df.fieldname,me.$w.find('.condition').val(),cstr(val)];}});wn.ui.FieldSelect=Class.extend({init:function(parent,doctype,filter_fields,with_blank){this.doctype=doctype;this.fields_by_name={};this.with_blank=with_blank;this.$select=$('<select>').appendTo(parent);if(filter_fields){for(var i in filter_fields)
-this.add_field_option(this.filter_fields[i])}else{this.build_options();}},build_options:function(){var me=this;me.table_fields=[];var std_filters=[{fieldname:'name',fieldtype:'Data',label:'ID',parent:me.doctype},{fieldname:'modified',fieldtype:'Date',label:'Last Modified',parent:me.doctype},{fieldname:'owner',fieldtype:'Data',label:'Created By',parent:me.doctype},{fieldname:'creation',fieldtype:'Date',label:'Created On',parent:me.doctype},{fieldname:'_user_tags',fieldtype:'Data',label:'Tags',parent:me.doctype}];if(this.with_blank){this.$select.append($('<option>',{value:''}).text(''));}
+this.add_field_option(this.filter_fields[i])}else{this.build_options();}},build_options:function(){var me=this;me.table_fields=[];var std_filters=[{fieldname:'name',fieldtype:'Data',label:'ID',parent:me.doctype},{fieldname:'modified',fieldtype:'Date',label:'Last Modified',parent:me.doctype},{fieldname:'owner',fieldtype:'Data',label:'Created By',parent:me.doctype},{fieldname:'creation',fieldtype:'Date',label:'Created On',parent:me.doctype},{fieldname:'_user_tags',fieldtype:'Data',label:'Tags',parent:me.doctype},{fieldname:'docstatus',fieldtype:'Int',label:'Doc Status',parent:me.doctype},];var doctype_obj=locals['DocType'][me.doctype];if(doctype_obj&&cint(doctype_obj.istable)){std_filters=std_filters.concat([{fieldname:'parent',fieldtype:'Data',label:'Parent',parent:me.doctype}]);}
+if(this.with_blank){this.$select.append($('<option>',{value:''}).text(''));}
$.each(std_filters.concat(wn.meta.docfield_list[me.doctype]),function(i,df){me.add_field_option(df);});$.each(me.table_fields,function(i,table_df){if(table_df.options){$.each(wn.meta.docfield_list[table_df.options],function(i,df){me.add_field_option(df);});}});},add_field_option:function(df){var me=this;if(me.doctype&&df.parent==me.doctype){var label=df.label;var table=me.doctype;if(df.fieldtype=='Table')me.table_fields.push(df);}else{var label=df.label+' ('+df.parent+')';var table=df.parent;}
if(wn.model.no_value_type.indexOf(df.fieldtype)==-1&&!me.fields_by_name[df.fieldname]){this.$select.append($('<option>',{value:df.fieldname,table:table}).text(label));me.fields_by_name[df.fieldname]=df;}}})
/*
@@ -361,7 +362,7 @@
var me=this;if(label.tagName){var page=label;}else{var page=wn.pages[label];}
if(!page){console.log('Page not found '+label);return;}
if(this.page){$(this.page).toggle(false);$(this.page).trigger('hide');}
-this.page=page;$(this.page).fadeIn();$(this.page).trigger('show');this.page._route=window.location.hash;document.title=this.page.label;scroll(0,0);return this.page;}});wn.views.add_module_btn=function(parent,module){$(parent).append(repl('<span class="label" style="margin-right: 8px; cursor: pointer;"\
+this.page=page;$(this.page).fadeIn();this.page._route=window.location.hash;document.title=this.page.label;$(this.page).trigger('show');scroll(0,0);return this.page;}});wn.views.add_module_btn=function(parent,module){$(parent).append(repl('<span class="label" style="margin-right: 8px; cursor: pointer;"\
onclick="wn.set_route(\'%(module_small)s-home\')">\
<i class="icon-home icon-white"></i> %(module)s Home\
</span>',{module:module,module_small:module.toLowerCase()}));}
@@ -394,9 +395,9 @@
return;}
if(r.server_messages)msgprint(r.server_messages)
if(r.exc){console.log(r.exc);};if(r['403']){wn.container.change_to('403');}
-if(r.docs)LocalDB.sync(r.docs);}
-wn.request.call=function(opts){wn.request.prepare(opts);$.ajax({url:opts.url||wn.request.url,data:opts.args,type:opts.type||'POST',dataType:opts.dataType||'json',success:function(r,xhr){wn.request.cleanup(opts,r);opts.success(r,xhr.responseText);},error:function(xhr,textStatus){wn.request.cleanup(opts,{});show_alert('Unable to complete request: '+textStatus)
-if(opts.error)opts.error(xhr)}})}
+if(r.docs){LocalDB.sync(r.docs);}}
+wn.request.call=function(opts){wn.request.prepare(opts);$.ajax({url:opts.url||wn.request.url,data:opts.args,type:opts.type||'POST',dataType:opts.dataType||'json',success:function(r,xhr){wn.request.cleanup(opts,r);opts.success&&opts.success(r,xhr.responseText);},error:function(xhr,textStatus){wn.request.cleanup(opts,{});show_alert('Unable to complete request: '+textStatus)
+opts.error&&opts.error(xhr)}})}
wn.call=function(opts){var args=$.extend({},opts.args)
if(opts.module&&opts.page){args.cmd=opts.module+'.page.'+opts.page+'.'+opts.page+'.'+opts.method}else if(opts.method){args.cmd=opts.method;}
for(key in args){if(args[key]&&typeof args[key]!='string'){args[key]=JSON.stringify(args[key]);}}
@@ -603,16 +604,12 @@
/*
* lib/js/legacy/utils/msgprint.js
*/
-var msg_dialog;function msgprint(msg,issmall,callback){if(!msg)return;if(typeof(msg)!='string')
-msg=JSON.stringify(msg);if(issmall){show_alert(msg);return;}
-if(msg.substr(0,8)=='__small:'){show_alert(msg.substr(8));return;}
-if(!msg_dialog){msg_dialog=new Dialog(500,200,"Message");msg_dialog.make_body([['HTML','Msg']])
-msg_dialog.onhide=function(){msg_dialog.msg_area.innerHTML='';$dh(msg_dialog.msg_icon);if(msg_dialog.custom_onhide)msg_dialog.custom_onhide();}
-$y(msg_dialog.rows['Msg'],{fontSize:'14px',lineHeight:'1.5em',padding:'16px'})
-var t=make_table(msg_dialog.rows['Msg'],1,2,'100%',['20px','250px'],{padding:'2px',verticalAlign:'Top'});msg_dialog.msg_area=$td(t,0,1);msg_dialog.msg_icon=$a($td(t,0,0),'img');}
-if(!msg_dialog.display)msg_dialog.show();var has_msg=msg_dialog.msg_area.innerHTML?1:0;var m=$a(msg_dialog.msg_area,'div','');if(has_msg)$y(m,{marginTop:'4px'});$dh(msg_dialog.msg_icon);if(msg.substr(0,6).toLowerCase()=='error:'){msg_dialog.msg_icon.src='images/lib/icons/error.gif';$di(msg_dialog.msg_icon);msg=msg.substr(6);}else if(msg.substr(0,8).toLowerCase()=='message:'){msg_dialog.msg_icon.src='images/lib/icons/application.gif';$di(msg_dialog.msg_icon);msg=msg.substr(8);}else if(msg.substr(0,3).toLowerCase()=='ok:'){msg_dialog.msg_icon.src='images/lib/icons/accept.gif';$di(msg_dialog.msg_icon);msg=msg.substr(3);}
-m.innerHTML=replace_newlines(msg);if(m.offsetHeight>200){$y(m,{height:'200px',width:'400px',overflow:'auto'})}
-msg_dialog.custom_onhide=callback;}
+var msg_dialog;function msgprint(msg,title){if(!msg)return;if(typeof(msg)!='string')
+msg=JSON.stringify(msg);if(msg.substr(0,8)=='__small:'){show_alert(msg.substr(8));return;}
+if(!msg_dialog){msg_dialog=new wn.ui.Dialog({title:"Message",onhide:function(){msg_dialog.msg_area.empty();}});msg_dialog.msg_area=$('<div class="msgprint">').appendTo(msg_dialog.body);}
+if(msg.search(/<br>|<p>|<li>/)==-1)
+msg=replace_newlines(msg);msg_dialog.set_title(title||'Message')
+msg_dialog.msg_area.append(msg);msg_dialog.show();}
var growl_area;function show_alert(txt,id){if(!growl_area){if(!$('#dialog-container').length){$('<div id="dialog-container">').appendTo('body');}
growl_area=$a($i('dialog-container'),'div','',{position:'fixed',bottom:'8px',right:'8px',width:'320px',zIndex:10});}
var wrapper=$a(growl_area,'div','',{position:'relative'});var body=$a(wrapper,'div','notice');var c=$a(body,'i','icon-remove-sign',{cssFloat:'right',cursor:'pointer'});$(c).click(function(){$dh(this.wrapper)});c.wrapper=wrapper;var t=$a(body,'div','',{color:'#FFF'});$(t).html(txt);if(id){$(t).attr('id',id);}
@@ -653,8 +650,9 @@
Field.prototype.set_description=function(){if(this.df.description){var p=in_list(['Text Editor','Code','Check'],this.df.fieldtype)?this.label_area:this.wrapper;this.desc_area=$a(p,'div','help small','',this.df.description)
if(in_list(['Text Editor','Code'],this.df.fieldtype))
$(this.desc_area).addClass('help small');}}
-Field.prototype.get_status=function(){if(this.in_filter)this.not_in_form=this.in_filter;if(this.not_in_form){return'Write';}
-if(!this.df.permlevel)this.df.permlevel=0;var p=this.perm[this.df.permlevel];var ret;if(cur_frm.editable&&p&&p[WRITE])ret='Write';else if(p&&p[READ])ret='Read';else ret='None';if(this.df.fieldtype=='Binary')
+Field.prototype.get_status=function(){if(this.in_filter)
+this.not_in_form=this.in_filter;if(this.not_in_form){return'Write';}
+if(!this.df.permlevel)this.df.permlevel=0;var p=this.perm[this.df.permlevel];var ret;if(cur_frm.editable&&p&&p[WRITE]&&!this.disabled)ret='Write';else if(p&&p[READ])ret='Read';else ret='None';if(this.df.fieldtype=='Binary')
ret='None';if(cint(this.df.hidden))
ret='None';if(ret=='Write'&&cint(cur_frm.doc.docstatus)>0)ret='Read';var a_o_s=cint(this.df.allow_on_submit);if(a_o_s&&(this.in_grid||(this.frm&&this.frm.not_in_container))){a_o_s=null;if(this.in_grid)a_o_s=this.grid.field.df.allow_on_submit;if(this.frm&&this.frm.not_in_container){a_o_s=cur_grid.field.df.allow_on_submit;}}
if(cur_frm.editable&&a_o_s&&cint(cur_frm.doc.docstatus)>0&&!this.df.hidden){tmp_perm=get_perm(cur_frm.doctype,cur_frm.docname,1);if(tmp_perm[this.df.permlevel]&&tmp_perm[this.df.permlevel][WRITE])ret='Write';}
@@ -733,19 +731,20 @@
$(me.btn2).css('display','inline-block');else $dh(me.btn2);}}
me.txt.field_object=this;me.input.set_input=function(val){if(val==undefined)val='';me.txt.value=val;}
me.get_value=function(){return me.txt.value;}
-$(me.txt).autocomplete({source:function(request,response){wn.call({method:'webnotes.widgets.search.search_link',args:{'txt':request.term,'dt':me.df.options,'query':me.get_custom_query()},callback:function(r){response(r.results);},});},select:function(event,ui){me.set_input_value(ui.item.value);}}).data('autocomplete')._renderItem=function(ul,item){return $('<li></li>').data('item.autocomplete',item).append(repl('<a>%(label)s<br><span style="font-size:10px">%(info)s</span></a>',item)).appendTo(ul);};$(this.txt).change(function(){if(!$(this).val()){if(selector&&selector.display)
-return;me.set_input_value('');}})}
+$(me.txt).autocomplete({source:function(request,response){wn.call({method:'webnotes.widgets.search.search_link',args:{'txt':request.term,'dt':me.df.options,'query':me.get_custom_query()},callback:function(r){response(r.results);},});},select:function(event,ui){me.set_input_value(ui.item.value);}}).data('autocomplete')._renderItem=function(ul,item){return $('<li></li>').data('item.autocomplete',item).append(repl('<a>%(label)s<br><span style="font-size:10px">%(info)s</span></a>',item)).appendTo(ul);};$(this.txt).change(function(){var val=$(this).val();me.set_input_value_executed=false;if(!val){if(selector&&selector.display)
+return;me.set_input_value('');}else{setTimeout(function(){if(!me.set_input_value_executed){me.set_input_value(val);}},1000);}})}
LinkField.prototype.get_custom_query=function(){this.set_get_query();if(this.get_query){if(cur_frm)
var doc=locals[cur_frm.doctype][cur_frm.docname];return this.get_query(doc,this.doctype,this.docname);}}
LinkField.prototype.setup_buttons=function(){var me=this;me.btn.onclick=function(){selector.set(me,me.df.options,me.df.label);selector.show(me.txt);}
if(me.btn1)me.btn1.onclick=function(){if(me.txt.value&&me.df.options){loaddoc(me.df.options,me.txt.value);}}
me.can_create=0;if((!me.not_in_form)&&in_list(profile.can_create,me.df.options)){me.can_create=1;me.btn2.onclick=function(){var on_save_callback=function(new_rec){if(new_rec){var d=_f.calling_doc_stack.pop();locals[d[0]][d[1]][me.df.fieldname]=new_rec;me.refresh();if(me.grid)me.grid.refresh();me.run_trigger();}}
_f.calling_doc_stack.push([me.doctype,me.docname]);new_doc(me.df.options,me.on_new,1,on_save_callback,me.doctype,me.docname,me.frm.not_in_container);}}else{$dh(me.btn2);$y($td(me.tab,0,2),{width:'0px'});}}
-LinkField.prototype.set_input_value=function(val){var me=this;var from_selector=false;if(selector&&selector.display)from_selector=true;me.refresh_label_icon();if(me.not_in_form){$(this.txt).val(val);return;}
+LinkField.prototype.set_input_value=function(val){var me=this;me.set_input_value_executed=true;var from_selector=false;if(selector&&selector.display)from_selector=true;me.refresh_label_icon();if(me.not_in_form){$(this.txt).val(val);return;}
if(cur_frm){if(val==locals[me.doctype][me.docname][me.df.fieldname]){me.run_trigger();return;}}
me.set(val);if(_f.cur_grid_cell)
_f.cur_grid_cell.grid.cell_deselect();if(locals[me.doctype][me.docname][me.df.fieldname]&&!val){me.run_trigger();return;}
-var fetch='';if(cur_frm.fetch_dict[me.df.fieldname])
+me.validate_link(val,from_selector);}
+LinkField.prototype.validate_link=function(val,from_selector){var me=this;var fetch='';if(cur_frm.fetch_dict[me.df.fieldname])
fetch=cur_frm.fetch_dict[me.df.fieldname].columns.join(', ');$c('webnotes.widgets.form.utils.validate_link',{'value':val,'options':me.df.options,'fetch':fetch},function(r,rt){if(r.message=='Ok'){if($(me.txt).val()!=val){if((me.grid&&!from_selector)||(!me.grid)){$(me.txt).val(val);}}
if(r.fetch_values)
me.set_fetch_values(r.fetch_values);me.run_trigger();}else{var astr='';if(in_list(profile.can_create,me.df.options))astr=repl('<br><br><span class="link_type" onclick="newdoc(\'%(dt)s\')">Click here</span> to create a new %(dtl)s',{dt:me.df.options,dtl:get_doctype_label(me.df.options)})
@@ -851,10 +850,14 @@
<span class="appframe-title"></span>\
<span class="close">×</span>\
</div>').appendTo(this.$w);this.$w.find('.close').click(function(){window.history.back();})
-if(title)this.title(title);},title:function(txt){this.$titlebar.find('.appframe-title').html(txt);},add_button:function(label,click,icon){if(!this.$w.find('.appframe-toolbar').length)
-this.$w.append('<div class="appframe-toolbar"></div>');args={label:label,icon:''};if(icon){args.icon='<i class="'+icon+'"></i>';}
+if(title)this.title(title);},title:function(txt){this.$titlebar.find('.appframe-title').html(txt);},make_toolbar:function(){if(!this.$w.find('.appframe-toolbar').length)
+this.$w.append('<div class="appframe-toolbar"></div>');},add_button:function(label,click,icon){this.make_toolbar();args={label:label,icon:''};if(icon){args.icon='<i class="icon '+icon+'"></i>';}
this.buttons[label]=$(repl('<button class="btn btn-small">\
- %(icon)s %(label)s</button>',args)).click(click).appendTo(this.$w.find('.appframe-toolbar'));return this.buttons[label];},clear_buttons:function(){this.$w.find('.appframe-toolbar').empty();}});wn.ui.make_app_page=function(opts){if(opts.single_column){$(opts.parent).html('<div class="layout-wrapper layout-wrapper-appframe">\
+ %(icon)s %(label)s</button>',args)).click(click).appendTo(this.$w.find('.appframe-toolbar'));return this.buttons[label];},add_help_button:function(txt){this.make_toolbar();$('<button class="btn btn-small" style="float:right;" button-type="help">\
+ <b>?</b></button>').data('help-text',txt).click(function(){msgprint($(this).data('help-text'),'Help');}).appendTo(this.$w.find('.appframe-toolbar'));},clear_buttons:function(){this.$w.find('.appframe-toolbar').empty();},add_breadcrumb:function(html){if(!this.$breadcrumbs)
+this.$breadcrumbs=$('</span>\
+ <span class="breadcrumb-area"></span>').appendTo(this.$titlebar);var crumb=$('<span>').html(html);if(!this.$breadcrumbs.find('span').length){crumb.addClass('appframe-title');}
+crumb.appendTo(this.$breadcrumbs);},clear_breadcrumbs:function(){this.$breadcrumbs&&this.$breadcrumbs.empty();}});wn.ui.make_app_page=function(opts){if(opts.single_column){$(opts.parent).html('<div class="layout-wrapper layout-wrapper-appframe">\
<div class="layout-appframe"></div>\
<div class="layout-main"></div>\
</div>');}else{$(opts.parent).html('<div class="layout-wrapper layout-wrapper-background">\
@@ -871,6 +874,7 @@
$y(this.body,{padding:'11px'});this.fields_dict={};for(var i=0;i<fl.length;i++){var df=fl[i];var div=$a(body,'div','',{margin:'6px 0px'})
f=make_field(df,null,div,null);f.not_in_form=1;this.fields_dict[df.fieldname]=f
f.refresh();if(df.fieldtype=='Button'&&!this.first_button){$(f.input).addClass('btn-info');this.first_button=true;}}}
+this.catch_enter_as_submit=function(){var me=this;$(this.body).find(':input[type="text"], :input[type="password"]').keypress(function(e){if(e.which==13){$(me.body).find('.btn-info:first').click();}})}
this.get_values=function(){var ret={};var errors=[];for(var key in this.fields_dict){var f=this.fields_dict[key];var v=f.get_value?f.get_value():null;if(f.df.reqd&&!v)
errors.push(f.df.label+' is mandatory');if(v)ret[f.df.fieldname]=v;}
if(errors.length){msgprint('<b>Please check the following Errors</b>\n'+errors.join('\n'));return null;}
@@ -878,19 +882,18 @@
this.set_value=function(key,val){var f=this.fields_dict[key];if(f){f.set_input(val);f.refresh_mandatory();}}
this.set_values=function(dict){for(var key in dict){if(this.fields_dict[key]){this.set_value(key,dict[key]);}}}
this.clear=function(){for(key in this.fields_dict){var f=this.fields_dict[key];if(f){f.set_input(f.df['default']||'');}}}}
-wn.widgets.Dialog=function(opts){this.opts=opts;this.display=false;this.make=function(opts){if(opts)
-this.opts=opts;if(!this.opts.width)this.opts.width=480;if(!$('#dialog-container').length){$('<div id="dialog-container">').appendTo('body');}
+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;if(!$('#dialog-container').length){$('<div id="dialog-container">').appendTo('body');}
this.wrapper=$('<div class="dialog_wrapper">').appendTo('#dialog-container').get(0);if(this.opts.width)
-this.wrapper.style.width=this.opts.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.wrapper.style.width=this.opts.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(){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.appframe.$titlebar.find('.appframe-title').html(t||'');}
this.set_postion=function(){this.wrapper.style.left=(($(window).width()-cint(this.wrapper.style.width))/2)+'px';this.wrapper.style.top=($(window).scrollTop()+60)+'px';top_index++;$y(this.wrapper,{zIndex:top_index});}
this.show=function(){if(this.display)return;this.set_postion()
-$ds(this.wrapper);freeze();this.display=true;cur_dialog=this;if(this.onshow)this.onshow();}
+$ds(this.wrapper);freeze();this.display=true;cur_dialog=this;if(this.onshow)this.onshow();$(this.wrapper).find(':input:first').focus();}
this.hide=function(){if(this.onhide)this.onhide();unfreeze();$dh(this.wrapper);this.display=false;cur_dialog=null;}
this.no_cancel=function(){this.appframe.$titlebar.find('.close').toggle(false);}
-if(opts)this.make();}
+if(opts)this.make(opts);}
wn.widgets.Dialog.prototype=new wn.widgets.FieldGroup();wn.provide('wn.ui');wn.ui.Dialog=wn.widgets.Dialog
$(document).bind('keydown',function(e){if(cur_dialog&&!cur_dialog.no_cancel_flag&&e.which==27){cur_dialog.hide();}});
/*
@@ -949,11 +952,9 @@
*/
wn.provide('wn.views.doclistview');wn.provide('wn.doclistviews');wn.views.doclistview.show=function(doctype){var page_name=wn.get_route_str();if(wn.pages[page_name]){wn.container.change_to(wn.pages[page_name]);}else{var route=wn.get_route();if(route[1]){wn.model.with_doctype(route[1],function(r){if(r&&r['403']){return;}
new wn.views.DocListView(route[1]);});}}}
-wn.views.DocListView=wn.ui.Listing.extend({init:function(doctype){this.doctype=doctype;this.label=get_doctype_label(doctype);this.label=(this.label.toLowerCase().substr(-4)=='list')?this.label:(this.label+' List');this.make_page();this.setup();},make_page:function(){var me=this;var page_name=wn.get_route_str();var page=wn.container.add_page(page_name);wn.container.change_to(page_name);this.$page=$(page);this.$page.html(repl('<div class="layout-wrapper layout-wrapper-background">\
+wn.views.DocListView=wn.ui.Listing.extend({init:function(doctype){this.doctype=doctype;this.label=get_doctype_label(doctype);this.label=(this.label.toLowerCase().substr(-4)=='list')?this.label:(this.label+' List');this.make_page();this.setup();},make_page:function(){var me=this;var page_name=wn.get_route_str();var page=wn.container.add_page(page_name);wn.container.change_to(page_name);this.$page=$(page);this.$page.html('<div class="layout-wrapper layout-wrapper-background">\
<div class="appframe-area"></div>\
<div class="layout-main-section">\
- <h1>%(label)s</h1>\
- <hr>\
<div class="wnlist-area"><div class="help">Loading...</div></div>\
</div>\
<div class="layout-side-section">\
@@ -965,15 +966,16 @@
</div>\
</div>\
<div style="clear: both"></div>\
- </div>',{label:this.label}));this.appframe=new wn.ui.AppFrame(this.$page.find('.appframe-area'));wn.views.breadcrumbs($('<span>').appendTo(this.appframe.$titlebar),locals.DocType[this.doctype].module);},setup:function(){var me=this;me.can_delete=wn.model.can_delete(me.doctype);me.meta=locals.DocType[me.doctype];me.$page.find('.wnlist-area').empty(),me.setup_docstatus_filter();me.setup_listview();me.init_list();me.init_stats();me.make_report_button();me.add_delete_option();},make_report_button:function(){var me=this;if(wn.boot.profile.can_get_report.indexOf(this.doctype)!=-1){this.appframe.add_button('Build Report',function(){wn.set_route('Report2',me.doctype);},'icon-th')}},setup_docstatus_filter:function(){var me=this;this.can_submit=$.map(locals.DocPerm,function(d){if(d.parent==me.meta.name&&d.submit)return 1
+ </div>');this.appframe=new wn.ui.AppFrame(this.$page.find('.appframe-area'));wn.views.breadcrumbs(this.appframe,locals.DocType[this.doctype].module,this.doctype);},setup:function(){var me=this;me.can_delete=wn.model.can_delete(me.doctype);me.meta=locals.DocType[me.doctype];me.$page.find('.wnlist-area').empty(),me.setup_docstatus_filter();me.setup_listview();me.init_list();me.init_stats();me.make_report_button();me.add_delete_option();me.make_help();},make_report_button:function(){var me=this;if(wn.boot.profile.can_get_report.indexOf(this.doctype)!=-1){this.appframe.add_button('Build Report',function(){wn.set_route('Report2',me.doctype);},'icon-th')}},make_help:function(){if(this.meta.description){this.appframe.add_help_button(wn.markdown('## '+this.meta.name+'\n\n'
++this.meta.description));}},setup_docstatus_filter:function(){var me=this;this.can_submit=$.map(locals.DocPerm,function(d){if(d.parent==me.meta.name&&d.submit)return 1
else return null;}).length;if(this.can_submit){this.$page.find('.show-docstatus').removeClass('hide');this.$page.find('.show-docstatus input').click(function(){me.run();})}},setup_listview:function(){if(this.meta.__listjs){eval(this.meta.__listjs);this.listview=new wn.doclistviews[this.doctype](this);}else{this.listview=new wn.views.ListView(this);}
-this.listview.parent=this;this.wrapper=this.$page.find('.wnlist-area');this.page_length=20;this.allow_delete=true;},init_list:function(auto_run){this.make({method:'webnotes.widgets.doclistview.get',get_args:this.get_args,parent:this.wrapper,start:0,page_length:this.page_length,show_filters:true,show_grid:true,new_doctype:this.doctype,allow_delete:this.allow_delete,no_result_message:this.make_no_result(),columns:this.listview.fields});if((auto_run!==false)&&(auto_run!==0))this.run();},make_no_result:function(){return repl('<div class="well"><p>No %(doctype_label)s found</p>\
- %(description)s\
+this.listview.parent=this;this.wrapper=this.$page.find('.wnlist-area');this.page_length=20;this.allow_delete=true;},init_list:function(auto_run){var me=this;this.make({method:'webnotes.widgets.doclistview.get',get_args:this.get_args,parent:this.wrapper,start:0,page_length:this.page_length,show_filters:true,show_grid:true,new_doctype:this.doctype,allow_delete:this.allow_delete,no_result_message:this.make_no_result(),columns:this.listview.fields});$(this.wrapper).find('button[list_view_doc="'+me.doctype+'"]').click(function(){me.make_new_doc(me.doctype);});if((auto_run!==false)&&(auto_run!==0))this.run();},make_no_result:function(){var no_result_message=repl('<div class="well">\
+ <p>No %(doctype_label)s found</p>\
<hr>\
- <p><button class="btn btn-info btn-small"\
- onclick="newdoc(\'%(doctype)s\');"\
- >Make a new %(doctype_label)s</button>\
- </p></div>',{doctype_label:get_doctype_label(this.doctype),doctype:this.doctype,description:wn.markdown(locals.DocType[this.doctype].description||'')});},render_row:function(row,data){data.doctype=this.doctype;this.listview.render(row,data,this);},get_query_fields:function(){return this.listview.fields;},get_args:function(){return{doctype:this.doctype,fields:this.get_query_fields(),filters:this.filter_list.get_filters(),docstatus:this.can_submit?$.map(this.$page.find('.show-docstatus :checked'),function(inp){return $(inp).attr('data-docstatus')}):[],order_by:this.listview.order_by||undefined,}},add_delete_option:function(){var me=this;if(this.can_delete){this.add_button('Delete',function(){me.delete_items();},'icon-remove')}},delete_items:function(){var me=this;var dl=$.map(me.$page.find('.list-delete:checked'),function(e){return $(e).data('name');});if(!dl.length)
+ <p><button class="btn btn-info btn-small" list_view_doc="%(doctype)s">\
+ Make a new %(doctype_label)s</button>\
+ </p></div>',{doctype_label:get_doctype_label(this.doctype),doctype:this.doctype});return no_result_message;},render_row:function(row,data){data.doctype=this.doctype;this.listview.render(row,data,this);},get_query_fields:function(){return this.listview.fields;},get_args:function(){return{doctype:this.doctype,fields:this.get_query_fields(),filters:this.filter_list.get_filters(),docstatus:this.can_submit?$.map(this.$page.find('.show-docstatus :checked'),function(inp){return $(inp).attr('data-docstatus')}):[],order_by:this.listview.order_by||undefined,}},add_delete_option:function(){var me=this;if(this.can_delete){this.add_button('Delete',function(){me.delete_items();},'icon-remove');$('<div style="padding: 4px"><input type="checkbox" name="select-all" />\
+ Select all</div>').insertBefore(this.$page.find('.result-list'));this.$page.find('[name="select-all"]').click(function(){me.$page.find('.list-delete').attr('checked',$(this).attr('checked')||false);})}},delete_items:function(){var me=this;var dl=$.map(me.$page.find('.list-delete:checked'),function(e){return $(e).data('name');});if(!dl.length)
return;if(!confirm('This is PERMANENT action and you cannot undo. Continue?')){return;}
me.set_working(true);wn.call({method:'webnotes.widgets.doclistview.delete_items',args:{items:dl,doctype:me.doctype},callback:function(){me.set_working(false);me.refresh();}})},init_stats:function(){var me=this
wn.call({method:'webnotes.widgets.doclistview.get_stats',args:{stats:me.listview.stats,doctype:me.doctype},callback:function(r){$.each(me.listview.stats,function(i,v){me.render_stat(v,r.message[v]);});if(me.listview.stats.length){$('<button class="btn btn-small"><i class="refresh"></i> Refresh</button>').click(function(){me.reload_stats();}).appendTo($('<div class="stat-wrapper">').appendTo(me.$page.find('.layout-side-section')))}}});},render_stat:function(field,stat){var me=this;if(!stat||!stat.length){if(field=='_user_tags'){this.$page.find('.layout-side-section').append('<div class="stat-wrapper"><h4>Tags</h4>\
@@ -1014,11 +1016,10 @@
else if(opts.type=='link'&&opts.doctype){$(parent).append(repl('<a href="#!Form/'+opts.doctype+'/'
+data[opts.content]+'">'+data[opts.content]+'</a>',data));}
else if(opts.template){$(parent).append(repl(opts.template,data));}
-else if(data[opts.content]){$(parent).append(' '+data[opts.content]);}},render:function(row,data){var me=this;this.prepare_data(data);rowhtml='';$.each(this.columns,function(i,v){rowhtml+=repl('<td style="width: %(width)s"></td>',v);});var tr=$(row).html('<table><tbody><tr>'+rowhtml+'</tr></tbody></table>').find('tr').get(0);$.each(this.columns,function(i,v){me.render_column(data,tr.cells[i],v);});},prepare_data:function(data){data.fullname=wn.user_info(data.owner).fullname;data.avatar=wn.user_info(data.owner).image;data.when=dateutil.str_to_user(data.modified).split(' ')[0];var diff=dateutil.get_diff(dateutil.get_today(),data.modified.split(' ')[0]);if(diff==0){data.when=dateutil.comment_when(data.modified);}
+else if(data[opts.content]){$(parent).append(' '+data[opts.content]);}},render:function(row,data){var me=this;this.prepare_data(data);rowhtml='';$.each(this.columns,function(i,v){rowhtml+=repl('<td style="width: %(width)s"></td>',v);});var tr=$(row).html('<table><tbody><tr>'+rowhtml+'</tr></tbody></table>').find('tr').get(0);$.each(this.columns,function(i,v){me.render_column(data,tr.cells[i],v);});},prepare_data:function(data){data.fullname=wn.user_info(data.owner).fullname;data.avatar=wn.user_info(data.owner).image;this.prepare_when(data,data.modified);if(data.docstatus==0||data.docstatus==null){data.docstatus_icon='icon-pencil';data.docstatus_title='Editable';}else if(data.docstatus==1){data.docstatus_icon='icon-lock';data.docstatus_title='Submitted';}else if(data.docstatus==2){data.docstatus_icon='icon-remove';data.docstatus_title='Cancelled';}
+for(key in data){if(data[key]==null){data[key]='';}}},prepare_when:function(data,date_str){if(!date_str)date_str=data.modified;data.when=dateutil.str_to_user(date_str).split(' ')[0];var diff=dateutil.get_diff(dateutil.get_today(),date_str.split(' ')[0]);if(diff==0){data.when=dateutil.comment_when(date_str);}
if(diff==1){data.when='Yesterday'}
-if(diff==2){data.when='2 days ago'}
-if(data.docstatus==0||data.docstatus==null){data.docstatus_icon='icon-pencil';data.docstatus_title='Editable';}else if(data.docstatus==1){data.docstatus_icon='icon-lock';data.docstatus_title='Submitted';}else if(data.docstatus==2){data.docstatus_icon='icon-remove';data.docstatus_title='Cancelled';}
-for(key in data){if(data[key]==null){data[key]='';}}},add_user_tags:function(parent,data){var me=this;if(data._user_tags){if($(parent).html().length>0){$(parent).append('<br />');}
+if(diff==2){data.when='2 days ago'}},add_user_tags:function(parent,data){var me=this;if(data._user_tags){if($(parent).html().length>0){$(parent).append('<br />');}
$.each(data._user_tags.split(','),function(i,t){if(t){$('<span class="label label-info" style="cursor: pointer; line-height: 200%">'
+strip(t)+'</span>').click(function(){me.doclistview.set_filter('_user_tags',$(this).text())}).appendTo(parent);}});}},show_hide_check_column:function(){if(!this.doclistview.can_delete){this.columns=$.map(this.columns,function(v,i){if(v.content!='check')return v});}}});wn.provide('wn.views.RecordListView');wn.views.RecordListView=wn.views.DocListView.extend({init:function(doctype,wrapper,ListView){this.doctype=doctype;this.wrapper=wrapper;this.listview=new ListView(this);this.listview.parent=this;this.setup();},setup:function(){var me=this;me.page_length=10;$(me.wrapper).empty();me.init_list();},get_args:function(){var args=this._super();$.each((this.default_filters||[]),function(i,f){args.filters.push(f);});args.docstatus=args.docstatus.concat((this.default_docstatus||[]));return args;},});
/*
@@ -1026,21 +1027,22 @@
*/
wn.provide('wn.views.formview');wn.views.formview={show:function(dt,dn){if(wn.model.new_names[dn])
dn=wn.model.new_names[dn];wn.model.with_doctype(dt,function(){wn.model.with_doc(dt,dn,function(dn,r){if(r&&r['403'])return;if(!(locals[dt]&&locals[dt][dn])){wn.container.change_to('404');return;}
-if(!wn.views.formview[dt]){wn.views.formview[dt]=wn.container.add_page('Form - '+dt);wn.views.formview[dt].frm=new _f.Frm(dt,wn.views.formview[dt]);}
+if(!wn.views.formview[dt]){wn.views.formview[dt]=wn.container.add_page('Form - '+dt);wn.views.formview[dt].frm=new _f.Frm(dt,wn.views.formview[dt],true);}
wn.container.change_to('Form - '+dt);wn.views.formview[dt].frm.refresh(dn);});})},create:function(dt){var new_name=LocalDB.create(dt);wn.set_route('Form',dt,new_name);}}
/*
* lib/js/wn/views/reportview.js
*/
wn.views.reportview={show:function(dt,rep_name){wn.require('js/report-legacy.js');dt=get_label_doctype(dt);if(!_r.rb_con){_r.rb_con=new _r.ReportContainer();}
-_r.rb_con.set_dt(dt,function(rb){if(rep_name){var t=rb.current_loaded;rb.load_criteria(rep_name);if((rb.dt)&&(!rb.dt.has_data()||rb.current_loaded!=t)){rb.dt.run();}}
+_r.rb_con.set_dt(dt,function(rb){if(rep_name){var route_changed=(rb.current_route!=wn.get_route_str())
+rb.load_criteria(rep_name);if(rb.dt&&route_changed){rb.dt.run();}}
if(!rb.forbidden){wn.container.change_to('Report Builder');}});}}
wn.views.reportview2={show:function(dt){var page_name=wn.get_route_str();if(wn.pages[page_name]){wn.container.change_to(wn.pages[page_name]);}else{var route=wn.get_route();if(route[1]){new wn.views.ReportViewPage(route[1],route[2]);}else{wn.set_route('404');}}}}
wn.views.ReportViewPage=Class.extend({init:function(doctype,docname){this.doctype=doctype;this.docname=docname;this.page_name=wn.get_route_str();this.make_page();var me=this;wn.model.with_doctype(doctype,function(){me.make_report_view();if(docname){wn.model.with_doc('Report',docname,function(r){me.reportview.set_columns_and_filters(JSON.parse(locals['Report'][docname].json));me.reportview.run();});}else{me.reportview.run();}});},make_page:function(){this.page=wn.container.add_page(this.page_name);wn.ui.make_app_page({parent:this.page,single_column:true});wn.container.change_to(this.page_name);},make_report_view:function(){wn.views.breadcrumbs($('<span>').appendTo(this.page.appframe.$titlebar),locals.DocType[this.doctype].module);this.reportview=new wn.views.ReportView(this.doctype,this.docname,this.page)}})
-wn.views.ReportView=wn.ui.Listing.extend({init:function(doctype,docname,page){var me=this;this.import_slickgrid();this.doctype=doctype;this.docname=docname;this.page=page;this.tab_name='`tab'+doctype+'`';this.setup();},import_slickgrid:function(){wn.require('js/lib/slickgrid/slick.grid.css');wn.require('js/lib/slickgrid/slick-default-theme.css');wn.require('js/lib/slickgrid/jquery.event.drag.min.js');wn.require('js/lib/slickgrid/slick.core.js');wn.require('js/lib/slickgrid/slick.grid.js');wn.dom.set_style('.slick-cell { font-size: 12px; }');},set_init_columns:function(){var columns=[['name'],['owner']];$.each(wn.meta.docfield_list[this.doctype],function(i,df){if(df.in_filter&&df.fieldname!='naming_series'&&df.fieldtype!='Table'){columns.push([df.fieldname]);}});this.columns=columns;},setup:function(){var me=this;this.make({title:'Report: '+(this.docname?(this.doctype+' - '+this.docname):this.doctype),appframe:this.page.appframe,method:'webnotes.widgets.doclistview.get',get_args:this.get_args,parent:$(this.page).find('.layout-main'),start:0,page_length:20,show_filters:true,new_doctype:this.doctype,allow_delete:true,});this.make_column_picker();this.make_sorter();this.make_export();this.set_init_columns();this.make_save();},set_columns_and_filters:function(opts){var me=this;if(opts.columns)this.columns=opts.columns;if(opts.filters)$.each(opts.filters,function(i,f){me.filter_list.add_filter(f[1],f[2],f[3]);});if(opts.sort_by)this.sort_by_select.val(opts.sort_by);if(opts.sort_order)this.sort_order_select.val(opts.sort_order);if(opts.sort_by_next)this.sort_by_next_select.val(opts.sort_by_next);if(opts.sort_order_next)this.sort_order_next_select.val(opts.sort_order_next);},get_args:function(){var me=this;return{doctype:this.doctype,fields:$.map(this.columns,function(v){return me.get_full_column_name(v)}),order_by:this.get_order_by(),filters:this.filter_list.get_filters(),docstatus:['0','1','2']}},get_order_by:function(){var order_by=this.get_full_column_name([this.sort_by_select.val()])
+wn.views.ReportView=wn.ui.Listing.extend({init:function(doctype,docname,page){var me=this;$(page).find('.layout-main').html('Loading Report...');this.import_slickgrid();$(page).find('.layout-main').empty();this.doctype=doctype;this.docname=docname;this.page=page;this.tab_name='`tab'+doctype+'`';this.setup();},import_slickgrid:function(){wn.require('js/lib/slickgrid/slick.grid.css');wn.require('js/lib/slickgrid/slick-default-theme.css');wn.require('js/lib/slickgrid/jquery.event.drag.min.js');wn.require('js/lib/slickgrid/slick.core.js');wn.require('js/lib/slickgrid/slick.grid.js');wn.dom.set_style('.slick-cell { font-size: 12px; }');},set_init_columns:function(){var columns=[['name'],['owner']];$.each(wn.meta.docfield_list[this.doctype],function(i,df){if(df.in_filter&&df.fieldname!='naming_series'&&df.fieldtype!='Table'){columns.push([df.fieldname]);}});this.columns=columns;},setup:function(){var me=this;this.make({title:'Report: '+(this.docname?(this.doctype+' - '+this.docname):this.doctype),appframe:this.page.appframe,method:'webnotes.widgets.doclistview.get',get_args:this.get_args,parent:$(this.page).find('.layout-main'),start:0,page_length:20,show_filters:true,new_doctype:this.doctype,allow_delete:true,});this.make_column_picker();this.make_sorter();this.make_export();this.set_init_columns();this.make_save();},set_columns_and_filters:function(opts){var me=this;if(opts.columns)this.columns=opts.columns;if(opts.filters)$.each(opts.filters,function(i,f){me.filter_list.add_filter(f[1],f[2],f[3]);});if(opts.sort_by)this.sort_by_select.val(opts.sort_by);if(opts.sort_order)this.sort_order_select.val(opts.sort_order);if(opts.sort_by_next)this.sort_by_next_select.val(opts.sort_by_next);if(opts.sort_order_next)this.sort_order_next_select.val(opts.sort_order_next);},get_args:function(){var me=this;return{doctype:this.doctype,fields:$.map(this.columns,function(v){return me.get_full_column_name(v)}),order_by:this.get_order_by(),filters:this.filter_list.get_filters(),docstatus:['0','1','2']}},get_order_by:function(){var order_by=this.get_selected_table_and_column(this.sort_by_select)
+' '+this.sort_order_select.val()
-if(this.sort_by_next_select.val()){order_by+=', '+this.get_full_column_name([this.sort_by_next_select.val()])
+if(this.sort_by_next_select.val()){order_by+=', '+this.get_selected_table_and_column(this.sort_by_next_select)
+' '+this.sort_order_next_select.val()}
-return order_by;},get_full_column_name:function(v){return(v[1]?('`tab'+v[1]+'`'):this.tab_name)+'.'+v[0];},build_columns:function(){var me=this;return $.map(this.columns,function(c){var docfield=wn.meta.docfield_map[c[1]||me.doctype][c[0]];coldef={id:c[0],field:c[0],docfield:docfield,name:(docfield?docfield.label:toTitle(c[0])),width:(docfield?cint(docfield.width):120)||120}
+return order_by;},get_selected_table_and_column:function($select){return this.get_full_column_name([$select.val(),$select.find('option:selected').attr('table')])},get_full_column_name:function(v){return(v[1]?('`tab'+v[1]+'`'):this.tab_name)+'.'+v[0];},build_columns:function(){var me=this;return $.map(this.columns,function(c){var docfield=wn.meta.docfield_map[c[1]||me.doctype][c[0]];coldef={id:c[0],field:c[0],docfield:docfield,name:(docfield?docfield.label:toTitle(c[0])),width:(docfield?cint(docfield.width):120)||120}
if(c[0]=='name'){coldef.formatter=function(row,cell,value,columnDef,dataContext){return repl("<a href='#!Form/%(doctype)s/%(name)s'>%(name)s</a>",{doctype:me.doctype,name:value});}}else if(docfield&&docfield.fieldtype=='Link'){coldef.formatter=function(row,cell,value,columnDef,dataContext){if(value){return repl("<a href='#!Form/%(doctype)s/%(name)s'>%(name)s</a>",{doctype:columnDef.docfield.options,name:value});}else{return'';}}}
return coldef;});},render_list:function(){var me=this;var columns=[{id:'_idx',field:'_idx',name:'Sr.',width:40}].concat(this.build_columns());$.each(this.data,function(i,v){v._idx=i+1;});var options={enableCellNavigation:true,enableColumnReorder:false};var grid=new Slick.Grid(this.$w.find('.result-list').css('border','1px solid grey').css('height','500px').get(0),this.data,columns,options);},make_column_picker:function(){var me=this;this.column_picker=new wn.ui.ColumnPicker(this);this.page.appframe.add_button('Pick Columns',function(){me.column_picker.show(me.columns);},'icon-th-list');},make_sorter:function(){var me=this;this.sort_dialog=new wn.ui.Dialog({title:'Sorting Preferences'});$(this.sort_dialog.body).html('<p class="help">Sort By</p>\
<div class="sort-column"></div>\
@@ -1219,14 +1221,14 @@
* lib/js/legacy/webpage/search.js
*/
search_fields={};function setlinkvalue(name){selector.input.set_input_value(name);selector.hide();}
-function makeselector(){var d=new Dialog(540,440,'Search');d.make_body([['Data','Beginning With','Tip: You can use wildcard "%"'],['Select','Search By'],['Button','Search'],['HTML','Help'],['HTML','Result']]);var inp=d.widgets['Beginning With'];var field_sel=d.widgets['Search By'];var btn=d.widgets['Search'];d.sel_type='';d.values_len=0;d.set=function(input,type,label){d.sel_type=type;d.input=input;if(d.style!='Link'){d.rows['Result'].innerHTML='';d.values_len=0;}
+function makeselector(){var d=new Dialog(540,440,'Search');d.make_body([['HTML','Help'],['Data','Beginning With','Tip: You can use wildcard "%"'],['Select','Search By'],['Button','Search'],['HTML','Result']]);var inp=d.widgets['Beginning With'];var field_sel=d.widgets['Search By'];var btn=d.widgets['Search'];d.sel_type='';d.values_len=0;d.set=function(input,type,label){d.sel_type=type;d.input=input;if(d.style!='Link'){d.rows['Result'].innerHTML='';d.values_len=0;}
d.style='Link';d.set_query_description()
-if(!d.sel_type)d.sel_type='Value';d.set_title('Select a "'+d.sel_type+'" for field "'+label+'"');}
+if(!d.sel_type)d.sel_type='Value';d.set_title("Select");d.set_query_description('Select a "'+d.sel_type+'" for field "'+label+'"');}
d.set_search=function(dt){if(d.style!='Search'){d.rows['Result'].innerHTML='';d.values_len=0;}
d.style='Search';if(d.input){d.input=null;sel_type=null;}
d.sel_type=get_label_doctype(dt);d.set_title('Quick Search for '+dt);}
$(inp).keydown(function(e){if(e.which==13){if(!btn.disabled)btn.onclick();}})
-d.set_query_description=function(){if(d.input&&d.input.query_description){d.rows['Help'].innerHTML='<div class="help_box">'+d.input.query_description+'</div>';}else{d.rows['Help'].innerHTML=''}}
+d.set_query_description=function(txt){txt=d.input&&d.input.query_description||txt;if(txt){d.rows['Help'].innerHTML='<div class="help-box" style="margin-top:0px">'+txt+'</div>';}else{d.rows['Help'].innerHTML=''}}
d.onshow=function(){if(d.set_doctype!=d.sel_type){d.rows['Result'].innerHTML='';d.values_len=0;}
inp.value='';if(d.input&&d.input.txt.value){inp.value=d.input.txt.value;}
try{inp.focus();}catch(e){}
@@ -1256,18 +1258,6 @@
$ds(dialog_back);fcount++;}
function unfreeze(){if(!fcount)return;fcount--;if(!fcount){$dh(dialog_back);}}
/*
- * lib/js/legacy/webpage/error_console.js
- */
-var err_console;var err_list=[];function errprint(t){if(!err_list)err_list=[];err_list.push('<pre style="font-family: Courier, Fixed; font-size: 11px; \
- border-bottom: 1px solid #AAA; overflow: auto; width: 90%;">'+t+'</pre>');}
-$(document).bind('startup',function(){err_console=new Dialog(640,480,'Error Console')
-err_console.make_body([['HTML','Error List'],['Button','Clear'],['HTML','Error Report']]);var span=$a(err_console.widgets['Error Report'],'span','link_type');span.innerHTML='Send Error Report';span.onclick=function(){msg=prompt('How / where did you get the error [optional]')
-var call_back=function(r,rt){err_console.hide();msgprint("Error Report Sent")}
-$c('webnotes.utils.send_error_report',{'err_msg':err_console.rows['Error List'].innerHTML,'msg':msg},call_back);}
-err_console.widgets['Clear'].onclick=function(){err_list=[];err_console.rows['Error List'].innerHTML='';err_console.hide();}
-err_console.onshow=function(){err_console.rows['Error List'].innerHTML='<div style="padding: 16px; height: 360px; width: 90%; overflow: auto;">'
-+err_list.join('<div style="height: 10px; margin-bottom: 10px; border-bottom: 1px solid #AAA"></div>')+'</div>';}});
-/*
* lib/js/legacy/webpage/loaders.js
*/
function loadreport(dt,rep_name,onload){if(rep_name)
@@ -1281,7 +1271,7 @@
* lib/js/legacy/wn/page_layout.js
*/
wn.PageLayout=function(args){$.extend(this,args)
-this.wrapper=$a(this.parent,'div','layout-wrapper layout-wrapper-background');this.head=$a(this.wrapper,'div');this.main=$a(this.wrapper,'div','layout-main-section');this.sidebar_area=$a(this.wrapper,'div','layout-side-section');$a(this.wrapper,'div','',{clear:'both'});this.main_head=$a(this.main,'div','form-title');this.body=$a(this.main,'div');this.footer=$a(this.main,'div');if(this.heading){this.page_head=new PageHeader(this.head,this.heading);}}
+this.wrapper=$a(this.parent,'div','layout-wrapper layout-wrapper-background');this.head=$a(this.wrapper,'div');this.main=$a(this.wrapper,'div','layout-main-section');this.sidebar_area=$a(this.wrapper,'div','layout-side-section');$a(this.wrapper,'div','',{clear:'both'});this.body=$a(this.main,'div');this.footer=$a(this.main,'div');if(this.heading){this.page_head=new PageHeader(this.head,this.heading);}}
/*
* lib/js/legacy/wn/widgets/page_sidebar.js
*/
@@ -1324,8 +1314,10 @@
LocalDB.delete_doc=function(dt,dn){var doc=get_local(dt,dn);for(var ndt in locals){if(locals[ndt]){for(var ndn in locals[ndt]){var doc=locals[ndt][ndn];if(doc&&doc.parenttype==dt&&(doc.parent==dn||doc.__oldparent==dn)){delete locals[ndt][ndn];}}}}
delete locals[dt][dn];}
function get_local(dt,dn){return locals[dt]?locals[dt][dn]:null;}
-LocalDB.sync=function(list){if(list._kl)list=expand_doclist(list);for(var i=0;i<list.length;i++){var d=list[i];if(!d.name)
+LocalDB.sync=function(list){if(list._kl)list=expand_doclist(list);if(list){LocalDB.clear_locals(list[0].doctype,list[0].name);}
+for(var i=0;i<list.length;i++){var d=list[i];if(!d.name)
d.name=LocalDB.get_localname(d.doctype);LocalDB.add(d.doctype,d.name);locals[d.doctype][d.name]=d;if(d.doctype=='DocField')wn.meta.add_field(d);if(d.localname){wn.model.new_names[d.localname]=d.name;$(document).trigger('rename',[d.doctype,d.localname,d.name]);delete locals[d.doctype][d.localname];}}}
+LocalDB.clear_locals=function(dt,dn){var doclist=make_doclist(dt,dn,1);$.each(doclist,function(i,v){v&&delete locals[v.doctype][v.name];});}
local_name_idx={};LocalDB.get_localname=function(doctype){if(!local_name_idx[doctype])local_name_idx[doctype]=1;var n='New '+get_doctype_label(doctype)+' '+local_name_idx[doctype];local_name_idx[doctype]++;return n;}
LocalDB.set_default_values=function(doc){var doctype=doc.doctype;var docfields=wn.meta.docfield_list[doctype];if(!docfields){return;}
var fields_to_refresh=[];for(var fid=0;fid<docfields.length;fid++){var f=docfields[fid];if(!in_list(no_value_fields,f.fieldtype)&&doc[f.fieldname]==null){var v=LocalDB.get_default_value(f.fieldname,f.fieldtype,f['default']);if(v){doc[f.fieldname]=v;fields_to_refresh.push(f.fieldname);}}}
@@ -1343,8 +1335,7 @@
return perm;}
LocalDB.create=function(doctype,n){if(!n)n=LocalDB.get_localname(doctype);var doc=LocalDB.add(doctype,n)
doc.__islocal=1;doc.owner=user;LocalDB.set_default_values(doc);return n;}
-LocalDB.delete_record=function(dt,dn){var d=locals[dt][dn];if(!d.__islocal)
-d.__oldparent=d.parent;d.parent='old_parent:'+d.parent;d.docstatus=2;d.__deleted=1;}
+LocalDB.delete_record=function(dt,dn){delete locals[dt][dn];}
LocalDB.get_default_value=function(fn,ft,df){if(df=='_Login'||df=='__user')
return user;else if(df=='_Full Name')
return user_fullname;else if(ft=='Date'&&(df=='Today'||df=='__today')){return get_today();}
@@ -1355,7 +1346,8 @@
LocalDB.add_child=function(doc,childtype,parentfield){var n=LocalDB.create(childtype);var d=locals[childtype][n];d.parent=doc.name;d.parentfield=parentfield;d.parenttype=doc.doctype;return d;}
LocalDB.no_copy_list=['amended_from','amendment_date','cancel_reason'];LocalDB.copy=function(dt,dn,from_amend){var newdoc=LocalDB.create(dt);for(var key in locals[dt][dn]){var df=get_field(dt,key);if(key!=='name'&&key.substr(0,2)!='__'&&!(df&&((!from_amend&&cint(df.no_copy)==1)||in_list(LocalDB.no_copy_list,df.fieldname)))){locals[dt][newdoc][key]=locals[dt][dn][key];}}
return locals[dt][newdoc];}
-function make_doclist(dt,dn,deleted){var dl=[];dl[0]=locals[dt][dn];for(var ndt in locals){if(locals[ndt]){for(var ndn in locals[ndt]){var doc=locals[ndt][ndn];if(doc&&doc.parenttype==dt&&(doc.parent==dn||(deleted&&doc.__oldparent==dn))){dl[dl.length]=doc;}}}}
+function make_doclist(dt,dn){if(!locals[dt]){return[];}
+var dl=[];dl[0]=locals[dt][dn];for(var ndt in locals){if(locals[ndt]){for(var ndn in locals[ndt]){var doc=locals[ndt][ndn];if(doc&&doc.parenttype==dt&&doc.parent==dn){dl.push(doc)}}}}
return dl;}
var Meta={};var local_dt={};Meta.make_local_dt=function(dt,dn){var dl=make_doclist('DocType',dt);if(!local_dt[dt])local_dt[dt]={};if(!local_dt[dt][dn])local_dt[dt][dn]={};for(var i=0;i<dl.length;i++){var d=dl[i];if(d.doctype=='DocField'){var key=d.fieldname?d.fieldname:d.label;local_dt[dt][dn][key]=copy_dict(d);}}}
Meta.get_field=function(dt,fn,dn){if(dn&&local_dt[dt]&&local_dt[dt][dn]){return local_dt[dt][dn][fn];}else{if(wn.meta.docfield_map[dt])var d=wn.meta.docfield_map[dt][fn];if(d)return d;}
@@ -1367,7 +1359,7 @@
/*
* lib/js/legacy/model/doclist.js
*/
-function compress_doclist(list){var kl={};var vl=[];var flx={};for(var i=0;i<list.length;i++){var o=list[i];var fl=[];if(!kl[o.doctype]){var tfl=['doctype','name','docstatus','owner','parent','parentfield','parenttype','idx','creation','modified','modified_by','__islocal','__deleted','__newname','__modified','_user_tags'];var fl=['doctype','name','docstatus','owner','parent','parentfield','parenttype','idx','creation','modified','modified_by','__islocal','__deleted','__newname','__modified','_user_tags'];for(key in wn.meta.docfield_map[o.doctype]){if(!in_list(fl,key)&&!in_list(no_value_fields,wn.meta.docfield_map[o.doctype][key].fieldtype)&&!wn.meta.docfield_map[o.doctype][key].no_column){fl[fl.length]=key;tfl[tfl.length]=key}}
+function compress_doclist(list){var kl={};var vl=[];var flx={};for(var i=0;i<list.length;i++){var o=list[i];var fl=[];if(!kl[o.doctype]){var tfl=['doctype','name','docstatus','owner','parent','parentfield','parenttype','idx','creation','modified','modified_by','__islocal','__newname','__modified','_user_tags'];var fl=[].concat(tfl);for(key in wn.meta.docfield_map[o.doctype]){if(!in_list(fl,key)&&!in_list(no_value_fields,wn.meta.docfield_map[o.doctype][key].fieldtype)&&!wn.meta.docfield_map[o.doctype][key].no_column){fl[fl.length]=key;tfl[tfl.length]=key}}
flx[o.doctype]=fl;kl[o.doctype]=tfl}
var nl=[];var fl=flx[o.doctype];for(var j=0;j<fl.length;j++){var v=o[fl[j]];nl.push(v);}
vl.push(nl);}
@@ -1383,7 +1375,8 @@
var _save=function(){$c('webnotes.widgets.form.save.savedocs',{'docs':compress_doclist(doclist),'docname':dn,'action':save_action,'user':user},function(r,rtxt){if(f){f.savingflag=false;}
if(r.saved){if(onsave)onsave(r);}else{if(onerr)onerr(r);}},function(){if(f){f.savingflag=false;}},0,(f?'Saving...':''));}
if(doc.__islocal&&(doctype&&doctype.autoname&&doctype.autoname.toLowerCase()=='prompt')){var newname=prompt('Enter the name of the new '+dt,'');if(newname){doc.__newname=strip(newname);_save();}else{msgprint('Not Saved');onerr();}}else{_save();}}
-function check_required(dt,dn,parent_dt){var doc=locals[dt][dn];if(doc.docstatus>1)return true;var fl=wn.meta.docfield_list[dt];if(!fl)return true;var all_clear=true;var errfld=[];for(var i=0;i<fl.length;i++){var key=fl[i].fieldname;var v=doc[key];if(fl[i].reqd&&is_null(v)&&fl[i].fieldname){errfld[errfld.length]=fl[i].label;if(cur_frm){var f=cur_frm.fields_dict[fl[i].fieldname];if(f){if(f.set_as_error)f.set_as_error(1);if(!cur_frm.error_in_section&&f.parent_section){cur_frm.error_in_section=1;}}}
+function check_required(dt,dn,parent_dt){var doc=locals[dt][dn];if(doc.docstatus>1)return true;var fl=wn.meta.docfield_list[dt];if(!fl)return true;var all_clear=true;var errfld=[];for(var i=0;i<fl.length;i++){var key=fl[i].fieldname;var v=doc[key];if(fl[i].fieldtype=='Table'){var no_value=true;$.each(locals[fl[i].options],function(k,d){if(d.parent==doc.name&&d.parenttype==doc.doctype&&d.parentfield==fl[i].fieldname){no_value=false;}});}else{var no_value=is_null(v);}
+if(fl[i].reqd&&no_value&&fl[i].fieldname){errfld[errfld.length]=fl[i].label;if(cur_frm){var f=cur_frm.fields_dict[fl[i].fieldname];if(f){if(f.set_as_error)f.set_as_error(1);if(!cur_frm.error_in_section&&f.parent_section){cur_frm.error_in_section=1;}}}
if(all_clear)all_clear=false;}}
if(errfld.length)msgprint('<b>Mandatory fields required in '+
(doc.parenttype?(wn.meta.docfield_map[doc.parenttype][doc.parentfield].label+' (Table)'):get_doctype_label(doc.doctype))+':</b>\n'+errfld.join('\n'));return all_clear;}
@@ -1456,7 +1449,6 @@
<a class="dropdown-toggle" data-toggle="dropdown" href="#" \
onclick="return false;">Tools<b class="caret"></b></a>\
<ul class="dropdown-menu" id="toolbar-tools">\
- <li><a href="#" onclick="return err_console.show();">Error Console</a></li>\
<li><a href="#" onclick="return wn.ui.toolbar.clear_cache();">Clear Cache & Refresh</a></li>\
<li><a href="#" onclick="return wn.ui.toolbar.show_about();">About</a></li>\
</ul>\
@@ -1470,11 +1462,8 @@
/*
* lib/js/wn/views/breadcrumbs.js
*/
-wn.provide('wn.views');wn.views.breadcrumbs=function(parent,module,doctype,name){$(parent).empty();var $bspan=$(repl('<span class="breadcrumbs">\
- <a href="#%(home_page)s">Home</a></span>',{home_page:wn.boot.home_page}));if(module&&wn.modules[module]){$bspan.append(repl(' / <a href="#!%(module_page)s">%(module)s Home</a>',{module:module,module_page:wn.modules[module]}))}
-if(doctype&&(locals.DocType[doctype]&&!locals.DocType[doctype].issingle)){$bspan.append(repl(' / <a href="#!List/%(doctype)s">%(doctype)s</a>',{doctype:doctype}))}
-if(name){$bspan.append(' / '+name.bold())}
-$bspan.appendTo(parent);}
+wn.provide('wn.views');wn.views.breadcrumbs=function(appframe,module,doctype,name){appframe.clear_breadcrumbs();if(name){appframe.add_breadcrumb(name);}else if(doctype){appframe.add_breadcrumb(doctype+' List');}else if(module){appframe.add_breadcrumb(module);}
+if(name&&doctype&&(!locals['DocType'][doctype].issingle)){appframe.add_breadcrumb(repl(' in <a href="#!List/%(doctype)s">%(doctype)s List</a>',{doctype:doctype}))};if(doctype&&module&&wn.modules&&wn.modules[module]){appframe.add_breadcrumb(repl(' in <a href="#!%(module_page)s">%(module)s</a>',{module:module,module_page:wn.modules[module]}))}}
/*
* lib/js/legacy/widgets/form/fields.js
*/
@@ -1494,8 +1483,9 @@
Field.prototype.set_description=function(){if(this.df.description){var p=in_list(['Text Editor','Code','Check'],this.df.fieldtype)?this.label_area:this.wrapper;this.desc_area=$a(p,'div','help small','',this.df.description)
if(in_list(['Text Editor','Code'],this.df.fieldtype))
$(this.desc_area).addClass('help small');}}
-Field.prototype.get_status=function(){if(this.in_filter)this.not_in_form=this.in_filter;if(this.not_in_form){return'Write';}
-if(!this.df.permlevel)this.df.permlevel=0;var p=this.perm[this.df.permlevel];var ret;if(cur_frm.editable&&p&&p[WRITE])ret='Write';else if(p&&p[READ])ret='Read';else ret='None';if(this.df.fieldtype=='Binary')
+Field.prototype.get_status=function(){if(this.in_filter)
+this.not_in_form=this.in_filter;if(this.not_in_form){return'Write';}
+if(!this.df.permlevel)this.df.permlevel=0;var p=this.perm[this.df.permlevel];var ret;if(cur_frm.editable&&p&&p[WRITE]&&!this.disabled)ret='Write';else if(p&&p[READ])ret='Read';else ret='None';if(this.df.fieldtype=='Binary')
ret='None';if(cint(this.df.hidden))
ret='None';if(ret=='Write'&&cint(cur_frm.doc.docstatus)>0)ret='Read';var a_o_s=cint(this.df.allow_on_submit);if(a_o_s&&(this.in_grid||(this.frm&&this.frm.not_in_container))){a_o_s=null;if(this.in_grid)a_o_s=this.grid.field.df.allow_on_submit;if(this.frm&&this.frm.not_in_container){a_o_s=cur_grid.field.df.allow_on_submit;}}
if(cur_frm.editable&&a_o_s&&cint(cur_frm.doc.docstatus)>0&&!this.df.hidden){tmp_perm=get_perm(cur_frm.doctype,cur_frm.docname,1);if(tmp_perm[this.df.permlevel]&&tmp_perm[this.df.permlevel][WRITE])ret='Write';}
@@ -1574,19 +1564,20 @@
$(me.btn2).css('display','inline-block');else $dh(me.btn2);}}
me.txt.field_object=this;me.input.set_input=function(val){if(val==undefined)val='';me.txt.value=val;}
me.get_value=function(){return me.txt.value;}
-$(me.txt).autocomplete({source:function(request,response){wn.call({method:'webnotes.widgets.search.search_link',args:{'txt':request.term,'dt':me.df.options,'query':me.get_custom_query()},callback:function(r){response(r.results);},});},select:function(event,ui){me.set_input_value(ui.item.value);}}).data('autocomplete')._renderItem=function(ul,item){return $('<li></li>').data('item.autocomplete',item).append(repl('<a>%(label)s<br><span style="font-size:10px">%(info)s</span></a>',item)).appendTo(ul);};$(this.txt).change(function(){if(!$(this).val()){if(selector&&selector.display)
-return;me.set_input_value('');}})}
+$(me.txt).autocomplete({source:function(request,response){wn.call({method:'webnotes.widgets.search.search_link',args:{'txt':request.term,'dt':me.df.options,'query':me.get_custom_query()},callback:function(r){response(r.results);},});},select:function(event,ui){me.set_input_value(ui.item.value);}}).data('autocomplete')._renderItem=function(ul,item){return $('<li></li>').data('item.autocomplete',item).append(repl('<a>%(label)s<br><span style="font-size:10px">%(info)s</span></a>',item)).appendTo(ul);};$(this.txt).change(function(){var val=$(this).val();me.set_input_value_executed=false;if(!val){if(selector&&selector.display)
+return;me.set_input_value('');}else{setTimeout(function(){if(!me.set_input_value_executed){me.set_input_value(val);}},1000);}})}
LinkField.prototype.get_custom_query=function(){this.set_get_query();if(this.get_query){if(cur_frm)
var doc=locals[cur_frm.doctype][cur_frm.docname];return this.get_query(doc,this.doctype,this.docname);}}
LinkField.prototype.setup_buttons=function(){var me=this;me.btn.onclick=function(){selector.set(me,me.df.options,me.df.label);selector.show(me.txt);}
if(me.btn1)me.btn1.onclick=function(){if(me.txt.value&&me.df.options){loaddoc(me.df.options,me.txt.value);}}
me.can_create=0;if((!me.not_in_form)&&in_list(profile.can_create,me.df.options)){me.can_create=1;me.btn2.onclick=function(){var on_save_callback=function(new_rec){if(new_rec){var d=_f.calling_doc_stack.pop();locals[d[0]][d[1]][me.df.fieldname]=new_rec;me.refresh();if(me.grid)me.grid.refresh();me.run_trigger();}}
_f.calling_doc_stack.push([me.doctype,me.docname]);new_doc(me.df.options,me.on_new,1,on_save_callback,me.doctype,me.docname,me.frm.not_in_container);}}else{$dh(me.btn2);$y($td(me.tab,0,2),{width:'0px'});}}
-LinkField.prototype.set_input_value=function(val){var me=this;var from_selector=false;if(selector&&selector.display)from_selector=true;me.refresh_label_icon();if(me.not_in_form){$(this.txt).val(val);return;}
+LinkField.prototype.set_input_value=function(val){var me=this;me.set_input_value_executed=true;var from_selector=false;if(selector&&selector.display)from_selector=true;me.refresh_label_icon();if(me.not_in_form){$(this.txt).val(val);return;}
if(cur_frm){if(val==locals[me.doctype][me.docname][me.df.fieldname]){me.run_trigger();return;}}
me.set(val);if(_f.cur_grid_cell)
_f.cur_grid_cell.grid.cell_deselect();if(locals[me.doctype][me.docname][me.df.fieldname]&&!val){me.run_trigger();return;}
-var fetch='';if(cur_frm.fetch_dict[me.df.fieldname])
+me.validate_link(val,from_selector);}
+LinkField.prototype.validate_link=function(val,from_selector){var me=this;var fetch='';if(cur_frm.fetch_dict[me.df.fieldname])
fetch=cur_frm.fetch_dict[me.df.fieldname].columns.join(', ');$c('webnotes.widgets.form.utils.validate_link',{'value':val,'options':me.df.options,'fetch':fetch},function(r,rt){if(r.message=='Ok'){if($(me.txt).val()!=val){if((me.grid&&!from_selector)||(!me.grid)){$(me.txt).val(val);}}
if(r.fetch_values)
me.set_fetch_values(r.fetch_values);me.run_trigger();}else{var astr='';if(in_list(profile.can_create,me.df.options))astr=repl('<br><br><span class="link_type" onclick="newdoc(\'%(dt)s\')">Click here</span> to create a new %(dtl)s',{dt:me.df.options,dtl:get_doctype_label(me.df.options)})
@@ -1706,11 +1697,12 @@
* lib/js/legacy/widgets/form/form_header.js
*/
_f.FrmHeader=Class.extend({init:function(parent,frm){this.appframe=new wn.ui.AppFrame(parent)
-this.appframe.$titlebar.append('<span class="label-area"></span>\
- <span class="breadcrumb-area"></span>');this.$w=this.appframe.$w;},refresh:function(){wn.views.breadcrumbs($(this.$w.find('.breadcrumb-area')),cur_frm.meta.module,cur_frm.meta.name,cur_frm.docname);this.refresh_labels();this.refresh_toolbar();},refresh_labels:function(){var labinfo={0:['Saved','label-success'],1:['Submitted','label-info'],2:['Cancelled','label-important']}[cint(cur_frm.doc.docstatus)];if(labinfo[0]=='Saved'&&cur_frm.meta.is_submittable){labinfo[0]='Saved, to Submit';}
+this.$w=this.appframe.$w;},refresh:function(){if(cur_frm.cscript.set_breadcrumbs){this.appframe.clear_breadcrumbs();cur_frm.cscript.set_breadcrumbs();}else{wn.views.breadcrumbs(this.appframe,cur_frm.meta.module,cur_frm.meta.name,cur_frm.docname);}
+this.refresh_labels();this.refresh_toolbar();},refresh_labels:function(){var labinfo={0:['Saved','label-success'],1:['Submitted','label-info'],2:['Cancelled','label-important']}[cint(cur_frm.doc.docstatus)];if(labinfo[0]=='Saved'&&cur_frm.meta.is_submittable){labinfo[0]='Saved, to Submit';}
if(cur_frm.doc.__unsaved||cur_frm.doc.__islocal){labinfo[0]='Not Saved';labinfo[1]='label-warning'}
-this.set_label(labinfo);if(cur_frm.doc.__unsaved&&cint(cur_frm.doc.docstatus)==1&&this.appframe.buttons['Update']){this.appframe.buttons['Update'].toggle(true);}},set_label:function(labinfo){this.$w.find('.label-area').html(repl('<span class="label %(lab_class)s">\
- %(lab_status)s</span>',{lab_status:labinfo[0],lab_class:labinfo[1]}));},refresh_toolbar:function(){this.appframe.clear_buttons();var p=cur_frm.get_doc_perms();if(cur_frm.meta.read_only_onload&&!cur_frm.doc.__islocal){if(!cur_frm.editable)
+this.set_label(labinfo);if(cur_frm.doc.__unsaved&&cint(cur_frm.doc.docstatus)==1&&this.appframe.buttons['Update']){this.appframe.buttons['Update'].toggle(true);}},set_label:function(labinfo){this.$w.find('.label').remove();$(repl('<span class="label %(lab_class)s">\
+ %(lab_status)s</span>',{lab_status:labinfo[0],lab_class:labinfo[1]})).insertBefore(this.$w.find('.breadcrumb-area'))},refresh_toolbar:function(){if(cur_frm.meta.hide_toolbar){$('.appframe-toolbar').toggle(false);return;}
+this.appframe.clear_buttons();var p=cur_frm.get_doc_perms();if(cur_frm.meta.read_only_onload&&!cur_frm.doc.__islocal){if(!cur_frm.editable)
this.appframe.add_button('Edit',function(){cur_frm.edit_doc();},'icon-pencil');else
this.appframe.add_button('Print View',function(){cur_frm.is_editable[cur_frm.docname]=0;cur_frm.refresh();},'icon-print');}
var docstatus=cint(cur_frm.doc.docstatus);if(docstatus==0&&p[WRITE]){this.appframe.add_button('Save',function(){cur_frm.save('Save');},'');this.appframe.buttons['Save'].addClass('btn-info');}
@@ -1718,11 +1710,12 @@
this.appframe.add_button('Submit',function(){cur_frm.savesubmit();},'icon-lock');if(docstatus==1&&p[SUBMIT]){this.appframe.add_button('Update',function(){cur_frm.saveupdate();},'');if(!cur_frm.doc.__unsaved)this.appframe.buttons['Update'].toggle(false);}
if(docstatus==1&&p[CANCEL])
this.appframe.add_button('Cancel',function(){cur_frm.savecancel()},'icon-remove');if(docstatus==2&&p[AMEND])
-this.appframe.add_button('Amend',function(){cur_frm.amend_doc()},'icon-pencil');},show:function(){},hide:function(){},hide_close:function(){this.$w.find('.close').toggle(false);}})
+this.appframe.add_button('Amend',function(){cur_frm.amend_doc()},'icon-pencil');if(cur_frm.meta.description){this.appframe.add_help_button(wn.markdown('## '+cur_frm.doctype+'\n\n'
++cur_frm.meta.description));}},show:function(){},hide:function(){},hide_close:function(){this.$w.find('.close').toggle(false);}})
/*
* lib/js/legacy/widgets/form/form.js
*/
-wn.provide('_f');_f.frms={};_f.Frm=function(doctype,parent){this.docname='';this.doctype=doctype;this.display=0;var me=this;this.is_editable={};this.opendocs={};this.sections=[];this.grids=[];this.cscript={};this.pformat={};this.fetch_dict={};this.parent=parent;this.tinymce_id_list=[];this.setup_meta(doctype);var me=this;$(document).bind('rename',function(event,dt,old_name,new_name){if(dt==me.doctype)
+wn.provide('_f');_f.frms={};_f.Frm=function(doctype,parent,in_form){this.docname='';this.doctype=doctype;this.display=0;var me=this;this.is_editable={};this.opendocs={};this.sections=[];this.grids=[];this.cscript={};this.pformat={};this.fetch_dict={};this.parent=parent;this.tinymce_id_list=[];this.setup_meta(doctype);this.in_form=in_form?true:false;var me=this;$(document).bind('rename',function(event,dt,old_name,new_name){if(dt==me.doctype)
me.rename_notify(dt,old_name,new_name)});}
_f.Frm.prototype.check_doctype_conflict=function(docname){var me=this;if(this.doctype=='DocType'&&docname=='DocType'){msgprint('Allowing DocType, DocType. Be careful!')}else if(this.doctype=='DocType'){if(wn.views.formview[docname]){msgprint("Cannot open DocType when its instance is open")
throw'doctype open conflict'}}else{if(wn.views.formview.DocType&&wn.views.formview.DocType.frm.opendocs[this.doctype]){msgprint("Cannot open instance when its DocType is open")
@@ -1730,9 +1723,9 @@
_f.Frm.prototype.setup=function(){var me=this;this.fields=[];this.fields_dict={};this.wrapper=this.parent;this.setup_print_layout();this.saved_wrapper=$a(this.wrapper,'div');this.setup_std_layout();this.setup_client_script();this.setup_done=true;}
_f.Frm.prototype.setup_print_layout=function(){this.print_wrapper=$a(this.wrapper,'div');this.print_head=$a(this.print_wrapper,'div');this.print_body=$a(this.print_wrapper,'div','layout_wrapper',{padding:'23px',minHeight:'800px'});var t=make_table(this.print_head,1,2,'100%',[],{padding:'6px'});this.view_btn_wrapper=$a($td(t,0,0),'span','green_buttons');this.view_btn=$btn(this.view_btn_wrapper,'View Details',function(){cur_frm.edit_doc()},{marginRight:'4px'},'green');this.print_btn=$btn($td(t,0,0),'Print',function(){cur_frm.print_doc()});$y($td(t,0,1),{textAlign:'right'});this.print_close_btn=$btn($td(t,0,1),'Close',function(){window.history.back();});}
_f.Frm.prototype.onhide=function(){if(_f.cur_grid_cell)_f.cur_grid_cell.grid.cell_deselect();}
-_f.Frm.prototype.setup_std_layout=function(){this.page_layout=new wn.PageLayout({parent:this.wrapper,main_width:this.meta.in_dialog?'100%':'75%',sidebar_width:this.meta.in_dialog?'0%':'25%'})
-this.meta.section_style='Simple';this.layout=new Layout(this.page_layout.body,'100%');if(this.meta.in_dialog){$(this.page_layout.wrapper).removeClass('layout-wrapper-background');$(this.page_layout.main).removeClass('layout-main-section');$(this.page_layout.sidebar_area).toggle(false);}else{this.setup_sidebar();}
-this.setup_footer();if(!(this.meta.istable||user=='Guest'||this.meta.in_dialog))
+_f.Frm.prototype.setup_std_layout=function(){this.page_layout=new wn.PageLayout({parent:this.wrapper,main_width:(this.meta.in_dialog&&!this.in_form)?'100%':'75%',sidebar_width:(this.meta.in_dialog&&!this.in_form)?'0%':'25%'})
+this.meta.section_style='Simple';this.layout=new Layout(this.page_layout.body,'100%');if(this.meta.in_dialog&&!this.in_form){$(this.page_layout.wrapper).removeClass('layout-wrapper-background');$(this.page_layout.main).removeClass('layout-main-section');$(this.page_layout.sidebar_area).toggle(false);}else{this.setup_sidebar();}
+this.setup_footer();if(!(this.meta.istable||user=='Guest'||(this.meta.in_dialog&&!this.in_form)))
this.frm_head=new _f.FrmHeader(this.page_layout.head,this);if(this.meta.colour)
this.layout.wrapper.style.backgroundColor='#'+this.meta.colour.split(':')[1];this.setup_fields_std();}
_f.Frm.prototype.setup_print=function(){var l=[]
@@ -1741,26 +1734,31 @@
this.default_format=this.meta.default_print_format;l.push('Standard');this.print_sel=$a(null,'select','',{width:'160px'});add_sel_options(this.print_sel,l);this.print_sel.value=this.default_format;}
_f.Frm.prototype.print_doc=function(){if(this.doc.docstatus==2){msgprint("Cannot Print Cancelled Documents.");return;}
_p.show_dialog();}
-_f.Frm.prototype.email_doc=function(){if(!_e.dialog)_e.make();sel=this.print_sel;var c=$td(_e.dialog.rows['Format'].tab,0,1);if(c.cur_sel){c.removeChild(c.cur_sel);c.cur_sel=null;}
+_f.Frm.prototype.email_doc=function(){if(!_e.dialog)_e.make();_e.dialog.widgets['To'].value='';if(cur_frm.doc&&cur_frm.doc.contact_email){_e.dialog.widgets['To'].value=cur_frm.doc.contact_email;}
+sel=this.print_sel;var c=$td(_e.dialog.rows['Format'].tab,0,1);if(c.cur_sel){c.removeChild(c.cur_sel);c.cur_sel=null;}
c.appendChild(this.print_sel);c.cur_sel=this.print_sel;_e.dialog.widgets['Send With Attachments'].checked=0;if(cur_frm.doc.file_list){$ds(_e.dialog.rows['Send With Attachments']);}else{$dh(_e.dialog.rows['Send With Attachments']);}
_e.dialog.widgets['Subject'].value=get_doctype_label(this.meta.name)+': '+this.docname;_e.dialog.show();}
-_f.Frm.prototype.rename_notify=function(dt,old,name){if(this.meta.in_dialog)
+_f.Frm.prototype.rename_notify=function(dt,old,name){if(this.meta.in_dialog&&!this.in_form)
return;if(this.docname==old)
this.docname=name;else
return;this.is_editable[name]=this.is_editable[old];delete this.is_editable[old];if(this&&this.opendocs[old]){local_dt[dt][name]=local_dt[dt][old];local_dt[dt][old]=null;}
-delete this.opendocs[old];this.opendocs[name]=true;wn.re_route[window.location.hash]='Form/'+encodeURIComponent(this.doctype)+'/'+encodeURIComponent(name);wn.set_route('Form',this.doctype,name);}
-_f.Frm.prototype.setup_meta=function(){this.meta=get_local('DocType',this.doctype);this.perm=get_perm(this.doctype);if(this.meta.istable){this.meta.in_dialog=1}
+delete this.opendocs[old];this.opendocs[name]=true;wn.re_route[window.location.hash]='#Form/'+encodeURIComponent(this.doctype)+'/'+encodeURIComponent(name);wn.set_route('Form',this.doctype,name);}
+_f.Frm.prototype.setup_meta=function(doctype){this.meta=get_local('DocType',this.doctype);this.perm=get_perm(this.doctype);if(this.meta.istable){this.meta.in_dialog=1}
this.setup_print();}
_f.Frm.prototype.setup_sidebar=function(){this.sidebar=new wn.widgets.form.sidebar.Sidebar(this);}
_f.Frm.prototype.setup_footer=function(){var me=this;var f=this.page_layout.footer;f.save_area=$a(this.page_layout.footer,'div','',{display:'none',marginTop:'11px'});f.help_area=$a(this.page_layout.footer,'div');var b=$btn(f.save_area,'Save',function(){cur_frm.save('Save');},{marginLeft:'0px'},'green');f.show_save=function(){$ds(me.page_layout.footer.save_area);}
f.hide_save=function(){$dh(me.page_layout.footer.save_area);}}
+_f.Frm.prototype.set_intro=function(txt){if(!this.intro_area){this.intro_area=$('<div class="help-box form-intro-area">').insertBefore(this.page_layout.body.firstChild);}
+if(txt){if(txt.search(/<p>/)==-1)txt='<p>'+txt+'</p>';this.intro_area.html(txt);}else{this.intro_area.remove();this.intro_area=null;}}
+_f.Frm.prototype.set_footnote=function(txt){if(!this.footnote_area){this.footnote_area=$('<div class="help-box form-intro-area">').insertAfter(this.page_layout.body.lastChild);}
+if(txt){if(txt.search(/<p>/)==-1)txt='<p>'+txt+'</p>';this.footnote_area.html(txt);}else{this.footnote_area.remove();this.footnote_area=null;}}
_f.Frm.prototype.setup_fields_std=function(){var fl=wn.meta.docfield_list[this.doctype];fl.sort(function(a,b){return a.idx-b.idx});if(fl[0]&&fl[0].fieldtype!="Section Break"||get_url_arg('embed')){this.layout.addrow();if(fl[0].fieldtype!="Column Break"){var c=this.layout.addcell();$y(c.wrapper,{padding:'8px'});}}
var sec;for(var i=0;i<fl.length;i++){var f=fl[i];if(f.fieldtype=='Section Break'&&fl[i+1]&&fl[i+1].fieldtype=='Section Break')
continue;var fn=f.fieldname?f.fieldname:f.label;var fld=make_field(f,this.doctype,this.layout.cur_cell,this);this.fields[this.fields.length]=fld;this.fields_dict[fn]=fld;if(sec&&['Section Break','Column Break'].indexOf(f.fieldtype)==-1){fld.parent_section=sec;sec.fields.push(fld);}
if(f.fieldtype=='Section Break'){sec=fld;this.sections.push(fld);}
-if((f.fieldtype=='Section Break')&&(fl[i+1])&&(fl[i+1].fieldtype!='Column Break')&&!f.hidden){var c=this.layout.addcell();$y(c.wrapper,{padding:'8px'});}}}
+if((f.fieldtype=='Section Break')&&(fl[i+1])&&(fl[i+1].fieldtype!='Column Break')){var c=this.layout.addcell();$y(c.wrapper,{padding:'8px'});}}}
_f.Frm.prototype.add_custom_button=function(label,fn,icon){this.frm_head.appframe.add_button(label,fn,icon);}
-_f.Frm.prototype.clear_custom_buttons=function(){}
+_f.Frm.prototype.clear_custom_buttons=function(){this.frm_head.refresh_toolbar()}
_f.Frm.prototype.add_fetch=function(link_field,src_field,tar_field){if(!this.fetch_dict[link_field]){this.fetch_dict[link_field]={'columns':[],'fields':[]}}
this.fetch_dict[link_field].columns.push(src_field);this.fetch_dict[link_field].fields.push(tar_field);}
_f.Frm.prototype.setup_client_script=function(){if(this.meta.client_script_core||this.meta.client_script||this.meta.__js){this.runclientscript('setup',this.doctype,this.docname);}}
@@ -1775,14 +1773,14 @@
_f.Frm.prototype.defocus_rest=function(){if(_f.cur_grid_cell)_f.cur_grid_cell.grid.cell_deselect();}
_f.Frm.prototype.get_doc_perms=function(){var p=[0,0,0,0,0,0];for(var i=0;i<this.perm.length;i++){if(this.perm[i]){if(this.perm[i][READ])p[READ]=1;if(this.perm[i][WRITE])p[WRITE]=1;if(this.perm[i][SUBMIT])p[SUBMIT]=1;if(this.perm[i][CANCEL])p[CANCEL]=1;if(this.perm[i][AMEND])p[AMEND]=1;}}
return p;}
-_f.Frm.prototype.refresh_header=function(){if(!this.meta.in_dialog){set_title(this.meta.issingle?this.doctype:this.docname);}
-this.page_layout.main_head.innerHTML='<h2>'+this.docname+'</h2>';if(this.frm_head)this.frm_head.refresh();if(wn.ui.toolbar.recent)
+_f.Frm.prototype.refresh_header=function(){if(!this.meta.in_dialog||this.in_form){set_title(this.meta.issingle?this.doctype:this.docname);}
+if(this.frm_head)this.frm_head.refresh();if(wn.ui.toolbar.recent)
wn.ui.toolbar.recent.add(this.doctype,this.docname,1);}
_f.Frm.prototype.check_doc_perm=function(){var dt=this.parent_doctype?this.parent_doctype:this.doctype;var dn=this.parent_docname?this.parent_docname:this.docname;this.perm=get_perm(dt,dn);this.orig_perm=get_perm(dt,dn,1);if(!this.perm[0][READ]){if(user=='Guest'){if(_f.temp_access[dt]&&_f.temp_access[dt][dn]){this.perm=[[1,0,0]]
return 1;}}
window.back();return 0;}
return 1}
-_f.Frm.prototype.refresh=function(docname){if(docname){if(this.docname!=docname&&!this.meta.in_dialog&&!this.meta.istable)scroll(0,0);this.docname=docname;}
+_f.Frm.prototype.refresh=function(docname){if(docname){if(this.docname!=docname&&(!this.meta.in_dialog||this.in_form)&&!this.meta.istable)scroll(0,0);this.docname=docname;}
if(!this.meta.istable){cur_frm=this;this.parent.cur_frm=this;}
if(this.docname){if(!this.check_doc_perm())return;if(!this.setup_done)this.setup();this.runclientscript('set_perm',this.doctype,this.docname);this.doc=get_local(this.doctype,this.docname);cur_frm.cscript.is_onload=false;if(!this.opendocs[this.docname]){cur_frm.cscript.is_onload=true;this.setnewdoc(this.docname);}
if(this.doc.__islocal)
@@ -1792,14 +1790,14 @@
if(this.doc.docstatus==0){$(this.wrapper).find('.form-layout-row :input:first').focus();}}else{this.refresh_header();if(this.print_wrapper){this.refresh_print_layout();}
this.runclientscript('edit_status_changed');}
$(cur_frm.wrapper).trigger('render_complete');}}
-_f.Frm.prototype.refresh_footer=function(){var f=this.page_layout.footer;if(f.save_area){if(get_url_arg('embed')||(this.editable&&!this.meta.in_dialog&&this.doc.docstatus==0&&!this.meta.istable&&this.get_doc_perms()[WRITE])){f.show_save();}else{f.hide_save();}}}
+_f.Frm.prototype.refresh_footer=function(){var f=this.page_layout.footer;if(f.save_area){if(this.editable&&(!this.meta.in_dialog||this.in_form)&&this.doc.docstatus==0&&!this.meta.istable&&this.get_doc_perms()[WRITE]&&(this.fields&&this.fields.length>7)){f.show_save();}else{f.hide_save();}}}
_f.Frm.prototype.refresh_fields=function(){for(var i=0;i<this.fields.length;i++){var f=this.fields[i];f.perm=this.perm;f.docname=this.docname;var fn=f.df.fieldname||f.df.label;if(fn)
f.df=get_field(this.doctype,fn,this.docname);if(f.df.fieldtype!='Section Break'&&f.refresh){f.refresh();}}
$.each(this.sections,function(i,f){f.refresh(true);})
this.cleanup_refresh(this);}
_f.Frm.prototype.cleanup_refresh=function(){var me=this;if(me.fields_dict['amended_from']){if(me.doc.amended_from){unhide_field('amended_from');unhide_field('amendment_date');}else{hide_field('amended_from');hide_field('amendment_date');}}
if(me.fields_dict['trash_reason']){if(me.doc.trash_reason&&me.doc.docstatus==2){unhide_field('trash_reason');}else{hide_field('trash_reason');}}
-if(me.meta.autoname&&me.meta.autoname.substr(0,6)=='field:'&&!me.doc.__islocal){var fn=me.meta.autoname.substr(6);set_field_permlevel(fn,1);}}
+if(me.meta.autoname&&me.meta.autoname.substr(0,6)=='field:'&&!me.doc.__islocal){var fn=me.meta.autoname.substr(6);cur_frm.toggle_fields(fn,false);}}
_f.Frm.prototype.refresh_dependency=function(){var me=this;var doc=locals[this.doctype][this.docname];var dep_dict={};var has_dep=false;for(fkey in me.fields){var f=me.fields[fkey];f.dependencies_clear=true;var guardian=f.df.depends_on;if(guardian){if(!dep_dict[guardian])
dep_dict[guardian]=[];dep_dict[guardian][dep_dict[guardian].length]=f;has_dep=true;}}
if(!has_dep)return;for(var i=me.fields.length-1;i>=0;i--){var f=me.fields[i];f.guardian_has_value=true;if(f.df.depends_on){var v=doc[f.df.depends_on];if(f.df.depends_on.substr(0,5)=='eval:'){f.guardian_has_value=eval(f.df.depends_on.substr(5));}else if(f.df.depends_on.substr(0,3)=='fn:'){f.guardian_has_value=me.runclientscript(f.df.depends_on.substr(3),me.doctype,me.docname);}else{if(v||(v==0&&!v.substr)){}else{f.guardian_has_value=false;}}
@@ -1815,10 +1813,7 @@
if(save_action=='Cancel'){var reason=prompt('Reason for cancellation (mandatory)','');if(!strip(reason)){msgprint('Reason is mandatory, not cancelled');return;}
locals[this.doctype][this.docname].cancel_reason=reason;locals[this.doctype][this.docname].cancelled_on=dateutil.full_str();locals[this.doctype][this.docname].cancelled_by=user;}else if(save_action=='Update'){}else{validated=true;if(this.cscript.validate)
this.runclientscript('validate',this.doctype,this.docname);if(!validated){this.savingflag=false;return'Error';}}
-var ret_fn=function(r){me.savingflag=false;if(user=='Guest'&&!r.exc){$dh(me.page_layout.wrapper);$ds(me.saved_wrapper);me.saved_wrapper.innerHTML='<div style="padding: 150px 16px; text-align: center; font-size: 14px;">'
-+(cur_frm.message_after_save?cur_frm.message_after_save:'Your information has been sent. Thank you!')
-+'</div>';return;}
-if(!me.meta.istable){me.refresh(r.docname);}
+var ret_fn=function(r){me.savingflag=false;if(!me.meta.istable&&r){me.refresh(r.docname);}
if(call_back){call_back(r);}}
var me=this;var ret_fn_err=function(r){var doc=locals[me.doctype][me.docname];me.savingflag=false;ret_fn(r);}
this.savingflag=true;if(this.docname&&validated){scroll(0,0);return this.savedoc(save_action,ret_fn,ret_fn_err);}}
@@ -1834,18 +1829,17 @@
if(doctype.client_string){this.cstring={};var elist=doctype.client_string.split('---');for(var i=1;i<elist.length;i=i+2){this.cstring[strip(elist[i])]=elist[i+1];}}}
return ret;}
_f.Frm.prototype.copy_doc=function(onload,from_amend){if(!this.perm[0][CREATE]){msgprint('You are not allowed to create '+this.meta.name);return;}
-var dn=this.docname;var newdoc=LocalDB.copy(this.doctype,dn,from_amend);if(this.meta.allow_attach&&newdoc.file_list)
+var dn=this.docname;var newdoc=LocalDB.copy(this.doctype,dn,from_amend);if(this.meta.allow_attach&&newdoc.file_list&&!from_amend)
newdoc.file_list=null;var dl=make_doclist(this.doctype,dn);var tf_dict={};for(var d in dl){d1=dl[d];if(!tf_dict[d1.parentfield]){tf_dict[d1.parentfield]=get_field(d1.parenttype,d1.parentfield);}
if(d1.parent==dn&&cint(tf_dict[d1.parentfield].no_copy)!=1){var ch=LocalDB.copy(d1.doctype,d1.name,from_amend);ch.parent=newdoc.name;ch.docstatus=0;ch.owner=user;ch.creation='';ch.modified_by=user;ch.modified='';}}
newdoc.__islocal=1;newdoc.docstatus=0;newdoc.owner=user;newdoc.creation='';newdoc.modified_by=user;newdoc.modified='';if(onload)onload(newdoc);loaddoc(newdoc.doctype,newdoc.name);}
_f.Frm.prototype.reload_doc=function(){this.check_doctype_conflict(this.docname);var me=this;var ret_fn=function(r,rtxt){me.runclientscript('setup',me.doctype,me.docname);me.refresh();}
-if(me.doc.__islocal){$c('webnotes.widgets.form.load.getdoctype',{'doctype':me.doctype},ret_fn,null,null,'Refreshing '+me.doctype+'...');}else{var gl=me.grids;for(var i=0;i<gl.length;i++){var dt=gl[i].df.options;for(var dn in locals[dt]){if(locals[dt][dn].__islocal&&locals[dt][dn].parent==me.docname){var d=locals[dt][dn];d.parent='';d.docstatus=2;d.__deleted=1;}}}
-$c('webnotes.widgets.form.load.getdoc',{'name':me.docname,'doctype':me.doctype,'getdoctype':1,'user':user},ret_fn,null,null,'Refreshing '+me.docname+'...');}}
+if(me.doc.__islocal){$c('webnotes.widgets.form.load.getdoctype',{'doctype':me.doctype},ret_fn,null,null,'Refreshing '+me.doctype+'...');}else{$c('webnotes.widgets.form.load.getdoc',{'name':me.docname,'doctype':me.doctype,'getdoctype':1,'user':user},ret_fn,null,null,'Refreshing '+me.docname+'...');}}
_f.Frm.prototype.savedoc=function(save_action,onsave,onerr){this.error_in_section=0;save_doclist(this.doctype,this.docname,save_action,onsave,onerr);}
_f.Frm.prototype.saveupdate=function(){this.save('Update');}
_f.Frm.prototype.savesubmit=function(){var answer=confirm("Permanently Submit "+this.docname+"?");var me=this;if(answer){this.save('Submit',function(r){if(!r.exc&&me.cscript.on_submit){me.runclientscript('on_submit',me.doctype,me.docname);}});}}
_f.Frm.prototype.savecancel=function(){var answer=confirm("Permanently Cancel "+this.docname+"?");if(answer)this.save('Cancel');}
-_f.Frm.prototype.savetrash=function(){var me=this;var answer=confirm("Permanently Delete "+this.docname+"? This action cannot be reversed");if(answer){$c('webnotes.model.delete_doc',{dt:this.doctype,dn:this.docname},function(r,rt){if(r.message=='okay'){LocalDB.delete_doc(me.doctype,me.docname);if(wn.ui.toolbar.recent)wn.ui.toolbar.recent.remove(me.doctype,me.docname);window.back();}})}}
+_f.Frm.prototype.savetrash=function(){var me=this;var answer=confirm("Permanently Delete "+this.docname+"? This action cannot be reversed");if(answer){$c('webnotes.model.delete_doc',{dt:this.doctype,dn:this.docname},function(r,rt){if(r.message=='okay'){LocalDB.delete_doc(me.doctype,me.docname);if(wn.ui.toolbar.recent)wn.ui.toolbar.recent.remove(me.doctype,me.docname);window.history.back();}})}}
_f.Frm.prototype.amend_doc=function(){if(!this.fields_dict['amended_from']){alert('"amended_from" field must be present to do an amendment.');return;}
var me=this;var fn=function(newdoc){newdoc.amended_from=me.docname;if(me.fields_dict&&me.fields_dict['amendment_date'])
newdoc.amendment_date=dateutil.obj_to_str(new Date());}
@@ -1859,18 +1853,24 @@
if(frm&&frm==cur_frm&&frm.frm_head&&!prev_unsaved){frm.frm_head.refresh_labels();}}}
_f.Frm.prototype.show_comments=function(){if(!cur_frm.comments){cur_frm.comments=new Dialog(540,400,'Comments');cur_frm.comments.comment_body=$a(cur_frm.comments.body,'div','dialog_frm');$y(cur_frm.comments.body,{backgroundColor:'#EEE'});cur_frm.comments.list=new CommentList(cur_frm.comments.comment_body);}
cur_frm.comments.list.dt=cur_frm.doctype;cur_frm.comments.list.dn=cur_frm.docname;cur_frm.comments.show();cur_frm.comments.list.run();}
+_f.Frm.prototype.get_doc=function(){return locals[this.doctype][this.docname];}
+_f.Frm.prototype.get_doclist=function(){return make_doclist(this.doctype,this.docname);}
+_f.Frm.prototype.toggle_fields=function(fields,show){if(show){unhide_field(fields)}
+else{hide_field(fields)}}
+_f.Frm.prototype.enable_fields=function(fields,enable){if(typeof fields=='string')fields=[fields];$.each(fields,function(i,f){var field=cur_frm.fields_dict[f];if(field){field.disabled=enable?false:true;field.refresh&&field.refresh();};})}
+_f.Frm.prototype.call_server=function(method,args,callback){$c_obj(cur_frm.get_doclist(),method,args,callback);}
+_f.Frm.prototype.set_value=function(field,value){cur_frm.get_doc()[field]=value;cur_frm.fields_dict[field].refresh();}
/*
* lib/js/legacy/widgets/form/form_fields.js
*/
_f.ColumnBreak=function(){this.set_input=function(){};}
-_f.ColumnBreak.prototype.make_body=function(){if((!this.perm[this.df.permlevel])||(!this.perm[this.df.permlevel][READ])||this.df.hidden){return;}
-this.cell=this.frm.layout.addcell(this.df.width);$y(this.cell.wrapper,{padding:'8px'});_f.cur_col_break_width=this.df.width;var fn=this.df.fieldname?this.df.fieldname:this.df.label;if(this.df&&this.df.label){this.label=$a(this.cell.wrapper,'div','','',this.df.label);}}
-_f.ColumnBreak.prototype.refresh=function(layout){if(!this.cell)return;if(this.set_hidden!=this.df.hidden){if(this.df.hidden)
+_f.ColumnBreak.prototype.make_body=function(){this.cell=this.frm.layout.addcell(this.df.width);$y(this.cell.wrapper,{padding:'8px'});_f.cur_col_break_width=this.df.width;var fn=this.df.fieldname?this.df.fieldname:this.df.label;if(this.df&&this.df.label){this.label=$a(this.cell.wrapper,'h4','','',this.df.label);}}
+_f.ColumnBreak.prototype.refresh=function(layout){var hidden=0;if((!this.perm[this.df.permlevel])||(!this.perm[this.df.permlevel][READ])||this.df.hidden){hidden=1;}
+if(this.set_hidden!=hidden){if(hidden)
this.cell.hide();else
-this.cell.show();this.set_hidden=this.df.hidden;}}
+this.cell.show();this.set_hidden=hidden;}}
_f.SectionBreak=function(){this.fields=[];this.set_input=function(){};this.make_row=function(){this.row=this.df.label?this.frm.layout.addrow():this.frm.layout.addsubrow();}}
-_f.SectionBreak.prototype.make_body=function(){var me=this;if((!this.perm[this.df.permlevel])||(!this.perm[this.df.permlevel][READ])||this.df.hidden){return;}
-this.make_row();if(this.df.label){if(!this.df.description)
+_f.SectionBreak.prototype.make_body=function(){var me=this;this.make_row();if(this.df.label){if(!this.df.description)
this.df.description='';$(this.row.main_head).html(repl('<div class="form-section-head">\
<h3 class="head">%(label)s</h3>\
<div class="help small" \
@@ -1886,7 +1886,8 @@
if(f.df.reqd&&!v){return true;}
if(f.df.fieldtype=='Table'){if(f.grid.get_children().length||f.df.reqd){return true;}}}
return false;}
-_f.SectionBreak.prototype.refresh=function(from_form){if(this.df.hidden){if(this.row)this.row.hide();}else{if(this.collapsible){}}}
+_f.SectionBreak.prototype.refresh=function(from_form){var hidden=0;if((!this.perm[this.df.permlevel])||(!this.perm[this.df.permlevel][READ])||this.df.hidden){hidden=1;}
+if(hidden){if(this.row)this.row.hide();}else{if(this.row)this.row.show();}}
_f.ImageField=function(){this.images={};}
_f.ImageField.prototype=new Field();_f.ImageField.prototype.onmake=function(){this.no_img=$a(this.wrapper,'div','no_img');this.no_img.innerHTML="No Image";$dh(this.no_img);}
_f.ImageField.prototype.get_image_src=function(doc){if(doc.file_list){file=doc.file_list.split(',');extn=file[0].split('.');extn=extn[extn.length-1].toLowerCase();var img_extn_list=['gif','jpg','bmp','jpeg','jp2','cgm','ief','jpm','jpx','png','tiff','jpe','tif'];if(in_list(img_extn_list,extn)){var src=wn.request.url+"?cmd=downloadfile&file_id="+file[1];}}else{var src="";}
@@ -1896,8 +1897,7 @@
$w(img,allow_width+'px');}else{$ds(this.no_img);}}
_f.ImageField.prototype.set_disp=function(val){}
_f.ImageField.prototype.set=function(val){}
-_f.TableField=function(){};_f.TableField.prototype=new Field();_f.TableField.prototype.with_label=0;_f.TableField.prototype.make_body=function(){if(this.perm[this.df.permlevel]&&this.perm[this.df.permlevel][READ]){if(this.df.description){this.desc_area=$a(this.parent,'div','help small','',this.df.description)}
-this.grid=new _f.FormGrid(this);if(this.frm)this.frm.grids[this.frm.grids.length]=this;this.grid.make_buttons();}}
+_f.TableField=function(){};_f.TableField.prototype=new Field();_f.TableField.prototype.with_label=0;_f.TableField.prototype.make_body=function(){if(this.perm[this.df.permlevel]&&this.perm[this.df.permlevel][READ]){this.grid=new _f.FormGrid(this);if(this.frm)this.frm.grids[this.frm.grids.length]=this;this.grid.make_buttons();if(this.df.description){this.desc_area=$a(this.parent,'div','help small',{marginBottom:'9px',marginTop:'0px'},this.df.description)}}}
_f.TableField.prototype.refresh=function(){if(!this.grid)return;var st=this.get_status();if(!this.df['default'])
this.df['default']='';this.grid.can_add_rows=false;this.grid.can_edit=false
if(st=='Write'){if(cur_frm.editable&&this.perm[this.df.permlevel]&&this.perm[this.df.permlevel][WRITE]){this.grid.can_edit=true;if(this.df['default'].toLowerCase()!='no toolbar')
@@ -1924,7 +1924,7 @@
_f.Grid.prototype.init=function(parent,row_height){var me=this;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();$(this.wrapper).bind('keydown',function(e){me.notify_keypress(e,e.which);})
$(cur_frm.wrapper).bind('render_complete',function(){me.set_ht();});}
-_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');this.tbar_tab=make_table(this.tbar_div,1,4,'100%',['25%','25%','25%','25%']);this.wrapper=$a(parent,'div','grid_wrapper');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%',['55%','45%']);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');this.tbar_tab=make_table(this.tbar_div,1,4,'100%',['25%','25%','25%','25%']);this.wrapper=$a(parent,'div','grid_wrapper round');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_edit&&this.field.df['default'].toLowerCase()!='no toolbar'){$ds(this.tbar_div);if(this.can_add_rows){$td(this.tbar_tab,0,0).style.display='table-cell';$td(this.tbar_tab,0,1).style.display='table-cell';}else{$td(this.tbar_tab,0,0).style.display='none';$td(this.tbar_tab,0,1).style.display='none';}}else{$dh(this.tbar_div);}
$ds(this.wrapper);}
_f.Grid.prototype.hide=function(){$dh(this.wrapper);$dh(this.tbar_div);}
@@ -1942,13 +1942,13 @@
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;}
_f.Grid.prototype.refresh_cell=function(docname,fieldname){for(var r=0;r<this.tab.rows.length;r++){if(this.tab.rows[r].docname==docname){for(var c=0;c<this.head_row.cells.length;c++){var hc=this.head_row.cells[c];if(hc.fieldname==fieldname){this.set_cell_value(this.tab.rows[r].cells[c]);}}}}}
-_f.cur_grid;_f.cur_grid_ridx;_f.Grid.prototype.set_cell_value=function(cell){if(cell.row.is_newrow)return;var hc=this.head_row.cells[cell.cellIndex];if(hc.fieldname){var v=locals[hc.doctype][cell.row.docname][hc.fieldname];}else{var v=(cell.row.rowIndex+1);}
+_f.cur_grid;_f.cur_grid_ridx;_f.Grid.prototype.set_cell_value=function(cell){if(cell.row.is_newrow)return;var hc=this.head_row.cells[cell.cellIndex];if(hc.fieldname&&locals[hc.doctype][cell.row.docname]){var v=locals[hc.doctype][cell.row.docname][hc.fieldname];}else{var v=(cell.row.rowIndex+1);}
if(v==null){v='';}
var me=this;if(cell.cellIndex){var ft=hc.fieldtype;if(ft=='Link'&&cur_frm.doc.docstatus<1)ft='Data';$s(cell.div,v,ft,hc.options);}else{cell.div.style.padding='2px';cell.div.style.textAlign='left';cell.innerHTML='';var t=make_table(cell,1,3,'60px',['20px','20px','20px'],{verticalAlign:'middle',padding:'2px'});$y($td(t,0,0),{paddingLeft:'4px'});$td(t,0,0).innerHTML=cell.row.rowIndex+1;if(cur_frm.editable&&this.can_edit){var ed=$a($td(t,0,1),'i','icon-edit',{cursor:'pointer'});ed.cell=cell;ed.title='Edit Row';ed.onclick=function(){_f.cur_grid=me;_f.cur_grid_ridx=this.cell.row.rowIndex;_f.edit_record(me.doctype,this.cell.row.docname,1);}}else{cell.div.innerHTML=(cell.row.rowIndex+1);cell.div.style.cursor='default';cell.div.onclick=function(){}}}}
$(document).bind('click',function(e){var me=this;var is_target_toolbar=function(){return $(e.target).parents('.grid_tbarlinks').length;}
var is_target_input=function(){if(e.target.tagName.toLowerCase()=='option')return true;return $(e.target).parents().get().indexOf(_f.cur_grid_cell)!=-1;}
if(_f.cur_grid_cell&&!is_target_input()&&!is_target_toolbar()){if(!(text_dialog&&text_dialog.display)&&!datepicker_active&&!(selector&&selector.display)){setTimeout('_f.cur_grid_cell.grid.cell_deselect()',500);return false;}}});_f.Grid.prototype.cell_deselect=function(){if(_f.cur_grid_cell){var c=_f.cur_grid_cell;c.grid.remove_template(c);c.div.className='grid_cell_div';if(c.is_odd)c.div.style.border='2px solid '+c.grid.alt_row_bg;else c.div.style.border='2px solid #FFF';_f.cur_grid_cell=null;}}
-_f.Grid.prototype.cell_select=function(cell,ri,ci){if(_f.cur_grid_cell==cell&&cell.hc)return;if(ri!=null&&ci!=null)
+_f.Grid.prototype.cell_select=function(cell,ri,ci){if(cell&&_f.cur_grid_cell==cell&&cell.hc)return;if(ri!=null&&ci!=null)
cell=this.tab.rows[ri].cells[ci];var hc=this.head_row.cells[cell.cellIndex];if(!hc.template){this.make_template(hc);}
hc.template.perm=this.field?this.field.perm:hc.perm;if(hc.fieldname&&hc.template.get_status()=='Write'){this.cell_deselect();cell.div.style.border='2px solid #88F';_f.cur_grid_cell=cell;this.add_template(cell);}}
_f.Grid.prototype.add_template=function(cell){if(!cell.row.docname&&this.add_newrow){this.add_newrow();this.cell_select(cell);}else{var hc=this.head_row.cells[cell.cellIndex];cell.div.innerHTML='';cell.div.appendChild(hc.template.wrapper);hc.template.activate(cell.row.docname);hc.template.activated=1;cell.hc=hc;if(hc.template.input&&hc.template.input.set_width){hc.template.input.set_width($(cell).width());}}}
@@ -1979,11 +1979,11 @@
_f.FormGrid=function(field){this.field=field;this.doctype=field.df.options;if(!this.doctype){show_alert('No Options for table '+field.df.label);}
this.col_break_width=cint(this.field.col_break_width);if(!this.col_break_width)this.col_break_width=100;$y(field.parent,{marginTop:'8px'});this.init(field.parent,field.df.width);this.setup();}
_f.FormGrid.prototype=new _f.Grid();_f.FormGrid.prototype.setup=function(){this.make_columns();}
+_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();},'icon-remove-sign');this.tbar_btns['Ins']=this.make_tbar_link($td(this.tbar_tab,0,1),'Ins',function(){me.insert_row();},'icon-plus');this.tbar_btns['Up']=this.make_tbar_link($td(this.tbar_tab,0,2),'Up',function(){me.move_row(true);},'icon-arrow-up');this.tbar_btns['Dn']=this.make_tbar_link($td(this.tbar_tab,0,3),'Dn',function(){me.move_row(false);},'icon-arrow-down');for(var i in this.btns)
+this.btns[i].isactive=true;}
_f.FormGrid.prototype.make_tbar_link=function(parent,label,fn,icon){var div=$a(parent,'div','',{cursor:'pointer'});var t=make_table(div,1,2,'90%',['20px',null]);var img=$a($td(t,0,0),'i',icon);$y($td(t,0,0),{textAlign:'right'});var l=$a($td(t,0,1),'span','link_type',{color:'#333'});l.style.fontSize='11px';l.innerHTML=label;div.onclick=fn;div.show=function(){$ds(this);}
div.hide=function(){$dh(this);}
$td(t,0,0).isactive=1;$td(t,0,1).isactive=1;l.isactive=1;div.isactive=1;img.isactive=1;return div;}
-_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();},'icon-remove-sign');this.tbar_btns['Ins']=this.make_tbar_link($td(this.tbar_tab,0,1),'Ins',function(){me.insert_row();},'icon-plus');this.tbar_btns['Up']=this.make_tbar_link($td(this.tbar_tab,0,2),'Up',function(){me.move_row(true);},'icon-arrow-up');this.tbar_btns['Dn']=this.make_tbar_link($td(this.tbar_tab,0,3),'Dn',function(){me.move_row(false);},'icon-arrow-down');for(var i in this.btns)
-this.btns[i].isactive=true;}
_f.FormGrid.prototype.make_columns=function(){var gl=wn.meta.docfield_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]){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;}}}
@@ -2004,7 +2004,7 @@
_f.FormGrid.prototype.check_selected=function(){if(!_f.cur_grid_cell){show_alert('Select a cell first');return false;}
if(_f.cur_grid_cell.grid!=this){show_alert('Select a cell first');return false;}
return true;}
-_f.FormGrid.prototype.delete_row=function(dt,dn){if(dt&&dn){LocalDB.delete_record(dt,dn);this.refresh();}else{if(!this.check_selected())return;var r=_f.cur_grid_cell.row;if(r.is_newrow)return;var ci=_f.cur_grid_cell.cellIndex;var ri=_f.cur_grid_cell.row.rowIndex;LocalDB.delete_record(this.doctype,r.docname);this.refresh();if(ri<(this.tab.rows.length-2))
+_f.FormGrid.prototype.delete_row=function(dt,dn){if(dt&&dn){LocalDB.delete_record(dt,dn);this.refresh();}else{if(!this.check_selected())return;var r=_f.cur_grid_cell.row;if(r.is_newrow)return;var ci=_f.cur_grid_cell.cellIndex;var ri=_f.cur_grid_cell.row.rowIndex;LocalDB.delete_record(this.doctype,r.docname);this.refresh();if(ri<(this.tab.rows.length-1))
this.cell_select(null,ri,ci);else _f.cur_grid_cell=null;}
this.set_unsaved();}
_f.FormGrid.prototype.move_row=function(up){if(!this.check_selected())return;var r=_f.cur_grid_cell.row;if(r.is_newrow)return;if(up&&r.rowIndex>0){var swap_row=this.tab.rows[r.rowIndex-1];}else if(!up){var len=this.tab.rows.length;if(this.tab.rows[len-1].is_newrow)
@@ -2077,13 +2077,15 @@
font-size: 14px; \
font-weight: bold; \
margin: 8px 0px; \
- }",print_std:function(no_letterhead){var docname=cur_frm.docname;var doctype=cur_frm.doctype;var data=getchildren('DocField',doctype,'fields','DocType');var layout=_p.add_layout(doctype);this.pf_list=[layout];var me=this;me.layout=layout;$.extend(this,{build_head:function(doctype,docname){var h1_style={fontSize:'22px',marginBottom:'8px'}
-var h1=$a(me.layout.cur_row.header,'h1','',h1_style);h1.innerHTML=cur_frm.pformat[docname]?cur_frm.pformat[docname]:get_doctype_label(doctype);var h2_style={fontSize:'16px',color:'#888',marginBottom:'8px',paddingBottom:'8px',borderBottom:(me.layout.with_border?'0px':'1px solid #000')}
+ }",print_std:function(no_letterhead){var docname=cur_frm.docname;var doctype=cur_frm.doctype;var data=getchildren('DocField',doctype,'fields','DocType');var layout=_p.add_layout(doctype);this.pf_list=[layout];var me=this;me.layout=layout;$.extend(this,{build_head:function(data,doctype,docname){var h1_style={fontSize:'22px',marginBottom:'8px'}
+var h1=$a(me.layout.cur_row.header,'h1','',h1_style);if(cur_frm.pformat[docname]){h1.innerHTML=cur_frm.pformat[docname];}else{var val=null;for(var i=0;i<data.length;i++){if(data[i].fieldname==='select_print_heading'){val=_f.get_value(doctype,docname,data[i].fieldname);break;}}
+h1.innerHTML=val?val:get_doctype_label(doctype);}
+var h2_style={fontSize:'16px',color:'#888',marginBottom:'8px',paddingBottom:'8px',borderBottom:(me.layout.with_border?'0px':'1px solid #000')}
var h2=$a(me.layout.cur_row.header,'div','',h2_style);h2.innerHTML=docname;},build_data:function(data,doctype,docname){if(data[0]&&data[0].fieldtype!="Section Break"){me.layout.addrow();if(data[0].fieldtype!="Column Break"){me.layout.addcell();}}
$.extend(this,{generate_custom_html:function(field,doctype,docname){var container=$a(me.layout.cur_cell,'div');container.innerHTML=cur_frm.pformat[field.fieldname](locals[doctype][docname]);},render_normal:function(field,data,i){switch(field.fieldtype){case'Section Break':me.layout.addrow();if(data[i+1]&&data[i+1].fieldtype!='Column Break'){me.layout.addcell();}
break;case'Column Break':me.layout.addcell(field.width,field.label);break;case'Table':var table=print_table(doctype,docname,field.fieldname,field.options,null,null,null,null);me.layout=_p.print_std_add_table(table,me.layout,me.pf_list,doctype,no_letterhead);break;case'HTML':var div=$a(me.layout.cur_cell,'div');div.innerHTML=field.options;break;case'Code':var div=$a(me.layout.cur_cell,'div');var val=_f.get_value(doctype,docname,field.fieldname);div.innerHTML='<div>'+field.label+': </div><pre style="font-family: Courier, Fixed;">'+(val?val:'')+'</pre>';break;case'Text Editor':var div=$a(me.layout.cur_cell,'div');var val=_f.get_value(doctype,docname,field.fieldname);div.innerHTML=val?val:'';break;default:_p.print_std_add_field(doctype,docname,field,me.layout);break;}}});for(var i=0;i<data.length;i++){var fieldname=data[i].fieldname?data[i].fieldname:data[i].label;var field=fieldname?get_field(doctype,fieldname,docname):data[i];if(!field.print_hide){if(cur_frm.pformat[field.fieldname]){this.generate_custom_html(field,doctype,docname);}else{this.render_normal(field,data,i);}}}
me.layout.close_borders();},build_html:function(){var html='';for(var i=0;i<me.pf_list.length;i++){if(me.pf_list[i].wrapper){html+=me.pf_list[i].wrapper.innerHTML;}else if(me.pf_list[i].innerHTML){html+=me.pf_list[i].innerHTML;}else{html+=me.pf_list[i];}}
-this.pf_list=[];return html;}});this.build_head(doctype,docname);this.build_data(data,doctype,docname);var html=this.build_html();return html;},add_layout:function(doctype){var layout=new Layout();layout.addrow();if(locals['DocType'][doctype].print_outline=='Yes'){layout.with_border=1}
+this.pf_list=[];return html;}});this.build_head(data,doctype,docname);this.build_data(data,doctype,docname);var html=this.build_html();return html;},add_layout:function(doctype){var layout=new Layout();layout.addrow();if(locals['DocType'][doctype].print_outline=='Yes'){layout.with_border=1}
return layout;},print_std_add_table:function(t,layout,pf_list,dt,no_letterhead){if(t.appendChild){layout.cur_cell.appendChild(t);}else{page_break='\n\
<div style = "page-break-after: always;" \
class = "page_break"></div><div class="page-settings"></div>';for(var i=0;i<t.length-1;i++){layout.cur_cell.appendChild(t[i]);layout.close_borders();pf_list.push(page_break);layout=_p.add_layout(dt,no_letterhead);pf_list.push(layout);layout.addrow();layout.addcell();var div=$a(layout.cur_cell,'div');div.innerHTML='Continued from previous page...';div.style.padding='4px';}
@@ -2126,7 +2128,7 @@
refresh_field(fl[i],dn,args.table_field);else
refresh_field(fl[i]);}}
$c('webnotes.widgets.form.utils.get_fields',args,call_back);}
-get_server_fields=function(method,arg,table_field,doc,dt,dn,allow_edit,call_back){if(!allow_edit)freeze('Fetching Data...');$c('runserverobj',args={'method':method,'docs':compress_doclist([doc]),'arg':arg},function(r,rt){if(r.message){var d=locals[dt][dn];var field_dict=r.message;for(var key in field_dict){d[key]=field_dict[key];if(table_field)refresh_field(key,d.name,table_field);else refresh_field(key);}}
+get_server_fields=function(method,arg,table_field,doc,dt,dn,allow_edit,call_back){if(!allow_edit)freeze('Fetching Data...');$c('runserverobj',args={'method':method,'docs':compress_doclist(make_doclist(doc.doctype,doc.name)),'arg':arg},function(r,rt){if(r.message){var d=locals[dt][dn];var field_dict=r.message;for(var key in field_dict){d[key]=field_dict[key];if(table_field)refresh_field(key,d.name,table_field);else refresh_field(key);}}
if(call_back){doc=locals[doc.doctype][doc.name];call_back(doc,dt,dn);}
if(!allow_edit)unfreeze();});}
set_multiple=function(dt,dn,dict,table_field){var d=locals[dt][dn];for(var key in dict){d[key]=dict[key];if(table_field)refresh_field(key,d.name,table_field);else refresh_field(key);}}
@@ -2141,10 +2143,10 @@
set_field_permlevel=function(n,level){var df=get_field(cur_frm.doctype,n,cur_frm.docname);if(df)df.permlevel=level;refresh_field(n);}
hide_field=function(n){function _hide_field(n,hidden){var df=get_field(cur_frm.doctype,n,cur_frm.docname);if(df){df.hidden=hidden;refresh_field(n);}
else{console.log("hide_field cannot find field "+n);}}
-if(cur_frm){if(n.substr)_hide_field(n,1);else{for(var i in n)_hide_field(n[i],1)}}}
+if(cur_frm){if(typeof n=='string')_hide_field(n,1);else{for(var i in n)_hide_field(n[i],1)}}}
unhide_field=function(n){function _hide_field(n,hidden){var df=get_field(cur_frm.doctype,n,cur_frm.docname);if(df){df.hidden=hidden;refresh_field(n);}
else{console.log("unhide_field cannot find field "+n);}}
-if(cur_frm){if(n.substr)_hide_field(n,0);else{for(var i in n)_hide_field(n[i],0)}}}
+if(cur_frm){if(typeof n=='string')_hide_field(n,0);else{for(var i in n)_hide_field(n[i],0)}}}
get_field_obj=function(fn){return cur_frm.fields_dict[fn];}
/*
* lib/js/legacy/widgets/form/form_comments.js
@@ -2177,14 +2179,13 @@
/*
* lib/js/legacy/wn/widgets/form/sidebar.js
*/
-wn.widgets.form.sidebar={Sidebar:function(form){var me=this;this.form=form;this.opts={sections:[{title:'Actions',items:[{type:'link',label:'New',icon:'icon-plus',display:function(){return in_list(profile.can_create,form.doctype)},onclick:function(){new_doc(me.form.doctype)}},{type:'link',label:'List',icon:'icon-list',display:function(){return!me.form.meta.issingle;},onclick:function(){window.location.href="#!List/"+me.form.doctype}},{type:'link',label:'Refresh',icon:'icon-refresh',onclick:function(){me.form.reload_doc()}},{type:'link',label:'Print',display:function(){return!(me.form.doc.__islocal||me.form.meta.allow_print);},icon:'icon-print',onclick:function(){me.form.print_doc()}},{type:'link',label:'Email',display:function(){return!(me.form.doc.__islocal||me.form.meta.allow_email);},icon:'icon-envelope',onclick:function(){me.form.email_doc()}},{type:'link',label:'Copy',display:function(){return in_list(profile.can_create,me.form.doctype)&&!me.form.meta.allow_copy},icon:'icon-file',onclick:function(){me.form.copy_doc()}},{type:'link',label:'Delete',display:function(){return me.form.meta.allow_trash&&cint(me.form.doc.docstatus)!=2&&(!me.form.doc.__islocal)&&me.form.perm[0][CANCEL]},icon:'icon-remove-sign',onclick:function(){me.form.savetrash()}}]},{title:'Assign To',render:function(wrapper){me.form.assign_to=new wn.widgets.form.sidebar.AssignTo(wrapper,me,me.form.doctype,me.form.docname);},display:function(){if(me.form.doc.__local)return false;else return true;}},{title:'Attachments',render:function(wrapper){me.form.attachments=new wn.widgets.form.sidebar.Attachments(wrapper,me,me.form.doctype,me.form.docname);},display:function(){return me.form.meta.allow_attach}},{title:'Comments',render:function(wrapper){new wn.widgets.form.sidebar.Comments(wrapper,me,me.form.doctype,me.form.docname);},display:function(){return!me.form.doc.__islocal}},{title:'Tags',render:function(wrapper){me.form.taglist=new TagList(wrapper,me.form.doc._user_tags?me.form.doc._user_tags.split(','):[],me.form.doctype,me.form.docname,0,function(){});},display:function(){return!me.form.doc.__islocal}},{title:'Users',render:function(wrapper){var doc=cur_frm.doc;var scrub_date=function(d){if(d)t=d.split(' ');else return'';return dateutil.str_to_user(t[0])+' '+t[1];}
+wn.widgets.form.sidebar={Sidebar:function(form){var me=this;this.form=form;this.opts={sections:[{title:'Actions',items:[{type:'link',label:'New',icon:'icon-plus',display:function(){return in_list(profile.can_create,form.doctype)},onclick:function(){new_doc(me.form.doctype)}},{type:'link',label:'List',icon:'icon-list',display:function(){return!me.form.meta.issingle&&!me.form.meta.read_only;},onclick:function(){window.location.href="#!List/"+me.form.doctype}},{type:'link',label:'Refresh',icon:'icon-refresh',onclick:function(){me.form.reload_doc()}},{type:'link',label:'Print',display:function(){return!(me.form.doc.__islocal||me.form.meta.allow_print);},icon:'icon-print',onclick:function(){me.form.print_doc()}},{type:'link',label:'Email',display:function(){return!(me.form.doc.__islocal||me.form.meta.allow_email);},icon:'icon-envelope',onclick:function(){me.form.email_doc()}},{type:'link',label:'Copy',display:function(){return in_list(profile.can_create,me.form.doctype)&&!me.form.meta.allow_copy},icon:'icon-file',onclick:function(){me.form.copy_doc()}},{type:'link',label:'Delete',display:function(){return(cint(me.form.doc.docstatus)!=1)&&!me.form.doc.__islocal&&wn.model.can_delete(me.form.doctype);},icon:'icon-remove-sign',onclick:function(){me.form.savetrash()}}],display:function(){return me.form.meta.hide_toolbar?false:true;}},{title:'Assign To',render:function(wrapper){me.form.assign_to=new wn.widgets.form.sidebar.AssignTo(wrapper,me,me.form.doctype,me.form.docname);},display:function(){if(me.form.doc.__local)return false;else return true;}},{title:'Attachments',render:function(wrapper){me.form.attachments=new wn.widgets.form.sidebar.Attachments(wrapper,me,me.form.doctype,me.form.docname);},display:function(){return me.form.meta.allow_attach}},{title:'Comments',render:function(wrapper){new wn.widgets.form.sidebar.Comments(wrapper,me,me.form.doctype,me.form.docname);},display:function(){return!me.form.doc.__islocal}},{title:'Tags',render:function(wrapper){me.form.taglist=new TagList(wrapper,me.form.doc._user_tags?me.form.doc._user_tags.split(','):[],me.form.doctype,me.form.docname,0,function(){});},display:function(){return!me.form.doc.__islocal}},{title:'Users',render:function(wrapper){var doc=cur_frm.doc;var scrub_date=function(d){if(d)t=d.split(' ');else return'';return dateutil.str_to_user(t[0])+' '+t[1];}
$(wrapper).html(repl('<p>Created:<br> <span class="avatar-small">\
<img title="%(created_by)s" src="%(avatar_created)s" /></span> \
<span class="help small">%(creation)s</span></p>\
<p>Modified:<br> <span class="avatar-small">\
<img title="%(modified_by)s" src="%(avatar_modified)s" /></span> \
- <span class="help small">%(modified)s</span></p>',{created_by:wn.user_info(doc.owner).fullname,avatar_created:wn.user_info(doc.owner).image,creation:scrub_date(doc.creation),modified_by:wn.user_info(doc.modified_by).fullname,avatar_modified:wn.user_info(doc.modified_by).image,modified:scrub_date(doc.modified)}));},display:function(){return!me.form.doc.__islocal}},{title:'Help',render:function(wrapper){$(wrapper).html('<div class="help small">'
-+wn.markdown(me.form.meta.description)+'</div>')},display:function(){return me.form.meta.description}}]}
+ <span class="help small">%(modified)s</span></p>',{created_by:wn.user_info(doc.owner).fullname,avatar_created:wn.user_info(doc.owner).image,creation:scrub_date(doc.creation),modified_by:wn.user_info(doc.modified_by).fullname,avatar_modified:wn.user_info(doc.modified_by).image,modified:scrub_date(doc.modified)}));},display:function(){return!me.form.doc.__islocal}}]}
this.refresh=function(){var parent=this.form.page_layout.sidebar_area;if(!this.sidebar){this.sidebar=new wn.widgets.PageSidebar(parent,this.opts);}else{this.sidebar.refresh();}}}}
/*
* lib/js/legacy/wn/widgets/form/comments.js
@@ -2215,7 +2216,7 @@
wn.widgets.form.sidebar.Attachment=function(parent,filedet,frm){filedet=filedet.split(',')
this.filename=filedet[0];this.fileid=filedet[1];this.frm=frm;var me=this;this.wrapper=$a(parent,'div','sidebar-comment-message');this.remove_fileid=function(){var doc=locals[me.frm.doctype][me.frm.docname];var fl=doc.file_list.split('\n');new_fl=[];for(var i=0;i<fl.length;i++){if(fl[i].split(',')[1]!=me.fileid)new_fl.push(fl[i]);}
doc.file_list=new_fl.join('\n');}
-var display_name=this.fileid;if(this.fileid.substr(0,8)=='FileData')
+var display_name=this.fileid;if(this.fileid&&this.fileid.substr(0,8)=='FileData')
display_name=this.filename;this.ln=$a(this.wrapper,'a','link_type small',{},display_name);this.ln.href='files/'+this.fileid;this.ln.target='_blank';this.del=$a(this.wrapper,'span','close','','×');this.del.onclick=function(){var yn=confirm("Are you sure you want to delete the attachment?")
if(yn){var callback=function(r,rt){locals[me.frm.doctype][me.frm.docname].modified=r.message;$dh(me.wrapper);me.remove_fileid();frm.refresh();}
$c('webnotes.widgets.form.utils.remove_attach',args={'fid':me.fileid,dt:me.frm.doctype,dn:me.frm.docname},callback);}}}
diff --git a/public/js/all-web.js b/public/js/all-web.js
index 7d1a690..9142b96 100644
--- a/public/js/all-web.js
+++ b/public/js/all-web.js
@@ -89,7 +89,7 @@
* lib/js/wn/misc/tools.js
*/
wn.markdown=function(txt){if(!wn.md2html){wn.require('js/lib/showdown.js');wn.md2html=new Showdown.converter();}
-return wn.md2html.makeHtml(txt);}
+return'<div class="markdown">'+wn.md2html.makeHtml(txt)+'</div>';}
/*
* lib/js/wn/misc/user.js
*/
@@ -136,7 +136,7 @@
* lib/js/wn/router.js
*/
wn.re_route={}
-wn.route=function(){if(wn.re_route[window.location.hash]){window.location.hash=wn.re_route[window.location.hash];}
+wn.route=function(){if(wn.re_route[window.location.hash]){var re_route_val=wn.get_route_str(wn.re_route[window.location.hash]);var cur_route_val=wn.get_route_str(wn._cur_route);if(decodeURIComponent(re_route_val)===decodeURIComponent(cur_route_val)){window.history.back();return;}else{window.location.hash=wn.re_route[window.location.hash];}}
wn._cur_route=window.location.hash;route=wn.get_route();switch(route[0]){case"List":wn.views.doclistview.show(route[1]);break;case"Form":if(route.length>3){route[2]=route.splice(2).join('/');}
wn.views.formview.show(route[1],route[2]);break;case"Report":wn.views.reportview.show(route[1],route[2]);break;case"Report2":wn.views.reportview2.show();break;default:wn.views.pageview.show(route[0]);}}
wn.get_route=function(route){return $.map(wn.get_route_str(route).split('/'),function(r){return decodeURIComponent(r);});}
@@ -236,7 +236,8 @@
if(df.fieldtype=='Check'){df.fieldtype='Select';df.options='No\nYes';}else if(['Text','Text Editor','Code','Link'].indexOf(df.fieldtype)!=-1){df.fieldtype='Data';}},set_default_condition:function(df,fieldtype){if(!fieldtype){if(df.fieldtype=='Data'){this.$w.find('.condition').val('like');}else{this.$w.find('.condition').val('=');}}},get_value:function(){var me=this;var val=me.field.get_value();var cond=me.$w.find('.condition').val();if(me.field.df.original_type=='Check'){val=(val=='Yes'?1:0);}
if(cond=='like'){val=val+'%';}
return[me.fieldselect.$select.find('option:selected').attr('table'),me.field.df.fieldname,me.$w.find('.condition').val(),cstr(val)];}});wn.ui.FieldSelect=Class.extend({init:function(parent,doctype,filter_fields,with_blank){this.doctype=doctype;this.fields_by_name={};this.with_blank=with_blank;this.$select=$('<select>').appendTo(parent);if(filter_fields){for(var i in filter_fields)
-this.add_field_option(this.filter_fields[i])}else{this.build_options();}},build_options:function(){var me=this;me.table_fields=[];var std_filters=[{fieldname:'name',fieldtype:'Data',label:'ID',parent:me.doctype},{fieldname:'modified',fieldtype:'Date',label:'Last Modified',parent:me.doctype},{fieldname:'owner',fieldtype:'Data',label:'Created By',parent:me.doctype},{fieldname:'creation',fieldtype:'Date',label:'Created On',parent:me.doctype},{fieldname:'_user_tags',fieldtype:'Data',label:'Tags',parent:me.doctype}];if(this.with_blank){this.$select.append($('<option>',{value:''}).text(''));}
+this.add_field_option(this.filter_fields[i])}else{this.build_options();}},build_options:function(){var me=this;me.table_fields=[];var std_filters=[{fieldname:'name',fieldtype:'Data',label:'ID',parent:me.doctype},{fieldname:'modified',fieldtype:'Date',label:'Last Modified',parent:me.doctype},{fieldname:'owner',fieldtype:'Data',label:'Created By',parent:me.doctype},{fieldname:'creation',fieldtype:'Date',label:'Created On',parent:me.doctype},{fieldname:'_user_tags',fieldtype:'Data',label:'Tags',parent:me.doctype},{fieldname:'docstatus',fieldtype:'Int',label:'Doc Status',parent:me.doctype},];var doctype_obj=locals['DocType'][me.doctype];if(doctype_obj&&cint(doctype_obj.istable)){std_filters=std_filters.concat([{fieldname:'parent',fieldtype:'Data',label:'Parent',parent:me.doctype}]);}
+if(this.with_blank){this.$select.append($('<option>',{value:''}).text(''));}
$.each(std_filters.concat(wn.meta.docfield_list[me.doctype]),function(i,df){me.add_field_option(df);});$.each(me.table_fields,function(i,table_df){if(table_df.options){$.each(wn.meta.docfield_list[table_df.options],function(i,df){me.add_field_option(df);});}});},add_field_option:function(df){var me=this;if(me.doctype&&df.parent==me.doctype){var label=df.label;var table=me.doctype;if(df.fieldtype=='Table')me.table_fields.push(df);}else{var label=df.label+' ('+df.parent+')';var table=df.parent;}
if(wn.model.no_value_type.indexOf(df.fieldtype)==-1&&!me.fields_by_name[df.fieldname]){this.$select.append($('<option>',{value:df.fieldname,table:table}).text(label));me.fields_by_name[df.fieldname]=df;}}})
/*
@@ -248,7 +249,7 @@
var me=this;if(label.tagName){var page=label;}else{var page=wn.pages[label];}
if(!page){console.log('Page not found '+label);return;}
if(this.page){$(this.page).toggle(false);$(this.page).trigger('hide');}
-this.page=page;$(this.page).fadeIn();$(this.page).trigger('show');this.page._route=window.location.hash;document.title=this.page.label;scroll(0,0);return this.page;}});wn.views.add_module_btn=function(parent,module){$(parent).append(repl('<span class="label" style="margin-right: 8px; cursor: pointer;"\
+this.page=page;$(this.page).fadeIn();this.page._route=window.location.hash;document.title=this.page.label;$(this.page).trigger('show');scroll(0,0);return this.page;}});wn.views.add_module_btn=function(parent,module){$(parent).append(repl('<span class="label" style="margin-right: 8px; cursor: pointer;"\
onclick="wn.set_route(\'%(module_small)s-home\')">\
<i class="icon-home icon-white"></i> %(module)s Home\
</span>',{module:module,module_small:module.toLowerCase()}));}
@@ -281,9 +282,9 @@
return;}
if(r.server_messages)msgprint(r.server_messages)
if(r.exc){console.log(r.exc);};if(r['403']){wn.container.change_to('403');}
-if(r.docs)LocalDB.sync(r.docs);}
-wn.request.call=function(opts){wn.request.prepare(opts);$.ajax({url:opts.url||wn.request.url,data:opts.args,type:opts.type||'POST',dataType:opts.dataType||'json',success:function(r,xhr){wn.request.cleanup(opts,r);opts.success(r,xhr.responseText);},error:function(xhr,textStatus){wn.request.cleanup(opts,{});show_alert('Unable to complete request: '+textStatus)
-if(opts.error)opts.error(xhr)}})}
+if(r.docs){LocalDB.sync(r.docs);}}
+wn.request.call=function(opts){wn.request.prepare(opts);$.ajax({url:opts.url||wn.request.url,data:opts.args,type:opts.type||'POST',dataType:opts.dataType||'json',success:function(r,xhr){wn.request.cleanup(opts,r);opts.success&&opts.success(r,xhr.responseText);},error:function(xhr,textStatus){wn.request.cleanup(opts,{});show_alert('Unable to complete request: '+textStatus)
+opts.error&&opts.error(xhr)}})}
wn.call=function(opts){var args=$.extend({},opts.args)
if(opts.module&&opts.page){args.cmd=opts.module+'.page.'+opts.page+'.'+opts.page+'.'+opts.method}else if(opts.method){args.cmd=opts.method;}
for(key in args){if(args[key]&&typeof args[key]!='string'){args[key]=JSON.stringify(args[key]);}}
@@ -490,16 +491,12 @@
/*
* lib/js/legacy/utils/msgprint.js
*/
-var msg_dialog;function msgprint(msg,issmall,callback){if(!msg)return;if(typeof(msg)!='string')
-msg=JSON.stringify(msg);if(issmall){show_alert(msg);return;}
-if(msg.substr(0,8)=='__small:'){show_alert(msg.substr(8));return;}
-if(!msg_dialog){msg_dialog=new Dialog(500,200,"Message");msg_dialog.make_body([['HTML','Msg']])
-msg_dialog.onhide=function(){msg_dialog.msg_area.innerHTML='';$dh(msg_dialog.msg_icon);if(msg_dialog.custom_onhide)msg_dialog.custom_onhide();}
-$y(msg_dialog.rows['Msg'],{fontSize:'14px',lineHeight:'1.5em',padding:'16px'})
-var t=make_table(msg_dialog.rows['Msg'],1,2,'100%',['20px','250px'],{padding:'2px',verticalAlign:'Top'});msg_dialog.msg_area=$td(t,0,1);msg_dialog.msg_icon=$a($td(t,0,0),'img');}
-if(!msg_dialog.display)msg_dialog.show();var has_msg=msg_dialog.msg_area.innerHTML?1:0;var m=$a(msg_dialog.msg_area,'div','');if(has_msg)$y(m,{marginTop:'4px'});$dh(msg_dialog.msg_icon);if(msg.substr(0,6).toLowerCase()=='error:'){msg_dialog.msg_icon.src='images/lib/icons/error.gif';$di(msg_dialog.msg_icon);msg=msg.substr(6);}else if(msg.substr(0,8).toLowerCase()=='message:'){msg_dialog.msg_icon.src='images/lib/icons/application.gif';$di(msg_dialog.msg_icon);msg=msg.substr(8);}else if(msg.substr(0,3).toLowerCase()=='ok:'){msg_dialog.msg_icon.src='images/lib/icons/accept.gif';$di(msg_dialog.msg_icon);msg=msg.substr(3);}
-m.innerHTML=replace_newlines(msg);if(m.offsetHeight>200){$y(m,{height:'200px',width:'400px',overflow:'auto'})}
-msg_dialog.custom_onhide=callback;}
+var msg_dialog;function msgprint(msg,title){if(!msg)return;if(typeof(msg)!='string')
+msg=JSON.stringify(msg);if(msg.substr(0,8)=='__small:'){show_alert(msg.substr(8));return;}
+if(!msg_dialog){msg_dialog=new wn.ui.Dialog({title:"Message",onhide:function(){msg_dialog.msg_area.empty();}});msg_dialog.msg_area=$('<div class="msgprint">').appendTo(msg_dialog.body);}
+if(msg.search(/<br>|<p>|<li>/)==-1)
+msg=replace_newlines(msg);msg_dialog.set_title(title||'Message')
+msg_dialog.msg_area.append(msg);msg_dialog.show();}
var growl_area;function show_alert(txt,id){if(!growl_area){if(!$('#dialog-container').length){$('<div id="dialog-container">').appendTo('body');}
growl_area=$a($i('dialog-container'),'div','',{position:'fixed',bottom:'8px',right:'8px',width:'320px',zIndex:10});}
var wrapper=$a(growl_area,'div','',{position:'relative'});var body=$a(wrapper,'div','notice');var c=$a(body,'i','icon-remove-sign',{cssFloat:'right',cursor:'pointer'});$(c).click(function(){$dh(this.wrapper)});c.wrapper=wrapper;var t=$a(body,'div','',{color:'#FFF'});$(t).html(txt);if(id){$(t).attr('id',id);}
@@ -511,10 +508,14 @@
<span class="appframe-title"></span>\
<span class="close">×</span>\
</div>').appendTo(this.$w);this.$w.find('.close').click(function(){window.history.back();})
-if(title)this.title(title);},title:function(txt){this.$titlebar.find('.appframe-title').html(txt);},add_button:function(label,click,icon){if(!this.$w.find('.appframe-toolbar').length)
-this.$w.append('<div class="appframe-toolbar"></div>');args={label:label,icon:''};if(icon){args.icon='<i class="'+icon+'"></i>';}
+if(title)this.title(title);},title:function(txt){this.$titlebar.find('.appframe-title').html(txt);},make_toolbar:function(){if(!this.$w.find('.appframe-toolbar').length)
+this.$w.append('<div class="appframe-toolbar"></div>');},add_button:function(label,click,icon){this.make_toolbar();args={label:label,icon:''};if(icon){args.icon='<i class="icon '+icon+'"></i>';}
this.buttons[label]=$(repl('<button class="btn btn-small">\
- %(icon)s %(label)s</button>',args)).click(click).appendTo(this.$w.find('.appframe-toolbar'));return this.buttons[label];},clear_buttons:function(){this.$w.find('.appframe-toolbar').empty();}});wn.ui.make_app_page=function(opts){if(opts.single_column){$(opts.parent).html('<div class="layout-wrapper layout-wrapper-appframe">\
+ %(icon)s %(label)s</button>',args)).click(click).appendTo(this.$w.find('.appframe-toolbar'));return this.buttons[label];},add_help_button:function(txt){this.make_toolbar();$('<button class="btn btn-small" style="float:right;" button-type="help">\
+ <b>?</b></button>').data('help-text',txt).click(function(){msgprint($(this).data('help-text'),'Help');}).appendTo(this.$w.find('.appframe-toolbar'));},clear_buttons:function(){this.$w.find('.appframe-toolbar').empty();},add_breadcrumb:function(html){if(!this.$breadcrumbs)
+this.$breadcrumbs=$('</span>\
+ <span class="breadcrumb-area"></span>').appendTo(this.$titlebar);var crumb=$('<span>').html(html);if(!this.$breadcrumbs.find('span').length){crumb.addClass('appframe-title');}
+crumb.appendTo(this.$breadcrumbs);},clear_breadcrumbs:function(){this.$breadcrumbs&&this.$breadcrumbs.empty();}});wn.ui.make_app_page=function(opts){if(opts.single_column){$(opts.parent).html('<div class="layout-wrapper layout-wrapper-appframe">\
<div class="layout-appframe"></div>\
<div class="layout-main"></div>\
</div>');}else{$(opts.parent).html('<div class="layout-wrapper layout-wrapper-background">\
@@ -531,6 +532,7 @@
$y(this.body,{padding:'11px'});this.fields_dict={};for(var i=0;i<fl.length;i++){var df=fl[i];var div=$a(body,'div','',{margin:'6px 0px'})
f=make_field(df,null,div,null);f.not_in_form=1;this.fields_dict[df.fieldname]=f
f.refresh();if(df.fieldtype=='Button'&&!this.first_button){$(f.input).addClass('btn-info');this.first_button=true;}}}
+this.catch_enter_as_submit=function(){var me=this;$(this.body).find(':input[type="text"], :input[type="password"]').keypress(function(e){if(e.which==13){$(me.body).find('.btn-info:first').click();}})}
this.get_values=function(){var ret={};var errors=[];for(var key in this.fields_dict){var f=this.fields_dict[key];var v=f.get_value?f.get_value():null;if(f.df.reqd&&!v)
errors.push(f.df.label+' is mandatory');if(v)ret[f.df.fieldname]=v;}
if(errors.length){msgprint('<b>Please check the following Errors</b>\n'+errors.join('\n'));return null;}
@@ -538,19 +540,18 @@
this.set_value=function(key,val){var f=this.fields_dict[key];if(f){f.set_input(val);f.refresh_mandatory();}}
this.set_values=function(dict){for(var key in dict){if(this.fields_dict[key]){this.set_value(key,dict[key]);}}}
this.clear=function(){for(key in this.fields_dict){var f=this.fields_dict[key];if(f){f.set_input(f.df['default']||'');}}}}
-wn.widgets.Dialog=function(opts){this.opts=opts;this.display=false;this.make=function(opts){if(opts)
-this.opts=opts;if(!this.opts.width)this.opts.width=480;if(!$('#dialog-container').length){$('<div id="dialog-container">').appendTo('body');}
+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;if(!$('#dialog-container').length){$('<div id="dialog-container">').appendTo('body');}
this.wrapper=$('<div class="dialog_wrapper">').appendTo('#dialog-container').get(0);if(this.opts.width)
-this.wrapper.style.width=this.opts.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.wrapper.style.width=this.opts.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(){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.appframe.$titlebar.find('.appframe-title').html(t||'');}
this.set_postion=function(){this.wrapper.style.left=(($(window).width()-cint(this.wrapper.style.width))/2)+'px';this.wrapper.style.top=($(window).scrollTop()+60)+'px';top_index++;$y(this.wrapper,{zIndex:top_index});}
this.show=function(){if(this.display)return;this.set_postion()
-$ds(this.wrapper);freeze();this.display=true;cur_dialog=this;if(this.onshow)this.onshow();}
+$ds(this.wrapper);freeze();this.display=true;cur_dialog=this;if(this.onshow)this.onshow();$(this.wrapper).find(':input:first').focus();}
this.hide=function(){if(this.onhide)this.onhide();unfreeze();$dh(this.wrapper);this.display=false;cur_dialog=null;}
this.no_cancel=function(){this.appframe.$titlebar.find('.close').toggle(false);}
-if(opts)this.make();}
+if(opts)this.make(opts);}
wn.widgets.Dialog.prototype=new wn.widgets.FieldGroup();wn.provide('wn.ui');wn.ui.Dialog=wn.widgets.Dialog
$(document).bind('keydown',function(e){if(cur_dialog&&!cur_dialog.no_cancel_flag&&e.which==27){cur_dialog.hide();}});
/*
@@ -624,8 +625,10 @@
LocalDB.delete_doc=function(dt,dn){var doc=get_local(dt,dn);for(var ndt in locals){if(locals[ndt]){for(var ndn in locals[ndt]){var doc=locals[ndt][ndn];if(doc&&doc.parenttype==dt&&(doc.parent==dn||doc.__oldparent==dn)){delete locals[ndt][ndn];}}}}
delete locals[dt][dn];}
function get_local(dt,dn){return locals[dt]?locals[dt][dn]:null;}
-LocalDB.sync=function(list){if(list._kl)list=expand_doclist(list);for(var i=0;i<list.length;i++){var d=list[i];if(!d.name)
+LocalDB.sync=function(list){if(list._kl)list=expand_doclist(list);if(list){LocalDB.clear_locals(list[0].doctype,list[0].name);}
+for(var i=0;i<list.length;i++){var d=list[i];if(!d.name)
d.name=LocalDB.get_localname(d.doctype);LocalDB.add(d.doctype,d.name);locals[d.doctype][d.name]=d;if(d.doctype=='DocField')wn.meta.add_field(d);if(d.localname){wn.model.new_names[d.localname]=d.name;$(document).trigger('rename',[d.doctype,d.localname,d.name]);delete locals[d.doctype][d.localname];}}}
+LocalDB.clear_locals=function(dt,dn){var doclist=make_doclist(dt,dn,1);$.each(doclist,function(i,v){v&&delete locals[v.doctype][v.name];});}
local_name_idx={};LocalDB.get_localname=function(doctype){if(!local_name_idx[doctype])local_name_idx[doctype]=1;var n='New '+get_doctype_label(doctype)+' '+local_name_idx[doctype];local_name_idx[doctype]++;return n;}
LocalDB.set_default_values=function(doc){var doctype=doc.doctype;var docfields=wn.meta.docfield_list[doctype];if(!docfields){return;}
var fields_to_refresh=[];for(var fid=0;fid<docfields.length;fid++){var f=docfields[fid];if(!in_list(no_value_fields,f.fieldtype)&&doc[f.fieldname]==null){var v=LocalDB.get_default_value(f.fieldname,f.fieldtype,f['default']);if(v){doc[f.fieldname]=v;fields_to_refresh.push(f.fieldname);}}}
@@ -643,8 +646,7 @@
return perm;}
LocalDB.create=function(doctype,n){if(!n)n=LocalDB.get_localname(doctype);var doc=LocalDB.add(doctype,n)
doc.__islocal=1;doc.owner=user;LocalDB.set_default_values(doc);return n;}
-LocalDB.delete_record=function(dt,dn){var d=locals[dt][dn];if(!d.__islocal)
-d.__oldparent=d.parent;d.parent='old_parent:'+d.parent;d.docstatus=2;d.__deleted=1;}
+LocalDB.delete_record=function(dt,dn){delete locals[dt][dn];}
LocalDB.get_default_value=function(fn,ft,df){if(df=='_Login'||df=='__user')
return user;else if(df=='_Full Name')
return user_fullname;else if(ft=='Date'&&(df=='Today'||df=='__today')){return get_today();}
@@ -655,7 +657,8 @@
LocalDB.add_child=function(doc,childtype,parentfield){var n=LocalDB.create(childtype);var d=locals[childtype][n];d.parent=doc.name;d.parentfield=parentfield;d.parenttype=doc.doctype;return d;}
LocalDB.no_copy_list=['amended_from','amendment_date','cancel_reason'];LocalDB.copy=function(dt,dn,from_amend){var newdoc=LocalDB.create(dt);for(var key in locals[dt][dn]){var df=get_field(dt,key);if(key!=='name'&&key.substr(0,2)!='__'&&!(df&&((!from_amend&&cint(df.no_copy)==1)||in_list(LocalDB.no_copy_list,df.fieldname)))){locals[dt][newdoc][key]=locals[dt][dn][key];}}
return locals[dt][newdoc];}
-function make_doclist(dt,dn,deleted){var dl=[];dl[0]=locals[dt][dn];for(var ndt in locals){if(locals[ndt]){for(var ndn in locals[ndt]){var doc=locals[ndt][ndn];if(doc&&doc.parenttype==dt&&(doc.parent==dn||(deleted&&doc.__oldparent==dn))){dl[dl.length]=doc;}}}}
+function make_doclist(dt,dn){if(!locals[dt]){return[];}
+var dl=[];dl[0]=locals[dt][dn];for(var ndt in locals){if(locals[ndt]){for(var ndn in locals[ndt]){var doc=locals[ndt][ndn];if(doc&&doc.parenttype==dt&&doc.parent==dn){dl.push(doc)}}}}
return dl;}
var Meta={};var local_dt={};Meta.make_local_dt=function(dt,dn){var dl=make_doclist('DocType',dt);if(!local_dt[dt])local_dt[dt]={};if(!local_dt[dt][dn])local_dt[dt][dn]={};for(var i=0;i<dl.length;i++){var d=dl[i];if(d.doctype=='DocField'){var key=d.fieldname?d.fieldname:d.label;local_dt[dt][dn][key]=copy_dict(d);}}}
Meta.get_field=function(dt,fn,dn){if(dn&&local_dt[dt]&&local_dt[dt][dn]){return local_dt[dt][dn][fn];}else{if(wn.meta.docfield_map[dt])var d=wn.meta.docfield_map[dt][fn];if(d)return d;}
@@ -667,7 +670,7 @@
/*
* lib/js/legacy/model/doclist.js
*/
-function compress_doclist(list){var kl={};var vl=[];var flx={};for(var i=0;i<list.length;i++){var o=list[i];var fl=[];if(!kl[o.doctype]){var tfl=['doctype','name','docstatus','owner','parent','parentfield','parenttype','idx','creation','modified','modified_by','__islocal','__deleted','__newname','__modified','_user_tags'];var fl=['doctype','name','docstatus','owner','parent','parentfield','parenttype','idx','creation','modified','modified_by','__islocal','__deleted','__newname','__modified','_user_tags'];for(key in wn.meta.docfield_map[o.doctype]){if(!in_list(fl,key)&&!in_list(no_value_fields,wn.meta.docfield_map[o.doctype][key].fieldtype)&&!wn.meta.docfield_map[o.doctype][key].no_column){fl[fl.length]=key;tfl[tfl.length]=key}}
+function compress_doclist(list){var kl={};var vl=[];var flx={};for(var i=0;i<list.length;i++){var o=list[i];var fl=[];if(!kl[o.doctype]){var tfl=['doctype','name','docstatus','owner','parent','parentfield','parenttype','idx','creation','modified','modified_by','__islocal','__newname','__modified','_user_tags'];var fl=[].concat(tfl);for(key in wn.meta.docfield_map[o.doctype]){if(!in_list(fl,key)&&!in_list(no_value_fields,wn.meta.docfield_map[o.doctype][key].fieldtype)&&!wn.meta.docfield_map[o.doctype][key].no_column){fl[fl.length]=key;tfl[tfl.length]=key}}
flx[o.doctype]=fl;kl[o.doctype]=tfl}
var nl=[];var fl=flx[o.doctype];for(var j=0;j<fl.length;j++){var v=o[fl[j]];nl.push(v);}
vl.push(nl);}
@@ -683,7 +686,8 @@
var _save=function(){$c('webnotes.widgets.form.save.savedocs',{'docs':compress_doclist(doclist),'docname':dn,'action':save_action,'user':user},function(r,rtxt){if(f){f.savingflag=false;}
if(r.saved){if(onsave)onsave(r);}else{if(onerr)onerr(r);}},function(){if(f){f.savingflag=false;}},0,(f?'Saving...':''));}
if(doc.__islocal&&(doctype&&doctype.autoname&&doctype.autoname.toLowerCase()=='prompt')){var newname=prompt('Enter the name of the new '+dt,'');if(newname){doc.__newname=strip(newname);_save();}else{msgprint('Not Saved');onerr();}}else{_save();}}
-function check_required(dt,dn,parent_dt){var doc=locals[dt][dn];if(doc.docstatus>1)return true;var fl=wn.meta.docfield_list[dt];if(!fl)return true;var all_clear=true;var errfld=[];for(var i=0;i<fl.length;i++){var key=fl[i].fieldname;var v=doc[key];if(fl[i].reqd&&is_null(v)&&fl[i].fieldname){errfld[errfld.length]=fl[i].label;if(cur_frm){var f=cur_frm.fields_dict[fl[i].fieldname];if(f){if(f.set_as_error)f.set_as_error(1);if(!cur_frm.error_in_section&&f.parent_section){cur_frm.error_in_section=1;}}}
+function check_required(dt,dn,parent_dt){var doc=locals[dt][dn];if(doc.docstatus>1)return true;var fl=wn.meta.docfield_list[dt];if(!fl)return true;var all_clear=true;var errfld=[];for(var i=0;i<fl.length;i++){var key=fl[i].fieldname;var v=doc[key];if(fl[i].fieldtype=='Table'){var no_value=true;$.each(locals[fl[i].options],function(k,d){if(d.parent==doc.name&&d.parenttype==doc.doctype&&d.parentfield==fl[i].fieldname){no_value=false;}});}else{var no_value=is_null(v);}
+if(fl[i].reqd&&no_value&&fl[i].fieldname){errfld[errfld.length]=fl[i].label;if(cur_frm){var f=cur_frm.fields_dict[fl[i].fieldname];if(f){if(f.set_as_error)f.set_as_error(1);if(!cur_frm.error_in_section&&f.parent_section){cur_frm.error_in_section=1;}}}
if(all_clear)all_clear=false;}}
if(errfld.length)msgprint('<b>Mandatory fields required in '+
(doc.parenttype?(wn.meta.docfield_map[doc.parenttype][doc.parentfield].label+' (Table)'):get_doctype_label(doc.doctype))+':</b>\n'+errfld.join('\n'));return all_clear;}
diff --git a/public/js/fields.js b/public/js/fields.js
index dba9e5c..cb5c9be 100644
--- a/public/js/fields.js
+++ b/public/js/fields.js
@@ -18,8 +18,9 @@
Field.prototype.set_description=function(){if(this.df.description){var p=in_list(['Text Editor','Code','Check'],this.df.fieldtype)?this.label_area:this.wrapper;this.desc_area=$a(p,'div','help small','',this.df.description)
if(in_list(['Text Editor','Code'],this.df.fieldtype))
$(this.desc_area).addClass('help small');}}
-Field.prototype.get_status=function(){if(this.in_filter)this.not_in_form=this.in_filter;if(this.not_in_form){return'Write';}
-if(!this.df.permlevel)this.df.permlevel=0;var p=this.perm[this.df.permlevel];var ret;if(cur_frm.editable&&p&&p[WRITE])ret='Write';else if(p&&p[READ])ret='Read';else ret='None';if(this.df.fieldtype=='Binary')
+Field.prototype.get_status=function(){if(this.in_filter)
+this.not_in_form=this.in_filter;if(this.not_in_form){return'Write';}
+if(!this.df.permlevel)this.df.permlevel=0;var p=this.perm[this.df.permlevel];var ret;if(cur_frm.editable&&p&&p[WRITE]&&!this.disabled)ret='Write';else if(p&&p[READ])ret='Read';else ret='None';if(this.df.fieldtype=='Binary')
ret='None';if(cint(this.df.hidden))
ret='None';if(ret=='Write'&&cint(cur_frm.doc.docstatus)>0)ret='Read';var a_o_s=cint(this.df.allow_on_submit);if(a_o_s&&(this.in_grid||(this.frm&&this.frm.not_in_container))){a_o_s=null;if(this.in_grid)a_o_s=this.grid.field.df.allow_on_submit;if(this.frm&&this.frm.not_in_container){a_o_s=cur_grid.field.df.allow_on_submit;}}
if(cur_frm.editable&&a_o_s&&cint(cur_frm.doc.docstatus)>0&&!this.df.hidden){tmp_perm=get_perm(cur_frm.doctype,cur_frm.docname,1);if(tmp_perm[this.df.permlevel]&&tmp_perm[this.df.permlevel][WRITE])ret='Write';}
@@ -98,19 +99,20 @@
$(me.btn2).css('display','inline-block');else $dh(me.btn2);}}
me.txt.field_object=this;me.input.set_input=function(val){if(val==undefined)val='';me.txt.value=val;}
me.get_value=function(){return me.txt.value;}
-$(me.txt).autocomplete({source:function(request,response){wn.call({method:'webnotes.widgets.search.search_link',args:{'txt':request.term,'dt':me.df.options,'query':me.get_custom_query()},callback:function(r){response(r.results);},});},select:function(event,ui){me.set_input_value(ui.item.value);}}).data('autocomplete')._renderItem=function(ul,item){return $('<li></li>').data('item.autocomplete',item).append(repl('<a>%(label)s<br><span style="font-size:10px">%(info)s</span></a>',item)).appendTo(ul);};$(this.txt).change(function(){if(!$(this).val()){if(selector&&selector.display)
-return;me.set_input_value('');}})}
+$(me.txt).autocomplete({source:function(request,response){wn.call({method:'webnotes.widgets.search.search_link',args:{'txt':request.term,'dt':me.df.options,'query':me.get_custom_query()},callback:function(r){response(r.results);},});},select:function(event,ui){me.set_input_value(ui.item.value);}}).data('autocomplete')._renderItem=function(ul,item){return $('<li></li>').data('item.autocomplete',item).append(repl('<a>%(label)s<br><span style="font-size:10px">%(info)s</span></a>',item)).appendTo(ul);};$(this.txt).change(function(){var val=$(this).val();me.set_input_value_executed=false;if(!val){if(selector&&selector.display)
+return;me.set_input_value('');}else{setTimeout(function(){if(!me.set_input_value_executed){me.set_input_value(val);}},1000);}})}
LinkField.prototype.get_custom_query=function(){this.set_get_query();if(this.get_query){if(cur_frm)
var doc=locals[cur_frm.doctype][cur_frm.docname];return this.get_query(doc,this.doctype,this.docname);}}
LinkField.prototype.setup_buttons=function(){var me=this;me.btn.onclick=function(){selector.set(me,me.df.options,me.df.label);selector.show(me.txt);}
if(me.btn1)me.btn1.onclick=function(){if(me.txt.value&&me.df.options){loaddoc(me.df.options,me.txt.value);}}
me.can_create=0;if((!me.not_in_form)&&in_list(profile.can_create,me.df.options)){me.can_create=1;me.btn2.onclick=function(){var on_save_callback=function(new_rec){if(new_rec){var d=_f.calling_doc_stack.pop();locals[d[0]][d[1]][me.df.fieldname]=new_rec;me.refresh();if(me.grid)me.grid.refresh();me.run_trigger();}}
_f.calling_doc_stack.push([me.doctype,me.docname]);new_doc(me.df.options,me.on_new,1,on_save_callback,me.doctype,me.docname,me.frm.not_in_container);}}else{$dh(me.btn2);$y($td(me.tab,0,2),{width:'0px'});}}
-LinkField.prototype.set_input_value=function(val){var me=this;var from_selector=false;if(selector&&selector.display)from_selector=true;me.refresh_label_icon();if(me.not_in_form){$(this.txt).val(val);return;}
+LinkField.prototype.set_input_value=function(val){var me=this;me.set_input_value_executed=true;var from_selector=false;if(selector&&selector.display)from_selector=true;me.refresh_label_icon();if(me.not_in_form){$(this.txt).val(val);return;}
if(cur_frm){if(val==locals[me.doctype][me.docname][me.df.fieldname]){me.run_trigger();return;}}
me.set(val);if(_f.cur_grid_cell)
_f.cur_grid_cell.grid.cell_deselect();if(locals[me.doctype][me.docname][me.df.fieldname]&&!val){me.run_trigger();return;}
-var fetch='';if(cur_frm.fetch_dict[me.df.fieldname])
+me.validate_link(val,from_selector);}
+LinkField.prototype.validate_link=function(val,from_selector){var me=this;var fetch='';if(cur_frm.fetch_dict[me.df.fieldname])
fetch=cur_frm.fetch_dict[me.df.fieldname].columns.join(', ');$c('webnotes.widgets.form.utils.validate_link',{'value':val,'options':me.df.options,'fetch':fetch},function(r,rt){if(r.message=='Ok'){if($(me.txt).val()!=val){if((me.grid&&!from_selector)||(!me.grid)){$(me.txt).val(val);}}
if(r.fetch_values)
me.set_fetch_values(r.fetch_values);me.run_trigger();}else{var astr='';if(in_list(profile.can_create,me.df.options))astr=repl('<br><br><span class="link_type" onclick="newdoc(\'%(dt)s\')">Click here</span> to create a new %(dtl)s',{dt:me.df.options,dtl:get_doctype_label(me.df.options)})
diff --git a/public/js/report-legacy.js b/public/js/report-legacy.js
index 6f7fae6..4228c86 100644
--- a/public/js/report-legacy.js
+++ b/public/js/report-legacy.js
@@ -45,13 +45,12 @@
if(sc&&sc.sort_order){sc.sort_order=='ASC'?this.dt.set_asc():this.dt.set_desc();}
if(sc&&sc.page_len){this.dt.page_len_sel.inp.value=sc.page_len;}
this.current_loaded=criteria_name;this.set_main_title(criteria_name,sc.description);}
-_r.ReportBuilder.prototype.setup_filters_and_cols=function(){function can_dt_be_submitted(dt){if(locals.DocType&&locals.DocType[dt]&&locals.DocType[dt].allow_trash)return 1;var plist=getchildren('DocPerm',dt,'permissions','DocType');for(var pidx in plist){if(plist[pidx].submit)return 1;}
-return 0;}
+_r.ReportBuilder.prototype.setup_filters_and_cols=function(){function can_dt_be_submitted(dt){return locals.DocType[dt]&&locals.DocType[dt].is_submittable||0;}
var me=this;var dt=me.parent_dt?me.parent_dt:me.doctype;var fl=[{'fieldtype':'Data','label':'ID','fieldname':'name','in_filter':1,'parent':dt},{'fieldtype':'Data','label':'Owner','fieldname':'owner','in_filter':1,'parent':dt},{'fieldtype':'Date','label':'Created on','fieldname':'creation','in_filter':0,'parent':dt},{'fieldtype':'Date','label':'Last modified on','fieldname':'modified','in_filter':0,'parent':dt},];if(can_dt_be_submitted(dt)){fl[fl.length]={'fieldtype':'Check','label':'Saved','fieldname':'docstatus','search_index':1,'in_filter':1,'def_filter':1,'parent':dt};fl[fl.length]={'fieldtype':'Check','label':'Submitted','fieldname':'docstatus','search_index':1,'in_filter':1,'def_filter':1,'parent':dt};fl[fl.length]={'fieldtype':'Check','label':'Cancelled','fieldname':'docstatus','search_index':1,'in_filter':1,'parent':dt};}
me.make_datatable();me.orig_sort_list=[];if(me.parent_dt){me.setup_dt_filters_and_cols(fl,me.parent_dt);var fl=[];}
me.setup_dt_filters_and_cols(fl,me.doctype);if(!this.has_primary_filters)
$dh(this.report_filters.first_page_filter);this.column_picker.refresh();$ds(me.body);}
-_r.ReportBuilder.prototype.set_filters_from_route=function(){var route=wn.get_route();if(route.length>3){for(var i=3;i<route.length;i++){var p=route[i].split('=');if(p.length==2){var dt=this.parent_dt?this.parent_dt:this.doctype;this.set_filter(dt,p[0],p[1]);}}}}
+_r.ReportBuilder.prototype.set_filters_from_route=function(){var route=wn.get_route();this.current_route=wn.get_route_str();if(route.length>3){for(var i=3;i<route.length;i++){var p=route[i].split('=');if(p.length==2){var dt=this.parent_dt?this.parent_dt:this.doctype;this.set_filter(dt,p[0],p[1]);}}}}
_r.ReportBuilder.prototype.add_filter=function(f){if(this.filter_fields_dict[f.parent+'\1'+f.label]){this.filter_fields_dict[f.parent+'\1'+f.label].df=f;}else{this.report_filters.add_field(f,f.parent,null,1);}}
_r.ReportBuilder.prototype.setup_dt_filters_and_cols=function(fl,dt){var me=this;var lab=$a(me.filter_area,'div','filter_dt_head');lab.innerHTML='Filters for '+get_doctype_label(dt);var lab=$a(me.picker_area,'div','builder_dt_head');lab.innerHTML='Select columns for '+get_doctype_label(dt);var dt_fields=wn.meta.docfield_list[dt];for(var i=0;i<dt_fields.length;i++){fl[fl.length]=dt_fields[i];}
var sf_list=locals.DocType[dt].search_fields?locals.DocType[dt].search_fields.split(','):[];for(var i in sf_list)sf_list[i]=strip(sf_list[i]);for(var i=0;i<fl.length;i++){var f=fl[i];if(f&&cint(f.in_filter)){me.report_filters.add_field(f,dt,in_list(sf_list,f.fieldname));}