diff --git a/accounts/__init__.py b/accounts/__init__.py index aa2af626fc..3fdf4ef926 100644 --- a/accounts/__init__.py +++ b/accounts/__init__.py @@ -18,6 +18,7 @@ from __future__ import unicode_literals import webnotes from webnotes.utils import flt from webnotes.model.code import get_obj +from accounts.utils import get_balance_on install_docs = [ {"doctype":"Role", "role_name":"Accounts Manager", "name":"Accounts Manager"}, @@ -107,7 +108,7 @@ def get_invoice_account_jv_record(doc, children, fiscal_year, obj): ret.update({ 'account': account, - 'balance': get_obj('GL Control').get_bal(account + "~~~" + fiscal_year) + 'balance': get_balance_on(account, doc.get("return_date")) }) return ret @@ -140,7 +141,8 @@ def get_item_accountwise_jv_record(doc, children, fiscal_year, obj): rec = { 'account': inv_ch.fields.get(ac_field), 'cost_center': inv_ch.fields.get('cost_center'), - 'balance': get_obj('GL Control').get_bal(inv_ch.fields.get(ac_field) + "~~~" + fiscal_year) + 'balance': get_balance_on(inv_ch.fields.get(ac_field), + doc.get("return_date")) } rec[amt_field] = amount accwise_list.append(rec) diff --git a/accounts/doctype/account/account.py b/accounts/doctype/account/account.py index 180aeaabc1..cc4c449994 100644 --- a/accounts/doctype/account/account.py +++ b/accounts/doctype/account/account.py @@ -25,14 +25,8 @@ 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, msgprint, errprint -set = webnotes.conn.set sql = webnotes.conn.sql get_value = webnotes.conn.get_value -in_transaction = webnotes.conn.in_transaction -convert_to_lists = webnotes.conn.convert_to_lists - -# ----------------------------------------------------------------------------------------- - class DocType: def __init__(self,d,dl): @@ -49,7 +43,6 @@ class DocType: ret={'address':add[0][0]} return ret - # 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: @@ -86,7 +79,6 @@ class DocType: if (self.doc.fields.get('__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: @@ -104,7 +96,6 @@ class DocType: elif self.doc.account_name in ['Source of Funds','Application of Funds']: 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) @@ -115,7 +106,6 @@ class DocType: self.doc.save() 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.", @@ -133,47 +123,15 @@ class DocType: 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: - sql("update `tabAccount Balance` t1, `tabAccount` t2 set t1.balance = t1.balance + (%s), t1.opening = t1.opening + (%s), t1.debit = t1.debit + (%s), t1.credit = t1.credit + (%s) where t1.period = %s and t1.account = t2.name and t2.lft<=%s and t2.rgt>=%s", (flt(flag)*flt(p[1]), flt(flag)*flt(p[2]), flt(flag)*flt(p[3]), flt(flag)*flt(p[4]), p[0], self.doc.lft, self.doc.rgt)) - - - # 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'") - for f in fy: - # get my opening, balance - per = sql("select period, balance, opening, debit, credit from `tabAccount Balance` where account = %s and fiscal_year = %s", (self.doc.name, f[0])) - for p in per: - period_det.append([p[0], p[1], p[2], p[3], p[4]]) - - # deduct balance from old_parent - op = get_obj('Account',self.doc.old_parent) - op.update_balance(fy, period_det, -1) - - # add to new parent_account - flag = 1 - if op.doc.debit_or_credit != self.doc.debit_or_credit: - flag = -1 - - get_obj('Account', self.doc.parent_account).update_balance(fy, period_det, flag) - msgprint('Balances updated') - def validate_mandatory(self): if not self.doc.debit_or_credit: msgprint("Debit or Credit field is mandatory", raise_exception=1) if not self.doc.is_pl_account: msgprint("Is PL Account field is mandatory", raise_exception=1) - - # VALIDATE def validate(self): self.validate_master_name() self.validate_rate_for_tax() @@ -185,27 +143,6 @@ class DocType: # Defaults if not self.doc.parent_account: self.doc.parent_account = '' - - # parent changed - if self.doc.old_parent and self.doc.parent_account and (self.doc.parent_account != self.doc.old_parent): - 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: - if not sql("select name from `tabAccount Balance` where account=%s and period=%s", (self.doc.name, d[0])): - ac = Document('Account Balance') - ac.account = self.doc.name - ac.period = d[0] - ac.start_date = d[1].strftime('%Y-%m-%d') - ac.end_date = d[2].strftime('%Y-%m-%d') - ac.fiscal_year = d[3] - ac.opening = 0 - ac.debit = 0 - ac.credit = 0 - ac.balance = 0 - ac.save(1) # Update Node Set Model def update_nsm_model(self): @@ -213,13 +150,9 @@ class DocType: 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): @@ -243,49 +176,31 @@ class DocType: msgprint("Total Outstanding amount (%s) for %s can not be greater than credit limit (%s). To change your credit limit settings, please update the %s" \ % (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): + def validate_trash(self): + """checks gl entries and if child exists""" if self.check_gle_exists(): msgprint("Account with existing transaction (Sales Invoice / Purchase Invoice / Journal Voucher) can not be trashed", raise_exception=1) if self.check_if_child_exists(): msgprint("Child account exists for this account. You can not trash this account.", raise_exception=1) - - # 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() + self.validate_trash() # rebuild tree - from webnotes.utils.nestedset import update_remove_node - update_remove_node('Account', self.doc.name) + self.update_nsm_model() # 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) - #delete Account Balance - sql("delete from `tabAccount Balance` where account = %s", self.doc.name) - - # On restore - def on_restore(self): - # rebuild tree - self.update_nsm_model() - # intiate balances - 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] newdnchk = newdn.split(" - ") - if newdnchk[-1].lower() != company_abbr.lower(): + if newdnchk[-1].lower() != company_abbr.lower(): msgprint("Please add company abbreviation %s" %(company_abbr), raise_exception=1) else: account_name = " - ".join(newdnchk[:-1]) - sql("update `tabAccount` set account_name = '%s' where name = '%s'" %(account_name,olddn)) + sql("update `tabAccount` set account_name = '%s' where name = '%s'" %(account_name,olddn)) diff --git a/accounts/doctype/account_balance/__init__.py b/accounts/doctype/account_balance/__init__.py deleted file mode 100644 index baffc48825..0000000000 --- a/accounts/doctype/account_balance/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from __future__ import unicode_literals diff --git a/accounts/doctype/account_balance/account_balance.txt b/accounts/doctype/account_balance/account_balance.txt deleted file mode 100644 index 903d270cd5..0000000000 --- a/accounts/doctype/account_balance/account_balance.txt +++ /dev/null @@ -1,177 +0,0 @@ -# DocType, Account Balance -[ - - # These values are common in all dictionaries - { - 'creation': '2012-03-27 14:35:40', - 'docstatus': 0, - 'modified': '2012-03-27 14:35:40', - 'modified_by': u'Administrator', - 'owner': u'Administrator' - }, - - # These values are common for all DocType - { - '_last_update': u'1322549700', - 'autoname': u'_ACB.######', - 'colour': u'White:FFF', - 'default_print_format': u'Standard', - 'doctype': 'DocType', - 'istable': 0, - 'module': u'Accounts', - 'name': '__common__', - 'search_fields': u'account, period, fiscal_year, balance', - 'section_style': u'Simple', - 'server_code_error': u' ', - 'show_in_menu': 0, - 'version': 6 - }, - - # These values are common for all DocField - { - 'doctype': u'DocField', - 'name': '__common__', - 'parent': u'Account Balance', - 'parentfield': u'fields', - 'parenttype': u'DocType', - 'permlevel': 0 - }, - - # These values are common for all DocPerm - { - 'amend': 0, - 'cancel': 0, - 'create': 0, - 'doctype': u'DocPerm', - 'name': '__common__', - 'parent': u'Account Balance', - 'parentfield': u'permissions', - 'parenttype': u'DocType', - 'permlevel': 0, - 'read': 1, - 'submit': 0, - 'write': 0 - }, - - # DocType, Account Balance - { - 'doctype': 'DocType', - 'name': u'Account Balance' - }, - - # DocPerm - { - 'doctype': u'DocPerm', - 'role': u'Accounts User' - }, - - # DocPerm - { - 'doctype': u'DocPerm', - 'role': u'Accounts Manager' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'account', - 'fieldtype': u'Link', - 'in_filter': 1, - 'label': u'Account', - 'options': u'Account', - 'search_index': 1 - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'period', - 'fieldtype': u'Link', - 'in_filter': 1, - 'label': u'Period', - 'oldfieldname': u'period', - 'oldfieldtype': u'Link', - 'options': u'Period', - 'search_index': 1 - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'opening', - 'fieldtype': u'Currency', - 'label': u'Opening', - 'oldfieldname': u'opening', - 'oldfieldtype': u'Currency' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'debit', - 'fieldtype': u'Currency', - 'label': u'Debit', - 'oldfieldname': u'debit', - 'oldfieldtype': u'Currency' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'credit', - 'fieldtype': u'Currency', - 'label': u'Credit', - 'oldfieldname': u'credit', - 'oldfieldtype': u'Currency' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'balance', - 'fieldtype': u'Currency', - 'label': u'Balance', - 'oldfieldname': u'balance', - 'oldfieldtype': u'Currency' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'fiscal_year', - 'fieldtype': u'Link', - 'hidden': 1, - 'in_filter': 1, - 'label': u'Fiscal Year', - 'oldfieldname': u'fiscal_year', - 'oldfieldtype': u'Link', - 'options': u'Fiscal Year', - 'search_index': 0 - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'start_date', - 'fieldtype': u'Date', - 'hidden': 1, - 'in_filter': 1, - 'label': u'Start Date', - 'oldfieldname': u'start_date', - 'oldfieldtype': u'Date', - 'search_index': 1 - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'end_date', - 'fieldtype': u'Date', - 'hidden': 1, - 'in_filter': 1, - 'label': u'End Date', - 'oldfieldname': u'end_date', - 'oldfieldtype': u'Date', - 'search_index': 1 - } -] \ No newline at end of file diff --git a/accounts/doctype/fiscal_year/fiscal_year.py b/accounts/doctype/fiscal_year/fiscal_year.py deleted file mode 100644 index 70702032cd..0000000000 --- a/accounts/doctype/fiscal_year/fiscal_year.py +++ /dev/null @@ -1,221 +0,0 @@ -# ERPNext - web based ERP (http://erpnext.com) -# Copyright (C) 2012 Web Notes Technologies Pvt Ltd -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Please edit this list and import only required elements -from __future__ import unicode_literals -import webnotes - -from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, 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, msgprint, errprint - -set = webnotes.conn.set -sql = webnotes.conn.sql -get_value = webnotes.conn.get_value -in_transaction = webnotes.conn.in_transaction -convert_to_lists = webnotes.conn.convert_to_lists - -# ----------------------------------------------------------------------------------------- - - -class DocType: - def __init__(self, d, dl): - self.doc, self.doclist = d,dl - - def repost(self): - if not self.doc.company: - msgprint("Please select company", raise_exception=1) - - if not in_transaction: - sql("start transaction") - - self.rebuid_account_tree() - self.clear_account_balances() - self.create_account_balances() - self.update_opening(self.doc.company) - self.post_entries() - sql("commit") - - msgprint("Account balance reposted for fiscal year: " + self.doc.name) - - def rebuid_account_tree(self): - from webnotes.utils.nestedset import rebuild_tree - rebuild_tree('Account', 'parent_account') - - def clear_account_balances(self): - # balances clear - `tabAccount Balance` for fiscal year - sql("update `tabAccount Balance` t1, tabAccount t2 set t1.opening=0, t1.balance=0, t1.debit=0, t1.credit=0 where t1.fiscal_year=%s and t2.company = %s and t1.account = t2.name", (self.doc.name, self.doc.company)) - - def create_account_balances(self): - # get periods - period_list = self.get_period_list() - cnt = 0 - - # get accounts - al = sql("select name from tabAccount") - - for a in al: - # check - if sql("select count(*) from `tabAccount Balance` where fiscal_year=%s and account=%s", (self.doc.name, a[0]))[0][0] < 13: - for p in period_list: - # check if missing - if not sql("select name from `tabAccount Balance` where period=%s and account=%s and fiscal_year=%s", (p[0], a[0], self.doc.name)): - d = Document('Account Balance') - d.account = a[0] - d.period = p[0] - d.start_date = p[1].strftime('%Y-%m-%d') - d.end_date = p[2].strftime('%Y-%m-%d') - d.fiscal_year = p[3] - d.debit = 0 - d.credit = 0 - d.opening = 0 - d.balance = 0 - d.save(1) - cnt += 1 - if cnt % 100 == 0: - sql("commit") - sql("start transaction") - return cnt - - # Get periods(month and year) - #================================= - def get_period_list(self): - periods = [] - pl = sql("SELECT name, start_date, end_date, fiscal_year FROM tabPeriod WHERE fiscal_year = '%s' and period_type in ('Month', 'Year') order by start_date ASC, end_date DESC" % self.doc.name) - for p in pl: - periods.append([p[0], p[1], p[2], p[3]]) - return periods - - # ==================================================================================== - def update_opening(self, company): - """ - set opening from last year closing - - """ - - abl = sql("select t1.account, t1.balance from `tabAccount Balance` t1, tabAccount t2 where t1.period= '%s' and t2.company= '%s' and ifnull(t2.is_pl_account, 'No') = 'No' and t1.account = t2.name for update" % (self.doc.past_year, company)) - - cnt = 0 - for ab in abl: - if cnt % 100 == 0: - sql("commit") - sql("start transaction") - - sql("update `tabAccount Balance` set opening=%s where period=%s and account=%s", (ab[1], self.doc.name, ab[0])) - sql("update `tabAccount Balance` set balance=%s where fiscal_year=%s and account=%s", (ab[1], self.doc.name, ab[0])) - cnt += 1 - - return cnt - - def get_account_details(self, account): - return sql("select debit_or_credit, lft, rgt, is_pl_account from tabAccount where name=%s", account)[0] - - # ==================================================================================== - def post_entries(self): - sql("LOCK TABLE `tabGL Entry` WRITE") - # post each gl entry (batch or complete) - gle = sql("select name, account, debit, credit, is_opening, posting_date from `tabGL Entry` where fiscal_year=%s and ifnull(is_cancelled,'No')='No' and company=%s", (self.doc.name, self.doc.company)) - account_details = {} - - cnt = 0 - for entry in gle: - # commit in batches of 100 - if cnt % 100 == 0: - sql("commit") - sql("start transaction") - cnt += 1 - #print cnt - - if not account_details.has_key(entry[1]): - account_details[entry[1]] = self.get_account_details(entry[1]) - - det = account_details[entry[1]] - diff = flt(entry[2])-flt(entry[3]) - if det[0]=='Credit': diff = -diff - - # build dict - p = { - 'debit': entry[4]=='No' and flt(entry[2]) or 0 - ,'credit': entry[4]=='No' and flt(entry[3]) or 0 - ,'opening': entry[4]=='Yes' and diff or 0 - - # end date conditino only if it is not opening - ,'end_date_condition':(entry[4]!='Yes' and ("and ab.end_date >= '"+entry[5].strftime('%Y-%m-%d')+"'") or '') - ,'diff': diff - ,'lft': det[1] - ,'rgt': det[2] - ,'posting_date': entry[5] - ,'fiscal_year': self.doc.name - } - - sql("""update `tabAccount Balance` ab, `tabAccount` a - set - ab.debit = ifnull(ab.debit,0) + %(debit)s - ,ab.credit = ifnull(ab.credit,0) + %(credit)s - ,ab.opening = ifnull(ab.opening,0) + %(opening)s - ,ab.balance = ifnull(ab.balance,0) + %(diff)s - where - a.lft <= %(lft)s - and a.rgt >= %(rgt)s - and ab.account = a.name - %(end_date_condition)s - and ab.fiscal_year = '%(fiscal_year)s' """ % p) - - sql("UNLOCK TABLES") - - - # Clear PV/RV outstanding - # ==================================================================================== - def clear_outstanding(self): - # clear o/s of current year - sql("update `tabPurchase Invoice` set outstanding_amount = 0 where fiscal_year=%s and company=%s", (self.doc.name, self.doc.company)) - sql("update `tabSales Invoice` set outstanding_amount = 0 where fiscal_year=%s and company=%s", (self.doc.name, self.doc.company)) - - # Update Voucher Outstanding - def update_voucher_outstanding(self): - # Clear outstanding - self.clear_outstanding() - against_voucher = sql("select against_voucher, against_voucher_type from `tabGL Entry` where fiscal_year=%s and ifnull(is_cancelled, 'No')='No' and company=%s and ifnull(against_voucher, '') != '' and ifnull(against_voucher_type, '') != '' group by against_voucher, against_voucher_type", (self.doc.name, self.doc.company)) - for d in against_voucher: - # get voucher balance - bal = sql("select sum(debit)-sum(credit) from `tabGL Entry` where against_voucher=%s and against_voucher_type=%s and ifnull(is_cancelled, 'No') = 'No'", (d[0], d[1])) - bal = bal and flt(bal[0][0]) or 0.0 - if d[1] == 'Purchase Invoice': - bal = -bal - # set voucher balance - sql("update `tab%s` set outstanding_amount=%s where name='%s'"% (d[1], bal, d[0])) - - # ==================================================================================== - # Generate periods - def create_periods(self): - get_obj('Period Control').generate_periods(self.doc.name) - - def validate(self): - 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) - - - # on update - def on_update(self): - self.create_periods() - self.create_account_balances() - - if self.doc.fields.get('localname', '')[:15] == 'New Fiscal Year': - for d in sql("select name from tabCompany"): - self.update_opening(d[0]) diff --git a/accounts/doctype/gl_control/gl_control.py b/accounts/doctype/gl_control/gl_control.py index 957b10ea00..d648ec76ae 100644 --- a/accounts/doctype/gl_control/gl_control.py +++ b/accounts/doctype/gl_control/gl_control.py @@ -41,36 +41,6 @@ class DocType: dcc = TransactionBase().get_company_currency(arg) return dcc - # Get current balance - # -------------------- - def get_bal(self,arg): - ac, fy = arg.split('~~~') - det = webnotes.conn.sql("select t1.balance, t2.debit_or_credit from `tabAccount Balance` t1, `tabAccount` t2 where t1.period = %s and t2.name=%s and t1.account = t2.name", (fy, ac)) - bal = det and flt(det[0][0]) or 0 - dr_or_cr = det and flt(det[0][1]) or '' - return fmt_money(bal) + ' ' + dr_or_cr - - def get_period_balance(self,arg): - acc, f, t = arg.split('~~~') - c, fy = '', get_defaults()['fiscal_year'] - - det = webnotes.conn.sql("select debit_or_credit, lft, rgt, is_pl_account from tabAccount where name=%s", acc) - if f: c += (' and t1.posting_date >= "%s"' % f) - if t: c += (' and t1.posting_date <= "%s"' % t) - bal = webnotes.conn.sql("select sum(ifnull(t1.debit,0))-sum(ifnull(t1.credit,0)) from `tabGL Entry` t1 where t1.account='%s' and ifnull(is_opening, 'No') = 'No' %s" % (acc, c)) - bal = bal and flt(bal[0][0]) or 0 - - if det[0][0] != 'Debit': - bal = (-1) * bal - - # add opening for balance sheet accounts - if det[0][3] == 'No': - opening = flt(webnotes.conn.sql("select opening from `tabAccount Balance` where account=%s and period=%s", (acc, fy))[0][0]) - bal = bal + opening - - return flt(bal) - - def get_period_difference(self,arg, cost_center =''): # used in General Ledger Page Report # used for Budget where cost center passed as extra argument @@ -89,32 +59,6 @@ class DocType: return flt(bal) - # Get Children (for tree) - # ----------------------- - def get_cl(self, arg): - - fy = get_defaults()['fiscal_year'] - parent, parent_acc_name, company, type = arg.split(',') - - # get children account details - if type=='Account': - - if parent=='Root Node': - - cl = webnotes.conn.sql("select t1.name, t1.group_or_ledger, t1.debit_or_credit, t2.balance, t1.account_name from tabAccount t1, `tabAccount Balance` t2 where ifnull(t1.parent_account, '') = '' and t1.docstatus != 2 and t1.company=%s and t1.name = t2.account and t2.period = %s order by t1.name asc", (company, fy),as_dict=1) - else: - cl = webnotes.conn.sql("select t1.name, t1.group_or_ledger, t1.debit_or_credit, t2.balance, t1.account_name from tabAccount t1, `tabAccount Balance` t2 where ifnull(t1.parent_account, '')=%s and t1.docstatus != 2 and t1.company=%s and t1.name = t2.account and t2.period = %s order by t1.name asc",(parent, company, fy) ,as_dict=1) - - # remove Decimals - for c in cl: c['balance'] = flt(c['balance']) - - # get children cost center details - elif type=='Cost Center': - if parent=='Root Node': - cl = webnotes.conn.sql("select name,group_or_ledger, cost_center_name from `tabCost Center` where ifnull(parent_cost_center, '')='' and docstatus != 2 and company_name=%s order by name asc",(company),as_dict=1) - else: - cl = webnotes.conn.sql("select name,group_or_ledger,cost_center_name from `tabCost Center` where ifnull(parent_cost_center, '')=%s and docstatus != 2 and company_name=%s order by name asc",(parent,company),as_dict=1) - return {'parent':parent, 'parent_acc_name':parent_acc_name, 'cl':cl} # Add a new account # ----------------- @@ -254,39 +198,10 @@ class DocType: # set as cancelled if cancel: - vt, vn = self.get_val(le_map['voucher_type'], doc, doc), self.get_val(le_map['voucher_no'], doc, doc) + vt = self.get_val(le_map['voucher_type'], doc, doc) + vn = self.get_val(le_map['voucher_no'], doc, doc) webnotes.conn.sql("update `tabGL Entry` set is_cancelled='Yes' where voucher_type=%s and voucher_no=%s", (vt, vn)) - - # Get account balance on any date - # ------------------------------- - def get_as_on_balance(self, account_name, fiscal_year, as_on, credit_or_debit, lft, rgt): - # initialization - det = webnotes.conn.sql("select start_date, opening from `tabAccount Balance` where period = %s and account = %s", (fiscal_year, account_name)) - from_date, opening, debit_bal, credit_bal, closing_bal = det and det[0][0] or getdate(nowdate()), det and flt(det[0][1]) or 0, 0, 0, det and flt(det[0][1]) or 0 - - # prev month closing - prev_month_det = webnotes.conn.sql("select end_date, debit, credit, balance from `tabAccount Balance` where account = %s and end_date <= %s and fiscal_year = %s order by end_date desc limit 1", (account_name, as_on, fiscal_year)) - if prev_month_det: - from_date = getdate(add_days(prev_month_det[0][0].strftime('%Y-%m-%d'), 1)) - opening = 0 - debit_bal = flt(prev_month_det[0][1]) - credit_bal = flt(prev_month_det[0][2]) - closing_bal = flt(prev_month_det[0][3]) - - # curr month transaction - if getdate(as_on) >= from_date: - curr_month_bal = webnotes.conn.sql("select SUM(t1.debit), SUM(t1.credit) from `tabGL Entry` t1, `tabAccount` t2 WHERE t1.posting_date >= %s AND t1.posting_date <= %s and ifnull(t1.is_opening, 'No') = 'No' AND t1.account = t2.name AND t2.lft >= %s AND t2.rgt <= %s and ifnull(t1.is_cancelled, 'No') = 'No'", (from_date, as_on, lft, rgt)) - curr_debit_amt, curr_credit_amt = flt(curr_month_bal[0][0]), flt(curr_month_bal[0][1]) - debit_bal = curr_month_bal and debit_bal + curr_debit_amt or debit_bal - credit_bal = curr_month_bal and credit_bal + curr_credit_amt or credit_bal - - if credit_or_debit == 'Credit': - curr_debit_amt, curr_credit_amt = -1*flt(curr_month_bal[0][0]), -1*flt(curr_month_bal[0][1]) - closing_bal = closing_bal + curr_debit_amt - curr_credit_amt - - return flt(debit_bal), flt(credit_bal), flt(closing_bal) - - + # ADVANCE ALLOCATION #------------------- def get_advances(self, obj, account_head, table_name,table_field_name, dr_or_cr): diff --git a/accounts/doctype/gl_entry/gl_entry.py b/accounts/doctype/gl_entry/gl_entry.py index 6010b88dc9..22774e6317 100644 --- a/accounts/doctype/gl_entry/gl_entry.py +++ b/accounts/doctype/gl_entry/gl_entry.py @@ -121,117 +121,8 @@ class DocType: if getdate(self.doc.posting_date) <= getdate(acc_frozen_upto) and not bde_auth_role in webnotes.user.get_roles(): msgprint("You are not authorized to do/modify back dated accounting entries before %s." % getdate(acc_frozen_upto).strftime('%d-%m-%Y'), raise_exception=1) - # create new bal if not exists - #----------------------------- - def create_new_balances(self, det): - # check - if sql("select count(t1.name) from `tabAccount Balance` t1, tabAccount t2 where t1.fiscal_year=%s and t2.lft <= %s and t2.rgt >= %s and t2.name = t1.account", (self.doc.fiscal_year, det[0][0], det[0][1]))[0][0] < 13*(cint(det[0][1]) - cint(det[0][0]) +1)/2: - period_list = self.get_period_list() - accounts = sql("select name from tabAccount where lft <= %s and rgt >= %s" % (det[0][0], det[0][1])) - - for p in period_list: - for a in accounts: - # check if missing - if not sql("select name from `tabAccount Balance` where period=%s and account=%s and fiscal_year=%s", (p[0], a[0], self.doc.fiscal_year)): - d = Document('Account Balance') - d.account = a[0] - d.period = p[0] - d.start_date = p[1].strftime('%Y-%m-%d') - d.end_date = p[2].strftime('%Y-%m-%d') - d.fiscal_year = self.doc.fiscal_year - d.debit = 0 - d.credit = 0 - d.opening = 0 - d.balance = 0 - d.save(1) - - # Post Balance - # ------------ - def post_balance(self, acc, cancel): - # get details - det = sql("select lft, rgt, debit_or_credit from `tabAccount` where name='%s'" % acc) - - # amount to debit - amt = flt(self.doc.debit) - flt(self.doc.credit) - if det[0][2] == 'Credit': amt = -amt - - if cancel: - debit = -1 * flt(self.doc.credit) - credit = -1 * flt(self.doc.debit) - else: - debit = flt(self.doc.debit) - credit = flt(self.doc.credit) - - self.create_new_balances(det) - - # build dict - p = { - 'debit': self.doc.is_opening=='No' and flt(debit) or 0 - ,'credit':self.doc.is_opening=='No' and flt(credit) or 0 - ,'opening': self.doc.is_opening=='Yes' and amt or 0 - # end date condition only if it is not opening - ,'end_date_condition':(self.doc.is_opening!='Yes' and ("and ab.end_date >= '"+self.doc.posting_date+"'") or '') - ,'diff': amt - ,'lft': cint(det[0][0]) - ,'rgt': cint(det[0][1]) - ,'posting_date': self.doc.posting_date - ,'fiscal_year': self.doc.fiscal_year - } - - # Update account balance for current year - sql("""update `tabAccount Balance` ab, `tabAccount` a - set - ab.debit = ifnull(ab.debit,0) + %(debit)s - ,ab.credit = ifnull(ab.credit,0) + %(credit)s - ,ab.opening = ifnull(ab.opening,0) + %(opening)s - ,ab.balance = ifnull(ab.balance,0) + %(diff)s - where - a.lft <= %(lft)s - and a.rgt >= %(rgt)s - and ab.account = a.name - %(end_date_condition)s - and ab.fiscal_year = '%(fiscal_year)s' """ % p) - - # Future year balances - # Update opening only where period_type is Year - sql("""update `tabAccount Balance` ab, `tabAccount` a, `tabFiscal Year` fy - set - ab.opening = ifnull(ab.opening,0) + %(diff)s - where - a.lft <= %(lft)s - and a.rgt >= %(rgt)s - and ab.account = a.name - and ifnull(a.is_pl_account, 'No') = 'No' - and ab.period = ab.fiscal_year - and fy.name = ab.fiscal_year - and fy.year_start_date > '%(posting_date)s'""" % p) - - # Update balance for all period for future years - sql("""update `tabAccount Balance` ab, `tabAccount` a, `tabFiscal Year` fy - set - ab.balance = ifnull(ab.balance,0) + %(diff)s - where - a.lft <= %(lft)s - and a.rgt >= %(rgt)s - and ab.account = a.name - and ifnull(a.is_pl_account, 'No') = 'No' - and fy.name = ab.fiscal_year - and fy.year_start_date > '%(posting_date)s'""" % p) - - - - - # Get periods(month and year) - #----------------------------- - def get_period_list(self): - pl = sql("SELECT name, start_date, end_date, fiscal_year FROM tabPeriod WHERE fiscal_year = '%s' and period_type in ('Month', 'Year')" % (self.doc.fiscal_year)) - return pl - - # Voucher Balance - # --------------- def update_outstanding_amt(self): # get final outstanding amt - bal = flt(sql("select sum(debit)-sum(credit) from `tabGL Entry` where against_voucher=%s and against_voucher_type=%s and ifnull(is_cancelled,'No') = 'No'", (self.doc.against_voucher, self.doc.against_voucher_type))[0][0] or 0.0) tds = 0 @@ -291,10 +182,7 @@ class DocType: # Posting date must be after freezing date self.check_freezing_date(adv_adj) - - # Update current account balance - self.post_balance(self.doc.account, cancel) - + # Update outstanding amt on against voucher if self.doc.against_voucher and self.doc.against_voucher_type not in ('Journal Voucher','POS') and update_outstanding == 'Yes': self.update_outstanding_amt() diff --git a/accounts/doctype/journal_voucher/journal_voucher.js b/accounts/doctype/journal_voucher/journal_voucher.js index 7dd09c5e62..fe407f52e6 100644 --- a/accounts/doctype/journal_voucher/journal_voucher.js +++ b/accounts/doctype/journal_voucher/journal_voucher.js @@ -145,7 +145,14 @@ cur_frm.cscript.get_balance = function(doc,dt,dn) { cur_frm.cscript.account = function(doc,dt,dn) { var d = locals[dt][dn]; - $c_obj('GL Control','get_bal',d.account+'~~~'+doc.fiscal_year, function(r,rt) { d.balance = r.message; refresh_field('balance',d.name,'entries'); }); + wn.call({ + method: "accounts.utils.get_balance_on", + args: {account: d.account, date: doc.posting_date}, + callback: function(r) { + d.balance = fmt_money(r.message); + refresh_field('balance',d.name,'entries'); + } + }); } cur_frm.cscript.validate = function(doc,cdt,cdn) { diff --git a/accounts/doctype/journal_voucher/journal_voucher.py b/accounts/doctype/journal_voucher/journal_voucher.py index 86765b60c6..2c9b7ae7b6 100644 --- a/accounts/doctype/journal_voucher/journal_voucher.py +++ b/accounts/doctype/journal_voucher/journal_voucher.py @@ -8,11 +8,11 @@ # # 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 . +# along with this program. If not, see . # Please edit this list and import only required elements from __future__ import unicode_literals @@ -35,431 +35,431 @@ convert_to_lists = webnotes.conn.convert_to_lists from utilities.transaction_base import TransactionBase class DocType: - def __init__(self,d,dl): - self.doc, self.doclist = d,dl - self.master_type = {} - self.credit_days_for = {} - self.credit_days_global = -1 - self.is_approving_authority = -1 + def __init__(self,d,dl): + self.doc, self.doclist = d,dl + self.master_type = {} + self.credit_days_for = {} + self.credit_days_global = -1 + self.is_approving_authority = -1 - #-------------------------------------------------------------------------------------------------------- - # Autoname - #-------------------------------------------------------------------------------------------------------- - def autoname(self): - self.doc.name = make_autoname(self.doc.naming_series+'.#####') + #-------------------------------------------------------------------------------------------------------- + # Autoname + #-------------------------------------------------------------------------------------------------------- + def autoname(self): + self.doc.name = make_autoname(self.doc.naming_series+'.#####') - #-------------------------------------------------------------------------------------------------------- - # Fetch outstanding amount from RV/PV - #-------------------------------------------------------------------------------------------------------- - def get_outstanding(self, args): - args = eval(args) - o_s = sql("select outstanding_amount from `tab%s` where name = '%s'" % (args['doctype'],args['docname'])) - if args['doctype'] == 'Purchase Invoice': - return {'debit': o_s and flt(o_s[0][0]) or 0} - if args['doctype'] == 'Sales Invoice': - return {'credit': o_s and flt(o_s[0][0]) or 0} + #-------------------------------------------------------------------------------------------------------- + # Fetch outstanding amount from RV/PV + #-------------------------------------------------------------------------------------------------------- + def get_outstanding(self, args): + args = eval(args) + o_s = sql("select outstanding_amount from `tab%s` where name = '%s'" % (args['doctype'],args['docname'])) + if args['doctype'] == 'Purchase Invoice': + return {'debit': o_s and flt(o_s[0][0]) or 0} + if args['doctype'] == 'Sales Invoice': + return {'credit': o_s and flt(o_s[0][0]) or 0} - #-------------------------------------------------------------------------------------------------------- - # Create remarks - #-------------------------------------------------------------------------------------------------------- - def create_remarks(self): - r = [] - if self.doc.cheque_no : - if self.doc.cheque_date: - r.append('Via cheque #%s dated %s' % (self.doc.cheque_no, formatdate(self.doc.cheque_date))) - else : - msgprint("Please enter cheque date") - raise Exception - - for d in getlist(self.doclist, 'entries'): - if d.against_invoice and d.credit: - currency = sql("select currency from `tabSales Invoice` where name = '%s'" % d.against_invoice) - currency = currency and currency[0][0] or '' - r.append('%s %s against Invoice: %s' % (cstr(currency), fmt_money(flt(d.credit)), d.against_invoice)) - if d.against_voucher and d.debit: - bill_no = sql("select bill_no, bill_date, currency from `tabPurchase Invoice` where name=%s", d.against_voucher) - if bill_no and bill_no[0][0] and bill_no[0][0].lower().strip() not in ['na', 'not applicable', 'none']: - bill_no = bill_no and bill_no[0] - r.append('%s %s against Bill %s dated %s' % (bill_no[2] and cstr(bill_no[2]) or '', fmt_money(flt(d.debit)), bill_no[0], bill_no[1] and formatdate(bill_no[1].strftime('%Y-%m-%d')) or '')) - if self.doc.ded_amount: - r.append("TDS Amount: %s" % self.doc.ded_amount) - - if self.doc.user_remark: - r.append("User Remark : %s"%self.doc.user_remark) + #-------------------------------------------------------------------------------------------------------- + # Create remarks + #-------------------------------------------------------------------------------------------------------- + def create_remarks(self): + r = [] + if self.doc.cheque_no : + if self.doc.cheque_date: + r.append('Via cheque #%s dated %s' % (self.doc.cheque_no, formatdate(self.doc.cheque_date))) + else : + msgprint("Please enter cheque date") + raise Exception + + for d in getlist(self.doclist, 'entries'): + if d.against_invoice and d.credit: + currency = sql("select currency from `tabSales Invoice` where name = '%s'" % d.against_invoice) + currency = currency and currency[0][0] or '' + r.append('%s %s against Invoice: %s' % (cstr(currency), fmt_money(flt(d.credit)), d.against_invoice)) + if d.against_voucher and d.debit: + bill_no = sql("select bill_no, bill_date, currency from `tabPurchase Invoice` where name=%s", d.against_voucher) + if bill_no and bill_no[0][0] and bill_no[0][0].lower().strip() not in ['na', 'not applicable', 'none']: + bill_no = bill_no and bill_no[0] + r.append('%s %s against Bill %s dated %s' % (bill_no[2] and cstr(bill_no[2]) or '', fmt_money(flt(d.debit)), bill_no[0], bill_no[1] and formatdate(bill_no[1].strftime('%Y-%m-%d')) or '')) + if self.doc.ded_amount: + r.append("TDS Amount: %s" % self.doc.ded_amount) + + if self.doc.user_remark: + r.append("User Remark : %s"%self.doc.user_remark) - if r: - self.doc.remark = ("\n").join(r) - - # -------------------------------------------------------------------------------------------------------- - # Check user role for approval process - # -------------------------------------------------------------------------------------------------------- - def get_authorized_user(self): - if self.is_approving_authority==-1: - self.is_approving_authority = 0 + if r: + self.doc.remark = ("\n").join(r) + + # -------------------------------------------------------------------------------------------------------- + # Check user role for approval process + # -------------------------------------------------------------------------------------------------------- + def get_authorized_user(self): + if self.is_approving_authority==-1: + self.is_approving_authority = 0 - # Fetch credit controller role - approving_authority = sql("select value from `tabSingles` where field='credit_controller' and doctype='Global Defaults'") - approving_authority = approving_authority and approving_authority[0][0] or '' - - # Check logged-in user is authorized - if approving_authority in webnotes.user.get_roles(): - self.is_approving_authority = 1 - - return self.is_approving_authority - - # get master type - # --------------- - def get_master_type(self, ac): - if not self.master_type.get(ac): - self.master_type[ac] = sql("select master_type from `tabAccount` where name=%s", ac)[0][0] or 'None' - return self.master_type[ac] - - # get credit days for - # ------------------- - def get_credit_days_for(self, ac): + # Fetch credit controller role + approving_authority = sql("select value from `tabSingles` where field='credit_controller' and doctype='Global Defaults'") + approving_authority = approving_authority and approving_authority[0][0] or '' + + # Check logged-in user is authorized + if approving_authority in webnotes.user.get_roles(): + self.is_approving_authority = 1 + + return self.is_approving_authority + + # get master type + # --------------- + def get_master_type(self, ac): + if not self.master_type.get(ac): + self.master_type[ac] = sql("select master_type from `tabAccount` where name=%s", ac)[0][0] or 'None' + return self.master_type[ac] + + # get credit days for + # ------------------- + def get_credit_days_for(self, ac): - if not self.credit_days_for.has_key(ac): - self.credit_days_for[ac] = sql("select credit_days from `tabAccount` where name='%s'" % ac)[0][0] or 0 + if not self.credit_days_for.has_key(ac): + self.credit_days_for[ac] = sql("select credit_days from `tabAccount` where name='%s'" % ac)[0][0] or 0 - if not self.credit_days_for[ac]: - if self.credit_days_global==-1: - self.credit_days_global = sql("select credit_days from `tabCompany` where name='%s'" % self.doc.company)[0][0] or 0 - return self.credit_days_global - else: - return self.credit_days_for[ac] - - - # -------------------------------------------------------------------------------------------------------- - # Check Credit Days - Cheque Date can not after (Posting date + Credit Days) - # -------------------------------------------------------------------------------------------------------- - def check_credit_days(self): - date_diff = 0 - if self.doc.cheque_date: - date_diff = (getdate(self.doc.cheque_date)-getdate(self.doc.posting_date)).days - - if date_diff <= 0: return - - # Get List of Customer Account - acc_list = filter(lambda d: self.get_master_type(d.account)=='Customer', getlist(self.doclist,'entries')) - - for d in acc_list: - credit_days = self.get_credit_days_for(d.account) - - # Check credit days - if credit_days > 0 and not self.get_authorized_user() and cint(date_diff) > credit_days: - msgprint("Credit Not Allowed: Cannot allow a check that is dated more than %s days after the posting date" % credit_days) - raise Exception - - #-------------------------------------------------------------------------------------------------------- - # validation of debit/credit account with Debit To Account(RV) or Credit To Account (PV) - #-------------------------------------------------------------------------------------------------------- - def check_account_against_entries(self): - for d in getlist(self.doclist,'entries'): - if d.against_invoice: - acc=sql("select debit_to from `tabSales Invoice` where name='%s'"%d.against_invoice) - if acc and acc[0][0] != d.account: - msgprint("Debit account is not matching with receivable voucher") - raise Exception - - if d.against_voucher: - acc=sql("select credit_to from `tabPurchase Invoice` where name='%s'"%d.against_voucher) - if acc and acc[0][0] != d.account: - msgprint("Credit account is not matching with payable voucher") - raise Exception - - #-------------------------------------------------------------------------------------------------------- - # Validate Cheque Info: Mandatory for Bank/Contra voucher - #-------------------------------------------------------------------------------------------------------- - def validate_cheque_info(self): - if self.doc.voucher_type in ['Bank Voucher']: - if not self.doc.cheque_no or not self.doc.cheque_date: - msgprint("Cheque No & Cheque Date is required for " + cstr(self.doc.voucher_type)) - raise Exception - - if self.doc.cheque_date and not self.doc.cheque_no: - msgprint("Cheque No is mandatory if you entered Cheque Date") - raise Exception - - #-------------------------------------------------------------------------------------------------------- - # Gives reminder for making is_advance = 'Yes' in Advance Entry - #-------------------------------------------------------------------------------------------------------- - def validate_entries_for_advance(self): - for d in getlist(self.doclist,'entries'): - if not d.is_advance and not d.against_voucher and not d.against_invoice and d.against_jv: - master_type = self.get_master_type(d.account) - if (master_type == 'Customer' and flt(d.credit) > 0) or (master_type == 'Supplier' and flt(d.debit) > 0): - msgprint("Message: Please check Is Advance as 'Yes' against Account %s if this is an advance entry." % d.account) - - #-------------------------------------------------------------------------------------------------------- - # TDS: Validate tds related fields - #-------------------------------------------------------------------------------------------------------- - def get_tds_category_account(self): - for d in getlist(self.doclist,'entries'): - if flt(d.debit) > 0 and not d.against_voucher and d.is_advance == 'Yes': - acc = sql("select tds_applicable from `tabAccount` where name = '%s'" % d.account) - acc_tds_applicable = acc and acc[0][0] or 'No' - if acc_tds_applicable == 'Yes': - # TDS applicable field become mandatory for advance payment towards supplier or related party - if not self.doc.tds_applicable: - msgprint("Please select TDS Applicable or Not") - raise Exception - - # If TDS applicable, category and supplier account bocome mandatory - elif self.doc.tds_applicable == 'Yes': - self.validate_category_account(d.account) - if self.doc.ded_amount and not self.doc.tax_code: - msgprint("Please enter Tax Code in TDS section") - raise Exception + if not self.credit_days_for[ac]: + if self.credit_days_global==-1: + self.credit_days_global = sql("select credit_days from `tabCompany` where name='%s'" % self.doc.company)[0][0] or 0 + return self.credit_days_global + else: + return self.credit_days_for[ac] + + + # -------------------------------------------------------------------------------------------------------- + # Check Credit Days - Cheque Date can not after (Posting date + Credit Days) + # -------------------------------------------------------------------------------------------------------- + def check_credit_days(self): + date_diff = 0 + if self.doc.cheque_date: + date_diff = (getdate(self.doc.cheque_date)-getdate(self.doc.posting_date)).days + + if date_diff <= 0: return + + # Get List of Customer Account + acc_list = filter(lambda d: self.get_master_type(d.account)=='Customer', getlist(self.doclist,'entries')) + + for d in acc_list: + credit_days = self.get_credit_days_for(d.account) + + # Check credit days + if credit_days > 0 and not self.get_authorized_user() and cint(date_diff) > credit_days: + msgprint("Credit Not Allowed: Cannot allow a check that is dated more than %s days after the posting date" % credit_days) + raise Exception + + #-------------------------------------------------------------------------------------------------------- + # validation of debit/credit account with Debit To Account(RV) or Credit To Account (PV) + #-------------------------------------------------------------------------------------------------------- + def check_account_against_entries(self): + for d in getlist(self.doclist,'entries'): + if d.against_invoice: + acc=sql("select debit_to from `tabSales Invoice` where name='%s'"%d.against_invoice) + if acc and acc[0][0] != d.account: + msgprint("Debit account is not matching with receivable voucher") + raise Exception + + if d.against_voucher: + acc=sql("select credit_to from `tabPurchase Invoice` where name='%s'"%d.against_voucher) + if acc and acc[0][0] != d.account: + msgprint("Credit account is not matching with payable voucher") + raise Exception + + #-------------------------------------------------------------------------------------------------------- + # Validate Cheque Info: Mandatory for Bank/Contra voucher + #-------------------------------------------------------------------------------------------------------- + def validate_cheque_info(self): + if self.doc.voucher_type in ['Bank Voucher']: + if not self.doc.cheque_no or not self.doc.cheque_date: + msgprint("Cheque No & Cheque Date is required for " + cstr(self.doc.voucher_type)) + raise Exception + + if self.doc.cheque_date and not self.doc.cheque_no: + msgprint("Cheque No is mandatory if you entered Cheque Date") + raise Exception + + #-------------------------------------------------------------------------------------------------------- + # Gives reminder for making is_advance = 'Yes' in Advance Entry + #-------------------------------------------------------------------------------------------------------- + def validate_entries_for_advance(self): + for d in getlist(self.doclist,'entries'): + if not d.is_advance and not d.against_voucher and not d.against_invoice and d.against_jv: + master_type = self.get_master_type(d.account) + if (master_type == 'Customer' and flt(d.credit) > 0) or (master_type == 'Supplier' and flt(d.debit) > 0): + msgprint("Message: Please check Is Advance as 'Yes' against Account %s if this is an advance entry." % d.account) + + #-------------------------------------------------------------------------------------------------------- + # TDS: Validate tds related fields + #-------------------------------------------------------------------------------------------------------- + def get_tds_category_account(self): + for d in getlist(self.doclist,'entries'): + if flt(d.debit) > 0 and not d.against_voucher and d.is_advance == 'Yes': + acc = sql("select tds_applicable from `tabAccount` where name = '%s'" % d.account) + acc_tds_applicable = acc and acc[0][0] or 'No' + if acc_tds_applicable == 'Yes': + # TDS applicable field become mandatory for advance payment towards supplier or related party + if not self.doc.tds_applicable: + msgprint("Please select TDS Applicable or Not") + raise Exception + + # If TDS applicable, category and supplier account bocome mandatory + elif self.doc.tds_applicable == 'Yes': + self.validate_category_account(d.account) + if self.doc.ded_amount and not self.doc.tax_code: + msgprint("Please enter Tax Code in TDS section") + raise Exception - #If TDS not applicable, all related fields should blank - else: - self.set_fields_null() - - # If tds amount but tds applicability not mentioned in account master - elif self.doc.ded_amount: - msgprint("Please select TDS Applicable = 'Yes' in account head: '%s' if you want to deduct TDS." % self.doc.supplier_account) - raise Exception - - + #If TDS not applicable, all related fields should blank + else: + self.set_fields_null() + + # If tds amount but tds applicability not mentioned in account master + elif self.doc.ded_amount: + msgprint("Please select TDS Applicable = 'Yes' in account head: '%s' if you want to deduct TDS." % self.doc.supplier_account) + raise Exception + + - #-------------------------------------------------------------------------------------------------------- - # If TDS applicable , TDS category and supplier account should be mandatory - #-------------------------------------------------------------------------------------------------------- - def validate_category_account(self, credit_account): - if not self.doc.tds_category: - msgprint("Please select TDS Category") - raise Exception - - if not self.doc.supplier_account: - self.doc.supplier_account = credit_account - elif self.doc.supplier_account and self.doc.supplier_account != credit_account: - msgprint("Supplier Account is not matching with the account mentioned in the table. Please select proper Supplier Account and click on 'Get TDS' button.") - raise Exception - + #-------------------------------------------------------------------------------------------------------- + # If TDS applicable , TDS category and supplier account should be mandatory + #-------------------------------------------------------------------------------------------------------- + def validate_category_account(self, credit_account): + if not self.doc.tds_category: + msgprint("Please select TDS Category") + raise Exception + + if not self.doc.supplier_account: + self.doc.supplier_account = credit_account + elif self.doc.supplier_account and self.doc.supplier_account != credit_account: + msgprint("Supplier Account is not matching with the account mentioned in the table. Please select proper Supplier Account and click on 'Get TDS' button.") + raise Exception + - #-------------------------------------------------------------------------------------------------------- - # If TDS is not applicable , all related fields should blank - #-------------------------------------------------------------------------------------------------------- - def set_fields_null(self): - self.doc.ded_amount = 0 - self.doc.rate = 0 - self.doc.tax_code = '' - self.doc.tds_category = '' - self.doc.supplier_account = '' - - #-------------------------------------------------------------------------------------------------------- - # Get TDS amount - #-------------------------------------------------------------------------------------------------------- - def get_tds(self): - if cstr(self.doc.is_opening) != 'Yes': - if self.doc.total_debit > 0: - self.get_tds_category_account() - if self.doc.supplier_account and self.doc.tds_category: - get_obj('TDS Control').get_tds_amount(self) + #-------------------------------------------------------------------------------------------------------- + # If TDS is not applicable , all related fields should blank + #-------------------------------------------------------------------------------------------------------- + def set_fields_null(self): + self.doc.ded_amount = 0 + self.doc.rate = 0 + self.doc.tax_code = '' + self.doc.tds_category = '' + self.doc.supplier_account = '' + + #-------------------------------------------------------------------------------------------------------- + # Get TDS amount + #-------------------------------------------------------------------------------------------------------- + def get_tds(self): + if cstr(self.doc.is_opening) != 'Yes': + if self.doc.total_debit > 0: + self.get_tds_category_account() + if self.doc.supplier_account and self.doc.tds_category: + get_obj('TDS Control').get_tds_amount(self) - - #-------------------------------------------------------------------------------------------------------- - # Insert new row to balance total debit and total credit - #-------------------------------------------------------------------------------------------------------- - def get_balance(self): - if not getlist(self.doclist,'entries'): - msgprint("Please enter atleast 1 entry in 'GL Entries' table") - else: - flag, self.doc.total_debit, self.doc.total_credit = 0,0,0 - diff = flt(self.doc.difference) - - # If any row without amount, set the diff on that row - for d in getlist(self.doclist,'entries'): - if (d.credit==0 or d.credit is None) and (d.debit==0 or d.debit is None) and (flt(diff) != 0): - if diff>0: - d.credit = flt(diff) - elif diff<0: - d.debit = flt(diff) - flag = 1 - - # Set the diff in a new row - if flag == 0 and (flt(diff) != 0): - jd = addchild(self.doc, 'entries', 'Journal Voucher Detail', 1, self.doclist) - if diff>0: - jd.credit = flt(diff) - elif diff<0: - jd.debit = flt(diff) - - # Set the total debit, total credit and difference - for d in getlist(self.doclist,'entries'): - self.doc.total_debit += flt(d.debit) - self.doc.total_credit += flt(d.credit) + + #-------------------------------------------------------------------------------------------------------- + # Insert new row to balance total debit and total credit + #-------------------------------------------------------------------------------------------------------- + def get_balance(self): + if not getlist(self.doclist,'entries'): + msgprint("Please enter atleast 1 entry in 'GL Entries' table") + else: + flag, self.doc.total_debit, self.doc.total_credit = 0,0,0 + diff = flt(self.doc.difference) + + # If any row without amount, set the diff on that row + for d in getlist(self.doclist,'entries'): + if (d.credit==0 or d.credit is None) and (d.debit==0 or d.debit is None) and (flt(diff) != 0): + if diff>0: + d.credit = flt(diff) + elif diff<0: + d.debit = flt(diff) + flag = 1 + + # Set the diff in a new row + if flag == 0 and (flt(diff) != 0): + jd = addchild(self.doc, 'entries', 'Journal Voucher Detail', 1, self.doclist) + if diff>0: + jd.credit = flt(diff) + elif diff<0: + jd.debit = flt(diff) + + # Set the total debit, total credit and difference + for d in getlist(self.doclist,'entries'): + self.doc.total_debit += flt(d.debit) + self.doc.total_credit += flt(d.credit) - if self.doc.tds_applicable == 'Yes': - self.doc.total_credit = flt(self.doc.total_credit) + flt(self.doc.ded_amount) + if self.doc.tds_applicable == 'Yes': + self.doc.total_credit = flt(self.doc.total_credit) + flt(self.doc.ded_amount) - self.doc.difference = flt(self.doc.total_debit) - flt(self.doc.total_credit) - - #-------------------------------------------------------------------------------------------------------- - # Set against account - #-------------------------------------------------------------------------------------------------------- - def get_against_account(self): - # Debit = Credit - debit, credit = 0.0, 0.0 - debit_list, credit_list = [], [] - for d in getlist(self.doclist, 'entries'): - debit += flt(d.debit) - credit += flt(d.credit) - if flt(d.debit)>0 and (d.account not in debit_list): debit_list.append(d.account) - if flt(d.credit)>0 and (d.account not in credit_list): credit_list.append(d.account) + self.doc.difference = flt(self.doc.total_debit) - flt(self.doc.total_credit) + + #-------------------------------------------------------------------------------------------------------- + # Set against account + #-------------------------------------------------------------------------------------------------------- + def get_against_account(self): + # Debit = Credit + debit, credit = 0.0, 0.0 + debit_list, credit_list = [], [] + for d in getlist(self.doclist, 'entries'): + debit += flt(d.debit) + credit += flt(d.credit) + if flt(d.debit)>0 and (d.account not in debit_list): debit_list.append(d.account) + if flt(d.credit)>0 and (d.account not in credit_list): credit_list.append(d.account) - self.doc.total_debit = debit - if self.doc.tds_applicable == 'Yes': - self.doc.total_credit = credit + flt(self.doc.ded_amount) - else: - self.doc.total_credit = credit + self.doc.total_debit = debit + if self.doc.tds_applicable == 'Yes': + self.doc.total_credit = credit + flt(self.doc.ded_amount) + else: + self.doc.total_credit = credit - if abs(self.doc.total_debit-self.doc.total_credit) > 0.001: - msgprint("Debit must be equal to Credit. The difference is %s" % (self.doc.total_debit-self.doc.total_credit)) - raise Exception - - # update against account - for d in getlist(self.doclist, 'entries'): - if flt(d.debit) > 0: d.against_account = ', '.join(credit_list) - if flt(d.credit) > 0: d.against_account = ', '.join(debit_list) + if abs(self.doc.total_debit-self.doc.total_credit) > 0.001: + msgprint("Debit must be equal to Credit. The difference is %s" % (self.doc.total_debit-self.doc.total_credit)) + raise Exception + + # update against account + for d in getlist(self.doclist, 'entries'): + if flt(d.debit) > 0: d.against_account = ', '.join(credit_list) + if flt(d.credit) > 0: d.against_account = ', '.join(debit_list) - # set aging date - #--------------- - def set_aging_date(self): - if self.doc.is_opening != 'Yes': - self.doc.aging_date = self.doc.posting_date - else: - # check account type whether supplier or customer - exists = '' - for d in getlist(self.doclist, 'entries'): - exists = sql("select name from tabAccount where account_type in ('Supplier', 'Customer') and name = '%s'" % d.account) - if exists: - break + # set aging date + #--------------- + def set_aging_date(self): + if self.doc.is_opening != 'Yes': + self.doc.aging_date = self.doc.posting_date + else: + # check account type whether supplier or customer + exists = '' + for d in getlist(self.doclist, 'entries'): + exists = sql("select name from tabAccount where account_type in ('Supplier', 'Customer') and name = '%s'" % d.account) + if exists: + break - # If cus/supp aging dt is mandatory - if exists and not self.doc.aging_date: - msgprint("Aging Date is mandatory for opening entry") - raise Exception - # otherwise aging dt = posting dt - else: - self.doc.aging_date = self.doc.posting_date + # If cus/supp aging dt is mandatory + if exists and not self.doc.aging_date: + msgprint("Aging Date is mandatory for opening entry") + raise Exception + # otherwise aging dt = posting dt + else: + self.doc.aging_date = self.doc.posting_date - # ------------------------ - # set print format fields - # ------------------------ - def set_print_format_fields(self): - for d in getlist(self.doclist, 'entries'): - #msgprint(self.doc.company) - chk_type = sql("select master_type, account_type from `tabAccount` where name='%s'" % d.account) - master_type, acc_type = chk_type and cstr(chk_type[0][0]) or '', chk_type and cstr(chk_type[0][1]) or '' - if master_type in ['Supplier', 'Customer']: - if not self.doc.pay_to_recd_from: - self.doc.pay_to_recd_from = get_value(master_type, ' - '.join(d.account.split(' - ')[:-1]), master_type == 'Customer' and 'customer_name' or 'supplier_name') - - if acc_type == 'Bank or Cash': - dcc = TransactionBase().get_company_currency(self.doc.company) - amt = cint(d.debit) and d.debit or d.credit - self.doc.total_amount = dcc +' '+ cstr(amt) - self.doc.total_amount_in_words = get_obj('Sales Common').get_total_in_words(dcc, cstr(amt)) + # ------------------------ + # set print format fields + # ------------------------ + def set_print_format_fields(self): + for d in getlist(self.doclist, 'entries'): + #msgprint(self.doc.company) + chk_type = sql("select master_type, account_type from `tabAccount` where name='%s'" % d.account) + master_type, acc_type = chk_type and cstr(chk_type[0][0]) or '', chk_type and cstr(chk_type[0][1]) or '' + if master_type in ['Supplier', 'Customer']: + if not self.doc.pay_to_recd_from: + self.doc.pay_to_recd_from = get_value(master_type, ' - '.join(d.account.split(' - ')[:-1]), master_type == 'Customer' and 'customer_name' or 'supplier_name') + + if acc_type == 'Bank or Cash': + dcc = TransactionBase().get_company_currency(self.doc.company) + amt = cint(d.debit) and d.debit or d.credit + self.doc.total_amount = dcc +' '+ cstr(amt) + self.doc.total_amount_in_words = get_obj('Sales Common').get_total_in_words(dcc, cstr(amt)) - # -------------------------------- - # get outstanding invoices values - # -------------------------------- - def get_values(self): - cond = (flt(self.doc.write_off_amount) > 0) and ' and outstanding_amount <= '+self.doc.write_off_amount or '' - if self.doc.write_off_based_on == 'Accounts Receivable': - return sql("select name, debit_to, outstanding_amount from `tabSales Invoice` where docstatus = 1 and company = '%s' and outstanding_amount > 0 %s" % (self.doc.company, cond)) - elif self.doc.write_off_based_on == 'Accounts Payable': - return sql("select name, credit_to, outstanding_amount from `tabPurchase Invoice` where docstatus = 1 and company = '%s' and outstanding_amount > 0 %s" % (self.doc.company, cond)) + # -------------------------------- + # get outstanding invoices values + # -------------------------------- + def get_values(self): + cond = (flt(self.doc.write_off_amount) > 0) and ' and outstanding_amount <= '+self.doc.write_off_amount or '' + if self.doc.write_off_based_on == 'Accounts Receivable': + return sql("select name, debit_to, outstanding_amount from `tabSales Invoice` where docstatus = 1 and company = '%s' and outstanding_amount > 0 %s" % (self.doc.company, cond)) + elif self.doc.write_off_based_on == 'Accounts Payable': + return sql("select name, credit_to, outstanding_amount from `tabPurchase Invoice` where docstatus = 1 and company = '%s' and outstanding_amount > 0 %s" % (self.doc.company, cond)) - # ------------------------- - # get outstanding invoices - # ------------------------- - def get_outstanding_invoices(self): - self.doclist = self.doc.clear_table(self.doclist, 'entries') - total = 0 - for d in self.get_values(): - total += flt(d[2]) - jd = addchild(self.doc, 'entries', 'Journal Voucher Detail', 1, self.doclist) - jd.account = cstr(d[1]) - if self.doc.write_off_based_on == 'Accounts Receivable': - jd.credit = flt(d[2]) - jd.against_invoice = cstr(d[0]) - elif self.doc.write_off_based_on == 'Accounts Payable': - jd.debit = flt(d[2]) - jd.against_voucher = cstr(d[0]) - jd.save(1) - jd = addchild(self.doc, 'entries', 'Journal Voucher Detail', 1, self.doclist) - if self.doc.write_off_based_on == 'Accounts Receivable': - jd.debit = total - elif self.doc.write_off_based_on == 'Accounts Payable': - jd.credit = total - jd.save(1) + # ------------------------- + # get outstanding invoices + # ------------------------- + def get_outstanding_invoices(self): + self.doclist = self.doc.clear_table(self.doclist, 'entries') + total = 0 + for d in self.get_values(): + total += flt(d[2]) + jd = addchild(self.doc, 'entries', 'Journal Voucher Detail', 1, self.doclist) + jd.account = cstr(d[1]) + if self.doc.write_off_based_on == 'Accounts Receivable': + jd.credit = flt(d[2]) + jd.against_invoice = cstr(d[0]) + elif self.doc.write_off_based_on == 'Accounts Payable': + jd.debit = flt(d[2]) + jd.against_voucher = cstr(d[0]) + jd.save(1) + jd = addchild(self.doc, 'entries', 'Journal Voucher Detail', 1, self.doclist) + if self.doc.write_off_based_on == 'Accounts Receivable': + jd.debit = total + elif self.doc.write_off_based_on == 'Accounts Payable': + jd.credit = total + jd.save(1) - #-------------------------------------------------------------------------------------------------------- - # VALIDATE - #-------------------------------------------------------------------------------------------------------- - def validate(self): - if not self.doc.is_opening: - self.doc.is_opening='No' - self.get_against_account() - self.validate_cheque_info() - self.create_remarks() - # tds - get_obj('TDS Control').validate_first_entry(self) - self.get_tds_category_account() + #-------------------------------------------------------------------------------------------------------- + # VALIDATE + #-------------------------------------------------------------------------------------------------------- + def validate(self): + if not self.doc.is_opening: + self.doc.is_opening='No' + self.get_against_account() + self.validate_cheque_info() + self.create_remarks() + # tds + get_obj('TDS Control').validate_first_entry(self) + self.get_tds_category_account() - self.validate_entries_for_advance() - self.set_aging_date() - - self.validate_against_jv() - self.set_print_format_fields() + self.validate_entries_for_advance() + self.set_aging_date() + + self.validate_against_jv() + self.set_print_format_fields() - #FY and Date validation - get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.posting_date,'Posting Date') + #FY and Date validation + get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.posting_date,'Posting Date') - #-------------------------------------------------------------------------------------------------------- - # On Update - Update Feed - #-------------------------------------------------------------------------------------------------------- - def on_update(self): - pass - - #-------------------------------------------------------------------------------------------------------- - # On submit - #-------------------------------------------------------------------------------------------------------- - def on_submit(self): - if self.doc.voucher_type in ['Bank Voucher', 'Contra Voucher', 'Journal Entry']: - self.check_credit_days() - self.check_account_against_entries() - get_obj(dt='GL Control').make_gl_entries(self.doc, self.doclist) + #-------------------------------------------------------------------------------------------------------- + # On Update - Update Feed + #-------------------------------------------------------------------------------------------------------- + def on_update(self): + pass + + #-------------------------------------------------------------------------------------------------------- + # On submit + #-------------------------------------------------------------------------------------------------------- + def on_submit(self): + if self.doc.voucher_type in ['Bank Voucher', 'Contra Voucher', 'Journal Entry']: + self.check_credit_days() + self.check_account_against_entries() + get_obj(dt='GL Control').make_gl_entries(self.doc, self.doclist) - # validate against jv no - def validate_against_jv(self): - for d in getlist(self.doclist, 'entries'): - if d.against_jv: - if d.against_jv == self.doc.name: - msgprint("You can not enter current voucher in 'Against JV' column") - raise Exception - elif not sql("select name from `tabJournal Voucher Detail` where account = '%s' and docstatus = 1 and parent = '%s'" % (d.account, d.against_jv)): - msgprint("Against JV: "+ d.against_jv + " is not valid. Please check") - raise Exception - - #-------------------------------------------------------------------------------------------------------- - # On cancel reverse gl entry - #-------------------------------------------------------------------------------------------------------- - def on_cancel(self): - self.check_tds_payment_voucher() - get_obj(dt='GL Control').make_gl_entries(self.doc, self.doclist, cancel=1) + # validate against jv no + def validate_against_jv(self): + for d in getlist(self.doclist, 'entries'): + if d.against_jv: + if d.against_jv == self.doc.name: + msgprint("You can not enter current voucher in 'Against JV' column") + raise Exception + elif not sql("select name from `tabJournal Voucher Detail` where account = '%s' and docstatus = 1 and parent = '%s'" % (d.account, d.against_jv)): + msgprint("Against JV: "+ d.against_jv + " is not valid. Please check") + raise Exception + + #-------------------------------------------------------------------------------------------------------- + # On cancel reverse gl entry + #-------------------------------------------------------------------------------------------------------- + def on_cancel(self): + self.check_tds_payment_voucher() + get_obj(dt='GL Control').make_gl_entries(self.doc, self.doclist, cancel=1) - # Check whether tds payment voucher has been created against this voucher - #--------------------------------------------------------------------------- - def check_tds_payment_voucher(self): - tdsp = sql("select parent from `tabTDS Payment Detail` where voucher_no = '%s' and docstatus = 1 and parent not like 'old%'") - if tdsp: - msgprint("TDS Payment voucher '%s' has been made against this voucher. Please cancel the payment voucher to proceed." % (tdsp and tdsp[0][0] or '')) - raise Exception + # Check whether tds payment voucher has been created against this voucher + #--------------------------------------------------------------------------- + def check_tds_payment_voucher(self): + tdsp = sql("select parent from `tabTDS Payment Detail` where voucher_no = '%s' and docstatus = 1 and parent not like 'old%'") + if tdsp: + msgprint("TDS Payment voucher '%s' has been made against this voucher. Please cancel the payment voucher to proceed." % (tdsp and tdsp[0][0] or '')) + raise Exception diff --git a/accounts/doctype/journal_voucher/test_journal_voucher.py b/accounts/doctype/journal_voucher/test_journal_voucher.py new file mode 100644 index 0000000000..bb0568752d --- /dev/null +++ b/accounts/doctype/journal_voucher/test_journal_voucher.py @@ -0,0 +1,118 @@ +# ERPNext - web based ERP (http://erpnext.com) +# Copyright (C) 2012 Web Notes Technologies Pvt Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please edit this list and import only required elements + +import unittest +import webnotes +import webnotes.model +from webnotes.utils import nowdate, flt, add_days +from accounts.utils import get_fiscal_year, get_balance_on + +company = webnotes.conn.get_default("company") +abbr = webnotes.conn.get_value("Company", company, "abbr") + +data = { + "expense_account": { + "doctype": "Account", + "account_name": "Test Expense", + "parent_account": "Direct Expenses - %s" % abbr, + "company": company, + "debit_or_credit": "Debit", + "is_pl_account": "Yes", + "group_or_ledger": "Ledger" + }, + "supplier_account": { + "doctype": "Account", + "account_name": "Test Supplier", + "parent_account": "Accounts Payable - %s" % abbr, + "company": company, + "debit_or_credit": "Credit", + "is_pl_account": "No", + "group_or_ledger": "Ledger" + }, + "journal_voucher": [ + { + "doctype": "Journal Voucher", + "voucher_type": "Journal Entry", + "naming_series": "JV", + "posting_date": nowdate(), + "remark": "Test Journal Voucher", + "fiscal_year": get_fiscal_year(nowdate())[0], + "company": company + }, + { + "doctype": "Journal Voucher Detail", + "parentfield": "entries", + "account": "Test Expense - %s" % abbr, + "debit": 5000, + "cost_center": "Default CC Ledger - %s" % abbr, + }, + { + "doctype": "Journal Voucher Detail", + "parentfield": "entries", + "account": "Test Supplier - %s" % abbr, + "credit": 5000, + }, + ] +} + +def get_name(s): + return s + " - " + abbr + +class TestJournalVoucher(unittest.TestCase): + def setUp(self): + webnotes.conn.begin() + + # create a dummy account + webnotes.model.insert([data["expense_account"]]) + webnotes.model.insert([data["supplier_account"]]) + + def tearDown(self): + webnotes.conn.rollback() + + def test_save_journal_voucher(self): + expense_ac_balance = get_balance_on(get_name("Test Expense"), nowdate()) + supplier_ac_balance = get_balance_on(get_name("Test Supplier"), nowdate()) + + dl = webnotes.model.insert(data["journal_voucher"]) + dl.submit() + dl.load_from_db() + + # test submitted jv + self.assertTrue(webnotes.conn.exists("Journal Voucher", dl.doclist[0].name)) + for d in dl.doclist[1:]: + self.assertEquals(webnotes.conn.get_value("Journal Voucher Detail", + d.name, "parent"), dl.doclist[0].name) + + # test gl entry + gle = webnotes.conn.sql("""select account, debit, credit + from `tabGL Entry` where voucher_no = %s order by account""", + dl.doclist[0].name) + + self.assertEquals((gle[0][0], flt(gle[0][1]), flt(gle[0][2])), + ('Test Expense - %s' % abbr, 5000.0, 0.0)) + self.assertEquals((gle[1][0], flt(gle[1][1]), flt(gle[1][2])), + ('Test Supplier - %s' % abbr, 0.0, 5000.0)) + + # check balance as on today + self.assertEqual(get_balance_on(get_name("Test Expense"), nowdate()), + expense_ac_balance + 5000) + self.assertEqual(get_balance_on(get_name("Test Supplier"), nowdate()), + supplier_ac_balance + 5000) + + # check previous balance + self.assertEqual(get_balance_on(get_name("Test Expense"), add_days(nowdate(), -1)), 0) \ No newline at end of file diff --git a/accounts/doctype/mis_control/mis_control.py b/accounts/doctype/mis_control/mis_control.py index 202864ee62..9b38b9082c 100644 --- a/accounts/doctype/mis_control/mis_control.py +++ b/accounts/doctype/mis_control/mis_control.py @@ -8,11 +8,11 @@ # # 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 . +# along with this program. If not, see . # Please edit this list and import only required elements from __future__ import unicode_literals @@ -30,390 +30,342 @@ 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 accounts.utils import get_balance_on, get_fiscal_year class DocType: - def __init__(self, doc, doclist): - self.doc = doc - self.doclist = doclist - self.account_list = [] - self.ac_details = {} # key: account id, values: debit_or_credit, lft, rgt - - self.roles = webnotes.user.get_roles() + def __init__(self, doc, doclist): + self.doc = doc + self.doclist = doclist + self.account_list = [] + self.ac_details = {} # key: account id, values: debit_or_credit, lft, rgt + + self.roles = webnotes.user.get_roles() - self.period_list = [] - self.period_start_date = {} - self.period_end_date = {} + self.period_list = [] + self.period_start_date = {} + self.period_end_date = {} - self.fs_list = [] - self.root_bal = [] - self.flag = 0 + self.fs_list = [] + self.root_bal = [] + self.flag = 0 - # Get defaults on load of MIS, MIS - Comparison Report and Financial statements - # ---------------------------------------------------- - def get_comp(self): - ret = {} - type = [] - comp = [] - # ------ get period ----------- - ret['period'] = ['Annual','Half Yearly','Quarterly','Monthly'] - - # ---- get companies --------- - res = sql("select name from `tabCompany`") - for r in res: - comp.append(r[0]) - #comp.append(r[0] for r in res) - ret['company'] = comp + # Get defaults on load of MIS, MIS - Comparison Report and Financial statements + # ---------------------------------------------------- + def get_comp(self): + ret = {} + type = [] + comp = [] + # ------ get period ----------- + ret['period'] = ['Annual','Half Yearly','Quarterly','Monthly'] + + # ---- get companies --------- + res = sql("select name from `tabCompany`") + for r in res: + comp.append(r[0]) + #comp.append(r[0] for r in res) + ret['company'] = comp - #--- to get fiscal year and start_date of that fiscal year ----- - res = sql("select name, year_start_date from `tabFiscal Year`") - ret['fiscal_year'] = [r[0] for r in res] - ret['start_dates'] = {} - for r in res: - ret['start_dates'][r[0]] = str(r[1]) - - #--- from month and to month (for MIS - Comparison Report) ------- - month_list = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] - fiscal_start_month = sql("select MONTH(year_start_date) from `tabFiscal Year` where name = %s",(get_defaults()['fiscal_year'])) - fiscal_start_month = fiscal_start_month and fiscal_start_month[0][0] or 1 - mon = [''] - for i in range(fiscal_start_month,13): mon.append(month_list[i-1]) - for i in range(0,fiscal_start_month-1): mon.append(month_list[i]) - ret['month'] = mon + #--- to get fiscal year and start_date of that fiscal year ----- + res = sql("select name, year_start_date from `tabFiscal Year`") + ret['fiscal_year'] = [r[0] for r in res] + ret['start_dates'] = {} + for r in res: + ret['start_dates'][r[0]] = str(r[1]) + + #--- from month and to month (for MIS - Comparison Report) ------- + month_list = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] + fiscal_start_month = sql("select MONTH(year_start_date) from `tabFiscal Year` where name = %s",(get_defaults()['fiscal_year'])) + fiscal_start_month = fiscal_start_month and fiscal_start_month[0][0] or 1 + mon = [''] + for i in range(fiscal_start_month,13): mon.append(month_list[i-1]) + for i in range(0,fiscal_start_month-1): mon.append(month_list[i]) + ret['month'] = mon - # ------------------------ get MIS Type on basis of roles of session user ------------------------------------------ - if has_common(self.roles, ['Sales Manager']): - type.append('Sales') - if has_common(self.roles, ['Purchase Manager']): - type.append('Purchase') - ret['type'] = type - return ret - - # Gets Transactions type and Group By options based on module - #------------------------------------------------------------------ - def get_trans_group(self,module): - ret = {} - st,group = [],[] - if module == 'Sales': - st = ['Quotation','Sales Order','Delivery Note','Sales Invoice'] - group = ['Item','Item Group','Customer','Customer Group','Cost Center'] - elif module == 'Purchase': - st = ['Purchase Order','Purchase Receipt','Purchase Invoice'] - group = ['Item','Item Group','Supplier','Supplier Type'] - - ret['stmt_type'] = st - ret['group_by'] = group - - return ret + # ------------------------ get MIS Type on basis of roles of session user ------------------------------------------ + if has_common(self.roles, ['Sales Manager']): + type.append('Sales') + if has_common(self.roles, ['Purchase Manager']): + type.append('Purchase') + ret['type'] = type + return ret + + # Gets Transactions type and Group By options based on module + #------------------------------------------------------------------ + def get_trans_group(self,module): + ret = {} + st,group = [],[] + if module == 'Sales': + st = ['Quotation','Sales Order','Delivery Note','Sales Invoice'] + group = ['Item','Item Group','Customer','Customer Group','Cost Center'] + elif module == 'Purchase': + st = ['Purchase Order','Purchase Receipt','Purchase Invoice'] + group = ['Item','Item Group','Supplier','Supplier Type'] + + ret['stmt_type'] = st + ret['group_by'] = group + + return ret - # Get Days based on month (for MIS Comparison Report) - # -------------------------------------------------------- - def get_days(self,month): - days = [] - ret = {} - if month == 'Jan' or month == 'Mar' or month == 'May' or month == 'Jul' or month == 'Aug' or month == 'Oct' or month == 'Dec': - for i in range(1,32): - days.append(i) - elif month == 'Apr' or month == 'Jun' or month == 'Sep' or month == 'Nov': - for i in range(1,31): - days.append(i) - elif month == 'Feb': - for i in range(1,29): - days.append(i) - ret['days'] = days - return ret + # Get Days based on month (for MIS Comparison Report) + # -------------------------------------------------------- + def get_days(self,month): + days = [] + ret = {} + if month == 'Jan' or month == 'Mar' or month == 'May' or month == 'Jul' or month == 'Aug' or month == 'Oct' or month == 'Dec': + for i in range(1,32): + days.append(i) + elif month == 'Apr' or month == 'Jun' or month == 'Sep' or month == 'Nov': + for i in range(1,31): + days.append(i) + elif month == 'Feb': + for i in range(1,29): + days.append(i) + ret['days'] = days + return ret - # Get from date and to date based on fiscal year (for in summary - comparison report) - # ----------------------------------------------------------------------------------------------------- - def dates(self,fiscal_year,from_date,to_date): - import datetime - ret = '' - start_date = cstr(sql("select year_start_date from `tabFiscal Year` where name = %s",fiscal_year)[0][0]) - st_mon = cint(from_date.split('-')[1]) - ed_mon = cint(to_date.split('-')[1]) - st_day = cint(from_date.split('-')[2]) - ed_day = cint(to_date.split('-')[2]) - fiscal_start_month = cint(start_date.split('-')[1]) - next_fiscal_year = cint(start_date.split('-')[0]) + 1 - current_year = '' - next_year = '' - - #CASE - 1 : Jan - Mar (Valid) - if st_mon < fiscal_start_month and ed_mon < fiscal_start_month: - current_year = cint(start_date.split('-')[0]) + 1 - next_year = cint(start_date.split('-')[0]) + 1 - - # Case - 2 : Apr - Dec (Valid) - elif st_mon >= fiscal_start_month and ed_mon <= 12 and ed_mon >= fiscal_start_month: - current_year = cint(start_date.split('-')[0]) - next_year = cint(start_date.split('-')[0]) + # Get from date and to date based on fiscal year (for in summary - comparison report) + # ----------------------------------------------------------------------------------------------------- + def dates(self,fiscal_year,from_date,to_date): + import datetime + ret = '' + start_date = cstr(sql("select year_start_date from `tabFiscal Year` where name = %s",fiscal_year)[0][0]) + st_mon = cint(from_date.split('-')[1]) + ed_mon = cint(to_date.split('-')[1]) + st_day = cint(from_date.split('-')[2]) + ed_day = cint(to_date.split('-')[2]) + fiscal_start_month = cint(start_date.split('-')[1]) + next_fiscal_year = cint(start_date.split('-')[0]) + 1 + current_year = '' + next_year = '' + + #CASE - 1 : Jan - Mar (Valid) + if st_mon < fiscal_start_month and ed_mon < fiscal_start_month: + current_year = cint(start_date.split('-')[0]) + 1 + next_year = cint(start_date.split('-')[0]) + 1 + + # Case - 2 : Apr - Dec (Valid) + elif st_mon >= fiscal_start_month and ed_mon <= 12 and ed_mon >= fiscal_start_month: + current_year = cint(start_date.split('-')[0]) + next_year = cint(start_date.split('-')[0]) - # Case 3 : Jan - May (Invalid) - elif st_mon < fiscal_start_month and ed_mon >= fiscal_start_month: - current_year = cint(start_date.split('-')[0]) + 1 - next_year = cint(start_date.split('-')[0]) + 2 + # Case 3 : Jan - May (Invalid) + elif st_mon < fiscal_start_month and ed_mon >= fiscal_start_month: + current_year = cint(start_date.split('-')[0]) + 1 + next_year = cint(start_date.split('-')[0]) + 2 - # check whether from date is within fiscal year - if datetime.date(current_year, st_mon, st_day) >= datetime.date(cint(start_date.split('-')[0]), cint(start_date.split('-')[1]), cint(start_date.split('-')[2])) and datetime.date(cint(current_year), cint(st_mon), cint(st_day)) < datetime.date((cint(start_date.split('-')[0])+1), cint(start_date.split('-')[1]), cint(start_date.split('-')[2])): - begin_date = cstr(current_year)+"-"+cstr(st_mon)+"-"+cstr(st_day) - else: - msgprint("Please enter appropriate from date.") - raise Exception - # check whether to date is within fiscal year - if datetime.date(next_year, ed_mon, ed_day) >= datetime.date(cint(start_date.split('-')[0]), cint(start_date.split('-')[1]), cint(start_date.split('-')[2])) and datetime.date(cint(next_year), cint(ed_mon), cint(ed_day)) < datetime.date(cint(start_date.split('-')[0])+1, cint(start_date.split('-')[1]), cint(start_date.split('-')[2])): - end_date = cstr(next_year)+"-"+cstr(ed_mon)+"-"+cstr(ed_day) - else: - msgprint("Please enter appropriate to date.") - raise Exception - ret = begin_date+'~~~'+end_date - return ret + # check whether from date is within fiscal year + if datetime.date(current_year, st_mon, st_day) >= datetime.date(cint(start_date.split('-')[0]), cint(start_date.split('-')[1]), cint(start_date.split('-')[2])) and datetime.date(cint(current_year), cint(st_mon), cint(st_day)) < datetime.date((cint(start_date.split('-')[0])+1), cint(start_date.split('-')[1]), cint(start_date.split('-')[2])): + begin_date = cstr(current_year)+"-"+cstr(st_mon)+"-"+cstr(st_day) + else: + msgprint("Please enter appropriate from date.") + raise Exception + # check whether to date is within fiscal year + if datetime.date(next_year, ed_mon, ed_day) >= datetime.date(cint(start_date.split('-')[0]), cint(start_date.split('-')[1]), cint(start_date.split('-')[2])) and datetime.date(cint(next_year), cint(ed_mon), cint(ed_day)) < datetime.date(cint(start_date.split('-')[0])+1, cint(start_date.split('-')[1]), cint(start_date.split('-')[2])): + end_date = cstr(next_year)+"-"+cstr(ed_mon)+"-"+cstr(ed_day) + else: + msgprint("Please enter appropriate to date.") + raise Exception + ret = begin_date+'~~~'+end_date + return ret - # Get MIS Totals - # --------------- - def get_totals(self, args): - args = eval(args) - #msgprint(args) - totals = sql("SELECT %s FROM %s WHERE %s %s %s %s" %(cstr(args['query_val']), cstr(args['tables']), cstr(args['company']), cstr(args['cond']), cstr(args['add_cond']), cstr(args['fil_cond'])), as_dict = 1)[0] - #msgprint(totals) - tot_keys = totals.keys() - # return in flt because JSON doesn't accept Decimal - for d in tot_keys: - totals[d] = flt(totals[d]) - return totals + # Get MIS Totals + # --------------- + def get_totals(self, args): + args = eval(args) + #msgprint(args) + totals = sql("SELECT %s FROM %s WHERE %s %s %s %s" %(cstr(args['query_val']), cstr(args['tables']), cstr(args['company']), cstr(args['cond']), cstr(args['add_cond']), cstr(args['fil_cond'])), as_dict = 1)[0] + #msgprint(totals) + tot_keys = totals.keys() + # return in flt because JSON doesn't accept Decimal + for d in tot_keys: + totals[d] = flt(totals[d]) + return totals - # Get Statement - # ------------- - - def get_statement(self, arg): - self.return_data = [] + # Get Statement + # ------------- + + def get_statement(self, arg): + self.return_data = [] - # define periods - arg = eval(arg) - pl = '' - - self.define_periods(arg['year'], arg['period']) # declares 1.period_list i.e. (['Jan','Feb','Mar'...] or ['Q1','Q2'...] or ['FY2009-2010']) based on period - # 2.period_start_date dict {'Jan':'01-01-2009'...} - # 3.period_start_date dict {'Jan':'31-01-2009'...} - self.return_data.append([4,'']+self.period_list) + # define periods + arg = eval(arg) + pl = '' + + self.define_periods(arg['year'], arg['period']) # declares 1.period_list i.e. (['Jan','Feb','Mar'...] or ['Q1','Q2'...] or ['FY2009-2010']) based on period + # 2.period_start_date dict {'Jan':'01-01-2009'...} + # 3.period_start_date dict {'Jan':'31-01-2009'...} + self.return_data.append([4,'']+self.period_list) - - if arg['statement'] == 'Balance Sheet': pl = 'No' - if arg['statement'] == 'Profit & Loss': pl = 'Yes' - - self.get_children('',0,pl,arg['company'], arg['year']) - - #self.balance_pl_statement(acct, arg['statement']) - #msgprint(self.return_data) - return self.return_data - - # Get Children - # ------------ - def get_children(self, parent_account, level, pl, company, fy): - cl = sql("select distinct account_name, name, debit_or_credit, lft, rgt from `tabAccount` where ifnull(parent_account, '') = %s and ifnull(is_pl_account, 'No')=%s and company=%s and docstatus != 2 order by name asc", (parent_account, pl, company)) - level0_diff = [0 for p in self.period_list] - if pl=='Yes' and level==0: # switch for income & expenses - cl = [c for c in cl] - cl.reverse() - if cl: - for c in cl: - self.ac_details[c[1]] = [c[2], c[3], c[4]] - bal_list = self.get_period_balance(c[1], level, pl, company, fy) - if level==0: # top level - put balances as totals - self.return_data.append([level, c[0]] + ['' for b in bal_list]) - totals = bal_list - for i in range(len(totals)): # make totals - if c[2]=='Credit': - level0_diff[i] += flt(totals[i]) - else: - level0_diff[i] -= flt(totals[i]) - else: - self.return_data.append([level, c[0]]+bal_list) - - if level < 2: - self.get_children(c[1], level+1, pl, company, fy) - - # make totals - for top level - # --------------------------- - if level==0: - # add rows for profit / loss in B/S - if pl=='No': - if c[2]=='Credit': - self.return_data.append([1, 'Total Liabilities'] + totals) - level0_diff = [-i for i in level0_diff] # convert to debit - self.return_data.append([5, 'Profit/Loss (Provisional)'] + level0_diff) - for i in range(len(totals)): # make totals - level0_diff[i] = flt(totals[i]) + level0_diff[i] - self.return_data.append([4, 'Total '+c[0]] + level0_diff) - else: - self.return_data.append([4, 'Total '+c[0]] + totals) + + if arg['statement'] == 'Balance Sheet': pl = 'No' + if arg['statement'] == 'Profit & Loss': pl = 'Yes' + + self.get_children('',0,pl,arg['company'], arg['year']) + + #self.balance_pl_statement(acct, arg['statement']) + #msgprint(self.return_data) + return self.return_data + + # Get Children + # ------------ + def get_children(self, parent_account, level, pl, company, fy): + cl = sql("select distinct account_name, name, debit_or_credit, lft, rgt from `tabAccount` where ifnull(parent_account, '') = %s and ifnull(is_pl_account, 'No')=%s and company=%s and docstatus != 2 order by name asc", (parent_account, pl, company)) + level0_diff = [0 for p in self.period_list] + if pl=='Yes' and level==0: # switch for income & expenses + cl = [c for c in cl] + cl.reverse() + if cl: + for c in cl: + self.ac_details[c[1]] = [c[2], c[3], c[4]] + bal_list = self.get_period_balance(c[1]) + if level==0: # top level - put balances as totals + self.return_data.append([level, c[0]] + ['' for b in bal_list]) + totals = bal_list + for i in range(len(totals)): # make totals + if c[2]=='Credit': + level0_diff[i] += flt(totals[i]) + else: + level0_diff[i] -= flt(totals[i]) + else: + self.return_data.append([level, c[0]]+bal_list) + + if level < 2: + self.get_children(c[1], level+1, pl, company, fy) + + # make totals - for top level + # --------------------------- + if level==0: + # add rows for profit / loss in B/S + if pl=='No': + if c[2]=='Credit': + self.return_data.append([1, 'Total Liabilities'] + totals) + level0_diff = [-i for i in level0_diff] # convert to debit + self.return_data.append([5, 'Profit/Loss (Provisional)'] + level0_diff) + for i in range(len(totals)): # make totals + level0_diff[i] = flt(totals[i]) + level0_diff[i] + self.return_data.append([4, 'Total '+c[0]] + level0_diff) + else: + self.return_data.append([4, 'Total '+c[0]] + totals) - # add rows for profit / loss in P/L - else: - if c[2]=='Debit': - self.return_data.append([1, 'Total Expenses (before Profit)'] + totals) - self.return_data.append([5, 'Profit/Loss (Provisional)'] + level0_diff) - for i in range(len(totals)): # make totals - level0_diff[i] = flt(totals[i]) + level0_diff[i] - self.return_data.append([4, 'Total '+c[0]] + level0_diff) - else: - self.return_data.append([4, 'Total '+c[0]] + totals) - - # Define Periods - # -------------- - - def define_periods(self, year, period): - - # get year start date - ysd = sql("select year_start_date from `tabFiscal Year` where name=%s", year) - ysd = ysd and ysd[0][0] or '' + # add rows for profit / loss in P/L + else: + if c[2]=='Debit': + self.return_data.append([1, 'Total Expenses (before Profit)'] + totals) + self.return_data.append([5, 'Profit/Loss (Provisional)'] + level0_diff) + for i in range(len(totals)): # make totals + level0_diff[i] = flt(totals[i]) + level0_diff[i] + self.return_data.append([4, 'Total '+c[0]] + level0_diff) + else: + self.return_data.append([4, 'Total '+c[0]] + totals) + + # Define Periods + # -------------- + + def define_periods(self, year, period): + + # get year start date + ysd = sql("select year_start_date from `tabFiscal Year` where name=%s", year) + ysd = ysd and ysd[0][0] or '' - self.ysd = ysd + self.ysd = ysd - # year - if period == 'Annual': - pn = 'FY'+year - self.period_list.append(pn) - self.period_start_date[pn] = ysd - self.period_end_date[pn] = get_last_day(get_first_day(ysd,0,11)) + # year + if period == 'Annual': + pn = 'FY'+year + self.period_list.append(pn) + self.period_start_date[pn] = ysd + self.period_end_date[pn] = get_last_day(get_first_day(ysd,0,11)) - # quarter - if period == 'Quarterly': - for i in range(4): - pn = 'Q'+str(i+1) - self.period_list.append(pn) - - self.period_start_date[pn] = get_first_day(ysd,0,i*3) - self.period_end_date[pn] = get_last_day(get_first_day(ysd,0,((i+1)*3)-1)) + # quarter + if period == 'Quarterly': + for i in range(4): + pn = 'Q'+str(i+1) + self.period_list.append(pn) + + self.period_start_date[pn] = get_first_day(ysd,0,i*3) + self.period_end_date[pn] = get_last_day(get_first_day(ysd,0,((i+1)*3)-1)) - # month - if period == 'Monthly': - mlist = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] - for i in range(12): - fd = get_first_day(ysd,0,i) - pn = mlist[fd.month-1] - self.period_list.append(pn) - - self.period_start_date[pn] = fd - self.period_end_date[pn] = get_last_day(fd) - - # Get Balance For A Period - # ------------------------ - - def get_period_balance(self, acc, level, pl, company, fy): - debit_or_credit, lft, rgt = self.ac_details[acc] - ret = [] - for p in self.period_list: - sd, ed = self.period_start_date[p].strftime('%Y-%m-%d'), self.period_end_date[p].strftime('%Y-%m-%d') - cond = "and t1.voucher_type != 'Period Closing Voucher'" - if pl=='No': - sd = self.ysd.strftime('%Y-%m-%d') - cond = "" + # month + if period == 'Monthly': + mlist = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] + for i in range(12): + fd = get_first_day(ysd,0,i) + pn = mlist[fd.month-1] + self.period_list.append(pn) + + self.period_start_date[pn] = fd + self.period_end_date[pn] = get_last_day(fd) + + def get_period_balance(self, acc): + ret = [] + for p in self.period_list: + period_end_date = self.period_end_date[p].strftime('%Y-%m-%d') + ret.append(get_balance_on(acc, period_end_date)) + return ret + + def get_top_5_cust(self, company): + rec_grp = sql("select receivables_group from tabCompany where name=%s", company) + if rec_grp: + pa_lft_rgt = sql("select lft, rgt from tabAccount where name=%s and company=%s", (rec_grp[0][0], company))[0] + return sql("select t1.account_name, SUM(t2.debit) from tabAccount t1, `tabGL Entry` t2 where t1.lft > %s and t1.rgt < %s and t2.account = t1.name and ifnull(t2.is_cancelled, 'No') = 'No' GROUP BY t1.name ORDER BY SUM(t2.debit) desc limit 5", (pa_lft_rgt[0], pa_lft_rgt[1])) + else: + return [] - bal = sql("select SUM(t1.debit), SUM(t1.credit) from `tabGL Entry` t1, `tabAccount` t2 WHERE t1.posting_date >= '%s' AND t1.posting_date <= '%s' AND t1.company = '%s' AND t1.account = t2.name AND t2.lft >= %s AND t2.rgt <= %s and ifnull(t1.is_opening,'No') = 'No' and ifnull(t1.is_cancelled, 'No') = 'No' %s" % (sd,ed,company,lft,rgt, cond)) - - - bal = bal and (flt(bal[0][0]) - flt(bal[0][1])) or 0 - if debit_or_credit == 'Credit' and bal: - bal = -bal - if pl=='No': - op = sql("select opening from `tabAccount Balance` where account=%s and period=%s", (acc, fy)) - op = op and op[0][0] or 0 - bal += flt(op) - - ret.append(bal) - return ret - - # Get Dashboard Amounts - # --------------------- - - def get_balance(self, acc, sd, ed, company, fy): - a = sql("select account_name, name, debit_or_credit, lft, rgt, is_pl_account from `tabAccount` where account_name=%s and company=%s", (acc, company), as_dict=1) - if a: - a = a[0] - bal = sql("select SUM(IFNULL(t1.debit,0)), SUM(IFNULL(t1.credit,0)) from `tabGL Entry` t1, `tabAccount` t2 WHERE t1.posting_date >= %s AND t1.posting_date <= %s AND t1.account = t2.name AND t2.lft >= %s AND t2.rgt <= %s and ifnull(is_opening, 'No') = 'No' and ifnull(t1.is_cancelled, 'No') = 'No'", (sd,ed,a['lft'],a['rgt'])) - if a['debit_or_credit']=='Debit': - bal = flt(flt(bal[0][0]) - flt(bal[0][1])) - else: - bal = flt(flt(bal[0][1]) - flt(bal[0][0])) + def get_top_5_exp(self, company): + a = sql("select distinct account_name, name, debit_or_credit, lft, rgt from `tabAccount` where account_name=%s and company=%s", ('Expenses', company), as_dict=1)[0] + return sql("select t1.account_name, SUM(t2.debit) from tabAccount t1, `tabGL Entry` t2 where t1.lft>%s and t1.rgt<%s and t1.group_or_ledger = 'Ledger' and t2.account = t1.name and ifnull(t2.is_cancelled, 'No') = 'No' and t2.voucher_type != 'Period Closing Voucher' GROUP BY t1.name ORDER BY SUM(t2.debit) desc limit 5", (a['lft'],a['rgt'])) + + def bl(self, acc, company): + dt = getdate(nowdate()) - if a['is_pl_account']=='No': - op = sql("select opening from `tabAccount Balance` where account=%s and period=%s", (acc, fy)) - op = op and op[0][0] or 0 - bal += flt(op) + r = [] + # cur + r.append(get_balance_on(acc, get_fiscal_year(nowdate()))) + # this month + r.append(get_balance_on(acc, get_last_day(dt))) + # last month + r.append(get_balance_on(acc, get_last_day(get_first_day(dt,0,-1)))) + + return r - return flt(bal) + def bl_bs(self, acc, company, sd): + dt = getdate(nowdate()) + r = [] + # cur + r.append(get_balance_on(acc, get_fiscal_year(nowdate()))) + # last month + r.append(self.get_balance_on(acc, get_last_day(get_first_day(dt,0,-1)))) + # opening + r.append(self.get_balance_on(acc, sd)) + return r - else: - msgprint("Did not find %s for %s" % (acc, company)) - return 0 + def get_dashboard_values(self, arg=''): + d = get_defaults() + self.fiscal_year = d['fiscal_year'] + if arg: + company = arg + else: + company = d['company'] - def get_cur_balance(self, acc, company): - bal = sql("select IFNULL(t1.balance,0) from `tabAccount Balance` t1, `tabAccount` t2 where t1.account = %s and t1.period=%s and t1.account = t2.name and t2.company=%s", (acc, self.fiscal_year, company)) - return bal and flt(bal[0][0]) or 0 - - def get_top_5_cust(self, company): - rec_grp = sql("select receivables_group from tabCompany where name=%s", company) - if rec_grp: - pa_lft_rgt = sql("select lft, rgt from tabAccount where name=%s and company=%s", (rec_grp[0][0], company))[0] - return sql("select t1.account_name, SUM(t2.debit) from tabAccount t1, `tabGL Entry` t2 where t1.lft > %s and t1.rgt < %s and t2.account = t1.name and ifnull(t2.is_cancelled, 'No') = 'No' GROUP BY t1.name ORDER BY SUM(t2.debit) desc limit 5", (pa_lft_rgt[0], pa_lft_rgt[1])) - else: - return [] + r = {} + r['Income'] = self.bl('Income', company) + r['Expenses'] = self.bl('Expenses', company) - def get_top_5_exp(self, company): - a = sql("select distinct account_name, name, debit_or_credit, lft, rgt from `tabAccount` where account_name=%s and company=%s", ('Expenses', company), as_dict=1)[0] - return sql("select t1.account_name, SUM(t2.debit) from tabAccount t1, `tabGL Entry` t2 where t1.lft>%s and t1.rgt<%s and t1.group_or_ledger = 'Ledger' and t2.account = t1.name and ifnull(t2.is_cancelled, 'No') = 'No' and t2.voucher_type != 'Period Closing Voucher' GROUP BY t1.name ORDER BY SUM(t2.debit) desc limit 5", (a['lft'],a['rgt'])) - - def bl(self, acc, company): - dt = getdate(nowdate()) + r['Profit'] = [] + for i in range(3): + r['Profit'].append(r['Income'][i] - r['Expenses'][i]) + + r['Current Assets'] = self.bl_bs('Current Assets', company, getdate(d['year_start_date'])) + r['Current Liabilities'] = self.bl_bs('Current Liabilities', company, getdate(d['year_start_date'])) + + r['Working Capital'] = [] + for i in range(3): + r['Working Capital'].append(r['Current Assets'][i] - r['Current Liabilities'][i]) - r = [] - # cur - r.append(self.get_cur_balance(acc, company)) - # this month - r.append(self.get_balance(acc, get_first_day(dt), get_last_day(dt), company, self.fiscal_year)) - # last month - r.append(self.get_balance(acc, get_first_day(dt,0,-1), get_last_day(get_first_day(dt,0,-1)), company, self.fiscal_year)) - return r - - def bl_bs(self, acc, company, sd): - dt = getdate(nowdate()) - r = [] - # cur - r.append(self.get_cur_balance(acc, company)) - # last month - r.append(self.get_balance(acc, sd, get_last_day(get_first_day(dt,0,-1)), company, self.fiscal_year)) - # opening - r.append(self.get_balance(acc, sd, sd, company, self.fiscal_year)) - return r - - def get_dashboard_values(self, arg=''): - d = get_defaults() - self.fiscal_year = d['fiscal_year'] - if arg: - company = arg - else: - company = d['company'] - - r = {} - r['Income'] = self.bl('Income', company) - r['Expenses'] = self.bl('Expenses', company) - - r['Profit'] = [] - for i in range(3): - r['Profit'].append(r['Income'][i] - r['Expenses'][i]) - - r['Current Assets'] = self.bl_bs('Current Assets', company, getdate(d['year_start_date'])) - r['Current Liabilities'] = self.bl_bs('Current Liabilities', company, getdate(d['year_start_date'])) - - r['Working Capital'] = [] - for i in range(3): - r['Working Capital'].append(r['Current Assets'][i] - r['Current Liabilities'][i]) - - r['Bank Accounts'] = self.bl_bs('Bank Accounts', company, getdate(d['year_start_date'])) - - r['Top Customers'] = convert_to_lists(self.get_top_5_cust(company)) - r['Top Expenses'] = convert_to_lists(self.get_top_5_exp(company)) - - return r + r['Bank Accounts'] = self.bl_bs('Bank Accounts', company, getdate(d['year_start_date'])) + + r['Top Customers'] = convert_to_lists(self.get_top_5_cust(company)) + r['Top Expenses'] = convert_to_lists(self.get_top_5_exp(company)) + + return r diff --git a/accounts/doctype/multi_ledger_report/__init__.py b/accounts/doctype/multi_ledger_report/__init__.py deleted file mode 100755 index baffc48825..0000000000 --- a/accounts/doctype/multi_ledger_report/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from __future__ import unicode_literals diff --git a/accounts/doctype/multi_ledger_report/multi_ledger_report.js b/accounts/doctype/multi_ledger_report/multi_ledger_report.js deleted file mode 100755 index 2dabb66356..0000000000 --- a/accounts/doctype/multi_ledger_report/multi_ledger_report.js +++ /dev/null @@ -1,19 +0,0 @@ -// ERPNext - web based ERP (http://erpnext.com) -// Copyright (C) 2012 Web Notes Technologies Pvt Ltd -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -cur_frm.cscript.export_report = function(doc, cdt, cdn) { - $c_obj_csv(make_doclist(cdt, cdn), 'get_report_data', ''); -} diff --git a/accounts/doctype/multi_ledger_report/multi_ledger_report.py b/accounts/doctype/multi_ledger_report/multi_ledger_report.py deleted file mode 100755 index 51dad0fc1f..0000000000 --- a/accounts/doctype/multi_ledger_report/multi_ledger_report.py +++ /dev/null @@ -1,150 +0,0 @@ -# ERPNext - web based ERP (http://erpnext.com) -# Copyright (C) 2012 Web Notes Technologies Pvt Ltd -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -from __future__ import unicode_literals -import webnotes -from webnotes.utils import add_days, cint, cstr, flt, getdate -from webnotes.model.doclist import getlist -from webnotes.model.code import get_obj -from webnotes import session, form, msgprint, errprint - -sql = webnotes.conn.sql -get_value = webnotes.conn.get_value - -#--------------------------------------------------------------------- - -class DocType: - def __init__(self, doc, doclist=[]): - self.doc = doc - self.doclist = doclist - - # Get fiscal year based on date - def get_year(self, dt): - yr = sql("select name from `tabFiscal Year` where %s between year_start_date and date_sub(date_add(year_start_date,interval 1 year), interval 1 day)",dt) - return yr and yr[0][0] or '' - - - def validate_date(self): - """check for from date and to date within same year""" - if not sql("select name from `tabFiscal Year` where %s between year_start_date and date_sub(date_add(year_start_date,interval 1 year), interval 1 day) and %s between year_start_date and date_sub(date_add(year_start_date,interval 1 year), interval 1 day)",(self.doc.from_date, self.doc.to_date)): - msgprint("From Date and To Date must be within same year") - raise Exception - - if not self.doc.from_date or not self.doc.to_date: - msgprint("From Date and To Date is mandatory") - raise Exception - - - def add_header(self): - title = 'Ledger Balances Between ' + getdate(self.doc.from_date).strftime('%d-%m-%Y') + ' and ' + getdate(self.doc.to_date).strftime('%d-%m-%Y') - return [[title], ['Account', 'Posting Date', 'Voucher Type', 'Voucher No', 'Debit', 'Credit', 'Remarks']] - - - - def get_account_subtree(self, acc): - return sql(""" - SELECT - CONCAT(REPEAT(' ', COUNT(parent.name) - (sub_tree.depth + 1)), node.name) as account, - node.lft AS lft, node.rgt AS rgt, - node.debit_or_credit as dr_or_cr, node.group_or_ledger as group_or_ledger, node.is_pl_account as is_pl_account - FROM tabAccount AS node, - tabAccount AS parent, - tabAccount AS sub_parent, - ( - SELECT node.name, (COUNT(parent.name) - 1) AS depth - FROM tabAccount AS node, tabAccount AS parent - WHERE node.lft BETWEEN parent.lft AND parent.rgt - AND node.name = %s - GROUP BY node.name - ORDER BY node.lft - )AS sub_tree - WHERE node.lft BETWEEN parent.lft AND parent.rgt - AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt - AND sub_parent.name = sub_tree.name - GROUP BY node.name - ORDER BY node.lft""", acc, as_dict = 1, as_utf8=1) - - - - def get_acc_summary(self, glc, acc_det): - from_date_year = self.get_year(add_days(self.doc.from_date, -1)) - to_date_year = self.get_year(self.doc.to_date) - acc = acc_det['account'].strip() - - if from_date_year == to_date_year: - debit_on_fromdate, credit_on_fromdate, opening = glc.get_as_on_balance(acc, from_date_year, add_days(self.doc.from_date, -1), acc_det['dr_or_cr'], acc_det['lft'], acc_det['rgt']) # opening = closing of prev_date - elif acc_det['is_pl_account'] == 'No': # if there is no previous year in system and not pl account - opening = sql("select opening from `tabAccount Balance` where account = %s and period = %s", (acc, to_date_year)) - debit_on_fromdate, credit_on_fromdate, opening = 0, 0, flt(opening[0][0]) - else: # if pl account and there is no previous year in system - debit_on_fromdate, credit_on_fromdate, opening = 0,0,0 - - # closing balance - #-------------------------------- - debit_on_todate, credit_on_todate, closing = glc.get_as_on_balance(acc, to_date_year, self.doc.to_date, acc_det['dr_or_cr'], acc_det['lft'], acc_det['rgt']) - - # transaction betn the period - #---------------------------------------- - debit = flt(debit_on_todate) - flt(debit_on_fromdate) - credit = flt(credit_on_todate) - flt(credit_on_fromdate) - - # Debit / Credit - if acc_det['dr_or_cr'] == 'Credit': - opening, closing = -1*opening, -1*closing - - return flt(opening>0 and opening or 0), flt(opening<0 and -opening or 0), \ - debit, credit, flt(closing>0.01 and closing or 0), flt(closing<-0.01 and -closing or 0) - - - def show_gl_entries(self, acc): - """Get gl entries for the period and account""" - gle = sql("select posting_date, voucher_type, voucher_no, debit, credit, remarks from `tabGL Entry` WHERE account = %s and posting_date >= %s AND posting_date <= %s and ifnull(is_opening, 'No') = 'No' and ifnull(is_cancelled, 'No') = 'No'", (acc, self.doc.from_date, self.doc.to_date), as_dict=1, as_utf8=1) - entries, dr, cr = [], 0, 0 - for d in gle: - entries.append(['', d['posting_date'], d['voucher_type'], d['voucher_no'], d['debit'], d['credit'], d['remarks']]) - return entries - - - - - # Get Report Data - def get_report_data(self): - self.validate_date() - - res = [] - res += self.add_header() - - glc = get_obj('GL Control') - - for d in getlist(self.doclist, 'ledger_details'): - # Fetch acc details - sub_tree = self.get_account_subtree(d.account) - - for acc_det in sub_tree: - acc_summary = self.get_acc_summary(glc, acc_det) - if acc_summary[0] or acc_summary[1] or acc_summary[2] or acc_summary[3] or acc_summary[4] or acc_summary[5]: - res.append([acc_det['account']]) - # Show gl entries if account is ledger - if acc_det['group_or_ledger'] == 'Ledger' and (acc_summary[2] or acc_summary[3]): - gle = self.show_gl_entries(acc_det['account'].strip()) - res += gle - - # Totals - res.append(['', '', '', 'Total Debit/Credit', acc_summary[2], acc_summary[3]]) - res.append(['', '', '', 'Opening Balance', acc_summary[0], acc_summary[1]]) - res.append(['', '', '', 'Closing Balance', acc_summary[4], acc_summary[5]]) - - return res diff --git a/accounts/doctype/multi_ledger_report/multi_ledger_report.txt b/accounts/doctype/multi_ledger_report/multi_ledger_report.txt deleted file mode 100755 index 0ef7a5d33f..0000000000 --- a/accounts/doctype/multi_ledger_report/multi_ledger_report.txt +++ /dev/null @@ -1,124 +0,0 @@ -# DocType, Multi Ledger Report -[ - - # These values are common in all dictionaries - { - 'creation': '2012-03-27 14:35:44', - 'docstatus': 0, - 'modified': '2012-03-27 14:35:44', - 'modified_by': u'Administrator', - 'owner': u'Administrator' - }, - - # These values are common for all DocType - { - '_last_update': u'1306229235', - 'allow_copy': 1, - 'allow_email': 1, - 'allow_print': 1, - 'colour': u'White:FFF', - 'doctype': 'DocType', - 'document_type': u'Other', - 'hide_heading': 0, - 'issingle': 1, - 'module': u'Accounts', - 'name': '__common__', - 'section_style': u'Simple', - 'show_in_menu': 0, - 'version': 9 - }, - - # These values are common for all DocField - { - 'doctype': u'DocField', - 'name': '__common__', - 'parent': u'Multi Ledger Report', - 'parentfield': u'fields', - 'parenttype': u'DocType', - 'permlevel': 0 - }, - - # These values are common for all DocPerm - { - 'create': 1, - 'doctype': u'DocPerm', - 'name': '__common__', - 'parent': u'Multi Ledger Report', - 'parentfield': u'permissions', - 'parenttype': u'DocType', - 'permlevel': 0, - 'read': 1, - 'write': 1 - }, - - # DocType, Multi Ledger Report - { - 'doctype': 'DocType', - 'name': u'Multi Ledger Report' - }, - - # DocPerm - { - 'doctype': u'DocPerm', - 'role': u'Accounts Manager' - }, - - # DocPerm - { - 'doctype': u'DocPerm', - 'role': u'Accounts User' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'select_date_range', - 'fieldtype': u'Column Break', - 'label': u'Select Date Range' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'from_date', - 'fieldtype': u'Date', - 'label': u'From Date', - 'reqd': 1 - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'to_date', - 'fieldtype': u'Date', - 'label': u'To Date', - 'reqd': 1 - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'select_ledgers', - 'fieldtype': u'Column Break', - 'label': u'Select ledgers' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'ledger_details', - 'fieldtype': u'Table', - 'label': u'Multi Ledger Report Details', - 'options': u'Multi Ledger Report Detail' - }, - - # DocField - { - 'colour': u'White:FFF', - 'doctype': u'DocField', - 'fieldname': u'export_report', - 'fieldtype': u'Button', - 'label': u'Export Report', - 'trigger': u'Client' - } -] \ No newline at end of file diff --git a/accounts/doctype/period_closing_voucher/period_closing_voucher.py b/accounts/doctype/period_closing_voucher/period_closing_voucher.py index f8d2c5444f..8889a09cc1 100644 --- a/accounts/doctype/period_closing_voucher/period_closing_voucher.py +++ b/accounts/doctype/period_closing_voucher/period_closing_voucher.py @@ -63,7 +63,8 @@ class DocType: def validate_posting_date(self): - yr = sql("select start_date, end_date from `tabPeriod` where fiscal_year = '%s' and period_type = 'Year'" % (self.doc.fiscal_year)) + yr = sql("""select year_start_date, adddate(year_start_date, interval 1 year) + from `tabFiscal Year` where name=%s""", (self.doc.fiscal_year, )) self.year_start_date = yr and yr[0][0] or '' self.year_end_date = yr and yr[0][1] or '' diff --git a/accounts/page/accounts_browser/accounts_browser.js b/accounts/page/accounts_browser/accounts_browser.js index 55d6be9c1c..e5a30b0bcc 100644 --- a/accounts/page/accounts_browser/accounts_browser.js +++ b/accounts/page/accounts_browser/accounts_browser.js @@ -122,8 +122,8 @@ erpnext.AccountsChart = Class.extend({ +encodeURIComponent(data.value)+'">Edit'); } if (data.expandable) { - if (wn.boot.profile.can_create.indexOf(this.ctype) !== -1 || - wn.boot.profile.in_create.indexOf(this.ctype) !== -1) { + if((wn.boot.profile.can_create.indexOf(this.ctype) !== -1) || + (wn.boot.profile.in_create.indexOf(this.ctype) !== -1)) { node_links.push('Add Child'); } } else if (this.ctype === 'Account' && wn.boot.profile.can_read.indexOf("GL Entry") !== -1) { diff --git a/accounts/page/accounts_browser/accounts_browser.py b/accounts/page/accounts_browser/accounts_browser.py index aa955aeff1..76c64b7ca8 100644 --- a/accounts/page/accounts_browser/accounts_browser.py +++ b/accounts/page/accounts_browser/accounts_browser.py @@ -1,6 +1,7 @@ from __future__ import unicode_literals import webnotes -from webnotes.utils import get_defaults, cstr +from webnotes.utils import get_defaults, fmt_money +from accounts.utils import get_balance_on @webnotes.whitelist() def get_companies(): @@ -49,16 +50,7 @@ def get_children(): if ctype == 'Account': currency = webnotes.conn.sql("select default_currency from `tabCompany` where name = %s", company)[0][0] for each in acc: - bal = webnotes.conn.sql("select balance from `tabAccount Balance` \ - where account = %s and period = %s", (each.get('value'), get_defaults('fiscal_year'))) - bal = bal and bal[0][0] or 0 - each['balance'] = currency + ' ' + cstr(bal) + bal = get_balance_on(each.get("value")) + each['balance'] = currency + ' ' + fmt_money(bal) return acc - - -@webnotes.whitelist() -def get_account_balance(): - args = webnotes.form_dict - acc = args['acc'] - return 'Rs. 100' \ No newline at end of file diff --git a/accounts/page/accounts_home/accounts_home.html b/accounts/page/accounts_home/accounts_home.html index 5950173c5b..3a6f2b8426 100644 --- a/accounts/page/accounts_home/accounts_home.html +++ b/accounts/page/accounts_home/accounts_home.html @@ -58,11 +58,6 @@ title="Clear your P/L account and balance your Balance Sheets" href="#!List/Period Closing Voucher">Close Period Entry -
. +# along with this program. If not, see . #get company from __future__ import unicode_literals @@ -20,10 +20,10 @@ company = filter_values.get('company') or get_defaults()['company'] # To date if not filter_values.get('clearance_date1'): - msgprint('Please enter To Clearance Date') - raise Exception + msgprint('Please enter To Clearance Date') + raise Exception else: - to_date = filter_values['clearance_date1'] + to_date = filter_values['clearance_date1'] #Fiscal year and year start date @@ -31,32 +31,33 @@ else: ysd, fiscal_year = sql("select year_start_date, name from `tabFiscal Year` where %s between year_start_date and date_add(year_start_date,interval 1 year)",to_date)[0] # Account if not filter_values.get('account'): - msgprint('Please select Account in filter section') - raise Exception + msgprint('Please select Account in filter section') + raise Exception else: - acc_name = filter_values.get('account') + acc_name = filter_values.get('account') if len(res) > 300 and from_export == 0: - msgprint("This is a very large report and cannot be shown in the browser as it is likely to make your browser very slow.Please select Account or click on 'Export' to open in excel") - raise Exception + msgprint("This is a very large report and cannot be shown in the browser as it is likely to make your browser very slow.Please select Account or click on 'Export' to open in excel") + raise Exception acc = sql("select debit_or_credit, is_pl_account, lft, rgt from tabAccount where name = '%s'" % acc_name) -opening = get_obj('GL Control').get_as_on_balance(acc_name, fiscal_year, to_date, acc[0][0], acc[0][2], acc[0][3])[2] +from accounts.utils import get_balance_on +opening = get_balance_on(acc_name, to_date) total_debit, total_credit = 0,0 out = [] for r in res: - total_debit = flt(total_debit) + flt(r[col_idx['Debit']]) - total_credit = flt(total_credit) + flt(r[col_idx['Credit']]) - out.append(r) + total_debit = flt(total_debit) + flt(r[col_idx['Debit']]) + total_credit = flt(total_credit) + flt(r[col_idx['Credit']]) + out.append(r) if acc and acc[0][0] == 'Debit': - bank_bal = flt(opening)-flt(total_debit)+flt(total_credit) + bank_bal = flt(opening)-flt(total_debit)+flt(total_credit) else: - bank_bal = flt(opening)+flt(total_debit)-flt(total_credit) + bank_bal = flt(opening)+flt(total_debit)-flt(total_credit) out.append(['','','','','','Balance as per Company Books: ', opening,'','']) out.append(['','','','','','Amounts not reflected in Bank: ', total_debit,total_credit,'']) diff --git a/accounts/search_criteria/cash_flow_statement/__init__.py b/accounts/search_criteria/cash_flow_statement/__init__.py deleted file mode 100644 index baffc48825..0000000000 --- a/accounts/search_criteria/cash_flow_statement/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from __future__ import unicode_literals diff --git a/accounts/search_criteria/cash_flow_statement/cash_flow_statement.py b/accounts/search_criteria/cash_flow_statement/cash_flow_statement.py deleted file mode 100644 index cf7d075a31..0000000000 --- a/accounts/search_criteria/cash_flow_statement/cash_flow_statement.py +++ /dev/null @@ -1,127 +0,0 @@ -# ERPNext - web based ERP (http://erpnext.com) -# Copyright (C) 2012 Web Notes Technologies Pvt Ltd -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -from __future__ import unicode_literals -cl = [['Account','Data', '200px'],['Debit/Credit', 'Data', '100px'], ['Group/Ledger', 'Data', '100px'], ['Opening','Data', '100px'],['Closing', 'Data', '100px'],['Inc in Cash','Data','100px']] - -for c in cl: - colnames.append(c[0]) - coltypes.append(c[1]) - colwidths.append(c[2]) - coloptions.append('') - col_idx[c[0]] = len(colnames)-1 - - -company = filter_values['company'] - -# transaction date -if not filter_values.get('transaction_date') or not filter_values.get('transaction_date1'): - msgprint("Please enter From Date and To Date") - raise Exception -else: - from_date = add_days(filter_values['transaction_date'], -1) - to_date = filter_values['transaction_date1'] - -ysd, fiscal_year = sql("select year_start_date, name from `tabFiscal Year` where %s between year_start_date and date_add(year_start_date,interval 1 year)",from_date)[0] - - -if from_export == 0 and len(res) >250: - msgprint("This is very large report and cannot be shown in the browser as it is likely to make your browser very slow. Please click on 'Export' to open in excel") - raise Exception - -total_debit, total_credit, total = 0,0,0 -glc = get_obj('GL Control') - -for r in res: - acc = r[col_idx['Account']].strip() - acc_det = sql("select debit_or_credit, is_pl_account, lft, rgt, group_or_ledger from tabAccount where name = '%s'" % acc) - r.append(acc_det[0][0]) - r.append(acc_det[0][4]) - - opening = glc.get_as_on_balance(acc, fiscal_year, from_date, acc_det[0][0], acc_det[0][2], acc_det[0][3])[2] - - amount = sql("select sum(t1.debit), sum(t1.credit) from `tabGL Entry` t1, `tabAccount` t2 WHERE t1.posting_date >= '%s' AND t1.posting_date <= '%s' and ifnull(t1.is_opening,'No') = 'No' AND t1.account = t2.name AND t2.lft >= %s AND t2.rgt <= %s AND is_cancelled = 'No'" % (from_date,to_date, acc_det[0][2], acc_det[0][3])) - if acc_det[0][0] == 'Debit': - closing = opening + flt(amount[0][0]) - flt(amount[0][1]) - else: - closing = opening + flt(amount[0][1]) - flt(amount[0][0]) - - r.append(fmt_money(flt(opening))) - r.append(fmt_money(flt(closing))) - - diff = flt(closing) - flt(opening) - if acc_det[0][0]=='Debit': - r.append(fmt_money(-diff)) - total -= diff - else: - r.append(fmt_money(diff)) - total += diff - - -# net profit -# ------------------ - -acc_det = sql("select debit_or_credit, is_pl_account, lft, rgt, group_or_ledger from tabAccount where account_name = %s AND company=%s", ('Income',company)) -amount = sql("select sum(t1.debit), sum(t1.credit) from `tabGL Entry` t1, `tabAccount` t2 WHERE t1.posting_date >= '%s' AND t1.posting_date <= '%s' and ifnull(t1.is_opening,'No') = 'No' AND t1.account = t2.name AND t2.lft >= %s AND t2.rgt <= %s AND is_cancelled = 'No'" % (from_date,to_date, acc_det[0][2], acc_det[0][3])) -net_income = flt(amount[0][1]) - flt(amount[0][0]) - -acc_det = sql("select debit_or_credit, is_pl_account, lft, rgt, group_or_ledger from tabAccount where account_name = %s AND company=%s", ('Expenses',company)) -amount = sql("select sum(t1.debit), sum(t1.credit) from `tabGL Entry` t1, `tabAccount` t2 WHERE t1.posting_date >= '%s' AND t1.posting_date <= '%s' and ifnull(t1.is_opening,'No') = 'No' AND t1.account = t2.name AND t2.lft >= %s AND t2.rgt <= %s AND is_cancelled = 'No'" % (from_date,to_date, acc_det[0][2], acc_det[0][3])) -net_expenses = flt(amount[0][0]) - flt(amount[0][1]) - -t_row = ['' for i in range(len(colnames))] -t_row[col_idx['Account']] = 'Net Profit' -t_row[col_idx['Inc in Cash']] = fmt_money(net_income - net_expenses) - -total += net_income - net_expenses - -res.append(t_row) - -# total row -# ------------------ -t_row = ['' for i in range(len(colnames))] -t_row[col_idx['Account']] = 'Total Cash Generated' -t_row[col_idx['Inc in Cash']] = fmt_money(total) - -res.append(t_row) - -# Show Inc / Dec in Bank and Cash Accounts -# ---------------------------------------- - -t_row = ['' for i in range(len(colnames))] -res.append(t_row) - -acc_det = sql("select debit_or_credit, is_pl_account, lft, rgt, group_or_ledger, name from tabAccount where account_type = 'Bank or Cash' AND company=%s AND level=%s", (company, cint(filter_values['level']))) -for acc in acc_det: - r = [acc[5],] - - opening = glc.get_as_on_balance(acc[5], fiscal_year, from_date, acc[0], acc[2], acc[3])[2] - - amount = sql("select sum(t1.debit), sum(t1.credit) from `tabGL Entry` t1, `tabAccount` t2 WHERE t1.posting_date >= '%s' AND t1.posting_date <= '%s' and ifnull(t1.is_opening,'No') = 'No' AND t1.account = t2.name AND t2.lft >= %s AND t2.rgt <= %s AND is_cancelled = 'No'" % (from_date,to_date, acc[2], acc[3])) - closing = opening + flt(amount[0][0]) - flt(amount[0][1]) - diff = closing - opening - - - r.append(acc_det[0][0]) - r.append(acc_det[0][4]) - - r.append(fmt_money(flt(opening))) - r.append(fmt_money(flt(closing))) - - r.append(fmt_money(diff)) - - res.append(r) - diff --git a/accounts/search_criteria/creditors_ledger/creditors_ledger.py b/accounts/search_criteria/creditors_ledger/creditors_ledger.py index 6635922295..8a3030ddc6 100644 --- a/accounts/search_criteria/creditors_ledger/creditors_ledger.py +++ b/accounts/search_criteria/creditors_ledger/creditors_ledger.py @@ -8,11 +8,11 @@ # # 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 . +# along with this program. If not, see . #get company from __future__ import unicode_literals @@ -25,11 +25,11 @@ l_head = l_head and l_head[0][0] or '' # Posting date, fiscal year and year start date #----------------------------------------------- if not filter_values.get('posting_date') or not filter_values.get('posting_date1'): - msgprint("Please enter From Date and To Date") - raise Exception + msgprint("Please enter From Date and To Date") + raise Exception else: - from_date = filter_values['posting_date'] - to_date = filter_values['posting_date1'] + from_date = filter_values['posting_date'] + to_date = filter_values['posting_date1'] ysd, from_date_year = sql("select year_start_date, name from `tabFiscal Year` where %s between year_start_date and date_add(year_start_date,interval 1 year)",from_date)[0] @@ -43,11 +43,11 @@ col.append(['Debit','Currency','75px','']) col.append(['Credit','Currency','75px','']) for c in col: - colnames.append(c[0]) - coltypes.append(c[1]) - colwidths.append(c[2]) - coloptions.append(c[3]) - col_idx[c[0]] = len(colnames) + colnames.append(c[0]) + coltypes.append(c[1]) + colwidths.append(c[2]) + coloptions.append(c[3]) + col_idx[c[0]] = len(colnames) total_debit, total_credit, total_opening, total_diff = 0,0,0,0 @@ -55,67 +55,69 @@ total_debit, total_credit, total_opening, total_diff = 0,0,0,0 #total query q = query.split('WHERE')[1].split('LIMIT') if len(q) > 2: - query_where_clause = 'LIMIT'.join(q[:-1]) + query_where_clause = 'LIMIT'.join(q[:-1]) else: - query_where_clause = q[0] + query_where_clause = q[0] tot = sql('select sum(`tabGL Entry`.debit),sum(`tabGL Entry`.credit) from `tabGL Entry`, tabAccount where %s' % query_where_clause) for t in tot: - total_debit += t and flt(t[0]) or 0 - total_credit += t and flt(t[1]) or 0 + total_debit += t and flt(t[0]) or 0 + total_credit += t and flt(t[1]) or 0 total_diff = total_debit - total_credit # opening account = filter_values.get('account') if account: - acc_det = sql("select debit_or_credit, is_pl_account, lft, rgt, group_or_ledger from tabAccount where name = '%s'" % account) - opening_bal = get_obj('GL Control').get_as_on_balance(account, from_date_year, add_days(from_date, -1), acc_det[0][0], acc_det[0][2], acc_det[0][3])[2] - if acc_det[0][0] == 'Credit': - opening_bal = -1*opening_bal - + acc_det = sql("select debit_or_credit, is_pl_account, lft, rgt, group_or_ledger from tabAccount where name = '%s'" % account) + from accounts.utils import get_balance_on + opening_bal = get_balance_on(account, add_days(from_date, -1)) + + if acc_det[0][0] == 'Credit': + opening_bal = -1*opening_bal + out = [] count = 0 for r in res: - count +=1 - det = r[1].split('~~~') - if from_export == 1: - a = "Account: " + det[0] + NEWLINE + det[1] + NEWLINE + "Against: " + det[2] + NEWLINE + "Voucher No: " + det[4] - else: - a = "Account: " + det[0]+ "" + NEWLINE + "
" +det[1]+ "
Against: " + det[2] + "
Voucher No: " + det[4] + "
" - r[1] = a - out.append(r) + count +=1 + det = r[1].split('~~~') + if from_export == 1: + a = "Account: " + det[0] + NEWLINE + det[1] + NEWLINE + "Against: " + det[2] + NEWLINE + "Voucher No: " + det[4] + else: + a = "Account: " + det[0]+ "" + NEWLINE + "
" +det[1]+ "
Against: " + det[2] + "
Voucher No: " + det[4] + "
" + r[1] = a + out.append(r) if total_debit != 0 or total_credit != 0: - # Total debit/credit - t_row = ['' for i in range(len(colnames))] - t_row[1] = 'Total' - t_row[col_idx['Debit']-1] = total_debit - t_row[col_idx['Credit']-1] = total_credit - out.append(t_row) - - # opening - if account: - t_row = ['' for i in range(len(colnames))] - t_row[1] = 'Opening Balance on '+ from_date - t_row[col_idx['Debit']-1] = opening_bal - out.append(t_row) - - # diffrence (dr-cr) - t_row = ['' for i in range(len(colnames))] - t_row[1] = 'Total(Dr-Cr)' - t_row[col_idx['Debit']-1] = total_diff - out.append(t_row) + # Total debit/credit + t_row = ['' for i in range(len(colnames))] + t_row[1] = 'Total' + t_row[col_idx['Debit']-1] = total_debit + t_row[col_idx['Credit']-1] = total_credit + out.append(t_row) + + # opening + if account: + t_row = ['' for i in range(len(colnames))] + t_row[1] = 'Opening Balance on '+ from_date + t_row[col_idx['Debit']-1] = opening_bal + out.append(t_row) + + # diffrence (dr-cr) + t_row = ['' for i in range(len(colnames))] + t_row[1] = 'Total(Dr-Cr)' + t_row[col_idx['Debit']-1] = total_diff + out.append(t_row) - # closing - if account: - t_row = ['' for i in range(len(colnames))] - t_row[1] = 'Closing Balance on ' + to_date - t_row[col_idx['Debit']-1] = flt(opening_bal) + flt(total_diff ) - out.append(t_row) - + # closing + if account: + t_row = ['' for i in range(len(colnames))] + t_row[1] = 'Closing Balance on ' + to_date + t_row[col_idx['Debit']-1] = flt(opening_bal) + flt(total_diff ) + out.append(t_row) + # Print Format myheader = """ @@ -123,8 +125,8 @@ myheader = """
"""+l_head+"""

%(acc)s

Ledger Between %(fdt)s and %(tdt)s
"""+l_head+"""

- """ % {'acc':account, - 'fdt':from_date, - 'tdt':to_date} + """ % {'acc':account, + 'fdt':from_date, + 'tdt':to_date} page_template = myheader+"
%(table)s
" \ No newline at end of file diff --git a/accounts/search_criteria/debtors_ledger/debtors_ledger.py b/accounts/search_criteria/debtors_ledger/debtors_ledger.py index 6635922295..6ba458a90c 100644 --- a/accounts/search_criteria/debtors_ledger/debtors_ledger.py +++ b/accounts/search_criteria/debtors_ledger/debtors_ledger.py @@ -8,11 +8,11 @@ # # 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 . +# along with this program. If not, see . #get company from __future__ import unicode_literals @@ -25,11 +25,11 @@ l_head = l_head and l_head[0][0] or '' # Posting date, fiscal year and year start date #----------------------------------------------- if not filter_values.get('posting_date') or not filter_values.get('posting_date1'): - msgprint("Please enter From Date and To Date") - raise Exception + msgprint("Please enter From Date and To Date") + raise Exception else: - from_date = filter_values['posting_date'] - to_date = filter_values['posting_date1'] + from_date = filter_values['posting_date'] + to_date = filter_values['posting_date1'] ysd, from_date_year = sql("select year_start_date, name from `tabFiscal Year` where %s between year_start_date and date_add(year_start_date,interval 1 year)",from_date)[0] @@ -43,11 +43,11 @@ col.append(['Debit','Currency','75px','']) col.append(['Credit','Currency','75px','']) for c in col: - colnames.append(c[0]) - coltypes.append(c[1]) - colwidths.append(c[2]) - coloptions.append(c[3]) - col_idx[c[0]] = len(colnames) + colnames.append(c[0]) + coltypes.append(c[1]) + colwidths.append(c[2]) + coloptions.append(c[3]) + col_idx[c[0]] = len(colnames) total_debit, total_credit, total_opening, total_diff = 0,0,0,0 @@ -55,67 +55,68 @@ total_debit, total_credit, total_opening, total_diff = 0,0,0,0 #total query q = query.split('WHERE')[1].split('LIMIT') if len(q) > 2: - query_where_clause = 'LIMIT'.join(q[:-1]) + query_where_clause = 'LIMIT'.join(q[:-1]) else: - query_where_clause = q[0] + query_where_clause = q[0] tot = sql('select sum(`tabGL Entry`.debit),sum(`tabGL Entry`.credit) from `tabGL Entry`, tabAccount where %s' % query_where_clause) for t in tot: - total_debit += t and flt(t[0]) or 0 - total_credit += t and flt(t[1]) or 0 + total_debit += t and flt(t[0]) or 0 + total_credit += t and flt(t[1]) or 0 total_diff = total_debit - total_credit # opening account = filter_values.get('account') if account: - acc_det = sql("select debit_or_credit, is_pl_account, lft, rgt, group_or_ledger from tabAccount where name = '%s'" % account) - opening_bal = get_obj('GL Control').get_as_on_balance(account, from_date_year, add_days(from_date, -1), acc_det[0][0], acc_det[0][2], acc_det[0][3])[2] - if acc_det[0][0] == 'Credit': - opening_bal = -1*opening_bal - + acc_det = sql("select debit_or_credit, is_pl_account, lft, rgt, group_or_ledger from tabAccount where name = '%s'" % account) + from accounts.utils import get_balance_on + opening_bal = get_balance_on(account, add_days(from_date, -1)) + if acc_det[0][0] == 'Credit': + opening_bal = -1*opening_bal + out = [] count = 0 for r in res: - count +=1 - det = r[1].split('~~~') - if from_export == 1: - a = "Account: " + det[0] + NEWLINE + det[1] + NEWLINE + "Against: " + det[2] + NEWLINE + "Voucher No: " + det[4] - else: - a = "Account: " + det[0]+ "" + NEWLINE + "
" +det[1]+ "
Against: " + det[2] + "
Voucher No: " + det[4] + "
" - r[1] = a - out.append(r) + count +=1 + det = r[1].split('~~~') + if from_export == 1: + a = "Account: " + det[0] + NEWLINE + det[1] + NEWLINE + "Against: " + det[2] + NEWLINE + "Voucher No: " + det[4] + else: + a = "Account: " + det[0]+ "" + NEWLINE + "
" +det[1]+ "
Against: " + det[2] + "
Voucher No: " + det[4] + "
" + r[1] = a + out.append(r) if total_debit != 0 or total_credit != 0: - # Total debit/credit - t_row = ['' for i in range(len(colnames))] - t_row[1] = 'Total' - t_row[col_idx['Debit']-1] = total_debit - t_row[col_idx['Credit']-1] = total_credit - out.append(t_row) - - # opening - if account: - t_row = ['' for i in range(len(colnames))] - t_row[1] = 'Opening Balance on '+ from_date - t_row[col_idx['Debit']-1] = opening_bal - out.append(t_row) - - # diffrence (dr-cr) - t_row = ['' for i in range(len(colnames))] - t_row[1] = 'Total(Dr-Cr)' - t_row[col_idx['Debit']-1] = total_diff - out.append(t_row) + # Total debit/credit + t_row = ['' for i in range(len(colnames))] + t_row[1] = 'Total' + t_row[col_idx['Debit']-1] = total_debit + t_row[col_idx['Credit']-1] = total_credit + out.append(t_row) + + # opening + if account: + t_row = ['' for i in range(len(colnames))] + t_row[1] = 'Opening Balance on '+ from_date + t_row[col_idx['Debit']-1] = opening_bal + out.append(t_row) + + # diffrence (dr-cr) + t_row = ['' for i in range(len(colnames))] + t_row[1] = 'Total(Dr-Cr)' + t_row[col_idx['Debit']-1] = total_diff + out.append(t_row) - # closing - if account: - t_row = ['' for i in range(len(colnames))] - t_row[1] = 'Closing Balance on ' + to_date - t_row[col_idx['Debit']-1] = flt(opening_bal) + flt(total_diff ) - out.append(t_row) - + # closing + if account: + t_row = ['' for i in range(len(colnames))] + t_row[1] = 'Closing Balance on ' + to_date + t_row[col_idx['Debit']-1] = flt(opening_bal) + flt(total_diff ) + out.append(t_row) + # Print Format myheader = """ @@ -123,8 +124,8 @@ myheader = """
"""+l_head+"""

%(acc)s

Ledger Between %(fdt)s and %(tdt)s
"""+l_head+"""

- """ % {'acc':account, - 'fdt':from_date, - 'tdt':to_date} + """ % {'acc':account, + 'fdt':from_date, + 'tdt':to_date} page_template = myheader+"
%(table)s
" \ No newline at end of file diff --git a/accounts/search_criteria/general_ledger/general_ledger.py b/accounts/search_criteria/general_ledger/general_ledger.py index 1f02478ceb..2533238b20 100644 --- a/accounts/search_criteria/general_ledger/general_ledger.py +++ b/accounts/search_criteria/general_ledger/general_ledger.py @@ -8,11 +8,11 @@ # # 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 . +# along with this program. If not, see . #get company letter head #--------------------------------------------------------------------- @@ -24,11 +24,11 @@ l_head = l_head and l_head[0][0] or '' # Posting date, fiscal year and year start date #--------------------------------------------------------------------- if not filter_values.get('posting_date') or not filter_values.get('posting_date1'): - msgprint("Please enter From Date and To Date") - raise Exception + msgprint("Please enter From Date and To Date") + raise Exception else: - from_date = filter_values['posting_date'] - to_date = filter_values['posting_date1'] + from_date = filter_values['posting_date'] + to_date = filter_values['posting_date1'] from_date_year = sql("select name from `tabFiscal Year` where %s between year_start_date and date_sub(date_add(year_start_date,interval 1 year), interval 1 day)",from_date) if not from_date_year: @@ -47,11 +47,11 @@ col.append(['Debit','Currency','75px','']) col.append(['Credit','Currency','75px','']) for c in col: - colnames.append(c[0]) - coltypes.append(c[1]) - colwidths.append(c[2]) - coloptions.append(c[3]) - col_idx[c[0]] = len(colnames) + colnames.append(c[0]) + coltypes.append(c[1]) + colwidths.append(c[2]) + coloptions.append(c[3]) + col_idx[c[0]] = len(colnames) #total query @@ -59,15 +59,15 @@ for c in col: total_debit, total_credit, total_opening, total_diff = 0,0,0,0 q = query.split('WHERE')[1].split('LIMIT') if len(q) > 2: - query_where_clause = 'LIMIT'.join(q[:-1]) + query_where_clause = 'LIMIT'.join(q[:-1]) else: - query_where_clause = q[0] + query_where_clause = q[0] tot = sql('select sum(debit),sum(credit) from `tabGL Entry` where %s' % query_where_clause) for t in tot: - total_debit += t and flt(t[0]) or 0 - total_credit += t and flt(t[1]) or 0 + total_debit += t and flt(t[0]) or 0 + total_credit += t and flt(t[1]) or 0 total_diff = total_debit - total_credit @@ -81,12 +81,13 @@ account = filter_values.get('account') if account and (total_debit != 0 or total_credit != 0): acc_det = sql("select debit_or_credit, is_pl_account, lft, rgt, group_or_ledger from tabAccount where name = '%s'" % account) - opening_bal = get_obj('GL Control').get_as_on_balance(account, from_date_year, add_days(from_date, -1), acc_det[0][0], acc_det[0][2], acc_det[0][3])[2] - closing_bal = get_obj('GL Control').get_as_on_balance(account, from_date_year, to_date, acc_det[0][0], acc_det[0][2], acc_det[0][3])[2] + from accounts.utils import get_balance_on + opening_bal = get_balance_on(account, add_days(from_date, -1)) + closing_bal = get_balance_on(account, to_date) if acc_det[0][0] == 'Credit': - closing_bal = -1*closing_bal - opening_bal = -1*opening_bal + closing_bal = -1*closing_bal + opening_bal = -1*opening_bal # add opening row t_row = ['' for i in range(len(colnames))] @@ -99,38 +100,38 @@ if account and (total_debit != 0 or total_credit != 0): #--------------------------------------------------------------------- count = 0 for r in res: - count +=1 - det = r[1].split('~~~') - if from_export == 1: - a = "Account: " + det[0] + NEWLINE + det[1] + NEWLINE + "Against: " + det[2] + NEWLINE + "Voucher No: " + det[4] - else: - a = "Account: " + det[0]+ "" + NEWLINE + "
" +det[1]+ "
Against: " + det[2] + "
Voucher No: " + det[4] + "
" - r[1] = a - out.append(r) + count +=1 + det = r[1].split('~~~') + if from_export == 1: + a = "Account: " + det[0] + NEWLINE + det[1] + NEWLINE + "Against: " + det[2] + NEWLINE + "Voucher No: " + det[4] + else: + a = "Account: " + det[0]+ "" + NEWLINE + "
" +det[1]+ "
Against: " + det[2] + "
Voucher No: " + det[4] + "
" + r[1] = a + out.append(r) # Total, Difference and closing balance #--------------------------------------------------------------------- if total_debit != 0 or total_credit != 0: - # Total debit/credit - t_row = ['' for i in range(len(colnames))] - t_row[1] = 'Total' - t_row[col_idx['Debit']-1] = total_debit - t_row[col_idx['Credit']-1] = total_credit - out.append(t_row) + # Total debit/credit + t_row = ['' for i in range(len(colnames))] + t_row[1] = 'Total' + t_row[col_idx['Debit']-1] = total_debit + t_row[col_idx['Credit']-1] = total_credit + out.append(t_row) - # diffrence (dr-cr) - t_row = ['' for i in range(len(colnames))] - t_row[1] = 'Total(Dr-Cr)' - t_row[col_idx['Debit']-1] = total_diff - out.append(t_row) + # diffrence (dr-cr) + t_row = ['' for i in range(len(colnames))] + t_row[1] = 'Total(Dr-Cr)' + t_row[col_idx['Debit']-1] = total_diff + out.append(t_row) - # closing - if account: - t_row = ['' for i in range(len(colnames))] - t_row[1] = 'Closing Balance on ' + formatdate(to_date) - t_row[col_idx['Debit']-1] = flt(closing_bal) - out.append(t_row) + # closing + if account: + t_row = ['' for i in range(len(colnames))] + t_row[1] = 'Closing Balance on ' + formatdate(to_date) + t_row[col_idx['Debit']-1] = flt(closing_bal) + out.append(t_row) # Print Format @@ -141,8 +142,8 @@ myheader = """

%(acc)s

Ledger Between %(fdt)s and %(tdt)s
"""+l_head+"""

- """ % {'acc':account, - 'fdt':from_date, - 'tdt':to_date} + """ % {'acc':account, + 'fdt':from_date, + 'tdt':to_date} page_template = myheader+"
%(table)s
" diff --git a/accounts/search_criteria/trial_balance/__init__.py b/accounts/search_criteria/trial_balance/__init__.py deleted file mode 100644 index baffc48825..0000000000 --- a/accounts/search_criteria/trial_balance/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from __future__ import unicode_literals diff --git a/accounts/search_criteria/trial_balance/trial_balance.js b/accounts/search_criteria/trial_balance/trial_balance.js deleted file mode 100644 index 9a26ea21e3..0000000000 --- a/accounts/search_criteria/trial_balance/trial_balance.js +++ /dev/null @@ -1,61 +0,0 @@ -// ERPNext - web based ERP (http://erpnext.com) -// Copyright (C) 2012 Web Notes Technologies Pvt Ltd -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -report.customize_filters = function() { - this.hide_all_filters(); - - this.add_filter({fieldname:'show_group_ledger', label:'Show Group/Ledger', fieldtype:'Select', options:'Only Groups'+NEWLINE+'Only Ledgers'+NEWLINE+'Both But Without Group Balance'+NEWLINE+'Both With Balance',ignore : 1, parent:'Account', 'report_default':'Both With Balance','in_first_page':1,single_select:1}); - - this.add_filter({fieldname:'show_zero_balance', label:'Show Zero Balance', fieldtype:'Select', options:'Yes'+NEWLINE+'No',ignore : 1, parent:'Account', 'report_default':'Yes','in_first_page':1,single_select:1}); - - this.add_filter({fieldname:'transaction_date', label:'Date', fieldtype:'Date', options:'',ignore : 1, parent:'Account', 'in_first_page':1}); - - this.filter_fields_dict['Account'+FILTER_SEP +'Company'].df.filter_hide = 0; - this.filter_fields_dict['Account'+FILTER_SEP +'From Date'].df.filter_hide = 0; - this.filter_fields_dict['Account'+FILTER_SEP +'To Date'].df.filter_hide = 0; - - this.filter_fields_dict['Account'+FILTER_SEP +'From Date'].df['report_default'] = sys_defaults.year_start_date; - this.filter_fields_dict['Account'+FILTER_SEP +'To Date'].df['report_default'] = dateutil.obj_to_str(new Date()); - this.filter_fields_dict['Account'+FILTER_SEP +'Company'].df['report_default'] = sys_defaults.company; - - this.filter_fields_dict['Account'+FILTER_SEP +'From Date'].df.in_first_page = 1; - this.filter_fields_dict['Account'+FILTER_SEP +'To Date'].df.in_first_page = 1; - this.filter_fields_dict['Account'+FILTER_SEP +'Company'].df.in_first_page = 1; - - this.dt.set_no_limit(1); -} - -report.aftertableprint = function(t) { - $yt(t,'*',1,{whiteSpace:'pre'}); -} - -$dh(this.mytabs.tabs['More Filters']); -$dh(this.mytabs.tabs['Select Columns']); - -report.get_query = function() { - var g_or_l = this.get_filter('Account', 'Show Group/Ledger').get_value(); - var comp = this.get_filter('Account', 'Company').get_value(); - - if (g_or_l == 'Only Ledgers') { - var q = "SELECT name FROM tabAccount WHERE group_or_ledger = 'Ledger' and company = '" + comp + "' and docstatus != 2 ORDER BY lft"; - } else if (g_or_l == 'Only Groups') { - var q = "SELECT CONCAT( REPEAT(' ', COUNT(parent.name) - 1), node.name) AS name FROM tabAccount AS node,tabAccount AS parent WHERE (node.lft BETWEEN parent.lft AND parent.rgt) and node.group_or_ledger = 'Group' and node.company = '" + comp + "' and node.docstatus != 2 GROUP BY node.name ORDER BY node.lft"; - } else { - var q = "SELECT CONCAT( REPEAT(' ', COUNT(parent.name) - 1), node.name) AS name FROM tabAccount AS node,tabAccount AS parent WHERE node.lft BETWEEN parent.lft AND parent.rgt and node.company = '" + comp + "' and node.docstatus != 2 GROUP BY node.name ORDER BY node.lft"; - } - - return q; -} diff --git a/accounts/search_criteria/trial_balance/trial_balance.py b/accounts/search_criteria/trial_balance/trial_balance.py deleted file mode 100644 index 8d798fa05e..0000000000 --- a/accounts/search_criteria/trial_balance/trial_balance.py +++ /dev/null @@ -1,142 +0,0 @@ -# ERPNext - web based ERP (http://erpnext.com) -# Copyright (C) 2012 Web Notes Technologies Pvt Ltd -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Columns -#---------- -from __future__ import unicode_literals -cl = [['Account','Data', '200px'],['Debit/Credit', 'Data', '100px'], ['Group/Ledger', 'Data', '100px'], ['Is PL Account', 'Data', '100px'], ['Opening (Dr)','Data', '100px'], ['Opening (Cr)','Data', '100px'],['Debit', 'Data', '100px'],['Credit', 'Data', '100px'],['Closing (Dr)', 'Data', '100px'],['Closing (Cr)', 'Data', '100px']] -for c in cl: - colnames.append(c[0]) - coltypes.append(c[1]) - colwidths.append(c[2]) - coloptions.append('') - col_idx[c[0]] = len(colnames)-1 - -# transaction date -# ------------------ -if not filter_values.get('transaction_date') or not filter_values.get('transaction_date1'): - msgprint("Please enter From Date and To Date") - raise Exception -else: - from_date = filter_values['transaction_date'] - to_date = filter_values['transaction_date1'] - -#check for from date and to date within same year -#------------------------------------------------ -if not sql("select name from `tabFiscal Year` where %s between year_start_date and date_sub(date_add(year_start_date,interval 1 year), interval 1 day) and %s between year_start_date and date_sub(date_add(year_start_date,interval 1 year), interval 1 day)",(from_date, to_date)): - msgprint("From Date and To Date must be within same year") - raise Exception - -# get year of the from date and to date -# -------------------------------------- -from_date_year = sql("select name from `tabFiscal Year` where %s between year_start_date and date_sub(date_add(year_start_date,interval 1 year), interval 1 day)",add_days(from_date, -1)) -from_date_year = from_date_year and from_date_year[0][0] or '' - -to_date_year = sql("select name from `tabFiscal Year` where %s between year_start_date and date_sub(date_add(year_start_date,interval 1 year), interval 1 day)",to_date) -to_date_year = to_date_year and to_date_year[0][0] or '' - -# if output is more than 500 lines then it will ask to export -# ------------------------------------------------------------ -if len(res) > 1000 and from_export == 0: - msgprint("This is a very large report and cannot be shown in the browser as it is likely to make your browser very slow.Please click on 'Export' to open in a spreadsheet") - raise Exception - - -acc_dict = {} -for t in sql("select name, debit_or_credit, is_pl_account, lft, rgt, group_or_ledger from tabAccount where docstatus != 2 and company = %s", filter_values['company']): - acc_dict[t[0]] = [t[1], t[2], t[3], t[4], t[5]] - - -total_debit, total_credit, total_opening_dr, total_opening_cr, total_closing_dr, total_closing_cr = 0, 0, 0, 0, 0, 0 -glc = get_obj('GL Control') - -# Main logic -# ---------- -for r in res: - # Fetch account details - acc = r[col_idx['Account']].strip() - r.append(acc_dict[acc][0]) - r.append(acc_dict[acc][4]) - r.append(acc_dict[acc][1]) - - #if shows group and ledger both but without group balance - if filter_values.get('show_group_ledger') == 'Both But Without Group Balance' and acc_dict[acc][4] == 'Group': - for i in range(4): - r.append('') - continue - - # Opening Balance - #----------------------------- - if from_date_year == to_date_year: - debit_on_fromdate, credit_on_fromdate, opening = glc.get_as_on_balance(acc, from_date_year, add_days(from_date, -1), acc_dict[acc][0], acc_dict[acc][2], acc_dict[acc][3]) # opening = closing of prev_date - elif acc_dict[acc][1] == 'No': # if there is no previous year in system and not pl account - opening = sql("select opening from `tabAccount Balance` where account = %s and period = %s", (acc, to_date_year)) - debit_on_fromdate, credit_on_fromdate, opening = 0, 0, flt(opening[0][0]) - else: # if pl account and there is no previous year in system - debit_on_fromdate, credit_on_fromdate, opening = 0,0,0 - - # closing balance - #-------------------------------- - debit_on_todate, credit_on_todate, closing = glc.get_as_on_balance(acc, to_date_year, to_date, acc_dict[acc][0], acc_dict[acc][2], acc_dict[acc][3]) - - # transaction betn the period - #---------------------------------------- - - debit = flt(debit_on_todate) - flt(debit_on_fromdate) - credit = flt(credit_on_todate) - flt(credit_on_fromdate) - - # Debit / Credit - if acc_dict[acc][0] == 'Credit': - opening, closing = -1*opening, -1*closing - - # Totals - total_opening_dr += opening>0 and flt(opening) or 0 - total_opening_cr += opening<0 and -1*flt(opening) or 0 - total_debit += debit - total_credit += credit - total_closing_dr += closing>0 and flt(closing) or 0 - total_closing_cr += closing<0 and -1*flt(closing) or 0 - - # Append in rows - r.append(flt(opening>0 and opening or 0)) - r.append(flt(opening<0 and -opening or 0)) - r.append(flt(debit)) - r.append(flt(credit)) - r.append(flt(closing>0.01 and closing or 0)) - r.append(flt(closing<-0.01 and -closing or 0)) - - -out =[] -for r in res: - # Remove accounts if opening bal = debit = credit = closing bal = 0 - # ------------------------------------------------------------------ - if filter_values.get('show_zero_balance') != 'No': - out.append(r) - elif r[col_idx['Opening (Dr)']] or r[col_idx['Opening (Cr)']] or r[col_idx['Debit']] or r[col_idx['Credit']] or r[col_idx['Closing (Dr)']] or r[col_idx['Closing (Cr)']] or (r[col_idx['Group/Ledger']] == 'Group' and filter_values.get('show_group_ledger') == 'Both But Without Group Balance'): - out.append(r) - -# Total Debit / Credit -# -------------------------- -if filter_values.get('show_group_ledger') in ['Only Ledgers', 'Both But Without Group Balance']: - t_row = ['' for i in range(len(colnames))] - t_row[col_idx['Account']] = 'Total' - t_row[col_idx['Opening (Dr)']] = '%.2f' % total_opening_dr - t_row[col_idx['Opening (Cr)']] = '%.2f' % total_opening_cr - t_row[col_idx['Debit']] = '%.2f' % total_debit - t_row[col_idx['Credit']] = '%.2f' % total_credit - t_row[col_idx['Closing (Dr)']] = '%.2f' % total_closing_dr - t_row[col_idx['Closing (Cr)']] = '%.2f' % total_closing_cr - out.append(t_row) diff --git a/accounts/search_criteria/trial_balance/trial_balance.txt b/accounts/search_criteria/trial_balance/trial_balance.txt deleted file mode 100644 index 175c8e60a4..0000000000 --- a/accounts/search_criteria/trial_balance/trial_balance.txt +++ /dev/null @@ -1,34 +0,0 @@ -# Search Criteria, trial_balance -[ - - # These values are common in all dictionaries - { - 'creation': '2012-04-03 12:49:53', - 'docstatus': 0, - 'modified': '2012-07-23 11:49:53', - 'modified_by': u'Administrator', - 'owner': u'Administrator' - }, - - # These values are common for all Search Criteria - { - 'columns': u'Account\x01ID', - 'criteria_name': u'Trial Balance', - 'dis_filters': u'transaction_date', - 'doc_type': u'Account', - 'doctype': 'Search Criteria', - 'filters': u"{'Account\x01Group or Ledger':'Ledger','Account\x01Is PL Account':'','Account\x01Account Type':'','Account\x01Show Group Balance':''}", - 'module': u'Accounts', - 'name': '__common__', - 'page_len': 50, - 'sort_by': u'`tabAccount`.`name`', - 'sort_order': u'DESC', - 'standard': u'Yes' - }, - - # Search Criteria, trial_balance - { - 'doctype': 'Search Criteria', - 'name': u'trial_balance' - } -] \ No newline at end of file diff --git a/accounts/utils/__init__.py b/accounts/utils/__init__.py index 3dbc728ad9..60f70fe0b6 100644 --- a/accounts/utils/__init__.py +++ b/accounts/utils/__init__.py @@ -17,14 +17,61 @@ from __future__ import unicode_literals import webnotes +from webnotes.utils import nowdate -def get_fiscal_year_from_date(date): +def get_fiscal_year(date): from webnotes.utils import formatdate - fy = webnotes.conn.sql("""select name from `tabFiscal Year` + fy = webnotes.conn.sql("""select name, year_start_date, + adddate(year_start_date, interval 1 year) + from `tabFiscal Year` where %s between year_start_date and adddate(year_start_date, interval 1 year)""", date) if not fy: webnotes.msgprint("""%s not in any Fiscal Year""" % formatdate(date), raise_exception=1) - return fy[0][0] \ No newline at end of file + return fy[0] + +@webnotes.whitelist() +def get_balance_on(account=None, date=None): + if not account and webnotes.form_dict.get("account"): + account = webnotes.form_dict.get("account") + date = webnotes.form_dict.get("date") + + cond = [] + if date: + cond.append("posting_date <= '%s'" % date) + + acc = webnotes.conn.get_value('Account', account, \ + ['lft', 'rgt', 'debit_or_credit', 'is_pl_account', 'group_or_ledger'], as_dict=1) + + # for pl accounts, get balance within a fiscal year + if acc.is_pl_account == 'Yes': + cond.append("posting_date >= '%s' and voucher_type != 'Period Closing Voucher'" % \ + get_fiscal_year(date or nowdate())[1]) + + # different filter for group and ledger - improved performance + if acc.group_or_ledger=="Group": + cond.append("""exists ( + select * from `tabAccount` ac where ac.name = gle.account + and ac.lft >= %s and ac.rgt <= %s + )""" % (acc.lft, acc.rgt)) + else: + cond.append("""gle.account = "%s" """ % (account, )) + + # join conditional conditions + cond = " and ".join(cond) + if cond: + cond += " and " + + bal = webnotes.conn.sql(""" + SELECT sum(ifnull(debit, 0)) - sum(ifnull(credit, 0)) + FROM `tabGL Entry` gle + WHERE %s ifnull(is_cancelled, 'No') = 'No' """ % (cond, ))[0][0] + + # if credit account, it should calculate credit - debit + if bal and acc.debit_or_credit == 'Credit': + bal = -bal + + # if bal is None, return 0 + return bal or 0 \ No newline at end of file diff --git a/home/page/dashboard/dashboard.py b/home/page/dashboard/dashboard.py index 71ce805137..179f71785c 100644 --- a/home/page/dashboard/dashboard.py +++ b/home/page/dashboard/dashboard.py @@ -152,14 +152,9 @@ class DashboardWidget: print acc raise e - fiscal_year = self.get_fiscal_year(start) - if fiscal_year: - return self.glc.get_as_on_balance(acc, fiscal_year, start, debit_or_credit, lft, rgt) - else: - webnotes.msgprint('Please select the START DATE and END DATE such that\ - they fall within fiscal year(s) as defined in\ - Setup > System > Fiscal Year.', raise_exception=1) - + from accounts.utils import get_fiscal_year, get_balance_on + fy_end_date = get_fiscal_year(start)[2] + return get_balance_on(acc, fy_end_date) def get_fiscal_year(self, dt): """ @@ -237,10 +232,10 @@ class DashboardWidget: return self.get_account_amt(opts['account'], start, end, debit_or_credit) elif opts['type']=='receivables': - return self.get_account_balance(self.receivables_group, end)[2] + return self.get_account_balance(self.receivables_group, end) elif opts['type']=='payables': - return self.get_account_balance(self.payables_group, end)[2] + return self.get_account_balance(self.payables_group, end) elif opts['type']=='collection': return self.get_bank_amt('credit', 'Customer', start, end) diff --git a/patches/before_jan_2012/index_patch.py b/patches/before_jan_2012/index_patch.py index 7cdc12ed61..2d822888de 100644 --- a/patches/before_jan_2012/index_patch.py +++ b/patches/before_jan_2012/index_patch.py @@ -84,7 +84,6 @@ def create_proper_index(): 'Campaign': [], 'SMS Parameter': [], 'Leave Type': [], - 'Account Balance': ['period', 'start_date', 'end_date', 'account'], 'Absent Days Detail': [], 'Tag': [], 'Raw Materials Supplied': ['raw_material'], @@ -102,7 +101,6 @@ def create_proper_index(): 'Appraisal Template': [], 'Budget Distribution': ['fiscal_year'], 'Workstation': ['warehouse'], - 'Period': [], 'Training Session Details': [], 'Sales Taxes and Charges Master': [], 'State': [], diff --git a/patches/july_2012/repost_stock_due_to_wrong_packing_list.py b/patches/july_2012/repost_stock_due_to_wrong_packing_list.py index 40e081c9f7..449dd1f03c 100644 --- a/patches/july_2012/repost_stock_due_to_wrong_packing_list.py +++ b/patches/july_2012/repost_stock_due_to_wrong_packing_list.py @@ -5,8 +5,8 @@ def execute(): # add index webnotes.conn.commit() try: - webnotes.conn.sql("""create index item_code_warehouse - on `tabDelivery Note Packing Item` (item_code, warehouse)""") + webnotes.conn.sql("""alter table `tabDelivery Note Packing Item` + add index item_code_warehouse (item_code, warehouse)""") except: pass webnotes.conn.begin() diff --git a/patches/patch_list.py b/patches/patch_list.py index 92e48a0bcd..da8fee392a 100644 --- a/patches/patch_list.py +++ b/patches/patch_list.py @@ -511,11 +511,6 @@ patch_list = [ 'patch_file': 'deprecate_bulk_rename', 'description': "Remove Bulk Rename Tool" }, - { - 'patch_module': 'patches.july_2012', - 'patch_file': 'sync_trial_balance', - 'description': "sync trial balance" - }, { 'patch_module': 'patches.july_2012', 'patch_file': 'blog_guest_permission', @@ -604,4 +599,12 @@ patch_list = [ 'patch_module': 'patches.september_2012', 'patch_file': 'rebuild_trees', }, + { + 'patch_module': 'patches.september_2012', + 'patch_file': 'deprecate_account_balance', + }, + { + 'patch_module': 'patches.september_2012', + 'patch_file': 'profile_delete_permission', + }, ] diff --git a/patches/september_2012/deprecate_account_balance.py b/patches/september_2012/deprecate_account_balance.py new file mode 100644 index 0000000000..0ca2c33519 --- /dev/null +++ b/patches/september_2012/deprecate_account_balance.py @@ -0,0 +1,12 @@ +import webnotes +from webnotes.model import delete_doc + +def execute(): + # remove doctypes + for dt in ["Period", "Account Balance", "Multi Ledger Report", + "Multi Ledger Report Detail", "Period Control", "Reposting Tool", + "Lease Agreement", "Lease Installment"]: + delete_doc("DocType", dt) + + # remove search criteria + delete_doc("Search Criteria", "Trial Balance") diff --git a/patches/september_2012/profile_delete_permission.py b/patches/september_2012/profile_delete_permission.py new file mode 100644 index 0000000000..40d569d337 --- /dev/null +++ b/patches/september_2012/profile_delete_permission.py @@ -0,0 +1,4 @@ +import webnotes +def execute(): + webnotes.conn.sql("""update `tabDocPerm` set cancel=1 + where parent='Profile' and role in ('System Manager', 'Administrator') and permlevel=0""") \ No newline at end of file diff --git a/public/js/all-app.js b/public/js/all-app.js new file mode 100644 index 0000000000..72463874e4 --- /dev/null +++ b/public/js/all-app.js @@ -0,0 +1,2402 @@ + +/* + * lib/js/lib/jquery/jquery.ui.core.js + */ +;/*! + * jQuery UI 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI + */ +(function(a,b){function d(b){return!a(b).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}function c(b,c){var e=b.nodeName.toLowerCase();if("area"===e){var f=b.parentNode,g=f.name,h;if(!b.href||!g||f.nodeName.toLowerCase()!=="map")return!1;h=a("img[usemap=#"+g+"]")[0];return!!h&&d(h)}return(/input|select|textarea|button|object/.test(e)?!b.disabled:"a"==e?b.href||c:c)&&d(b)}a.ui=a.ui||{};a.ui.version||(a.extend(a.ui,{version:"1.8.18",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}}),a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(b,c){return typeof b=="number"?this.each(function(){var d=this;setTimeout(function(){a(d).focus(),c&&c.call(d)},b)}):this._focus.apply(this,arguments)},scrollParent:function(){var b;a.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?b=this.parents().filter(function(){return/(relative|absolute|fixed)/.test(a.curCSS(this,"position",1))&&/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0):b=this.parents().filter(function(){return/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!b.length?a(document):b},zIndex:function(c){if(c!==b)return this.css("zIndex",c);if(this.length){var d=a(this[0]),e,f;while(d.length&&d[0]!==document){e=d.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){f=parseInt(d.css("zIndex"),10);if(!isNaN(f)&&f!==0)return f}d=d.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),a.each(["Width","Height"],function(c,d){function h(b,c,d,f){a.each(e,function(){c-=parseFloat(a.curCSS(b,"padding"+this,!0))||0,d&&(c-=parseFloat(a.curCSS(b,"border"+this+"Width",!0))||0),f&&(c-=parseFloat(a.curCSS(b,"margin"+this,!0))||0)});return c}var e=d==="Width"?["Left","Right"]:["Top","Bottom"],f=d.toLowerCase(),g={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};a.fn["inner"+d]=function(c){if(c===b)return g["inner"+d].call(this);return this.each(function(){a(this).css(f,h(this,c)+"px")})},a.fn["outer"+d]=function(b,c){if(typeof b!="number")return g["outer"+d].call(this,b);return this.each(function(){a(this).css(f,h(this,b,!0,c)+"px")})}}),a.extend(a.expr[":"],{data:function(b,c,d){return!!a.data(b,d[3])},focusable:function(b){return c(b,!isNaN(a.attr(b,"tabindex")))},tabbable:function(b){var d=a.attr(b,"tabindex"),e=isNaN(d);return(e||d>=0)&&c(b,!e)}}),a(function(){var b=document.body,c=b.appendChild(c=document.createElement("div"));c.offsetHeight,a.extend(c.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0}),a.support.minHeight=c.offsetHeight===100,a.support.selectstart="onselectstart"in c,b.removeChild(c).style.display="none"}),a.extend(a.ui,{plugin:{add:function(b,c,d){var e=a.ui[b].prototype;for(var f in d)e.plugins[f]=e.plugins[f]||[],e.plugins[f].push([c,d[f]])},call:function(a,b,c){var d=a.plugins[b];if(!!d&&!!a.element[0].parentNode)for(var e=0;e0)return!0;b[d]=1,e=b[d]>0,b[d]=0;return e},isOverAxis:function(a,b,c){return a>b&&a=9)&&!b.button)return this._mouseUp(b);if(this._mouseStarted){this._mouseDrag(b);return b.preventDefault()}this._mouseDistanceMet(b)&&this._mouseDelayMet(b)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,b)!==!1,this._mouseStarted?this._mouseDrag(b):this._mouseUp(b));return!this._mouseStarted},_mouseUp:function(b){a(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,b.target==this._mouseDownEvent.target&&a.data(b.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(b));return!1},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(a){return this.mouseDelayMet},_mouseStart:function(a){},_mouseDrag:function(a){},_mouseStop:function(a){},_mouseCapture:function(a){return!0}})})(jQuery); +/* + * jQuery UI Position 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Position + */ +(function(a,b){a.ui=a.ui||{};var c=/left|center|right/,d=/top|center|bottom/,e="center",f={},g=a.fn.position,h=a.fn.offset;a.fn.position=function(b){if(!b||!b.of)return g.apply(this,arguments);b=a.extend({},b);var h=a(b.of),i=h[0],j=(b.collision||"flip").split(" "),k=b.offset?b.offset.split(" "):[0,0],l,m,n;i.nodeType===9?(l=h.width(),m=h.height(),n={top:0,left:0}):i.setTimeout?(l=h.width(),m=h.height(),n={top:h.scrollTop(),left:h.scrollLeft()}):i.preventDefault?(b.at="left top",l=m=0,n={top:b.of.pageY,left:b.of.pageX}):(l=h.outerWidth(),m=h.outerHeight(),n=h.offset()),a.each(["my","at"],function(){var a=(b[this]||"").split(" ");a.length===1&&(a=c.test(a[0])?a.concat([e]):d.test(a[0])?[e].concat(a):[e,e]),a[0]=c.test(a[0])?a[0]:e,a[1]=d.test(a[1])?a[1]:e,b[this]=a}),j.length===1&&(j[1]=j[0]),k[0]=parseInt(k[0],10)||0,k.length===1&&(k[1]=k[0]),k[1]=parseInt(k[1],10)||0,b.at[0]==="right"?n.left+=l:b.at[0]===e&&(n.left+=l/2),b.at[1]==="bottom"?n.top+=m:b.at[1]===e&&(n.top+=m/2),n.left+=k[0],n.top+=k[1];return this.each(function(){var c=a(this),d=c.outerWidth(),g=c.outerHeight(),h=parseInt(a.curCSS(this,"marginLeft",!0))||0,i=parseInt(a.curCSS(this,"marginTop",!0))||0,o=d+h+(parseInt(a.curCSS(this,"marginRight",!0))||0),p=g+i+(parseInt(a.curCSS(this,"marginBottom",!0))||0),q=a.extend({},n),r;b.my[0]==="right"?q.left-=d:b.my[0]===e&&(q.left-=d/2),b.my[1]==="bottom"?q.top-=g:b.my[1]===e&&(q.top-=g/2),f.fractions||(q.left=Math.round(q.left),q.top=Math.round(q.top)),r={left:q.left-h,top:q.top-i},a.each(["left","top"],function(c,e){a.ui.position[j[c]]&&a.ui.position[j[c]][e](q,{targetWidth:l,targetHeight:m,elemWidth:d,elemHeight:g,collisionPosition:r,collisionWidth:o,collisionHeight:p,offset:k,my:b.my,at:b.at})}),a.fn.bgiframe&&c.bgiframe(),c.offset(a.extend(q,{using:b.using}))})},a.ui.position={fit:{left:function(b,c){var d=a(window),e=c.collisionPosition.left+c.collisionWidth-d.width()-d.scrollLeft();b.left=e>0?b.left-e:Math.max(b.left-c.collisionPosition.left,b.left)},top:function(b,c){var d=a(window),e=c.collisionPosition.top+c.collisionHeight-d.height()-d.scrollTop();b.top=e>0?b.top-e:Math.max(b.top-c.collisionPosition.top,b.top)}},flip:{left:function(b,c){if(c.at[0]!==e){var d=a(window),f=c.collisionPosition.left+c.collisionWidth-d.width()-d.scrollLeft(),g=c.my[0]==="left"?-c.elemWidth:c.my[0]==="right"?c.elemWidth:0,h=c.at[0]==="left"?c.targetWidth:-c.targetWidth,i=-2*c.offset[0];b.left+=c.collisionPosition.left<0?g+h+i:f>0?g+h+i:0}},top:function(b,c){if(c.at[1]!==e){var d=a(window),f=c.collisionPosition.top+c.collisionHeight-d.height()-d.scrollTop(),g=c.my[1]==="top"?-c.elemHeight:c.my[1]==="bottom"?c.elemHeight:0,h=c.at[1]==="top"?c.targetHeight:-c.targetHeight,i=-2*c.offset[1];b.top+=c.collisionPosition.top<0?g+h+i:f>0?g+h+i:0}}}},a.offset.setOffset||(a.offset.setOffset=function(b,c){/static/.test(a.curCSS(b,"position"))&&(b.style.position="relative");var d=a(b),e=d.offset(),f=parseInt(a.curCSS(b,"top",!0),10)||0,g=parseInt(a.curCSS(b,"left",!0),10)||0,h={top:c.top-e.top+f,left:c.left-e.left+g};"using"in c?c.using.call(b,h):d.css(h)},a.fn.offset=function(b){var c=this[0];if(!c||!c.ownerDocument)return null;if(b)return this.each(function(){a.offset.setOffset(this,b)});return h.call(this)}),function(){var b=document.getElementsByTagName("body")[0],c=document.createElement("div"),d,e,g,h,i;d=document.createElement(b?"div":"body"),g={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},b&&a.extend(g,{position:"absolute",left:"-1000px",top:"-1000px"});for(var j in g)d.style[j]=g[j];d.appendChild(c),e=b||document.documentElement,e.insertBefore(d,e.firstChild),c.style.cssText="position: absolute; left: 10.7432222px; top: 10.432325px; height: 30px; width: 201px;",h=a(c).offset(function(a,b){return b}).offset(),d.innerHTML="",e.removeChild(d),i=h.top+h.left+(b?2e3:0),f.fractions=i>21&&i<22}()})(jQuery); + + +/* + * lib/js/lib/jquery/jquery.ui.datepicker.js + */ +/* jQuery UI Datepicker 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Datepicker + * + * Depends: + * jquery.ui.core.js + */(function($,undefined){function isArray(a){return a&&($.browser.safari&&typeof a=="object"&&a.length||a.constructor&&a.constructor.toString().match(/\Array\(\)/))}function extendRemove(a,b){$.extend(a,b);for(var c in b)if(b[c]==null||b[c]==undefined)a[c]=b[c];return a}function bindHover(a){var b="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return a.bind("mouseout",function(a){var c=$(a.target).closest(b);!c.length||c.removeClass("ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover")}).bind("mouseover",function(c){var d=$(c.target).closest(b);!$.datepicker._isDisabledDatepicker(instActive.inline?a.parent()[0]:instActive.input[0])&&!!d.length&&(d.parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),d.addClass("ui-state-hover"),d.hasClass("ui-datepicker-prev")&&d.addClass("ui-datepicker-prev-hover"),d.hasClass("ui-datepicker-next")&&d.addClass("ui-datepicker-next-hover"))})}function Datepicker(){this.debug=!1,this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},$.extend(this._defaults,this.regional[""]),this.dpDiv=bindHover($('
'))}$.extend($.ui,{datepicker:{version:"1.8.18"}});var PROP_NAME="datepicker",dpuuid=(new Date).getTime(),instActive;$.extend(Datepicker.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(a){extendRemove(this._defaults,a||{});return this},_attachDatepicker:function(target,settings){var inlineSettings=null;for(var attrName in this._defaults){var attrValue=target.getAttribute("date:"+attrName);if(attrValue){inlineSettings=inlineSettings||{};try{inlineSettings[attrName]=eval(attrValue)}catch(err){inlineSettings[attrName]=attrValue}}}var nodeName=target.nodeName.toLowerCase(),inline=nodeName=="div"||nodeName=="span";target.id||(this.uuid+=1,target.id="dp"+this.uuid);var inst=this._newInst($(target),inline);inst.settings=$.extend({},settings||{},inlineSettings||{}),nodeName=="input"?this._connectDatepicker(target,inst):inline&&this._inlineDatepicker(target,inst)},_newInst:function(a,b){var c=a[0].id.replace(/([^A-Za-z0-9_-])/g,"\\\\$1");return{id:c,input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:b?bindHover($('
')):this.dpDiv}},_connectDatepicker:function(a,b){var c=$(a);b.append=$([]),b.trigger=$([]);c.hasClass(this.markerClassName)||(this._attachments(c,b),c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(a,c,d){b.settings[c]=d}).bind("getData.datepicker",function(a,c){return this._get(b,c)}),this._autoSize(b),$.data(a,PROP_NAME,b),b.settings.disabled&&this._disableDatepicker(a))},_attachments:function(a,b){var c=this._get(b,"appendText"),d=this._get(b,"isRTL");b.append&&b.append.remove(),c&&(b.append=$(''+c+""),a[d?"before":"after"](b.append)),a.unbind("focus",this._showDatepicker),b.trigger&&b.trigger.remove();var e=this._get(b,"showOn");(e=="focus"||e=="both")&&a.focus(this._showDatepicker);if(e=="button"||e=="both"){var f=this._get(b,"buttonText"),g=this._get(b,"buttonImage");b.trigger=$(this._get(b,"buttonImageOnly")?$("").addClass(this._triggerClass).attr({src:g,alt:f,title:f}):$('').addClass(this._triggerClass).html(g==""?f:$("").attr({src:g,alt:f,title:f}))),a[d?"before":"after"](b.trigger),b.trigger.click(function(){$.datepicker._datepickerShowing&&$.datepicker._lastInput==a[0]?$.datepicker._hideDatepicker():$.datepicker._datepickerShowing&&$.datepicker._lastInput!=a[0]?($.datepicker._hideDatepicker(),$.datepicker._showDatepicker(a[0])):$.datepicker._showDatepicker(a[0]);return!1})}},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var d=function(a){var b=0,c=0;for(var d=0;db&&(b=a[d].length,c=d);return c};b.setMonth(d(this._get(a,c.match(/MM/)?"monthNames":"monthNamesShort"))),b.setDate(d(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a,b){var c=$(a);c.hasClass(this.markerClassName)||(c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",function(a,c,d){b.settings[c]=d}).bind("getData.datepicker",function(a,c){return this._get(b,c)}),$.data(a,PROP_NAME,b),this._setDate(b,this._getDefaultDate(b),!0),this._updateDatepicker(b),this._updateAlternate(b),b.settings.disabled&&this._disableDatepicker(a),b.dpDiv.css("display","block"))},_dialogDatepicker:function(a,b,c,d,e){var f=this._dialogInst;if(!f){this.uuid+=1;var g="dp"+this.uuid;this._dialogInput=$(''),this._dialogInput.keydown(this._doKeyDown),$("body").append(this._dialogInput),f=this._dialogInst=this._newInst(this._dialogInput,!1),f.settings={},$.data(this._dialogInput[0],PROP_NAME,f)}extendRemove(f.settings,d||{}),b=b&&b.constructor==Date?this._formatDate(f,b):b,this._dialogInput.val(b),this._pos=e?e.length?e:[e.pageX,e.pageY]:null;if(!this._pos){var h=document.documentElement.clientWidth,i=document.documentElement.clientHeight,j=document.documentElement.scrollLeft||document.body.scrollLeft,k=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[h/2-100+j,i/2-150+k]}this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),f.settings.onSelect=c,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),$.blockUI&&$.blockUI(this.dpDiv),$.data(this._dialogInput[0],PROP_NAME,f);return this},_destroyDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!!b.hasClass(this.markerClassName)){var d=a.nodeName.toLowerCase();$.removeData(a,PROP_NAME),d=="input"?(c.append.remove(),c.trigger.remove(),b.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):(d=="div"||d=="span")&&b.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!!b.hasClass(this.markerClassName)){var d=a.nodeName.toLowerCase();if(d=="input")a.disabled=!1,c.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""});else if(d=="div"||d=="span"){var e=b.children("."+this._inlineClass);e.children().removeClass("ui-state-disabled"),e.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled")}this._disabledInputs=$.map(this._disabledInputs,function(b){return b==a?null:b})}},_disableDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!!b.hasClass(this.markerClassName)){var d=a.nodeName.toLowerCase();if(d=="input")a.disabled=!0,c.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"});else if(d=="div"||d=="span"){var e=b.children("."+this._inlineClass);e.children().addClass("ui-state-disabled"),e.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled")}this._disabledInputs=$.map(this._disabledInputs,function(b){return b==a?null:b}),this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(a){if(!a)return!1;for(var b=0;b-1}},_doKeyUp:function(a){var b=$.datepicker._getInst(a.target);if(b.input.val()!=b.lastVal)try{var c=$.datepicker.parseDate($.datepicker._get(b,"dateFormat"),b.input?b.input.val():null,$.datepicker._getFormatConfig(b));c&&($.datepicker._setDateFromField(b),$.datepicker._updateAlternate(b),$.datepicker._updateDatepicker(b))}catch(a){$.datepicker.log(a)}return!0},_showDatepicker:function(a){a=a.target||a,a.nodeName.toLowerCase()!="input"&&(a=$("input",a.parentNode)[0]);if(!$.datepicker._isDisabledDatepicker(a)&&$.datepicker._lastInput!=a){var b=$.datepicker._getInst(a);$.datepicker._curInst&&$.datepicker._curInst!=b&&($.datepicker._curInst.dpDiv.stop(!0,!0),b&&$.datepicker._datepickerShowing&&$.datepicker._hideDatepicker($.datepicker._curInst.input[0]));var c=$.datepicker._get(b,"beforeShow"),d=c?c.apply(a,[a,b]):{};if(d===!1)return;extendRemove(b.settings,d),b.lastVal=null,$.datepicker._lastInput=a,$.datepicker._setDateFromField(b),$.datepicker._inDialog&&(a.value=""),$.datepicker._pos||($.datepicker._pos=$.datepicker._findPos(a),$.datepicker._pos[1]+=a.offsetHeight);var e=!1;$(a).parents().each(function(){e|=$(this).css("position")=="fixed";return!e}),e&&$.browser.opera&&($.datepicker._pos[0]-=document.documentElement.scrollLeft,$.datepicker._pos[1]-=document.documentElement.scrollTop);var f={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null,b.dpDiv.empty(),b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),$.datepicker._updateDatepicker(b),f=$.datepicker._checkOffset(b,f,e),b.dpDiv.css({position:$.datepicker._inDialog&&$.blockUI?"static":e?"fixed":"absolute",display:"none",left:f.left+"px",top:f.top+"px"});if(!b.inline){var g=$.datepicker._get(b,"showAnim"),h=$.datepicker._get(b,"duration"),i=function(){var a=b.dpDiv.find("iframe.ui-datepicker-cover");if(!!a.length){var c=$.datepicker._getBorders(b.dpDiv);a.css({left:-c[0],top:-c[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})}};b.dpDiv.zIndex($(a).zIndex()+1),$.datepicker._datepickerShowing=!0,$.effects&&$.effects[g]?b.dpDiv.show(g,$.datepicker._get(b,"showOptions"),h,i):b.dpDiv[g||"show"](g?h:null,i),(!g||!h)&&i(),b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus(),$.datepicker._curInst=b}}},_updateDatepicker:function(a){var b=this;b.maxRows=4;var c=$.datepicker._getBorders(a.dpDiv);instActive=a,a.dpDiv.empty().append(this._generateHTML(a));var d=a.dpDiv.find("iframe.ui-datepicker-cover");!d.length||d.css({left:-c[0],top:-c[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()}),a.dpDiv.find("."+this._dayOverClass+" a").mouseover();var e=this._getNumberOfMonths(a),f=e[1],g=17;a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),f>1&&a.dpDiv.addClass("ui-datepicker-multi-"+f).css("width",g*f+"em"),a.dpDiv[(e[0]!=1||e[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi"),a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),a==$.datepicker._curInst&&$.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&&!a.input.is(":disabled")&&a.input[0]!=document.activeElement&&a.input.focus();if(a.yearshtml){var h=a.yearshtml;setTimeout(function(){h===a.yearshtml&&a.yearshtml&&a.dpDiv.find("select.ui-datepicker-year:first").replaceWith(a.yearshtml),h=a.yearshtml=null},0)}},_getBorders:function(a){var b=function(a){return{thin:1,medium:2,thick:3}[a]||a};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,b,c){var d=a.dpDiv.outerWidth(),e=a.dpDiv.outerHeight(),f=a.input?a.input.outerWidth():0,g=a.input?a.input.outerHeight():0,h=document.documentElement.clientWidth+$(document).scrollLeft(),i=document.documentElement.clientHeight+$(document).scrollTop();b.left-=this._get(a,"isRTL")?d-f:0,b.left-=c&&b.left==a.input.offset().left?$(document).scrollLeft():0,b.top-=c&&b.top==a.input.offset().top+g?$(document).scrollTop():0,b.left-=Math.min(b.left,b.left+d>h&&h>d?Math.abs(b.left+d-h):0),b.top-=Math.min(b.top,b.top+e>i&&i>e?Math.abs(e+g):0);return b},_findPos:function(a){var b=this._getInst(a),c=this._get(b,"isRTL");while(a&&(a.type=="hidden"||a.nodeType!=1||$.expr.filters.hidden(a)))a=a[c?"previousSibling":"nextSibling"];var d=$(a).offset();return[d.left,d.top]},_hideDatepicker:function(a){var b=this._curInst;if(!(!b||a&&b!=$.data(a,PROP_NAME))&&this._datepickerShowing){var c=this._get(b,"showAnim"),d=this._get(b,"duration"),e=this,f=function(){$.datepicker._tidyDialog(b),e._curInst=null};$.effects&&$.effects[c]?b.dpDiv.hide(c,$.datepicker._get(b,"showOptions"),d,f):b.dpDiv[c=="slideDown"?"slideUp":c=="fadeIn"?"fadeOut":"hide"](c?d:null,f),c||f(),this._datepickerShowing=!1;var g=this._get(b,"onClose");g&&g.apply(b.input?b.input[0]:null,[b.input?b.input.val():"",b]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),$.blockUI&&($.unblockUI(),$("body").append(this.dpDiv))),this._inDialog=!1}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(a){if(!!$.datepicker._curInst){var b=$(a.target),c=$.datepicker._getInst(b[0]);(b[0].id!=$.datepicker._mainDivId&&b.parents("#"+$.datepicker._mainDivId).length==0&&!b.hasClass($.datepicker.markerClassName)&&!b.closest("."+$.datepicker._triggerClass).length&&$.datepicker._datepickerShowing&&(!$.datepicker._inDialog||!$.blockUI)||b.hasClass($.datepicker.markerClassName)&&$.datepicker._curInst!=c)&&$.datepicker._hideDatepicker()}},_adjustDate:function(a,b,c){var d=$(a),e=this._getInst(d[0]);this._isDisabledDatepicker(d[0])||(this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"):0),c),this._updateDatepicker(e))},_gotoToday:function(a){var b=$(a),c=this._getInst(b[0]);if(this._get(c,"gotoCurrent")&&c.currentDay)c.selectedDay=c.currentDay,c.drawMonth=c.selectedMonth=c.currentMonth,c.drawYear=c.selectedYear=c.currentYear;else{var d=new Date;c.selectedDay=d.getDate(),c.drawMonth=c.selectedMonth=d.getMonth(),c.drawYear=c.selectedYear=d.getFullYear()}this._notifyChange(c),this._adjustDate(b)},_selectMonthYear:function(a,b,c){var d=$(a),e=this._getInst(d[0]);e["selected"+(c=="M"?"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10),this._notifyChange(e),this._adjustDate(d)},_selectDay:function(a,b,c,d){var e=$(a);if(!$(d).hasClass(this._unselectableClass)&&!this._isDisabledDatepicker(e[0])){var f=this._getInst(e[0]);f.selectedDay=f.currentDay=$("a",d).html(),f.selectedMonth=f.currentMonth=b,f.selectedYear=f.currentYear=c,this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))}},_clearDate:function(a){var b=$(a),c=this._getInst(b[0]);this._selectDate(b,"")},_selectDate:function(a,b){var c=$(a),d=this._getInst(c[0]);b=b!=null?b:this._formatDate(d),d.input&&d.input.val(b),this._updateAlternate(d);var e=this._get(d,"onSelect");e?e.apply(d.input?d.input[0]:null,[b,d]):d.input&&d.input.trigger("change"),d.inline?this._updateDatepicker(d):(this._hideDatepicker(),this._lastInput=d.input[0],typeof d.input[0]!="object"&&d.input.focus(),this._lastInput=null)},_updateAlternate:function(a){var b=this._get(a,"altField");if(b){var c=this._get(a,"altFormat")||this._get(a,"dateFormat"),d=this._getDate(a),e=this.formatDate(c,d,this._getFormatConfig(a));$(b).each(function(){$(this).val(e)})}},noWeekends:function(a){var b=a.getDay();return[b>0&&b<6,""]},iso8601Week:function(a){var b=new Date(a.getTime());b.setDate(b.getDate()+4-(b.getDay()||7));var c=b.getTime();b.setMonth(0),b.setDate(1);return Math.floor(Math.round((c-b)/864e5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b=="object"?b.toString():b+"";if(b=="")return null;var d=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff;d=typeof d!="string"?d:(new Date).getFullYear()%100+parseInt(d,10);var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,g=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,h=(c?c.monthNames:null)||this._defaults.monthNames,i=-1,j=-1,k=-1,l=-1,m=!1,n=function(b){var c=s+1-1){j=1,k=l;for(;;){var u=this._getDaysInMonth(i,j-1);if(k<=u)break;j++,k-=u}}var t=this._daylightSavingAdjust(new Date(i,j-1,k));if(t.getFullYear()!=i||t.getMonth()+1!=j||t.getDate()!=k)throw"Invalid date";return t},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1e7,formatDate:function(a,b,c){if(!b)return"";var d=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,e=(c?c.dayNames:null)||this._defaults.dayNames,f=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c?c.monthNames:null)||this._defaults.monthNames,h=function(b){var c=m+112?a.getHours()+2:0);return a},_setDate:function(a,b,c){var d=!b,e=a.selectedMonth,f=a.selectedYear,g=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=a.currentDay=g.getDate(),a.drawMonth=a.selectedMonth=a.currentMonth=g.getMonth(),a.drawYear=a.selectedYear=a.currentYear=g.getFullYear(),(e!=a.selectedMonth||f!=a.selectedYear)&&!c&&this._notifyChange(a),this._adjustInstDate(a),a.input&&a.input.val(d?"":this._formatDate(a))},_getDate:function(a){var b=!a.currentYear||a.input&&a.input.val()==""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return b},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(),b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),d=this._get(a,"showButtonPanel"),e=this._get(a,"hideIfNoPrevNext"),f=this._get(a,"navigationAsDateFormat"),g=this._getNumberOfMonths(a),h=this._get(a,"showCurrentAtPos"),i=this._get(a,"stepMonths"),j=g[0]!=1||g[1]!=1,k=this._daylightSavingAdjust(a.currentDay?new Date(a.currentYear,a.currentMonth,a.currentDay):new Date(9999,9,9)),l=this._getMinMaxDate(a,"min"),m=this._getMinMaxDate(a,"max"),n=a.drawMonth-h,o=a.drawYear;n<0&&(n+=12,o--);if(m){var p=this._daylightSavingAdjust(new Date(m.getFullYear(),m.getMonth()-g[0]*g[1]+1,m.getDate()));p=l&&pp)n--,n<0&&(n=11,o--)}a.drawMonth=n,a.drawYear=o;var q=this._get(a,"prevText");q=f?this.formatDate(q,this._daylightSavingAdjust(new Date(o,n-i,1)),this._getFormatConfig(a)):q;var r=this._canAdjustMonth(a,-1,o,n)?'
'+q+"":e?"":''+q+"",s=this._get(a,"nextText");s=f?this.formatDate(s,this._daylightSavingAdjust(new Date(o,n+i,1)),this._getFormatConfig(a)):s;var t=this._canAdjustMonth(a,1,o,n)?''+s+"":e?"":''+s+"",u=this._get(a,"currentText"),v=this._get(a,"gotoCurrent")&&a.currentDay?k:b;u=f?this.formatDate(u,v,this._getFormatConfig(a)):u;var w=a.inline?"":'",x=d?'
'+(c?w:"")+(this._isInRange(a,v)?'":"")+(c?"":w)+"
":"",y=parseInt(this._get(a,"firstDay"),10);y=isNaN(y)?0:y;var z=this._get(a,"showWeek"),A=this._get(a,"dayNames"),B=this._get(a,"dayNamesShort"),C=this._get(a,"dayNamesMin"),D=this._get(a,"monthNames"),E=this._get(a,"monthNamesShort"),F=this._get(a,"beforeShowDay"),G=this._get(a,"showOtherMonths"),H=this._get(a,"selectOtherMonths"),I=this._get(a,"calculateWeek")||this.iso8601Week,J=this._getDefaultDate(a),K="";for(var L=0;L1)switch(N){case 0:Q+=" ui-datepicker-group-first",P=" ui-corner-"+(c?"right":"left");break;case g[1]-1:Q+=" ui-datepicker-group-last",P=" ui-corner-"+(c?"left":"right");break;default:Q+=" ui-datepicker-group-middle",P=""}Q+='">'}Q+='
'+(/all|left/.test(P)&&L==0?c?t:r:"")+(/all|right/.test(P)&&L==0?c?r:t:"")+this._generateMonthYearHeader(a,n,o,l,m,L>0||N>0,D,E)+'
'+"";var R=z?'":"";for(var S=0;S<7;S++){var T=(S+y)%7;R+="=5?' class="ui-datepicker-week-end"':"")+">"+''+C[T]+""}Q+=R+"";var U=this._getDaysInMonth(o,n);o==a.selectedYear&&n==a.selectedMonth&&(a.selectedDay=Math.min(a.selectedDay,U));var V=(this._getFirstDayOfMonth(o,n)-y+7)%7,W=Math.ceil((V+U)/7),X=j?this.maxRows>W?this.maxRows:W:W;this.maxRows=X;var Y=this._daylightSavingAdjust(new Date(o,n,1-V));for(var Z=0;Z";var _=z?'":"";for(var S=0;S<7;S++){var ba=F?F.apply(a.input?a.input[0]:null,[Y]):[!0,""],bb=Y.getMonth()!=n,bc=bb&&!H||!ba[0]||l&&Ym;_+='",Y.setDate(Y.getDate()+1),Y=this._daylightSavingAdjust(Y)}Q+=_+""}n++,n>11&&(n=0,o++),Q+="
'+this._get(a,"weekHeader")+"
'+this._get(a,"calculateWeek")(Y)+""+(bb&&!G?" ":bc?''+Y.getDate()+"":''+Y.getDate()+"")+"
"+(j?"
"+(g[0]>0&&N==g[1]-1?'
':""):""),M+=Q}K+=M}K+=x+($.browser.msie&&parseInt($.browser.version,10)<7&&!a.inline?'':""), +a._keyEvent=!1;return K},_generateMonthYearHeader:function(a,b,c,d,e,f,g,h){var i=this._get(a,"changeMonth"),j=this._get(a,"changeYear"),k=this._get(a,"showMonthAfterYear"),l='
',m="";if(f||!i)m+=''+g[b]+"";else{var n=d&&d.getFullYear()==c,o=e&&e.getFullYear()==c;m+='"}k||(l+=m+(f||!i||!j?" ":""));if(!a.yearshtml){a.yearshtml="";if(f||!j)l+=''+c+"";else{var q=this._get(a,"yearRange").split(":"),r=(new Date).getFullYear(),s=function(a){var b=a.match(/c[+-].*/)?c+parseInt(a.substring(1),10):a.match(/[+-].*/)?r+parseInt(a,10):parseInt(a,10);return isNaN(b)?r:b},t=s(q[0]),u=Math.max(t,s(q[1]||""));t=d?Math.max(t,d.getFullYear()):t,u=e?Math.min(u,e.getFullYear()):u,a.yearshtml+='",l+=a.yearshtml,a.yearshtml=null}}l+=this._get(a,"yearSuffix"),k&&(l+=(f||!i||!j?" ":"")+m),l+="
";return l},_adjustInstDate:function(a,b,c){var d=a.drawYear+(c=="Y"?b:0),e=a.drawMonth+(c=="M"?b:0),f=Math.min(a.selectedDay,this._getDaysInMonth(d,e))+(c=="D"?b:0),g=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(d,e,f)));a.selectedDay=g.getDate(),a.drawMonth=a.selectedMonth=g.getMonth(),a.drawYear=a.selectedYear=g.getFullYear(),(c=="M"||c=="Y")&&this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max"),e=c&&bd?d:e;return e},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear");b&&b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){var b=this._get(a,"numberOfMonths");return b==null?[1,1]:typeof b=="number"?[1,b]:b},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,d){var e=this._getNumberOfMonths(a),f=this._daylightSavingAdjust(new Date(c,d+(b<0?b:e[0]*e[1]),1));b<0&&f.setDate(this._getDaysInMonth(f.getFullYear(),f.getMonth()));return this._isInRange(a,f)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!d||b.getTime()<=d.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a,"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,d){b||(a.currentDay=a.selectedDay,a.currentMonth=a.selectedMonth,a.currentYear=a.selectedYear);var e=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(d,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),e,this._getFormatConfig(a))}}),$.fn.datepicker=function(a){if(!this.length)return this;$.datepicker.initialized||($(document).mousedown($.datepicker._checkExternalClick).find("body").append($.datepicker.dpDiv),$.datepicker.initialized=!0);var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return $.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return $.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this[0]].concat(b));return this.each(function(){typeof a=="string"?$.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this].concat(b)):$.datepicker._attachDatepicker(this,a)})},$.datepicker=new Datepicker,$.datepicker.initialized=!1,$.datepicker.uuid=(new Date).getTime(),$.datepicker.version="1.8.18",window["DP_jQuery_"+dpuuid]=$})(jQuery); + +/* + * lib/js/lib/jquery/jquery.ui.autocomplete.js + */ +/* jQuery UI Autocomplete 1.8.18 +* +* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) +* Dual licensed under the MIT or GPL Version 2 licenses. +* http://jquery.org/license +* +* http://docs.jquery.com/UI/Autocomplete +* +* Depends: +* jquery.ui.core.js +* jquery.ui.widget.js +* jquery.ui.position.js +*/(function(a,b){var c=0;a.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var b=this,c=this.element[0].ownerDocument,d;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(!b.options.disabled&&!b.element.propAttr("readOnly")){d=!1;var e=a.ui.keyCode;switch(c.keyCode){case e.PAGE_UP:b._move("previousPage",c);break;case e.PAGE_DOWN:b._move("nextPage",c);break;case e.UP:b._move("previous",c),c.preventDefault();break;case e.DOWN:b._move("next",c),c.preventDefault();break;case e.ENTER:case e.NUMPAD_ENTER:b.menu.active&&(d=!0,c.preventDefault());case e.TAB:if(!b.menu.active)return;b.menu.select(c);break;case e.ESCAPE:b.element.val(b.term),b.close(c);break;default:clearTimeout(b.searching),b.searching=setTimeout(function(){b.term!=b.element.val()&&(b.selectedItem=null,b.search(null,c))},b.options.delay)}}}).bind("keypress.autocomplete",function(a){d&&(d=!1,a.preventDefault())}).bind("focus.autocomplete",function(){b.options.disabled||(b.selectedItem=null,b.previous=b.element.val())}).bind("blur.autocomplete",function(a){b.options.disabled||(clearTimeout(b.searching),b.closing=setTimeout(function(){b.close(a),b._change(a)},150))}),this._initSource(),this.response=function(){return b._response.apply(b,arguments)},this.menu=a("
    ").addClass("ui-autocomplete").appendTo(a(this.options.appendTo||"body",c)[0]).mousedown(function(c){var d=b.menu.element[0];a(c.target).closest(".ui-menu-item").length||setTimeout(function(){a(document).one("mousedown",function(c){c.target!==b.element[0]&&c.target!==d&&!a.ui.contains(d,c.target)&&b.close()})},1),setTimeout(function(){clearTimeout(b.closing)},13)}).menu({focus:function(a,c){var d=c.item.data("item.autocomplete");!1!==b._trigger("focus",a,{item:d})&&/^key/.test(a.originalEvent.type)&&b.element.val(d.value)},selected:function(a,d){var e=d.item.data("item.autocomplete"),f=b.previous;b.element[0]!==c.activeElement&&(b.element.focus(),b.previous=f,setTimeout(function(){b.previous=f,b.selectedItem=e},1)),!1!==b._trigger("select",a,{item:e})&&b.element.val(e.value),b.term=b.element.val(),b.close(a),b.selectedItem=e},blur:function(a,c){b.menu.element.is(":visible")&&b.element.val()!==b.term&&b.element.val(b.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu"),a.fn.bgiframe&&this.menu.element.bgiframe(),b.beforeunloadHandler=function(){b.element.removeAttr("autocomplete")},a(window).bind("beforeunload",b.beforeunloadHandler)},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup"),this.menu.element.remove(),a(window).unbind("beforeunload",this.beforeunloadHandler),a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments),b==="source"&&this._initSource(),b==="appendTo"&&this.menu.element.appendTo(a(c||"body",this.element[0].ownerDocument)[0]),b==="disabled"&&c&&this.xhr&&this.xhr.abort()},_initSource:function(){var b=this,d,e;a.isArray(this.options.source)?(d=this.options.source,this.source=function(b,c){c(a.ui.autocomplete.filter(d,b.term))}):typeof this.options.source=="string"?(e=this.options.source,this.source=function(d,f){b.xhr&&b.xhr.abort(),b.xhr=a.ajax({url:e,data:d,dataType:"json",context:{autocompleteRequest:++c},success:function(a,b){this.autocompleteRequest===c&&f(a)},error:function(){this.autocompleteRequest===c&&f([])}})}):this.source=this.options.source},search:function(a,b){a=a!=null?a:this.element.val(),this.term=this.element.val();if(a.length").data("item.autocomplete",c).append(a("").text(c.label)).appendTo(b)},_move:function(a,b){if(!this.menu.element.is(":visible"))this.search(null,b);else{if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term),this.menu.deactivate();return}this.menu[a](b)}},widget:function(){return this.menu.element}}),a.extend(a.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")},filter:function(b,c){var d=new RegExp(a.ui.autocomplete.escapeRegex(c),"i");return a.grep(b,function(a){return d.test(a.label||a.value||a)})}})})(jQuery),function(a){a.widget("ui.menu",{_create:function(){var b=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(c){!a(c.target).closest(".ui-menu-item a").length||(c.preventDefault(),b.select(c))}),this.refresh()},refresh:function(){var b=this,c=this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem");c.children("a").addClass("ui-corner-all").attr("tabindex",-1).mouseenter(function(c){b.activate(c,a(this).parent())}).mouseleave(function(){b.deactivate()})},activate:function(a,b){this.deactivate();if(this.hasScroll()){var c=b.offset().top-this.element.offset().top,d=this.element.scrollTop(),e=this.element.height();c<0?this.element.scrollTop(d+c):c>=e&&this.element.scrollTop(d+c-e+b.height())}this.active=b.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end(),this._trigger("focus",a,{item:b})},deactivate:function(){!this.active||(this.active.children("a").removeClass("ui-state-hover").removeAttr("id"),this._trigger("blur"),this.active=null)},next:function(a){this.move("next",".ui-menu-item:first",a)},previous:function(a){this.move("prev",".ui-menu-item:last",a)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(a,b,c){if(!this.active)this.activate(c,this.element.children(b));else{var d=this.active[a+"All"](".ui-menu-item").eq(0);d.length?this.activate(c,d):this.activate(c,this.element.children(b))}},nextPage:function(b){if(this.hasScroll()){if(!this.active||this.last()){this.activate(b,this.element.children(".ui-menu-item:first"));return}var c=this.active.offset().top,d=this.element.height(),e=this.element.children(".ui-menu-item").filter(function(){var b=a(this).offset().top-c-d+a(this).height();return b<10&&b>-10});e.length||(e=this.element.children(".ui-menu-item:last")),this.activate(b,e)}else this.activate(b,this.element.children(".ui-menu-item").filter(!this.active||this.last()?":first":":last"))},previousPage:function(b){if(this.hasScroll()){if(!this.active||this.first()){this.activate(b,this.element.children(".ui-menu-item:last"));return}var c=this.active.offset().top,d=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var b=a(this).offset().top-c+d-a(this).height();return b<10&&b>-10}),result.length||(result=this.element.children(".ui-menu-item:first")),this.activate(b,result)}else this.activate(b,this.element.children(".ui-menu-item").filter(!this.active||this.first()?":last":":first"))},hasScroll:function(){return this.element.height()0){if(l=tinyMCE.get(m[0].id)){return l.getContent()}}}}function h(m){var l=null;(m)&&(m.id)&&(c.tinymce)&&(l=tinyMCE.get(m.id));return l}function g(l){return !!((l)&&(l.length)&&(c.tinymce)&&(l.is(":tinymce")))}var j={};b.each(["text","html","val"],function(n,l){var o=j[l]=b.fn[l],m=(l==="text");b.fn[l]=function(s){var p=this;if(!g(p)){return o.apply(p,arguments)}if(s!==e){k.call(p.filter(":tinymce"),s);o.apply(p.not(":tinymce"),arguments);return p}else{var r="";var q=arguments;(m?p:p.eq(0)).each(function(u,v){var t=h(v);r+=t?(m?t.getContent().replace(/<(?:"[^"]*"|'[^']*'|[^'">])*>/g,""):t.getContent()):o.apply(b(v),q)});return r}}});b.each(["append","prepend"],function(n,m){var o=j[m]=b.fn[m],l=(m==="prepend");b.fn[m]=function(q){var p=this;if(!g(p)){return o.apply(p,arguments)}if(q!==e){p.filter(":tinymce").each(function(s,t){var r=h(t);r&&r.setContent(l?q+r.getContent():r.getContent()+q)});o.apply(p.not(":tinymce"),arguments);return p}}});b.each(["remove","replaceWith","replaceAll","empty"],function(m,l){var n=j[l]=b.fn[l];b.fn[l]=function(){i.call(this,l);return n.apply(this,arguments)}});j.attr=b.fn.attr;b.fn.attr=function(n,q,o){var m=this;if((!n)||(n!=="value")||(!g(m))){return j.attr.call(m,n,q,o)}if(q!==e){k.call(m.filter(":tinymce"),q);j.attr.call(m.not(":tinymce"),n,q,o);return m}else{var p=m[0],l=h(p);return l?l.getContent():j.attr.call(b(p),n,q,o)}}}})(jQuery); + +/* + * lib/js/lib/bootstrap.min.js + */ +!function(a){a(function(){"use strict",a.support.transition=function(){var b=document.body||document.documentElement,c=b.style,d=c.transition!==undefined||c.WebkitTransition!==undefined||c.MozTransition!==undefined||c.MsTransition!==undefined||c.OTransition!==undefined;return d&&{end:function(){var b="TransitionEnd";return a.browser.webkit?b="webkitTransitionEnd":a.browser.mozilla?b="transitionend":a.browser.opera&&(b="oTransitionEnd"),b}()}}()})}(window.jQuery),!function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype={constructor:c,close:function(b){function f(){e.remove(),e.trigger("closed")}var c=a(this),d=c.attr("data-target"),e;d||(d=c.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),e=a(d),e.trigger("close"),b&&b.preventDefault(),e.length||(e=c.hasClass("alert")?c:c.parent()),e.removeClass("in"),a.support.transition&&e.hasClass("fade")?e.on(a.support.transition.end,f):f()}},a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("alert");e||d.data("alert",e=new c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.alert.Constructor=c,a(function(){a("body").on("click.alert.data-api",b,c.prototype.close)})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.button.defaults,c)};b.prototype={constructor:b,setState:function(a){var b="disabled",c=this.$element,d=c.data(),e=c.is("input")?"val":"html";a+="Text",d.resetText||c.data("resetText",c[e]()),c[e](d[a]||this.options[a]),setTimeout(function(){a=="loadingText"?c.addClass(b).attr(b,b):c.removeClass(b).removeAttr(b)},0)},toggle:function(){var a=this.$element.parent('[data-toggle="buttons-radio"]');a&&a.find(".active").removeClass("active"),this.$element.toggleClass("active")}},a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("button"),f=typeof c=="object"&&c;e||d.data("button",e=new b(this,f)),c=="toggle"?e.toggle():c&&e.setState(c)})},a.fn.button.defaults={loadingText:"loading..."},a.fn.button.Constructor=b,a(function(){a("body").on("click.button.data-api","[data-toggle^=button]",function(b){a(b.target).button("toggle")})})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.carousel.defaults,c),this.options.slide&&this.slide(this.options.slide)};b.prototype={cycle:function(){return this.interval=setInterval(a.proxy(this.next,this),this.options.interval),this},to:function(b){var c=this.$element.find(".active"),d=c.parent().children(),e=d.index(c),f=this;if(b>d.length-1||b<0)return;return this.sliding?this.$element.one("slid",function(){f.to(b)}):e==b?this.pause().cycle():this.slide(b>e?"next":"prev",a(d[b]))},pause:function(){return clearInterval(this.interval),this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(b,c){var d=this.$element.find(".active"),e=c||d[b](),f=this.interval,g=b=="next"?"left":"right",h=b=="next"?"first":"last",i=this;return this.sliding=!0,f&&this.pause(),e=e.length?e:this.$element.find(".item")[h](),!a.support.transition&&this.$element.hasClass("slide")?(this.$element.trigger("slide"),d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger("slid")):(e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),this.$element.trigger("slide"),this.$element.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger("slid")},0)})),f&&this.cycle(),this}},a.fn.carousel=function(c){return this.each(function(){var d=a(this),e=d.data("carousel"),f=typeof c=="object"&&c;e||d.data("carousel",e=new b(this,f)),typeof c=="number"?e.to(c):typeof c=="string"||(c=f.slide)?e[c]():e.cycle()})},a.fn.carousel.defaults={interval:5e3},a.fn.carousel.Constructor=b,a(function(){a("body").on("click.carousel.data-api","[data-slide]",function(b){var c=a(this),d,e=a(c.attr("data-target")||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,"")),f=!e.data("modal")&&a.extend({},e.data(),c.data());e.carousel(f),b.preventDefault()})})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.collapse.defaults,c),this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.prototype={constructor:b,dimension:function(){var a=this.$element.hasClass("width");return a?"width":"height"},show:function(){var b=this.dimension(),c=a.camelCase(["scroll",b].join("-")),d=this.$parent&&this.$parent.find(".in"),e;d&&d.length&&(e=d.data("collapse"),d.collapse("hide"),e||d.data("collapse",null)),this.$element[b](0),this.transition("addClass","show","shown"),this.$element[b](this.$element[0][c])},hide:function(){var a=this.dimension();this.reset(this.$element[a]()),this.transition("removeClass","hide","hidden"),this.$element[a](0)},reset:function(a){var b=this.dimension();this.$element.removeClass("collapse")[b](a||"auto")[0].offsetWidth,this.$element.addClass("collapse")},transition:function(b,c,d){var e=this,f=function(){c=="show"&&e.reset(),e.$element.trigger(d)};this.$element.trigger(c)[b]("in"),a.support.transition&&this.$element.hasClass("collapse")?this.$element.one(a.support.transition.end,f):f()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}},a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("collapse"),f=typeof c=="object"&&c;e||d.data("collapse",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.collapse.defaults={toggle:!0},a.fn.collapse.Constructor=b,a(function(){a("body").on("click.collapse.data-api","[data-toggle=collapse]",function(b){var c=a(this),d,e=c.attr("data-target")||b.preventDefault()||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""),f=a(e).data("collapse")?"toggle":c.data();a(e).collapse(f)})})}(window.jQuery),!function(a){function d(){a(b).parent().removeClass("open")}"use strict";var b='[data-toggle="dropdown"]',c=function(b){var c=a(b).on("click.dropdown.data-api",this.toggle);a("html").on("click.dropdown.data-api",function(){c.parent().removeClass("open")})};c.prototype={constructor:c,toggle:function(b){var c=a(this),e=c.attr("data-target"),f,g;return e||(e=c.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,"")),f=a(e),f.length||(f=c.parent()),g=f.hasClass("open"),d(),!g&&f.toggleClass("open"),!1}},a.fn.dropdown=function(b){return this.each(function(){var d=a(this),e=d.data("dropdown");e||d.data("dropdown",e=new c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.dropdown.Constructor=c,a(function(){a("html").on("click.dropdown.data-api",d),a("body").on("click.dropdown.data-api",b,c.prototype.toggle)})}(window.jQuery),!function(a){function c(){var b=this,c=setTimeout(function(){b.$element.off(a.support.transition.end),d.call(b)},500);this.$element.one(a.support.transition.end,function(){clearTimeout(c),d.call(b)})}function d(a){this.$element.hide().trigger("hidden"),e.call(this)}function e(b){var c=this,d=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var e=a.support.transition&&d;this.$backdrop=a('',args);}} +wn.get_cookie=function(c){var clist=(document.cookie+'').split(';');var cookies={};for(var i=0;i').html(label).attr('value',value).appendTo(this);} +this.selectedIndex=0;return $(this);} +$.fn.set_working=function(){var ele=this.get(0);$(ele).attr('disabled','disabled');if(ele.loading_img){$(ele.loading_img).toggle(true);}else{ele.loading_img=$('').insertAfter(ele);}} +$.fn.done_working=function(){var ele=this.get(0);$(ele).attr('disabled',null);if(ele.loading_img){$(ele.loading_img).toggle(false);};}})(jQuery);wn.to_csv=function(data){var res=[];$.each(data,function(i,row){row=$.map(row,function(col){return typeof(col)==="string"?('"'+col.replace(/"/g,'\"')+'"'):col;});res.push(row.join(","));});return res.join("\n");} +/* + * lib/js/wn/model.js + */ +wn.provide('wn.model');wn.model={no_value_type:['Section Break','Column Break','HTML','Table','Button','Image'],new_names:{},with_doctype:function(doctype,callback){if(locals.DocType[doctype]){callback();}else{wn.call({method:'webnotes.widgets.form.load.getdoctype',args:{doctype:doctype},callback:callback});}},with_doc:function(doctype,name,callback){if(!name)name=doctype;if(locals[doctype]&&locals[doctype][name]){callback(name);}else{wn.call({method:'webnotes.widgets.form.load.getdoc',args:{doctype:doctype,name:name},callback:function(r){callback(name,r);}});}},can_delete:function(doctype){if(!doctype)return false;return wn.boot.profile.can_cancel.indexOf(doctype)!=-1;},has_value:function(dt,dn,fn){var val=locals[dt]&&locals[dt][dn]&&locals[dt][dn][fn];var df=wn.meta.get_docfield(dt,fn,dn);if(df.fieldtype=='Table'){var ret=false;$.each(locals[df.options]||{},function(k,d){if(d.parent==dn&&d.parenttype==dt&&d.parentfield==df.fieldname){ret=true;}});}else{var ret=!is_null(val);} +return ret?true:false;}} +/* + * lib/js/wn/meta.js + */ +wn.provide('wn.meta.docfield_map');wn.provide('wn.meta.docfield_list');wn.provide('wn.meta.doctypes');$.extend(wn.meta,{add_field:function(df){wn.provide('wn.meta.docfield_map.'+df.parent);wn.meta.docfield_map[df.parent][df.fieldname||df.label]=df;if(!wn.meta.docfield_list[df.parent]) +wn.meta.docfield_list[df.parent]=[];for(var i in wn.meta.docfield_list[df.parent]){var d=wn.meta.docfield_list[df.parent][i];if(df.fieldname==d.fieldname) +return;} +wn.meta.docfield_list[df.parent].push(df);},get_docfield:function(dt,fn,dn){if(dn&&local_dt[dt]&&local_dt[dt][dn]){return local_dt[dt][dn][fn];}else{return wn.meta.docfield_map[dt][fn];}}}); +/* + * 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)+'
    ';} +/* + * lib/js/wn/misc/user.js + */ +wn.user_info=function(uid){var def={'fullname':uid,'image':'images/lib/ui/no_img_m.gif'} +if(!wn.boot.user_info)return def +if(!wn.boot.user_info[uid])return def +if(!wn.boot.user_info[uid].fullname) +wn.boot.user_info[uid].fullname=uid;if(!wn.boot.user_info[uid].image) +wn.boot.user_info[uid].image=def.image;return wn.boot.user_info[uid];} +wn.provide('wn.user');$.extend(wn.user,{name:(wn.boot?wn.boot.profile.name:'Guest'),has_role:function(rl){if(typeof rl=='string') +rl=[rl];for(var i in rl){if((wn.boot?wn.boot.profile.roles:['Guest']).indexOf(rl[i])!=-1) +return true;}},is_report_manager:function(){return wn.user.has_role(['Administrator','System Manager','Report Manager']);}}) +wn.session_alive=true;$(document).bind('mousemove',function(){wn.session_alive=true;if(wn.session_alive_timeout) +clearTimeout(wn.session_alive_timeout);wn.session_alive_timeout=setTimeout('wn.session_alive=false;',30000);}) +/* + * lib/js/lib/json2.js + */ +var JSON;if(!JSON){JSON={};} +(function(){"use strict";function f(n){return n<10?'0'+n:n;} +if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+'-'+ +f(this.getUTCMonth()+1)+'-'+ +f(this.getUTCDate())+'T'+ +f(this.getUTCHours())+':'+ +f(this.getUTCMinutes())+':'+ +f(this.getUTCSeconds())+'Z':null;};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf();};} +var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==='string'?c:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);})+'"':'"'+string+'"';} +function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);} +if(typeof rep==='function'){value=rep.call(holder,key,value);} +switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';} +gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==='[object Array]'){length=value.length;for(i=0;i3){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);});} +wn.get_route_str=function(route){if(!route) +route=window.location.hash;if(route.substr(0,1)=='#')route=route.substr(1);if(route.substr(0,1)=='!')route=route.substr(1);return route;} +wn.set_route=function(){route=$.map(arguments,function(a){return encodeURIComponent(a)}).join('/');window.location.hash=route;wn.app.set_favicon();} +wn._cur_route=null;$(window).bind('hashchange',function(){if(location.hash==wn._cur_route) +return;wn.route();}); +/* + * lib/js/wn/ui/listing.js + */ +wn.provide('wn.ui');wn.ui.Listing=Class.extend({init:function(opts){this.opts=opts||{};this.page_length=20;this.start=0;this.data=[];if(opts){this.make();}},prepare_opts:function(){if(this.opts.new_doctype){if(wn.boot.profile.can_create.indexOf(this.opts.new_doctype)==-1){this.opts.new_doctype=null;}else{this.opts.new_doctype=get_doctype_label(this.opts.new_doctype);}} +if(!this.opts.no_result_message){this.opts.no_result_message='Nothing to show'}},make:function(opts){if(opts){this.opts=opts;} +this.prepare_opts();$.extend(this,this.opts);$(this.parent).html(repl('\ +
    \ +

    %(title)s

    \ + \ +
    \ +
    \ +
    \ +
    \ + \ + \ +
    \ +
    \ +
    \ + \ +
    \ +
    \ +
    \ +
    \ +
    \ +
    \ + \ +
    \ + %(no_result_message)s\ +
    \ + \ +
    \ +
    \ +
    \ + \ +
    \ +
    \ +
    \ + \ + ',this.opts));this.$w=$(this.parent).find('.wnlist');this.set_events();if(this.appframe){this.$w.find('.list-toolbar-wrapper').toggle(false);} +if(this.show_filters){this.make_filters();}},add_button:function(label,click,icon){if(this.appframe){return this.appframe.add_button(label,click,icon)}else{$button=$('').appendTo(this.$w.find('.list-toolbar')) +if(icon){$('').addClass(icon).appendTo($button);} +$button.html(label).click(click);return $button}},show_view:function($btn,$div,$btn_unsel,$div_unsel){$btn_unsel.removeClass('btn-info');$btn_unsel.find('i').removeClass('icon-white');$div_unsel.toggle(false);$btn.addClass('btn-info');$btn.find('i').addClass('icon-white');$div.toggle(true);},set_events:function(){var me=this;this.$w.find('.btn-more').click(function(){me.run({append:true});});if(this.title){this.$w.find('h3').html(this.title).toggle(true);} +if(!(this.hide_refresh||this.no_refresh)){this.add_button('Refresh',function(){me.run();},'icon-refresh');} +if(this.new_doctype){this.add_button('New '+this.new_doctype,function(){(me.custom_new_doc||me.make_new_doc)(me.new_doctype);},'icon-plus');} +if(me.show_filters){this.add_button('Show Filters',function(){me.filter_list.show_filters();},'icon-search').addClass('btn-filter');} +if(me.no_toolbar||me.hide_toolbar){me.$w.find('.list-toolbar-wrapper').toggle(false);}},make_new_doc:function(new_doctype){new_doc(new_doctype);},make_filters:function(){this.filter_list=new wn.ui.FilterList({listobj:this,$parent:this.$w.find('.list-filters').toggle(true),doctype:this.doctype,filter_fields:this.filter_fields});},clear:function(){this.data=[];this.$w.find('.result-list').empty();this.$w.find('.result').toggle(true);this.$w.find('.no-result').toggle(false);this.start=0;},run:function(){var me=this;var a0=arguments[0];var a1=arguments[1];if(a0&&typeof a0=='function') +this.onrun=a0;if(a0&&a0.callback) +this.onrun=a0.callback;if(!a1&&!(a0&&a0.append)) +this.start=0;me.set_working(true);wn.call({method:this.opts.method||'webnotes.widgets.query_builder.runquery',args:this.get_call_args(a0),callback:function(r){me.set_working(false);me.render_results(r)},no_spinner:this.opts.no_loading});},set_working:function(flag){this.$w.find('.img-load').toggle(flag);},get_call_args:function(opts){if(!this.method){var query=this.get_query?this.get_query():this.query;query=this.add_limits(query);var args={query_max:this.query_max,as_dict:1} +args.simple_query=query;}else{var args={limit_start:this.start,limit_page_length:this.page_length}} +if(this.args) +$.extend(args,this.args) +if(this.get_args){$.extend(args,this.get_args(opts));} +return args;},render_results:function(r){if(this.start==0)this.clear();this.$w.find('.btn-more').toggle(false);if(r.message)r.values=r.message;if(r.values&&r.values.length){this.data=this.data.concat(r.values);this.render_list(r.values);this.update_paging(r.values);}else{if(this.start==0){this.$w.find('.result').toggle(false);this.$w.find('.no-result').toggle(true);}} +if(this.onrun)this.onrun();if(this.callback)this.callback(r);},render_list:function(values){var m=Math.min(values.length,this.page_length);for(var i=0;i=this.page_length){this.$w.find('.btn-more').toggle(true);this.start+=this.page_length;}},add_row:function(){return $('
    ').appendTo(this.$w.find('.result-list')).get(0);},refresh:function(){this.run();},add_limits:function(query){query+=' LIMIT '+this.start+','+(this.page_length+1);return query}}); +/* + * lib/js/wn/ui/filters.js + */ +wn.ui.FilterList=Class.extend({init:function(opts){wn.require('js/fields.js');$.extend(this,opts);this.filters=[];this.$w=this.$parent;this.set_events();},set_events:function(){var me=this;this.$w.find('.add-filter-btn').bind('click',function(){me.add_filter();});this.$w.find('.search-btn').bind('click',function(){me.listobj.run();});},show_filters:function(){this.$w.find('.show_filters').toggle();if(!this.filters.length) +this.add_filter();},add_filter:function(tablename,fieldname,condition,value){this.push_new_filter(tablename,fieldname,condition,value);if(fieldname){this.$w.find('.show_filters').toggle(true);}},push_new_filter:function(tablename,fieldname,condition,value){this.filters.push(new wn.ui.Filter({flist:this,tablename:tablename,fieldname:fieldname,condition:condition,value:value}));},get_filters:function(){var values=[];$.each(this.filters,function(i,f){if(f.field) +values.push(f.get_value());}) +return values;},update_filters:function(){var fl=[];$.each(this.filters,function(i,f){if(f.field)fl.push(f);}) +this.filters=fl;},get_filter:function(fieldname){for(var i in this.filters){if(this.filters[i].field.df.fieldname==fieldname) +return this.filters[i];}}});wn.ui.Filter=Class.extend({init:function(opts){$.extend(this,opts);this.doctype=this.flist.doctype;this.make();this.make_select();this.set_events();},make:function(){this.flist.$w.find('.filter_area').append('
    \ + \ + \ + \ + ×\ +
    ');this.$w=this.flist.$w.find('.list_filter:last-child');},make_select:function(){this.fieldselect=new wn.ui.FieldSelect(this.$w.find('.fieldname_select_area'),this.doctype,this.filter_fields);},set_events:function(){var me=this;this.fieldselect.$select.bind('change',function(){var $selected=$(this).find("option:selected") +me.set_field($selected.attr("table"),$selected.attr("fieldname"));});this.$w.find('a.close').bind('click',function(){me.$w.css('display','none');var value=me.field.get_value();me.field=null;if(!me.flist.get_filters().length){me.flist.$w.find('.set_filters').toggle(true);me.flist.$w.find('.show_filters').toggle(false);} +if(value){me.flist.listobj.run();} +me.flist.update_filters();return false;});me.$w.find('.condition').change(function(){if($(this).val()=='in'){me.set_field(me.field.df.parent,me.field.df.fieldname,'Data');if(!me.field.desc_area) +me.field.desc_area=$a(me.field.wrapper,'span','help',null,'values separated by comma');}else{me.set_field(me.field.df.parent,me.field.df.fieldname);}});if(me.fieldname){this.set_values(me.tablename,me.fieldname,me.condition,me.value);}else{me.set_field(me.doctype,'name');}},set_values:function(tablename,fieldname,condition,value){this.set_field(tablename,fieldname);if(condition)this.$w.find('.condition').val(condition).change();if(value)this.field.set_input(value)},set_field:function(tablename,fieldname,fieldtype){var me=this;var cur=me.field?{fieldname:me.field.df.fieldname,fieldtype:me.field.df.fieldtype,parent:me.field.df.parent,}:{} +var df=me.fieldselect.fields_by_name[tablename][fieldname];this.set_fieldtype(df,fieldtype);if(me.field&&cur.fieldname==fieldname&&df.fieldtype==cur.fieldtype&&df.parent==cur.parent){return;} +me.fieldselect.$select.val(tablename+"."+fieldname);var field_area=me.$w.find('.filter_field').empty().get(0);f=make_field(df,null,field_area,null,0,1);f.df.single_select=1;f.not_in_form=1;f.with_label=0;f.refresh();me.field=f;this.set_default_condition(df,fieldtype);$(me.field.wrapper).find(':input').keydown(function(ev){if(ev.which==13){me.flist.listobj.run();}})},set_fieldtype:function(df,fieldtype){if(df.original_type) +df.fieldtype=df.original_type;else +df.original_type=df.fieldtype;df.description='';df.reqd=0;if(fieldtype){df.fieldtype=fieldtype;return;} +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'){if((val.length===0)||(val.lastIndexOf("%")!==(val.length-1))){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=$('").add_options(options).appendTo(this.toolbar);},add_data:function(label){this.add_toolbar();return $("").appendTo(this.toolbar);},add_date:function(label,date){this.add_toolbar();return $("").datepicker({dateFormat:sys_defaults.date_format.replace("yyyy","yy"),changeYear:true,}).val(dateutil.str_to_user(date)||"").appendTo(this.toolbar);},});wn.ui.make_app_page=function(opts){if(opts.single_column){$(opts.parent).html('
    \ +
    \ +
    \ +
    ');}else{$(opts.parent).html('
    \ +
    \ +
    \ +
    \ +
    \ +
    ');} +opts.parent.appframe=new wn.ui.AppFrame($(opts.parent).find('.layout-appframe'));if(opts.title)opts.parent.appframe.title(opts.title);} +/* + * lib/js/wn/ui/dialog.js + */ +wn.widgets.FieldGroup=function(){this.first_button=false;this.make_fields=function(body,fl){if(!window.make_field){wn.require('css/fields.css');wn.require('js/fields.js');} +$y(this.body,{padding:'11px'});this.fields_dict={};for(var i=0;iPlease check the following Errors\n'+errors.join('\n'));return null;} +return ret;} +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.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){$('
    ').appendTo('body');} +this.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.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();$(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(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();}}); +/* + * lib/js/wn/ui/button.js + */ +wn.ui.Button=function(args){var me=this;$.extend(this,{make:function(){me.btn=wn.dom.add(args.parent,'button','btn btn-small '+(args.css_class||''));me.btn.args=args;me.loading_img=wn.dom.add(me.btn.args.parent,'img','',{margin:'0px 4px -2px 4px',display:'none'});me.loading_img.src='images/lib/ui/button-load.gif';me.btn.innerHTML=args.label;me.btn.user_onclick=args.onclick;$(me.btn).bind('click',function(){if(!this.disabled&&this.user_onclick) +this.user_onclick(this);}) +me.btn.set_working=me.set_working;me.btn.done_working=me.done_working;if(me.btn.args.style) +wn.dom.css(me.btn,args.style);},set_working:function(){me.btn.disabled='disabled';$(me.loading_img).css('display','inline');},done_working:function(){me.btn.disabled=false;$(me.loading_img).toggle(false);}});this.make();} +/* + * lib/js/wn/ui/search.js + */ +wn.ui.Search=Class.extend({init:function(opts){$.extend(this,opts);var me=this;wn.model.with_doctype(this.doctype,function(r){me.make();me.dialog.show();me.list.$w.find('.list-filters input[type="text"]').focus();});},make:function(){var me=this;this.dialog=new wn.ui.Dialog({title:this.doctype+' Search',width:500});this.list=new wn.ui.Listing({parent:$(this.dialog.body),appframe:this.dialog.appframe,new_doctype:this.doctype,doctype:this.doctype,method:'webnotes.widgets.doclistview.get',show_filters:true,style:'compact',get_args:function(){if(me.query){me.page_length=50;return{query:me.query}}else{return{doctype:me.doctype,fields:['`tab'+me.doctype+'`.name'],filters:me.list.filter_list.get_filters(),docstatus:['0','1']}}},render_row:function(parent,data){$ln=$('' ++data.name+'').appendTo(parent).click(function(){var val=$(this).attr('data-name');me.dialog.hide();if(me.callback) +me.callback(val);else +wn.set_route('Form',me.doctype,val);});}});this.list.filter_list.add_filter(this.doctype,'name','like');this.list.run();}}) +/* + * lib/js/wn/ui/tree.js + */ +wn.ui.Tree=Class.extend({init:function(args){$.extend(this,args);this.nodes={};this.$w=$('
    ').appendTo(this.parent);this.rootnode=new wn.ui.TreeNode({tree:this,parent:this.$w,label:this.label,expandable:true});this.set_style();},set_style:function(){wn.dom.set_style("\ + .tree li { list-style: none; }\ + .tree ul { margin-top: 2px; }\ + .tree-link { cursor: pointer; }\ + ")}}) +wn.ui.TreeNode=Class.extend({init:function(args){var me=this;$.extend(this,args);this.loaded=false;this.expanded=false;this.tree.nodes[this.label]=this;this.$a=$('').click(function(){if(me.expandable&&me.tree.method&&!me.loaded){me.load()}else{me.selectnode();} +if(me.tree.click)me.tree.click(this);}).bind('reload',function(){me.reload();}).data('label',this.label).appendTo(this.parent);if(this.expandable){this.$a.append(' '+this.label);}else{this.$a.append(' '+this.label);} +if(this.tree.onrender){this.tree.onrender(this);}},selectnode:function(){if(this.$ul){this.$ul.toggle();this.$a.find('i').removeClass();if(this.$ul.css('display').toLowerCase()=='block'){this.$a.find('i').addClass('icon-folder-open');}else{this.$a.find('i').addClass('icon-folder-close');}} +this.tree.$w.find('a.selected').removeClass('selected');this.$a.toggleClass('selected');this.expanded=!this.expanded;},reload:function(){if(this.expanded){this.$a.click();} +if(this.$ul){this.$ul.empty();} +this.load();},addnode:function(data){if(!this.$ul){this.$ul=$('
      ').toggle(false).appendTo(this.parent);} +return new wn.ui.TreeNode({tree:this.tree,parent:$('
    • ').appendTo(this.$ul),label:data.value,expandable:data.expandable,data:data});},load:function(){var me=this;args=$.extend(this.tree.args,{parent:this.label});$(me.$a).set_working();wn.call({method:this.tree.method,args:args,callback:function(r){$(me.$a).done_working();$.each(r.message,function(i,v){node=me.addnode(v);node.$a.data('node-data',v);});me.loaded=true;me.selectnode();}})}}) +/* + * lib/js/wn/upload.js + */ +wn.upload={make:function(opts){var id=wn.dom.set_unique_id();$(opts.parent).append(repl('\ +
      \ +

      \ + \ +
      ',{id:id,action:wn.request.url}));opts.args.cmd='uploadfile';opts.args._id=id;for(key in opts.args){if(opts.args[key]){$('').attr('name',key).attr('value',opts.args[key]).appendTo($(opts.parent).find('form'));}} +$('#'+id).get(0).callback=opts.callback},callback:function(id,file_id,args){$('#'+id).get(0).callback(file_id,args);}} +/* + * lib/js/wn/misc/about.js + */ +wn.provide('wn.ui.misc');wn.ui.misc.about=function(){if(!wn.ui.misc.about_dialog){var d=new wn.widgets.Dialog({title:'About wnframework'}) +$(d.body).html(repl("
      Application Name: %(name)s

      \ +

      Version: %(version)s

      \ +

      License: %(license)s

      \ +

      Source Code: %(source)s

      \ +

      Publisher: %(publisher)s

      \ +

      Copyright: %(copyright)s

      ",wn.app));wn.ui.misc.about_dialog=d;} +wn.ui.misc.about_dialog.show();} +/* + * lib/js/wn/views/doclistview.js + */ +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('
      \ +
      \ +
      \ +
      Loading...
      \ +
      \ +
      \ +
      \ +

      Show

      \ +
      Drafts
      \ +
      Submitted
      \ +
      Cancelled
      \ +
      \ +
      \ +
      \ +
      ');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){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,custom_new_doc:me.listview.make_new_doc||undefined,});$(this.wrapper).find('button[list_view_doc="'+me.doctype+'"]').click(function(){(me.listview.make_new_doc||me.make_new_doc)(me.doctype);});if((auto_run!==false)&&(auto_run!==0))this.run();},make_no_result:function(){var no_result_message=repl('
      \ +

      No %(doctype_label)s found

      \ +
      \ +

      \ +

      ',{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(){var args={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,group_by:this.listview.group_by||undefined,} +$.each((this.listview.default_filters||[]),function(i,f){args.filters.push(f);});return args;},add_delete_option:function(){var me=this;if(this.can_delete){this.add_button('Delete',function(){me.delete_items();},'icon-remove');$('
      \ + Select all
      ').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){$('').click(function(){me.reload_stats();}).appendTo($('
      ').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('

      Tags

      \ +
      No records tagged.

      \ + To add a tag, open the document and click on \ + "Add Tag" on the sidebar
      ');} +return;} +var label=wn.meta.docfield_map[this.doctype][field]?wn.meta.docfield_map[this.doctype][field].label:field;if(label=='_user_tags')label='Tags';var $w=$('
      \ +

      '+label+'

      \ +
      \ +
      \ +
      ');stat=stat.sort(function(a,b){return b[1]-a[1]});var sum=0;$.each(stat,function(i,v){sum=sum+v[1];}) +$.each(stat,function(i,v){me.render_stat_item(i,v,sum,field).appendTo($w.find('.stat-grid'));});$w.appendTo(this.$page.find('.layout-side-section'));},render_stat_item:function(i,v,max,field){var me=this;var args={} +args.label=v[0];args.width=flt(v[1])/max*100;args.count=v[1];args.field=field;$item=$(repl('
      \ +
      \ +
      \ + \ + %(label)s \ + (%(count)s)
      \ +
      ',args));this.setup_stat_item_click($item);return $item;},reload_stats:function(){this.$page.find('.layout-side-section .stat-wrapper').remove();this.init_stats();},setup_stat_item_click:function($item){var me=this;$item.find('a').click(function(){var fieldname=$(this).attr('data-field');var label=$(this).attr('data-label');me.set_filter(fieldname,label);return false;});},set_filter:function(fieldname,label){var filter=this.filter_list.get_filter(fieldname);if(filter){var v=filter.field.get_value();if(v.indexOf(label)!=-1){return false;}else{if(fieldname=='_user_tags'){this.filter_list.add_filter(this.doctype,fieldname,'like','%'+label);}else{filter.set_values(this.doctype,fieldname,'in',v+', '+label);}}}else{if(fieldname=='_user_tags'){this.filter_list.add_filter(this.doctype,fieldname,'like','%'+label);}else{this.filter_list.add_filter(this.doctype,fieldname,'=',label);}} +this.run();}});wn.views.ListView=Class.extend({init:function(doclistview){this.doclistview=doclistview;this.doctype=doclistview.doctype;var t="`tab"+this.doctype+"`.";this.fields=[t+'name',t+'owner',t+'docstatus',t+'_user_tags',t+'modified'];this.stats=['_user_tags'];this.show_hide_check_column();},columns:[{width:'3%',content:'check'},{width:'4%',content:'avatar'},{width:'3%',content:'docstatus',css:{"text-align":"center"}},{width:'35%',content:'name'},{width:'40%',content:'tags',css:{'color':'#aaa'}},{width:'15%',content:'modified',css:{'text-align':'right','color':'#222'}}],render_column:function(data,parent,opts){var me=this;if(opts.css){$.each(opts.css,function(k,v){$(parent).css(k,v)});} +if(opts.content.indexOf&&opts.content.indexOf('+')!=-1){$.map(opts.content.split('+'),function(v){me.render_column(data,parent,{content:v});});return;} +if(typeof opts.content=='function'){opts.content(parent,data,me);} +else if(opts.content=='name'){$(parent).append(repl('%(name)s',data));} +else if(opts.content=='avatar'){$(parent).append(repl('',data));} +else if(opts.content=='check'){$(parent).append('');$(parent).find('input').data('name',data.name);} +else if(opts.content=='docstatus'){$(parent).append(repl('',data));} +else if(opts.content=='tags'){this.add_user_tags(parent,data);} +else if(opts.content=='modified'){$(parent).append(data.when);} +else if(opts.type=='bar-graph'){this.render_bar_graph(parent,data,opts.content,opts.label);} +else if(opts.type=='link'&&opts.doctype){$(parent).append(repl(''+data[opts.content]+'',data));} +else if(opts.template){$(parent).append(repl(opts.template,data));} +else if(data[opts.content]){if(opts.type=="date"){data[opts.content]=wn.datetime.str_to_user(data[opts.content])} +$(parent).append(repl(' %(content)s',{"title":opts.title||opts.content,"content":data[opts.content]}));}},render:function(row,data){var me=this;this.prepare_data(data);rowhtml='';$.each(this.columns,function(i,v){rowhtml+=repl('',v);});var tr=$(row).html(''+rowhtml+'
      ').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;if(data.modified) +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'}},add_user_tags:function(parent,data){var me=this;if(data._user_tags){if($(parent).html().length>0){$(parent).append('
      ');} +$.each(data._user_tags.split(','),function(i,t){if(t){$('' ++strip(t)+'').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});}},render_bar_graph:function(parent,data,field,label){var args={percent:data[field],fully_delivered:(data[field]>99?'bar-complete':''),label:label} +$(parent).append(repl('\ + \ + ',args));},render_icon:function(parent,icon_class,label){var icon_html="";$(parent).append(repl(icon_html,{icon_class:icon_class,label:label||''}));}});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;},}); +/* + * lib/js/wn/views/formview.js + */ +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],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 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(){this.page.appframe.add_breadcrumb(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;$(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[0],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_selected_table_and_column(this.sort_by_next_select) ++' '+this.sort_order_next_select.val();} +return order_by;},get_selected_table_and_column:function($select){return this.get_full_column_name([$select.find('option:selected').attr('fieldname'),$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("%(name)s",{doctype:me.doctype,name:value});}}else if(docfield&&docfield.fieldtype=='Link'){coldef.formatter=function(row,cell,value,columnDef,dataContext){if(value){return repl("%(name)s",{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('

      Sort By

      \ +
      \ +
      \ +

      Then By (optional)

      \ +
      \ +

      \ +
      ');this.sort_by_select=new wn.ui.FieldSelect($(this.sort_dialog.body).find('.sort-column'),this.doctype).$select;this.sort_by_select.css('width','60%');this.sort_order_select=$(this.sort_dialog.body).find('.sort-order');this.sort_by_next_select=new wn.ui.FieldSelect($(this.sort_dialog.body).find('.sort-column-1'),this.doctype,null,true).$select;this.sort_by_next_select.css('width','60%');this.sort_order_next_select=$(this.sort_dialog.body).find('.sort-order-1');this.sort_by_select.val('modified');this.sort_order_select.val('desc');this.sort_by_next_select.val('');this.sort_order_next_select.val('desc');this.page.appframe.add_button('Sort By',function(){me.sort_dialog.show();},'icon-arrow-down');$(this.sort_dialog.body).find('.btn-info').click(function(){me.sort_dialog.hide();me.run();});},make_export:function(){var me=this;if(wn.user.is_report_manager()){this.page.appframe.add_button('Export',function(){var args=me.get_args();args.cmd='webnotes.widgets.doclistview.export_query' +open_url_post(wn.request.url,args);},'icon-download-alt');}},make_save:function(){var me=this;if(wn.user.is_report_manager()){this.page.appframe.add_button('Save',function(){if(me.docname){var name=me.docname}else{var name=prompt('Select Report Name');if(!name){return;}} +wn.call({method:'webnotes.widgets.doclistview.save_report',args:{name:name,doctype:me.doctype,json:JSON.stringify({filters:me.filter_list.get_filters(),columns:me.columns,sort_by:me.sort_by_select.val(),sort_order:me.sort_order_select.val(),sort_by_next:me.sort_by_next_select.val(),sort_order_next:me.sort_order_next_select.val()})},callback:function(r){if(r.exc)return;if(r.message!=me.docname) +wn.set_route('Report2',me.doctype,r.message);}});},'icon-upload');}}});wn.ui.ColumnPicker=Class.extend({init:function(list){this.list=list;this.doctype=list.doctype;this.selects={};},show:function(columns){wn.require('js/lib/jquery/jquery.ui.sortable.js');var me=this;if(!this.dialog){this.dialog=new wn.ui.Dialog({title:'Pick Columns',width:'400'});} +$(this.dialog.body).html('
      Drag to sort columns
      \ +
      \ +
      \ +
      \ +
      ');$.each(columns,function(i,c){me.add_column(c);});$(this.dialog.body).find('.column-list').sortable();$(this.dialog.body).find('.btn-add').click(function(){me.add_column(['name']);});$(this.dialog.body).find('.btn-info').click(function(){me.dialog.hide();me.list.columns=[];$(me.dialog.body).find('select').each(function(){var $selected=$(this).find('option:selected');me.list.columns.push([$selected.attr('fieldname'),$selected.attr('table')]);}) +me.list.run();});this.dialog.show();},add_column:function(c){var w=$('
      \ + ×\ +
      ').appendTo($(this.dialog.body).find('.column-list'));var fieldselect=new wn.ui.FieldSelect(w,this.doctype);fieldselect.$select.css('width','90%').val((c[1]||this.doctype)+"."+c[0]);w.find('.close').click(function(){$(this).parent().remove();});}}); +/* + * lib/js/wn/views/grid_report.js + */ +wn.provide("wn.report_dump");$.extend(wn.report_dump,{data:{},with_data:function(doctypes,callback,progress_bar){var missing=[];$.each(doctypes,function(i,v){if(!wn.report_dump.data[v])missing.push(v);}) +if(missing.length){wn.call({method:"webnotes.widgets.report_dump.get_data",args:{doctypes:doctypes,missing:missing},callback:function(r){$.each(r.message,function(doctype,doctype_data){var data=[];$.each(doctype_data.data,function(i,d){var row={};$.each(doctype_data.columns,function(idx,col){row[col]=d[idx];});row.id=row.name||doctype+"-"+i;row.doctype=doctype;data.push(row);});wn.report_dump.data[doctype]=data;});$.each(r.message,function(doctype,doctype_data){if(doctype_data.links){$.each(wn.report_dump.data[doctype],function(row_idx,row){$.each(doctype_data.links,function(link_key,link){if(wn.report_dump.data[link[0]][row[link_key]]){row[link_key]=wn.report_dump.data[link[0]][row[link_key]][link[1]];}else{row[link_key]=null;}})})}});callback();},progress_bar:progress_bar})}else{callback();}}});wn.provide("wn.views");wn.views.GridReport=Class.extend({init:function(opts){this.filter_inputs={};this.preset_checks=[];this.tree_grid={show:false};$.extend(this,opts);this.wrapper=$('
      ').appendTo(this.parent);if(this.filters){this.make_filters();} +this.make_waiting();this.import_slickgrid();var me=this;this.get_data();},bind_show:function(){var me=this;$(this.page).bind('show',function(){wn.cur_grid_report=me;me.apply_filters_from_route();me.refresh();});},get_data:function(){var me=this;wn.report_dump.with_data(this.doctypes,function(){me.setup_filters();me.init_filter_values();me.refresh();},this.wrapper.find(".progress .bar"));},setup_filters:function(){var me=this;$.each(me.filter_inputs,function(i,v){var opts=v.get(0).opts;if(opts.fieldtype=="Select"&&inList(me.doctypes,opts.link)){$(v).add_options($.map(wn.report_dump.data[opts.link],function(d){return d.name;}));}});this.filter_inputs.refresh&&this.filter_inputs.refresh.click(function(){me.set_route();});this.filter_inputs.reset_filters&&this.filter_inputs.reset_filters.click(function(){me.init_filter_values();me.set_route();});this.filter_inputs.range&&this.filter_inputs.range.change(function(){me.set_route();});},init_filter_values:function(){var me=this;$.each(this.filter_inputs,function(key,filter){var opts=filter.get(0).opts;if(sys_defaults[key]){filter.val(sys_defaults[key]);}else if(opts.fieldtype=='Select'){filter.get(0).selectedIndex=0;}else if(opts.fieldtype=='Data'){filter.val("");}}) +if(this.filter_inputs.from_date) +this.filter_inputs.from_date.val(dateutil.str_to_user(sys_defaults.year_start_date));if(this.filter_inputs.to_date) +this.filter_inputs.to_date.val(dateutil.str_to_user(sys_defaults.year_end_date));},make_filters:function(){var me=this;$.each(this.filters,function(i,v){v.fieldname=v.fieldname||v.label.replace(/ /g,'_').toLowerCase();var input=null;if(v.fieldtype=='Select'){input=me.appframe.add_select(v.label,v.options||[v.default_value]);}else if(v.fieldtype=='Button'){input=me.appframe.add_button(v.label);if(v.icon){$('').prependTo(input);}}else if(v.fieldtype=='Date'){input=me.appframe.add_date(v.label);}else if(v.fieldtype=='Label'){input=me.appframe.add_label(v.label);}else if(v.fieldtype=='Data'){input=me.appframe.add_data(v.label);} +if(input){input&&(input.get(0).opts=v);if(v.cssClass){input.addClass(v.cssClass);} +input.keypress(function(e){if(e.which==13){me.set_route();}})} +me.filter_inputs[v.fieldname]=input;});},make_waiting:function(){this.waiting=$('
      \ +

      Loading Report...

      \ +
      \ +
      ').appendTo(this.wrapper);},load_filter_values:function(){var me=this;$.each(this.filter_inputs,function(i,f){var opts=f.get(0).opts;if(opts.fieldtype!='Button'){me[opts.fieldname]=f.val();if(opts.fieldtype=="Date"){me[opts.fieldname]=dateutil.user_to_str(me[opts.fieldname]);}else if(opts.fieldtype=="Select"){me[opts.fieldname+'_default']=opts.default_value;}}});if(this.filter_inputs.from_date&&this.filter_inputs.to_date&&(this.to_date
      ').appendTo(this.wrapper);$('
      \ + \ + Print \ + | \ + Export \ +
      ').appendTo(this.wrapper);this.wrapper.find(".grid-report-export").click(function(){return me.export();});this.wrapper.find(".grid-report-print").click(function(){msgprint("Coming Soon");return false;});this.grid_wrapper=$("
      ").appendTo(this.wrapper);this.id=wn.dom.set_unique_id(this.grid_wrapper.get(0));$('').appendTo(this.wrapper);this.bind_show();wn.cur_grid_report=this;this.apply_filters_from_route();$(this.wrapper).trigger('make');},apply_filters_from_route:function(){var hash=decodeURIComponent(window.location.hash);var me=this;if(hash.indexOf('/')!=-1){$.each(hash.split('/').splice(1).join('/').split('&'),function(i,f){var f=f.split("=");if(me.filter_inputs[f[0]]){me.filter_inputs[f[0]].val(decodeURIComponent(f[1]));}else{console.log("Invalid filter: "+f[0]);}});}else{this.init_filter_values();}},set_route:function(){wn.set_route(wn.container.page.page_name,$.map(this.filter_inputs,function(v){var val=v.val();var opts=v.get(0).opts;if(val&&val!=opts.default_value) +return encodeURIComponent(opts.fieldname) ++'='+encodeURIComponent(val);}).join('&'))},options:{editable:false,enableColumnReorder:false},render:function(){this.grid=new Slick.Grid("#"+this.id,this.dataView,this.dataview_columns,this.options);var me=this;this.dataView.onRowsChanged.subscribe(function(e,args){me.grid.invalidateRows(args.rows);me.grid.render();});this.dataView.onRowCountChanged.subscribe(function(e,args){me.grid.updateRowCount();me.grid.render();});this.tree_grid.show&&this.add_tree_grid_events();},prepare_data_view:function(){this.dataView=new Slick.Data.DataView({inlineFilters:true});this.dataView.beginUpdate();this.dataView.setItems(this.data);if(this.dataview_filter)this.dataView.setFilter(this.dataview_filter);if(this.tree_grid.show)this.dataView.setFilter(this.tree_dataview_filter);this.dataView.endUpdate();},export:function(){var me=this;var res=[$.map(this.columns,function(v){return v.name;})].concat(this.get_view_data());wn.require("js/lib/downloadify/downloadify.min.js");wn.require("js/lib/downloadify/swfobject.js");var id=wn.dom.set_unique_id();var msgobj=msgprint('

      You must have Flash 10 installed to download this file.

      ');Downloadify.create(id,{filename:function(){return me.title+'.csv';},data:function(){return wn.to_csv(res);},swf:'js/lib/downloadify/downloadify.swf',downloadImage:'js/lib/downloadify/download.png',onComplete:function(){msgobj.hide();},onCancel:function(){msgobj.hide();},onError:function(){msgobj.hide();},width:100,height:30,transparent:true,append:false});return false;},apply_filters:function(item){var filters=this.filter_inputs;if(item._show)return true;for(i in filters){if(!this.apply_filter(item,i))return false;} +return true;},apply_filter:function(item,fieldname){var filter=this.filter_inputs[fieldname].get(0);if(filter.opts.filter){if(!filter.opts.filter(this[filter.opts.fieldname],item,filter.opts,this)){return false;}} +return true;},apply_zero_filter:function(val,item,opts,me){if(!me.show_zero){for(var i=0,j=me.columns.length;i0.001||flt(item[col.field])<-0.001){return true;}}} +return false;} +return true;},show_zero_check:function(){var me=this;this.wrapper.bind('make',function(){me.wrapper.find('.show-zero').toggle(true).find('input').click(function(){me.refresh();});});},is_default:function(fieldname){return this[fieldname]==this[fieldname+"_default"];},date_formatter:function(row,cell,value,columnDef,dataContext){return dateutil.str_to_user(value);},currency_formatter:function(row,cell,value,columnDef,dataContext){return repl('
      %(value)s
      ',{_style:dataContext._style||"",value:fmt_money(value)});},text_formatter:function(row,cell,value,columnDef,dataContext){return repl('%(value)s',{_style:dataContext._style||"",esc_value:cstr(value).replace(/"/g,'\"'),value:cstr(value)});},check_formatter:function(row,cell,value,columnDef,dataContext){return repl("",{"id":dataContext.id,"checked":dataContext.checked?"checked":""})},apply_link_formatters:function(){var me=this;$.each(this.dataview_columns,function(i,col){if(col.link_formatter){col.formatter=function(row,cell,value,columnDef,dataContext){if(!value)return"";var me=wn.cur_grid_report;if(dataContext._show){return repl('%(value)s',{_style:dataContext._style||"",value:value});} +var link_formatter=me.dataview_columns[cell].link_formatter;var html=repl('\ + %(value)s',{value:value,col_name:link_formatter.filter_input,page_name:wn.container.page.page_name}) +if(link_formatter.open_btn){var doctype=link_formatter.doctype?eval(link_formatter.doctype):dataContext.doctype;html+=me.get_link_open_icon(doctype,value);} +return html;}}})},get_link_open_icon:function(doctype,name){return repl(' \ + ',{name:name,doctype:doctype});},make_date_range_columns:function(){this.columns=[];var me=this;var range=this.filter_inputs.range.val();this.from_date=dateutil.user_to_str(this.filter_inputs.from_date.val());this.to_date=dateutil.user_to_str(this.filter_inputs.to_date.val());var date_diff=dateutil.get_diff(this.to_date,this.from_date);me.column_map={};var add_column=function(date){me.columns.push({id:date,name:dateutil.str_to_user(date),field:date,formatter:me.currency_formatter,width:100});} +var build_columns=function(condition){for(var i=0;i'+contents+'
      ').css({position:'absolute',display:'none',top:y+5,left:x+5,border:'1px solid #fdd',padding:'2px','background-color':'#fee',opacity:0.80}).appendTo("body").fadeIn(200);} +this.previousPoint=null;this.wrapper.find('.plot').bind("plothover",function(event,pos,item){if(item){if(me.previousPoint!=item.dataIndex){me.previousPoint=item.dataIndex;$("#"+me.tooltip_id).remove();showTooltip(item.pageX,item.pageY,me.get_tooltip_text(item.series.label,item.datapoint[0],item.datapoint[1]));}} +else{$("#"+me.tooltip_id).remove();me.previousPoint=null;}});},get_tooltip_text:function(label,x,y){var date=dateutil.obj_to_user(new Date(x));var value=fmt_money(y);return value+" on "+date;},get_view_data:function(){var res=[];var col_map=$.map(this.columns,function(v){return v.field;});for(var i=0,len=this.dataView.getLength();i/g,">");var data=me.data;var spacer="";var idx=me.dataView.getIdxById(dataContext.id);var link=me.tree_grid.formatter(dataContext);if(dataContext.doctype){link+=me.get_link_open_icon(dataContext.doctype,value);} +if(data[idx+1]&&data[idx+1].indent>data[idx].indent){if(dataContext._collapsed){return spacer+"  "+link;}else{return spacer+"  "+link;}}else{return spacer+"  "+link;}},tree_dataview_filter:function(item){var me=wn.cur_grid_report;if(!me.apply_filters(item))return false;var parent=item[me.tree_grid.parent_field];while(parent){if(me.item_by_name[parent]._collapsed){return false;} +parent=me.parent_map[parent];} +return true;},prepare_tree:function(item_dt,group_dt){var group_data=wn.report_dump.data[group_dt];var item_data=wn.report_dump.data[item_dt];var me=this;var item_group_map={};var group_ids=$.map(group_data,function(v){return v.id;});$.each(item_data,function(i,item){var parent=item[me.tree_grid.parent_field];if(!item_group_map[parent])item_group_map[parent]=[];if(group_ids.indexOf(item.name)==-1){item_group_map[parent].push(item);}else{msgprint("Ignoring Item "+item.name.bold()+", because a group exists with the same name!");}});var items=[];$.each(group_data,function(i,group){group.is_group=true;items.push(group);items=items.concat(item_group_map[group.name]||[]);});return items;},set_indent:function(){var me=this;$.each(this.data,function(i,d){var indent=0;var parent=me.parent_map[d.name];if(parent){while(parent){indent++;parent=me.parent_map[parent];}} +d.indent=indent;});},}); +/* + * lib/js/legacy/widgets/dialog.js + */ +var cur_dialog;var top_index=91;function Dialog(w,h,title,content){this.make({width:w,title:title});if(content)this.make_body(content);this.onshow='';this.oncancel='';this.no_cancel_flag=0;this.display=false;this.first_button=false;} +Dialog.prototype=new wn.widgets.Dialog() +Dialog.prototype.make_body=function(content){this.rows={};this.widgets={};for(var i in content)this.make_row(content[i]);} +Dialog.prototype.clear_inputs=function(d){for(var wid in this.widgets){var w=this.widgets[wid];var tn=w.tagName?w.tagName.toLowerCase():'';if(tn=='input'||tn=='textarea'){w.value='';}else if(tn=='select'){sel_val(w.options[0].value);}else if(w.txt){w.txt.value='';}else if(w.input){w.input.value='';}}} +Dialog.prototype.make_row=function(d){var me=this;this.rows[d[1]]=$a(this.body,'div','dialog_row');var row=this.rows[d[1]];if(d[0]!='HTML'){var t=make_table(row,1,2,'100%',['30%','70%']);row.tab=t;var c1=$td(t,0,0);var c2=$td(t,0,1);if(d[0]!='Check'&&d[0]!='Button') +$(c1).text(d[1]);} +if(d[0]=='HTML'){if(d[2])row.innerHTML=d[2];this.widgets[d[1]]=row;} +else if(d[0]=='Check'){var i=$a_input(c2,'checkbox','',{width:'20px'});c1.innerHTML=d[1];this.widgets[d[1]]=i;} +else if(d[0]=='Data'){c1.innerHTML=d[1];c2.style.overflow='auto';this.widgets[d[1]]=$a_input(c2,'text');if(d[2])$a(c2,'div','field_description').innerHTML=d[2];} +else if(d[0]=='Link'){c1.innerHTML=d[1];var f=make_field({fieldtype:'Link','label':d[1],'options':d[2]},'',c2,this,0,1);f.not_in_form=1;f.dialog=this;f.refresh();this.widgets[d[1]]=f.input;} +else if(d[0]=='Date'){c1.innerHTML=d[1];var f=make_field({fieldtype:'Date','label':d[1],'options':d[2]},'',c2,this,0,1);f.not_in_form=1;f.refresh();f.dialog=this;this.widgets[d[1]]=f.input;} +else if(d[0]=='Password'){c1.innerHTML=d[1];c2.style.overflow='auto';this.widgets[d[1]]=$a_input(c2,'password');if(d[3])$a(c2,'div','field_description').innerHTML=d[3];} +else if(d[0]=='Select'){c1.innerHTML=d[1];this.widgets[d[1]]=$a(c2,'select','',{width:'160px'}) +if(d[2])$a(c2,'div','field_description').innerHTML=d[2];if(d[3])add_sel_options(this.widgets[d[1]],d[3],d[3][0]);} +else if(d[0]=='Text'){c1.innerHTML=d[1];c2.style.overflow='auto';this.widgets[d[1]]=$a(c2,'textarea');if(d[2])$a(c2,'div','field_description').innerHTML=d[2];} +else if(d[0]=='Button'){c2.style.height='32px';var b=$btn(c2,d[1],function(btn){if(btn._onclick)btn._onclick(me)},null,null,1);b.dialog=me;if(!this.first_button){$(b).addClass('btn-info');this.first_button=true;} +if(d[2]){b._onclick=d[2];} +this.widgets[d[1]]=b;}} +/* + * lib/js/legacy/widgets/layout.js + */ +function Layout(parent,width){if(parent&&parent.substr){parent=$i(parent);} +this.wrapper=$a(parent,'div','',{display:'none'});if(width){this.width=this.wrapper.style.width;} +this.myrows=[];} +Layout.prototype.addrow=function(){this.cur_row=new LayoutRow(this,this.wrapper);this.myrows[this.myrows.length]=this.cur_row;return this.cur_row} +Layout.prototype.addsubrow=function(){this.cur_row=new LayoutRow(this,this.cur_row.main_body);this.myrows[this.myrows.length]=this.cur_row;return this.cur_row} +Layout.prototype.addcell=function(width){return this.cur_row.addCell(width);} +Layout.prototype.setcolour=function(col){$bg(cc,col);} +Layout.prototype.show=function(){$ds(this.wrapper);} +Layout.prototype.hide=function(){$dh(this.wrapper);} +Layout.prototype.close_borders=function(){if(this.with_border){this.myrows[this.myrows.length-1].wrapper.style.borderBottom='1px solid #000';}} +function LayoutRow(layout,parent){this.layout=layout;this.wrapper=$a(parent,'div','form-layout-row');this.main_head=$a(this.wrapper,'div');this.main_body=$a(this.wrapper,'div');if(layout.with_border){this.wrapper.style.border='1px solid #000';this.wrapper.style.borderBottom='0px';} +this.header=$a(this.main_body,'div','',{padding:(layout.with_border?'0px 8px':'0px')});this.body=$a(this.main_body,'div');this.table=$a(this.body,'table','',{width:'100%',borderCollapse:'collapse',tableLayout:'fixed'});this.row=this.table.insertRow(0);this.mycells=[];} +LayoutRow.prototype.hide=function(){$dh(this.wrapper);} +LayoutRow.prototype.show=function(){$ds(this.wrapper);} +LayoutRow.prototype.addCell=function(wid){var lc=new LayoutCell(this.layout,this,wid);this.mycells[this.mycells.length]=lc;return lc;} +function LayoutCell(layout,layoutRow,width){if(width){var w=width+'';if(w.substr(w.length-2,2)!='px'){if(w.substr(w.length-1,1)!="%"){width=width+'%'};}} +this.width=width;this.layout=layout;var cidx=layoutRow.row.cells.length;this.cell=layoutRow.row.insertCell(cidx);this.cell.style.verticalAlign='top';this.set_width(layoutRow.row,width);var h=$a(this.cell,'div','',{padding:(layout.with_border?'0px 8px':'0px')});this.wrapper=$a(this.cell,'div','',{padding:(layout.with_border?'8px':'0px')});layout.cur_cell=this.wrapper;layout.cur_cell.header=h;} +LayoutCell.prototype.set_width=function(row,width){var w=100;var n_cells=row.cells.length;var cells_with_no_width=n_cells;if(width){$y(row.cells[n_cells-1],{width:cint(width)+'%'})}else{row.cells[n_cells-1].estimated_width=1;} +for(var i=0;i '):'';var $button=$('').click(fn).appendTo(tb);if(green){$button.addClass('btn-info');$button.find('i').addClass('icon-white');} +if(bold)$button.css('font-weight','bold');this.buttons[label]=$button.get(0);$ds(this.toolbar_area);return this.buttons[label];} +PageHeader.prototype.clear_toolbar=function(){this.toolbar_area.innerHTML='';this.buttons={};} +PageHeader.prototype.make_buttonset=function(){$(this.toolbar_area).buttonset();} +/* + * lib/js/legacy/widgets/tags.js + */ +_tags={dialog:null,color_map:{},all_tags:[],colors:{'Default':'#add8e6'}} +TagList=function(parent,start_list,dt,dn,static,onclick){this.start_list=start_list?start_list:[];this.tag_list=[];this.dt=dt;this.onclick=onclick;this.dn=dn;this.static;this.parent=parent;this.make_body();} +TagList.prototype.make=function(parent){for(var i=0;iNo tags yet!, please start tagging
      ');} +this.render=function(refresh){$c('webnotes.widgets.tags.get_top_tags',{doctype:doctype,refresh:(refresh?1:0)},this.make);} +this.render();} +wn.widgets.TagCloud.Tag=function(args,count_cell,det){$(count_cell).css('text-align','right').html(det[1]+' x');args.static=1;this.tag=new SingleTag(args)} +/* + * lib/js/legacy/widgets/export_query.js + */ +var export_dialog;function export_query(query,callback){if(!export_dialog){var d=new Dialog(400,300,"Export...");d.make_body([['Data','Max rows','Blank to export all rows'],['Button','Go'],]);d.widgets['Go'].onclick=function(){export_dialog.hide();n=export_dialog.widgets['Max rows'].value;if(cint(n)) +export_dialog.query+=' LIMIT 0,'+cint(n);callback(export_dialog.query);} +d.onshow=function(){this.widgets['Max rows'].value='500';} +export_dialog=d;} +export_dialog.query=query;export_dialog.show();} +function export_csv(q,report_name,sc_id,is_simple,filter_values,colnames){var args={} +args.cmd='webnotes.widgets.query_builder.runquery_csv';if(is_simple) +args.simple_query=q;else +args.query=q;args.sc_id=sc_id?sc_id:'';args.filter_values=filter_values?filter_values:'';if(colnames) +args.colnames=colnames.join(',');args.report_name=report_name?report_name:'';open_url_post(wn.request.url,args);} +/* + * 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([['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");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(txt){txt=d.input&&d.input.query_description||txt;if(txt){d.rows['Help'].innerHTML='
      '+txt+'
      ';}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){} +if(d.input)d.input.set_get_query();var get_sf_list=function(dt){var l=[];var lf=search_fields[dt];for(var i=0;i0){for(pl in perm) +perm[pl][WRITE]=0;} +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){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();} +else if(df) +return df;else if(user_defaults[fn]) +return user_defaults[fn][0];else if(sys_defaults[fn]) +return sys_defaults[fn];} +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=wn.meta.get_docfield(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){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;i1)return true;var fl=wn.meta.docfield_list[dt];if(!fl)return true;var all_clear=true;var errfld=[];for(var i=0;i
    • ');this.setup();this.bind_events();},bind_events:function(){var me=this;$(document).bind('rename',function(event,dt,old_name,new_name){me.rename_notify(dt,old_name,new_name)});},rename_notify:function(dt,old,name){this.remove(dt,old);this.add(dt,name,1);},add:function(dt,dn,on_top){if(this.istable(dt))return;this.remove(dt,dn);var html=repl('
    • \ + \ + %(dn)s (%(dt)s)\ +
    • ',{dt:dt,dn:dn});if(on_top){$('#toolbar-recent').prepend(html);}else{$('#toolbar-recent').append(html);}},istable:function(dt){return locals.DocType[dt]&&locals.DocType[dt].istable||false;},remove:function(dt,dn){$(repl('#toolbar-recent li[data-docref="%(dt)s/%(dn)s"]',{dt:dt,dn:dn})).remove();},setup:function(){var rlist=JSON.parse(profile.recent||"[]");var m=rlist.length;if(m>15)m=15;for(var i=0;i\ + \ +
    ');},make_home:function(){$('.navbar .brand').attr('href',"#");},make_document:function(){wn.ui.toolbar.new_dialog=new wn.ui.toolbar.NewDialog();wn.ui.toolbar.search=new wn.ui.toolbar.Search();wn.ui.toolbar.report=new wn.ui.toolbar.Report();$('.navbar .nav:first').append('');},make_tools:function(){$('.navbar .nav:first').append('');if(has_common(user_roles,['Administrator','System Manager'])){$('#toolbar-tools').append('
  • \ + Download Backup
  • ');}},set_user_name:function(){var fn=user_fullname;if(fn.length>15)fn=fn.substr(0,12)+'...';$('#toolbar-user-link').html(fn+'');},make_logout:function(){$('#toolbar-user').append('
  • Logout
  • ');}});wn.ui.toolbar.clear_cache=function(){localStorage&&localStorage.clear();$c('webnotes.session_cache.clear',{},function(r,rt){if(!r.exc){show_alert(r.message);location.reload();}});return false;} +wn.ui.toolbar.download_backup=function(){$c('webnotes.utils.backups.get_backup',{},function(r,rt){});return false;} +wn.ui.toolbar.show_about=function(){try{wn.ui.misc.about();}catch(e){console.log(e);} +return false;} + +/* + * lib/js/wn/views/breadcrumbs.js + */ +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 %(doctype)s List',{doctype:doctype}))};if(doctype&&module&&wn.modules&&wn.modules[module]){appframe.add_breadcrumb(repl(' in %(module)s',{module:module,module_page:wn.modules[module]}))}} +/* + * lib/js/legacy/widgets/form/fields.js + */ +var no_value_fields=['Section Break','Column Break','HTML','Table','FlexTable','Button','Image'];var codeid=0;var code_editors={};function Field(){this.with_label=1;} +Field.prototype.make_body=function(){var ischk=(this.df.fieldtype=='Check'?1:0);if(this.parent) +this.wrapper=$a(this.parent,(this.with_label?'div':'span'));else +this.wrapper=document.createElement((this.with_label?'div':'span'));this.label_area=$a(this.wrapper,'div','',{margin:'0px 0px 2px 0px',minHeight:'1em'});if(ischk&&!this.in_grid){this.input_area=$a(this.label_area,'span','',{marginRight:'4px'});this.disp_area=$a(this.label_area,'span','',{marginRight:'4px'});} +if(this.with_label){this.label_span=$a(this.label_area,'span','small',{cssFloat:'left'}) +this.label_icon=$('').toggle(false).appendTo(this.label_area).css('float','left').css('margin-left','7px').attr("title","This field is mandatory.");this.suggest_icon=$('').toggle(false).appendTo(this.label_area).css('float','left').css('margin-left','7px').attr("title","will show suggestions as you type.");}else{this.label_span=$a(this.label_area,'span','',{marginRight:'4px'}) +$dh(this.label_area);} +if(!this.input_area){this.input_area=$a(this.wrapper,(this.with_label?'div':'span'));this.disp_area=$a(this.wrapper,(this.with_label?'div':'span'));} +if(this.in_grid){if(this.label_area)$dh(this.label_area);}else{this.input_area.className='input_area';$y(this.wrapper,{marginBottom:'9px'});this.set_description();} +if(this.onmake)this.onmake();} +Field.prototype.set_max_width=function(){var no_max=['Code','Text Editor','Text','Table','HTML'] +if(this.wrapper&&this.layout_cell&&this.layout_cell.parentNode.cells&&this.layout_cell.parentNode.cells.length==1&&!in_list(no_max,this.df.fieldtype)){$y(this.wrapper,{paddingRight:'50%'});}} +Field.prototype.set_label=function(){if(this.with_label&&this.label_area&&this.label!=this.df.label){this.label_span.innerHTML=this.df.label;this.label=this.df.label;}} +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]&&!this.df.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';}} +return ret;} +Field.prototype.set_style_mandatory=function(add){if(add){$(this.txt?this.txt:this.input).addClass('input-mandatory');if(this.disp_area)$(this.disp_area).addClass('input-mandatory');}else{$(this.txt?this.txt:this.input).removeClass('input-mandatory');if(this.disp_area)$(this.disp_area).removeClass('input-mandatory');}} +Field.prototype.refresh_mandatory=function(){if(this.in_filter)return;if(this.df.reqd){if(this.label_area)this.label_area.style.color="#d22";this.set_style_mandatory(1);}else{if(this.label_area)this.label_area.style.color="#222";this.set_style_mandatory(0);} +this.refresh_label_icon() +this.set_reqd=this.df.reqd;} +Field.prototype.refresh_display=function(){if(!this.current_status||this.current_status!=this.disp_status){if(this.disp_status=='Write'){if(this.make_input&&(!this.input)){this.make_input();if(this.onmake_input)this.onmake_input();} +if(this.show)this.show() +else{$ds(this.wrapper);} +if(this.input){$ds(this.input_area);$dh(this.disp_area);if(this.input.refresh)this.input.refresh();}else{$dh(this.input_area);$ds(this.disp_area);}}else if(this.disp_status=='Read'){if(this.show)this.show() +else{$ds(this.wrapper);} +$dh(this.input_area);$ds(this.disp_area);}else{if(this.hide)this.hide();else $dh(this.wrapper);} +this.current_status=this.disp_status;}} +Field.prototype.refresh=function(){this.disp_status=this.get_status();if(this.in_grid&&this.table_refresh&&this.disp_status=='Write') +{this.table_refresh();return;} +this.set_label();this.refresh_display();if(this.onrefresh) +this.onrefresh();if(this.input){if(this.input.refresh)this.input.refresh(this.df);} +if(this.wrapper){this.wrapper.fieldobj=this;$(this.wrapper).trigger('refresh');} +if(!this.not_in_form) +this.set_input(_f.get_value(this.doctype,this.docname,this.df.fieldname));this.refresh_mandatory();this.set_max_width();} +Field.prototype.refresh_label_icon=function(){var to_update=false;if(this.df.reqd&&this.get_value&&is_null(this.get_value())) +to_update=true;if(!to_update&&this.df.has_error)this.df.has_error=false;if(this.label_icon)this.label_icon.toggle(to_update);$(this.txt?this.txt:this.input).toggleClass('field-to-update',to_update);$(this.txt?this.txt:this.input).toggleClass('field-has-error',this.df.has_error?true:false);} +Field.prototype.set=function(val){if(this.not_in_form) +return;if((!this.docname)&&this.grid){this.docname=this.grid.add_newrow();} +if(this.validate) +val=this.validate(val);cur_frm.set_value_in_locals(this.doctype,this.docname,this.df.fieldname,val);this.value=val;} +Field.prototype.set_input=function(val){this.value=val;if(this.input&&this.input.set_input){if(val==null)this.input.set_input('');else this.input.set_input(val);} +var disp_val=val;if(val==null)disp_val='';this.set_disp(disp_val);} +Field.prototype.run_trigger=function(){this.refresh_label_icon();if(this.not_in_form){return;} +if(cur_frm.cscript[this.df.fieldname]) +cur_frm.runclientscript(this.df.fieldname,this.doctype,this.docname);cur_frm.refresh_dependency();} +Field.prototype.set_disp_html=function(t){if(this.disp_area){$(this.disp_area).addClass('disp_area');this.disp_area.innerHTML=(t==null?'':t);if(!t)$(this.disp_area).addClass('disp_area_no_val');}} +Field.prototype.set_disp=function(val){this.set_disp_html(val);} +Field.prototype.activate=function(docname){this.docname=docname;this.refresh();if(this.input){var v=_f.get_value(this.doctype,this.docname,this.df.fieldname);this.last_value=v;if(this.input.onchange&&this.input.get_value&&this.input.get_value()!=v){if(this.validate) +this.input.set_value(this.validate(v));else +this.input.set_value((v==null)?'':v);if(this.format_input) +this.format_input();} +if(this.input.focus){try{this.input.focus();}catch(e){}}} +if(this.txt){try{this.txt.focus();}catch(e){} +this.txt.field_object=this;}} +function DataField(){}DataField.prototype=new Field();DataField.prototype.make_input=function(){var me=this;this.input=$a_input(this.input_area,this.df.fieldtype=='Password'?'password':'text');this.get_value=function(){var v=this.input.value;if(this.validate) +v=this.validate(v);return v;} +this.input.name=this.df.fieldname;$(this.input).change(function(){me.set_value(me.get_value?me.get_value():$(this.input).val());});this.set_value=function(val){if(!me.last_value)me.last_value='';if(me.validate){val=me.validate(val);me.input.value=val==undefined?'':val;} +me.set(val);if(me.format_input) +me.format_input();if(in_list(['Currency','Float','Int'],me.df.fieldtype)){if(flt(me.last_value)==flt(val)){me.last_value=val;return;}} +me.last_value=val;me.run_trigger();} +this.input.set_input=function(val){if(val==null)val='';me.input.value=val;if(me.format_input)me.format_input();} +if(this.df.options=='Suggest'){if(this.suggest_icon)this.suggest_icon.toggle(true);$(me.input).autocomplete({source:function(request,response){wn.call({method:'webnotes.widgets.search.search_link',args:{'txt':request.term,'dt':me.df.options,'query':repl('SELECT DISTINCT `%(fieldname)s` FROM \ + `tab%(dt)s` WHERE `%(fieldname)s` LIKE "%s" LIMIT 50',{fieldname:me.df.fieldname,dt:me.df.parent})},callback:function(r){response(r.results);}});},select:function(event,ui){me.set(ui.item.value);}});}} +DataField.prototype.validate=function(v){if(this.df.options=='Phone'){if(v+''=='')return'';v1='' +v=v.replace(/ /g,'').replace(/-/g,'').replace(/\(/g,'').replace(/\)/g,'');if(v&&v.substr(0,1)=='+'){v1='+';v=v.substr(1);} +if(v&&v.substr(0,2)=='00'){v1+='00';v=v.substr(2);} +if(v&&v.substr(0,1)=='0'){v1+='0';v=v.substr(1);} +v1+=cint(v)+'';return v1;}else if(this.df.options=='Email'){if(v+''=='')return'';if(!validate_email(v)){msgprint(this.df.label+': '+v+' is not a valid email id');return'';}else +return v;}else{return v;}} +function ReadOnlyField(){} +ReadOnlyField.prototype=new Field();function HTMLField(){} +HTMLField.prototype=new Field();HTMLField.prototype.with_label=0;HTMLField.prototype.set_disp=function(val){if(this.disp_area)this.disp_area.innerHTML=val;} +HTMLField.prototype.set_input=function(val){if(val)this.set_disp(val);} +HTMLField.prototype.onrefresh=function(){if(this.df.options)this.set_disp(this.df.options);} +var datepicker_active=0;function DateField(){}DateField.prototype=new Field();DateField.prototype.make_input=function(){var me=this;this.user_fmt=sys_defaults.date_format;if(!this.user_fmt)this.user_fmt='dd-mm-yy';this.input=$a(this.input_area,'input');$(this.input).datepicker({dateFormat:me.user_fmt.replace('yyyy','yy'),altFormat:'yy-mm-dd',changeYear:true,beforeShow:function(input,inst){datepicker_active=1},onClose:function(dateText,inst){datepicker_active=0;if(_f.cur_grid_cell) +_f.cur_grid_cell.grid.cell_deselect();}});var me=this;me.input.onchange=function(){if(this.value==null)this.value='';if(!this.not_in_form) +me.set(dateutil.user_to_str(me.input.value));me.run_trigger();} +me.input.set_input=function(val){if(val==null)val='';else val=dateutil.str_to_user(val);me.input.value=val;} +me.get_value=function(){if(me.input.value) +return dateutil.user_to_str(me.input.value);}} +DateField.prototype.set_disp=function(val){var v=dateutil.str_to_user(val);if(v==null)v='';this.set_disp_html(v);} +DateField.prototype.validate=function(v){if(!v)return;var me=this;this.clear=function(){msgprint("Date must be in format "+this.user_fmt);me.input.set_input('');return'';} +var t=v.split('-');if(t.length!=3){return this.clear();} +else if(cint(t[1])>12||cint(t[1])<1){return this.clear();} +else if(cint(t[2])>31||cint(t[2])<1){return this.clear();} +return v;};function LinkField(){}LinkField.prototype=new Field();LinkField.prototype.make_input=function(){var me=this;if(me.df.no_buttons){this.txt=$a(this.input_area,'input');this.input=this.txt;}else{makeinput_popup(this,'icon-search','icon-play','icon-plus');me.setup_buttons();me.onrefresh=function(){if(me.can_create) +$(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 $('
  • ').data('item.autocomplete',item).append(repl('%(label)s
    %(info)s
    ',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);}}else{$dh(me.btn2);$y($td(me.tab,0,2),{width:'0px'});}} +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;} +if(val){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('

    Click here to create a new %(dtl)s',{dt:me.df.options,dtl:get_doctype_label(me.df.options)}) +msgprint(repl('error:%(val)s is not a valid %(dt)s.

    You must first create a new %(dt)s %(val)s and then select its value. To find an existing %(dt)s, click on the magnifying glass next to the field.%(add)s',{val:me.txt.value,dt:get_doctype_label(me.df.options),add:astr}));me.txt.value='';me.set('');}});} +LinkField.prototype.set_fetch_values=function(fetch_values){var fl=cur_frm.fetch_dict[this.df.fieldname].fields;var changed_fields=[];for(var i=0;i"+val+"";this.set_disp_html(t);} +function IntField(){}IntField.prototype=new DataField();IntField.prototype.validate=function(v){if(isNaN(parseInt(v)))return null;return cint(v);};IntField.prototype.format_input=function(){if(this.input.value==null)this.input.value='';} +function FloatField(){}FloatField.prototype=new DataField();FloatField.prototype.validate=function(v){var v=parseFloat(v);if(isNaN(v)) +return null;return v;};FloatField.prototype.format_input=function(){if(this.input.value==null)this.input.value='';} +function CurrencyField(){}CurrencyField.prototype=new DataField();CurrencyField.prototype.format_input=function(){var v=fmt_money(this.input.value);if(this.not_in_form){if(!flt(this.input.value))v='';} +this.input.value=v;} +CurrencyField.prototype.validate=function(v){if(v==null||v=='') +return 0;return flt(v,2);} +CurrencyField.prototype.set_disp=function(val){var v=fmt_money(val);this.set_disp_html(v);} +CurrencyField.prototype.onmake_input=function(){if(!this.input)return;this.input.onfocus=function(){if(flt(this.value)==0)this.select();}} +function CheckField(){}CheckField.prototype=new Field();CheckField.prototype.validate=function(v){var v=parseInt(v);if(isNaN(v))return 0;return v;};CheckField.prototype.onmake=function(){this.checkimg=$a(this.disp_area,'div');var img=$a(this.checkimg,'img');img.src='images/lib/ui/tick.gif';$dh(this.checkimg);} +CheckField.prototype.make_input=function(){var me=this;this.input=$a_input(this.input_area,'checkbox');$y(this.input,{width:"16px",border:'0px',margin:'2px'});$(this.input).click(function(){me.set(this.checked?1:0);me.run_trigger();}) +this.input.set_input=function(v){v=parseInt(v);if(isNaN(v))v=0;if(v)me.input.checked=true;else me.input.checked=false;} +this.get_value=function(){return this.input.checked?1:0;}} +CheckField.prototype.set_disp=function(val){if(val){$ds(this.checkimg);} +else{$dh(this.checkimg);}} +function TextField(){}TextField.prototype=new Field();TextField.prototype.set_disp=function(val){this.disp_area.innerHTML=replace_newlines(val);} +TextField.prototype.make_input=function(){var me=this;if(this.in_grid) +return;this.input=$a(this.input_area,'textarea');if(this.df.fieldtype=='Small Text') +this.input.style.height="80px";this.input.set_input=function(v){me.input.value=v;} +this.input.onchange=function(){me.set(me.input.value);me.run_trigger();} +this.get_value=function(){return this.input.value;}} +var text_dialog;function make_text_dialog(){var d=new Dialog(520,410,'Edit Text');d.make_body([['Text','Enter Text'],['HTML','Description'],['Button','Update']]);d.widgets['Update'].onclick=function(){var t=this.dialog;t.field.set(t.widgets['Enter Text'].value);t.hide();} +d.onshow=function(){this.widgets['Enter Text'].style.height='300px';var v=_f.get_value(this.field.doctype,this.field.docname,this.field.df.fieldname);this.widgets['Enter Text'].value=v==null?'':v;this.widgets['Enter Text'].focus();this.widgets['Description'].innerHTML='' +if(this.field.df.description) +$a(this.widgets['Description'],'div','help small','',this.field.df.description);} +d.onhide=function(){if(_f.cur_grid_cell) +_f.cur_grid_cell.grid.cell_deselect();} +text_dialog=d;} +TextField.prototype.table_refresh=function(){if(!this.text_dialog) +make_text_dialog();text_dialog.set_title('Enter text for "'+this.df.label+'"');text_dialog.field=this;text_dialog.show();} +function SelectField(){}SelectField.prototype=new Field();SelectField.prototype.make_input=function(){var me=this;var opt=[];if(this.in_filter&&(!this.df.single_select)){this.input=$a(this.input_area,'select');this.input.multiple=true;this.input.style.height='4em';this.input.lab=$a(this.input_area,'div',{fontSize:'9px',color:'#999'});this.input.lab.innerHTML='(Use Ctrl+Click to select multiple or de-select)'}else{this.input=$a(this.input_area,'select');this.input.onchange=function(){if(me.validate) +me.validate();me.set(sel_val(this));me.run_trigger();} +if(this.df.options=='attach_files:'){this.file_attach=true;}} +this.set_as_single=function(){var i=this.input;i.multiple=false;i.style.height=null;if(i.lab)$dh(i.lab)} +this.refresh_options=function(options){if(options) +me.df.options=options;if(this.file_attach) +this.set_attach_options();me.options_list=me.df.options?me.df.options.split('\n'):[''];empty_select(this.input);if(me.in_filter&&me.options_list[0]!=''){me.options_list=add_lists([''],me.options_list);} +add_sel_options(this.input,me.options_list);} +this.onrefresh=function(){this.refresh_options();if(this.not_in_form){this.input.value='';return;} +if(_f.get_value) +var v=_f.get_value(this.doctype,this.docname,this.df.fieldname);else{if(this.options_list&&this.options_list.length) +var v=this.options_list[0];else +var v=null;} +this.input.set_input(v);} +this.input.set_input=function(v){if(!v){if(!me.input.multiple){if(me.docname){if(me.options_list&&me.options_list.length){me.set(me.options_list[0]);me.input.value=me.options_list[0];}else{me.input.value='';}}}}else{if(me.options_list){if(me.input.multiple){for(var i=0;i\ + %(lab_status)s',{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');} +if(docstatus==0&&p[SUBMIT]&&(!cur_frm.doc.__islocal)) +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');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,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]||wn.pages['List/'+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") +throw'doctype open conflict'}}} +_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&&!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);this.setup_fields_std();} +_f.Frm.prototype.setup_print=function(){var l=[] +this.default_format='Standard';for(var key in locals['Print Format']){if(locals['Print Format'][key].doc_type==this.meta.name){l.push(locals['Print Format'][key].name);}} +if(this.meta.default_print_format) +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();_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&&!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(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=$('
    ').insertBefore(this.page_layout.body.firstChild);} +if(txt){if(txt.search(/

    /)==-1)txt='

    '+txt+'

    ';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=$('
    ').insertAfter(this.page_layout.body.lastChild);} +if(txt){if(txt.search(/

    /)==-1)txt='

    '+txt+'

    ';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;i7)){f.show_save();}else{f.hide_save();}}} +_f.Frm.prototype.refresh_field=function(fname){cur_frm.fields_dict[fname]&&cur_frm.fields_dict[fname].refresh&&cur_frm.fields_dict[fname].refresh();} +_f.Frm.prototype.refresh_fields=function(){for(var i=0;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;}} +if(f.guardian_has_value){f.df.hidden=0;f.refresh()}else{f.df.hidden=1;f.refresh()}}}} +_f.Frm.prototype.setnewdoc=function(docname){if(this.opendocs[docname]){this.docname=docname;return;} +Meta.make_local_dt(this.doctype,docname);this.docname=docname;var me=this;var viewname=docname;if(this.meta.issingle)viewname=this.doctype;this.runclientscript('onload',this.doctype,this.docname);this.is_editable[docname]=1;if(this.meta.read_only_onload)this.is_editable[docname]=0;this.opendocs[docname]=true;} +_f.Frm.prototype.edit_doc=function(){this.is_editable[this.docname]=true;this.refresh();} +_f.Frm.prototype.show_doc=function(dn){this.refresh(dn);} +var validated;_f.Frm.prototype.save=function(save_action,call_back){if(!save_action)save_action='Save';var me=this;if(this.savingflag){msgprint("Document is currently saving....");return;} +if(save_action=='Submit'){locals[this.doctype][this.docname].submitted_on=dateutil.full_str();locals[this.doctype][this.docname].submitted_by=user;} +if(save_action=='Trash'){var reason=prompt('Reason for trash (mandatory)','');if(!strip(reason)){msgprint('Reason is mandatory, not trashed');return;} +locals[this.doctype][this.docname].trash_reason=reason;} +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');if(!validated){this.savingflag=false;return'Error';}} +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);}} +_f.Frm.prototype.runscript=function(scriptname,callingfield,onrefresh){var me=this;if(this.docname){var doclist=compress_doclist(make_doclist(this.doctype,this.docname));if(callingfield) +$(callingfield.input).set_working();$c('runserverobj',{'docs':doclist,'method':scriptname},function(r,rtxt){if(onrefresh) +onrefresh(r,rtxt);me.refresh_fields();me.refresh_dependency();if(callingfield) +$(callingfield.input).done_working();});}} +_f.Frm.prototype.runclientscript=function(caller,cdt,cdn){if(!cdt)cdt=this.doctype;if(!cdn)cdn=this.docname;var ret=null;var doc=locals[cur_frm.doc.doctype][cur_frm.doc.name];try{if(this.cscript[caller]) +ret=this.cscript[caller](doc,cdt,cdn);if(this.cscript['custom_'+caller]) +ret+=this.cscript['custom_'+caller](doc,cdt,cdn);}catch(e){console.log(e);} +if(caller&&caller.toLowerCase()=='setup'){var doctype=get_local('DocType',this.doctype);var cs=doctype.__js||(doctype.client_script_core+doctype.client_script);if(cs){try{var tmp=eval(cs);}catch(e){console.log(e);}} +if(doctype.__css)set_style(doctype.__css) +if(doctype.client_string){this.cstring={};var elist=doctype.client_string.split('---');for(var i=1;i
    ',this.df));}else{$(this.wrapper).html('
    ');} +this.section_collapse=function(){$(me.row.main_head).find('.head').html(' \ + Show "'+me.df.label+'"');$(me.row.main_body).toggle(false);} +this.section_expand=function(no_animation){$(me.row.main_head).find('.head').html('

    ' ++me.df.label+'

    ');if(no_animation) +$(me.row.main_body).toggle(true);else +$(me.row.main_body).slideDown();}} +_f.SectionBreak.prototype.has_data=function(){var me=this;for(var i in me.fields){var f=me.fields[i];var v=f.get_value?f.get_value():null;defaultval=f.df['default']||sys_defaults[f.fieldname]||user_defaults[f.fieldname];if(v&&v!=defaultval){return true;} +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){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="";} +return src;} +_f.ImageField.prototype.onrefresh=function(){var me=this;if(!this.images[this.docname])this.images[this.docname]=$a(this.wrapper,'img');else $di(this.images[this.docname]);var img=this.images[this.docname] +for(var dn in this.images)if(dn!=this.docname)$dh(this.images[dn]);var doc=locals[this.frm.doctype][this.frm.docname];if(!this.df.options)var src=this.get_image_src(doc);else var src=wn.request.url+'?cmd=get_file&fname='+this.df.options+"&__account="+account_id+(__sid150?("&sid150="+__sid150):'');if(src){$dh(this.no_img);if(img.getAttribute('src')!=src)img.setAttribute('src',src);canvas=this.wrapper;canvas.img=this.images[this.docname];canvas.style.overflow="auto";$w(canvas,"100%");if(!this.col_break_width)this.col_break_width='100%';var allow_width=cint(1000*(cint(this.col_break_width)-10)/100);if((!img.naturalWidth)||cint(img.naturalWidth)>allow_width) +$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]){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') +this.grid.can_add_rows=true;} +if(cur_frm.editable&&cur_frm.doc.docstatus>0){if(this.df.allow_on_submit&&cur_frm.doc.docstatus==1){this.grid.can_edit=true;if(this.df['default'].toLowerCase()=='no toolbar'){this.grid.can_add_rows=false;}else{this.grid.can_add_rows=true;}}else{this.grid.can_add_rows=false;this.grid.can_edit=false;}} +if(this.df['default'].toLowerCase()=='no add rows'){this.grid.can_add_rows=false;}} +if(st=='Write'){this.grid.show();}else if(st=='Read'){this.grid.show();}else{this.grid.hide();} +this.grid.refresh();} +_f.TableField.prototype.set=function(v){};_f.TableField.prototype.set_input=function(v){};_f.CodeField=function(){};_f.CodeField.prototype=new Field();_f.CodeField.prototype.make_input=function(){var me=this;this.label_span.innerHTML=this.df.label;if(this.df.fieldtype=='Text Editor'){this.input=$a(this.input_area,'text_area','',{fontSize:'12px'});this.myid=wn.dom.set_unique_id(this.input);$(me.input).tinymce({script_url:'js/lib/tiny_mce_33/tiny_mce.js',theme:"advanced",plugins:"style,inlinepopups,table,advimage",extended_valid_elements:"div[id|dir|class|align|style]",width:'100%',height:'360px',theme_advanced_buttons1:"bold,italic,underline,strikethrough,hr,|,justifyleft,justifycenter,justifyright,|,formatselect,fontselect,fontsizeselect,|,image",theme_advanced_buttons2:"bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,code,|,forecolor,backcolor,|,tablecontrols",theme_advanced_buttons3:"",theme_advanced_toolbar_location:"top",theme_advanced_toolbar_align:"left",content_css:"js/lib/tiny_mce_33/custom_content.css?q=1",oninit:function(){me.init_editor();}});this.input.set_input=function(v){if(me.editor){me.editor.setContent(v);}else{$(me.input).val(v);}} +this.input.onchange=function(){me.set(me.editor.getContent());me.run_trigger();} +this.get_value=function(){return me.editor.getContent();}}else{wn.require('js/lib/ace/ace.js');$(this.input_area).css('border','1px solid #aaa');this.pre=$a(this.input_area,'pre','',{position:'relative',height:'400px',width:'100%'});this.input={};this.myid=wn.dom.set_unique_id(this.pre);this.editor=ace.edit(this.myid);if(me.df.options=='Markdown'||me.df.options=='HTML'){wn.require('js/lib/ace/mode-html.js');var HTMLMode=require("ace/mode/html").Mode;me.editor.getSession().setMode(new HTMLMode());} +else if(me.df.options=='Javascript'){wn.require('js/lib/ace/mode-javascript.js');var JavascriptMode=require("ace/mode/javascript").Mode;me.editor.getSession().setMode(new JavascriptMode());} +else if(me.df.options=='Python'){wn.require('js/lib/ace/mode-python.js');var PythonMode=require("ace/mode/python").Mode;me.editor.getSession().setMode(new PythonMode());} +this.input.set_input=function(v){me.setting_value=true;me.editor.getSession().setValue(v);me.setting_value=false;} +this.get_value=function(){return me.editor.getSession().getValue();} +$(cur_frm.wrapper).bind('render_complete',function(){me.editor.resize();me.editor.getSession().on('change',function(){if(me.setting_value)return;var val=me.get_value();if(locals[cur_frm.doctype][cur_frm.docname][me.df.fieldname]!=val){me.set(me.get_value());me.run_trigger();}})});}} +_f.CodeField.prototype.init_editor=function(){var me=this;this.editor=tinymce.get(this.myid);this.editor.onKeyUp.add(function(ed,e){me.set(ed.getContent());});this.editor.onPaste.add(function(ed,e){me.set(ed.getContent());});this.editor.onSetContent.add(function(ed,e){me.set(ed.getContent());});var c=locals[cur_frm.doctype][cur_frm.docname][this.df.fieldname];if(cur_frm&&c){this.editor.setContent(c);}} +_f.CodeField.prototype.set_disp=function(val){$y(this.disp_area,{width:'90%'}) +if(this.df.fieldtype=='Text Editor'){this.disp_area.innerHTML=val;}else{this.disp_area.innerHTML='';}} +/* + * lib/js/legacy/widgets/form/grid.js + */ +_f.cur_grid_cell=null;_f.Grid=function(parent){} +_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%',['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);} +_f.Grid.prototype.insert_column=function(doctype,fieldname,fieldtype,label,width,options,perm,reqd){var idx=this.head_row.cells.length;if(!width)width='100px';if((width+'').slice(-2)!='px'){width=width+'px';} +var col=this.head_row.insertCell(idx);col.doctype=doctype;col.fieldname=fieldname;col.fieldtype=fieldtype;col.innerHTML='
    '+label+'
    ';col.label=label;if(reqd) +col.childNodes[0].style.color="#D22";col.style.width=width;col.options=options;col.perm=perm;this.col_idx_by_name[fieldname]=idx;} +_f.Grid.prototype.reset_table_width=function(){var w=0;$.each(this.head_row.cells,function(i,cell){if((cell.style.display||'').toLowerCase()!='none') +w+=cint(cell.style.width);}) +this.head_tab.style.width=w+'px';this.tab.style.width=w+'px';} +_f.Grid.prototype.set_column_disp=function(fieldname,show){var cidx=this.col_idx_by_name[fieldname];if(!cidx){msgprint('Trying to hide unknown column: '+fieldname);return;} +var disp=show?'table-cell':'none';this.head_row.cells[cidx].style.display=disp;for(var i=0,len=this.tab.rows.length;i=37&&keycode<=40&&e.shiftKey){if(text_dialog&&text_dialog.display){return;}}else +return;if(!_f.cur_grid_cell)return;if(_f.cur_grid_cell.grid!=this)return;var ri=_f.cur_grid_cell.row.rowIndex;var ci=_f.cur_grid_cell.cellIndex;switch(keycode){case 38:if(ri>0){this.cell_select('',ri-1,ci);}break;case 40:if(ri<(this.tab.rows.length-1)){this.cell_select('',ri+1,ci);}break;case 39:if(ci<(this.head_row.cells.length-1)){this.cell_select('',ri,ci+1);}break;case 37:if(ci>1){this.cell_select('',ri,ci-1);}break;}} +_f.Grid.prototype.make_template=function(hc){hc.template=make_field(wn.meta.get_docfield(hc.doctype,hc.fieldname),hc.doctype,'',this.field.frm,true);hc.template.grid=this;} +_f.Grid.prototype.append_rows=function(n){for(var i=0;ithis.tab.rows.length) +this.append_rows(data.length-this.tab.rows.length);if(data.lengthmax_ht)ht=max_ht;ht+=4;$y(this.wrapper,{height:ht+'px'});} +_f.Grid.prototype.refresh_row=function(ridx,docname){var row=this.tab.rows[ridx];row.docname=docname;row.is_newrow=false;for(var cidx=0;cidx'+label+'
    ';c.cur_label=label;break;}}} +_f.FormGrid.prototype.get_children=function(){return getchildren(this.doctype,this.field.frm.docname,this.field.df.fieldname,this.field.frm.doctype);} +_f.FormGrid.prototype.refresh=function(){var docset=this.get_children();var data=[];for(var i=0;i*';r.is_newrow=true;} +_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-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) +len=len-1;if(r.rowIndex<(len-1)) +var swap_row=this.tab.rows[r.rowIndex+1];} +if(swap_row){var cidx=_f.cur_grid_cell.cellIndex;this.cell_deselect();var aidx=locals[this.doctype][r.docname].idx;locals[this.doctype][r.docname].idx=locals[this.doctype][swap_row.docname].idx;locals[this.doctype][swap_row.docname].idx=aidx;var adocname=swap_row.docname;this.refresh_row(swap_row.rowIndex,r.docname);this.refresh_row(r.rowIndex,adocname);this.cell_select(this.tab.rows[swap_row.rowIndex].cells[cidx]);this.set_unsaved();}} +/* + * lib/js/legacy/widgets/form/print_format.js + */ +_p.def_print_style_body="html, body, div, span, td { font-family: Arial, Helvetica; font-size: 12px; }"+"\npre { margin:0; padding:0;}" +_p.def_print_style_other="\n.simpletable, .noborder { border-collapse: collapse; margin-bottom: 10px;}" ++"\n.simpletable td {border: 1pt solid #000; vertical-align: top; padding: 2px; }" ++"\n.noborder td { vertical-align: top; }" +_p.go=function(html){var d=document.createElement('div') +d.innerHTML=html +$(d).printElement();} +_p.preview=function(html){var w=window.open('');if(!w)return;w.document.write(html) +w.document.close();} +$.extend(_p,{show_dialog:function(){if(!_p.dialog){_p.make_dialog();} +_p.dialog.show();},make_dialog:function(){var d=new Dialog(360,140,'Print Formats',[['HTML','Select'],['Check','No Letterhead'],['HTML','Buttons']]);$btn(d.widgets.Buttons,'Print',function(){_p.build(sel_val(cur_frm.print_sel),_p.go,d.widgets['No Letterhead'].checked);},{cssFloat:'right',marginBottom:'16px',marginLeft:'7px'},'green');$btn(d.widgets.Buttons,'Preview',function(){_p.build(sel_val(cur_frm.print_sel),_p.preview,d.widgets['No Letterhead'].checked);},{cssFloat:'right',marginBottom:'16px'},'');d.onshow=function(){var c=_p.dialog.widgets['Select'];if(c.cur_sel&&c.cur_sel.parentNode==c){c.removeChild(c.cur_sel);} +c.appendChild(cur_frm.print_sel);c.cur_sel=cur_frm.print_sel;} +_p.dialog=d;},formats:{},build:function(fmtname,onload,no_letterhead,only_body){args={fmtname:fmtname,onload:onload,no_letterhead:no_letterhead,only_body:only_body};if(!cur_frm){alert('No Document Selected');return;} +var doc=locals[cur_frm.doctype][cur_frm.docname];if(args.fmtname=='Standard'){args.onload(_p.render({body:_p.print_std(args.no_letterhead),style:_p.print_style,doc:doc,title:doc.name,no_letterhead:args.no_letterhead,only_body:args.only_body}));}else{if(!_p.formats[args.fmtname]){var build_args=args;$c(command='webnotes.widgets.form.print_format.get',args={'name':build_args.fmtname},fn=function(r,rt){_p.formats[build_args.fmtname]=r.message;build_args.onload(_p.render({body:_p.formats[build_args.fmtname],style:'',doc:doc,title:doc.name,no_letterhead:build_args.no_letterhead,only_body:build_args.only_body}));});}else{args.onload(_p.render({body:_p.formats[args.fmtname],style:'',doc:doc,title:doc.name,no_letterhead:args.no_letterhead,only_body:args.only_body}));}}},render:function(args){var container=document.createElement('div');var stat='';stat+=_p.show_draft(args);stat+=_p.show_archived(args);stat+=_p.show_cancelled(args);container.innerHTML=args.body;_p.show_letterhead(container,args);_p.run_embedded_js(container,args.doc);var style=_p.consolidate_css(container,args);_p.render_header_on_break(container,args);return _p.render_final(style,stat,container,args);},head_banner_format:function(){return"\ +
    \ +
    \ + {{HEAD}}\ +
    \ + {{DESCRIPTION}}\ +
    "},show_draft:function(args){var is_doctype_submittable=0;var plist=locals['DocPerm'];for(var perm in plist){var p=plist[perm];if((p.parent==args.doc.doctype)&&(p.submit==1)){is_doctype_submittable=1;break;}} +if(args.doc&&cint(args.doc.docstatus)==0&&is_doctype_submittable){draft=_p.head_banner_format();draft=draft.replace("{{HEAD}}","DRAFT");draft=draft.replace("{{DESCRIPTION}}","This box will go away after the document is submitted.");return draft;}else{return"";}},show_archived:function(args){if(args.doc&&args.doc.__archived){archived=_p.head_banner_format();archived=archived.replace("{{HEAD}}","ARCHIVED");archived=archived.replace("{{DESCRIPTION}}","You must restore this document to make it editable.");return archived;}else{return"";}},show_cancelled:function(args){if(args.doc&&args.doc.docstatus==2){cancelled=_p.head_banner_format();cancelled=cancelled.replace("{{HEAD}}","CANCELLED");cancelled=cancelled.replace("{{DESCRIPTION}}","You must amend this document to make it editable.");return cancelled;}else{return"";}},consolidate_css:function(container,args){var body_style='';var style_list=container.getElementsByTagName('style');while(style_list&&style_list.length>0){for(i in style_list){if(style_list[i]&&style_list[i].innerHTML){body_style+=style_list[i].innerHTML;var parent=style_list[i].parentNode;if(parent){parent.removeChild(style_list[i]);}else{container.removeChild(style_list[i]);}}} +style_list=container.getElementsByTagName('style');} +style_concat=(args.only_body?'':_p.def_print_style_body) ++_p.def_print_style_other+args.style+body_style;return style_concat;},run_embedded_js:function(container,doc){var jslist=container.getElementsByTagName('script');while(jslist&&jslist.length>0){for(i in jslist){if(jslist[i]&&jslist[i].innerHTML){var code=jslist[i].innerHTML;var parent=jslist[i].parentNode;var span=$a(parent,'span');parent.replaceChild(span,jslist[i]);var val=code?eval(code):'';if(!val||typeof(val)=='object'){val='';} +span.innerHTML=val;}} +jslist=container.getElementsByTagName('script');}},show_letterhead:function(container,args){if(!(args.no_letterhead||args.only_body)){container.innerHTML='
    '+_p.get_letter_head()+'
    ' ++container.innerHTML;}},render_header_on_break:function(container,args){var page_set=container.getElementsByClassName('page-settings');if(page_set.length){for(var i=0;i\ + \ + \ + \n'+header;footer=footer+'\n\n\ + ';} +var finished=header ++stat ++container.innerHTML.replace(/
    '+field.label+':
    '+(val?val:'')+'
    ';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;iSR';$y(cell,{width:'30px'});$y(cell,me.head_cell_style);col_start++;} +for(var c=col_start;c1)?me.table_list:me.table_list[0];} +/* + * lib/js/legacy/widgets/form/email.js + */ +_e.email_as_field='email_id';_e.email_as_dt='Contact';_e.email_as_in='email_id,contact_name';sendmail=function(emailto,emailfrom,cc,subject,message,fmt,with_attachments){var fn=function(html){$c('webnotes.utils.email_lib.send_form',{'sendto':emailto,'sendfrom':emailfrom?emailfrom:'','cc':cc?cc:'','subject':subject,'message':replace_newlines(message),'body':html,'full_domain':wn.urllib.get_base_url(),'with_attachments':with_attachments?1:0,'dt':cur_frm.doctype,'dn':cur_frm.docname,'customer':cur_frm.doc.customer||'','supplier':cur_frm.doc.supplier||''},function(r,rtxt){});} +_p.build(fmt,fn);} +_e.make=function(){var d=new Dialog(440,440,"Send Email");var email_go=function(){var emailfrom=d.widgets['From'].value;var emailto=d.widgets['To'].value;if(!emailfrom) +emailfrom=user_email;emailto=emailto.replace(/ /g,"");var email_list=emailto.split(/[,|;]/);var valid=1;for(var i=0;i12){time=(parseInt(hr)-12)+':'+min+' PM'} +else{time=hr+':'+min+' AM'}} +this.cmt_dtl.innerHTML='On '+d[ri][10].substring(0,3)+' '+d[ri][9]+', '+d[ri][11]+' at '+time;this.cmt.innerHTML=replace_newlines(d[ri][1]);} +CommentItem.prototype.cmt_delete=function(cell,ri,ci,d){var me=this;if(d[ri][2]==user||d[ri][3]==user){del=$a(cell,'i','icon-remove-sign',{cursor:'pointer'});del.cmt_id=d[ri][0];del.onclick=function(){wn.widgets.form.comments.remove(cur_frm.doctype,cur_frm.docname,this.cmt_id,function(){me.comment.lst.run();})}}} +/* + * 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&&!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(){return!me.form.doc.__islocal}},{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('

    Created:
    \ + \ + %(creation)s

    \ +

    Modified:
    \ + \ + %(modified)s

    ',{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 + */ +wn.widgets.form.sidebar.Comments=function(parent,sidebar,doctype,docname){var me=this;this.sidebar=sidebar;this.doctype=doctype;this.docname=docname;this.refresh=function(){$c('webnotes.widgets.form.comments.get_comments',{dt:me.doctype,dn:me.docname,limit:5},function(r,rt){wn.widgets.form.comments.sync(me.doctype,me.docname,r);me.make_body();});} +this.make_body=function(){if(this.wrapper)this.wrapper.innerHTML='';else this.wrapper=$a(parent,'div','sidebar-comment-wrapper');this.input=$a_input(this.wrapper,'text');this.btn=$btn(this.wrapper,'Post',function(){me.add_comment()},{marginLeft:'8px'});this.render_comments()} +this.render_comments=function(){var f=wn.widgets.form.comments;var cl=f.comment_list[me.docname] +this.msg=$a(this.wrapper,'div','help small');if(cl){this.msg.innerHTML=cl.length+' out of '+f.n_comments[me.docname]+' comments';if(f.n_comments[me.docname]>cl.length){this.msg.innerHTML+=' Show all'} +for(var i=0;iAttachments can be \ + uploaded after saving
    ';return;} +var n=this.frm.doc.file_list?this.frm.doc.file_list.split('\n').length:0;if(n%(owner)s \ + ×
    ',d[i]))} +$(this.body).find('a.close').click(function(){$c('webnotes.widgets.form.assign_to.remove',{doctype:me.doctype,name:me.name,assign_to:$(this).attr('data-owner')},function(r,rt){me.render(r.message);});return false;});},add:function(){var me=this;if(!me.dialog){me.dialog=new wn.widgets.Dialog({title:'Add to To Do',width:350,fields:[{fieldtype:'Link',fieldname:'assign_to',options:'Profile',label:'Assign To',description:'Add to To Do List of',reqd:true},{fieldtype:'Data',fieldname:'description',label:'Comment'},{fieldtype:'Date',fieldname:'date',label:'Complete By'},{fieldtype:'Select',fieldname:'priority',label:'Priority',options:'Low\nMedium\nHigh','default':'Medium'},{fieldtype:'Check',fieldname:'notify',label:'Notify By Email'},{fieldtype:'Button',label:'Add',fieldname:'add_btn'}]});me.dialog.fields_dict.add_btn.input.onclick=function(){var assign_to=me.dialog.fields_dict.assign_to.get_value();if(assign_to){$c('webnotes.widgets.form.assign_to.add',{doctype:me.doctype,name:me.name,assign_to:assign_to,description:me.dialog.fields_dict.description.get_value(),priority:me.dialog.fields_dict.priority.get_value(),date:me.dialog.fields_dict.date.get_value(),notify:me.dialog.fields_dict.notify.get_value()},function(r,rt){me.render(r.message);});}}} +me.dialog.clear();me.dialog.show();}}); +/* + * lib/js/wn/app.js + */ +wn.Application=Class.extend({init:function(){var me=this;if(window.app){wn.call({method:'startup',callback:function(r,rt){wn.provide('wn.boot');wn.boot=r;if(wn.boot.profile.name=='Guest'){window.location='index.html';return;} +me.startup();}})}else{this.startup();}},startup:function(){this.load_bootinfo();this.make_page_container();this.make_nav_bar();this.set_favicon();$(document).trigger('startup');if(wn.boot){wn.route();} +$(document).trigger('app_ready');},load_bootinfo:function(){if(wn.boot){LocalDB.sync(wn.boot.docs);wn.control_panel=wn.boot.control_panel;this.set_globals();if(wn.boot.developer_mode){console.log("LocalStorage is OFF for developer mode. Please build before going live.");}}else{this.set_as_guest();}},set_globals:function(){profile=wn.boot.profile;user=wn.boot.profile.name;user_fullname=wn.user_info(user).fullname;user_defaults=profile.defaults;user_roles=profile.roles;user_email=profile.email;sys_defaults=wn.boot.sysdefaults;},set_as_guest:function(){profile={name:'Guest'};user='Guest';user_fullname='Guest';user_defaults={};user_roles=['Guest'];user_email='';sys_defaults={};},make_page_container:function(){wn.container=new wn.views.Container();wn.views.make_403();wn.views.make_404();},make_nav_bar:function(){if(wn.boot){wn.container.wntoolbar=new wn.ui.toolbar.Toolbar();}},logout:function(){var me=this;me.logged_out=true;wn.call({method:'logout',callback:function(r){if(r.exc){console.log(r.exc);} +me.redirect_to_login();}})},redirect_to_login:function(){window.location.href='index.html';},set_favicon:function(){var link=$('link[type="image/x-icon"]').remove().attr("href");var favicon='\ + \ + ' +$(favicon).appendTo('head');}}) +/* + * erpnext/startup/startup.js + */ +var current_module;var is_system_manager=0;wn.provide('erpnext.startup');erpnext.modules={'Selling':'selling-home','Accounts':'accounts-home','Stock':'stock-home','Buying':'buying-home','Support':'support-home','Projects':'projects-home','Production':'production-home','Website':'website-home','HR':'hr-home','Setup':'Setup','Activity':'activity','To Do':'todo','Calendar':'calendar','Messages':'messages','Knowledge Base':'questions','Dashboard':'dashboard'} +wn.provide('wn.modules');$.extend(wn.modules,erpnext.modules);wn.modules['Core']='Setup';erpnext.startup.set_globals=function(){if(inList(user_roles,'System Manager'))is_system_manager=1;} +erpnext.startup.start=function(){console.log('Starting up...');$('#startup_div').html('Starting up...').toggle(true);erpnext.startup.set_globals();if(user!='Guest'){if(wn.boot.user_background){erpnext.set_user_background(wn.boot.user_background);} +wn.boot.profile.allow_modules=wn.boot.profile.allow_modules.concat(['To Do','Knowledge Base','Calendar','Activity','Messages']) +erpnext.toolbar.setup();erpnext.startup.set_periodic_updates();$('footer').html('');if(in_list(user_roles,'System Manager')&&(wn.boot.setup_complete=='No')){wn.require("js/app/complete_setup.js");erpnext.complete_setup.show();} +if(wn.boot.expires_on&&in_list(user_roles,'System Manager')){var today=dateutil.str_to_obj(dateutil.get_today());var expires_on=dateutil.str_to_obj(wn.boot.expires_on);var diff=dateutil.get_diff(expires_on,today);if(0<=diff&&diff<=15){var expiry_string=diff==0?"today":repl("in %(diff)s day(s)",{diff:diff});$('header').append(repl('
    \ + Your ERPNext subscription will expire %(expiry_string)s. \ + Please renew your subscription to continue using ERPNext \ + (and remove this annoying banner). \ +
    ',{expiry_string:expiry_string}));}else if(diff<0){$('header').append(repl('
    \ + This ERPNext subscription has expired. \ +
    ',{expiry_string:expiry_string}));}} +erpnext.set_about();if(wn.control_panel.custom_startup_code) +eval(wn.control_panel.custom_startup_code);}} +erpnext.update_messages=function(reset){if(inList(['Guest'],user)||!wn.session_alive){return;} +if(!reset){var set_messages=function(r){if(!r.exc){erpnext.toolbar.set_new_comments(r.message.unread_messages);var show_in_circle=function(parent_id,msg){var parent=$('#'+parent_id);if(parent){if(msg){parent.find('span:first').text(msg);parent.toggle(true);}else{parent.toggle(false);}}} +show_in_circle('unread_messages',r.message.unread_messages.length);show_in_circle('open_support_tickets',r.message.open_support_tickets);show_in_circle('things_todo',r.message.things_todo);show_in_circle('todays_events',r.message.todays_events);show_in_circle('open_tasks',r.message.open_tasks);show_in_circle('unanswered_questions',r.message.unanswered_questions);}else{clearInterval(wn.updates.id);}} +wn.call({method:'startup.startup.get_global_status_messages',callback:set_messages});}else{erpnext.toolbar.set_new_comments(0);$('#unread_messages').toggle(false);}} +erpnext.startup.set_periodic_updates=function(){wn.updates={};if(wn.updates.id){clearInterval(wn.updates.id);} +wn.updates.id=setInterval(erpnext.update_messages,60000);} +erpnext.set_user_background=function(src){set_style(repl('#body_div { background: url("files/%(src)s") repeat;}',{src:src}))} +$(document).bind('startup',function(){erpnext.startup.start();});erpnext.send_message=function(opts){if(opts.btn){$(opts.btn).start_working();} +wn.call({method:'website.send_message',args:opts,callback:function(r){if(opts.btn){$(opts.btn).done_working();} +if(opts.callback)opts.callback(r)}});} +erpnext.hide_naming_series=function(){if(cur_frm.fields_dict.naming_series){hide_field('naming_series');if(cur_frm.doc.__islocal){unhide_field('naming_series');}}} +/* + * erpnext/startup/js/modules.js + */ +wn.provide('erpnext.module_page');erpnext.module_page.setup_page=function(module,wrapper){erpnext.module_page.hide_links(wrapper);erpnext.module_page.make_list(module,wrapper);$(wrapper).find("a[title]").tooltip({delay:{show:500,hide:100}});} +erpnext.module_page.hide_links=function(wrapper){$(wrapper).find('[href*="List/"]').each(function(){var href=$(this).attr('href');var dt=href.split('/')[1];if(wn.boot.profile.all_read.indexOf(get_label_doctype(dt))==-1){var txt=$(this).text();$(this).parent().css('color','#999').html(txt);}});$(wrapper).find('[data-doctype]').each(function(){var dt=$(this).attr('data-doctype');if(wn.boot.profile.all_read.indexOf(dt)==-1){var txt=$(this).text();$(this).parent().css('color','#999').html(txt);}});$(wrapper).find('[href*="Form/"]').each(function(){var href=$(this).attr('href');var dt=href.split('/')[1];if(wn.boot.profile.all_read.indexOf(get_label_doctype(dt))==-1){var txt=$(this).text();$(this).parent().css('color','#999').html(txt);}});$(wrapper).find('[data-role]').each(function(){if(!has_common(user_roles,[$(this).attr("data-role"),"System Manager"])){var html=$(this).html();$(this).parent().css('color','#999');$(this).replaceWith(html);}});} +erpnext.module_page.make_list=function(module,wrapper){var $w=$(wrapper).find('.reports-list');var $parent1=$('
    ').appendTo($w);var $parent2=$('
    ').appendTo($w);wrapper.list1=new wn.ui.Listing({parent:$parent1,method:'utilities.get_sc_list',render_row:function(row,data){if(!data.parent_doc_type)data.parent_doc_type=data.doc_type;$(row).html(repl('\ + %(criteria_name)s',data))},args:{module:module},no_refresh:true,callback:function(r){erpnext.module_page.hide_links($parent1)}});wrapper.list1.run();wrapper.list2=new wn.ui.Listing({parent:$parent2,method:'utilities.get_report_list',render_row:function(row,data){$(row).html(repl('\ + %(name)s',data))},args:{module:module},no_refresh:true,callback:function(r){erpnext.module_page.hide_links($parent2)}});wrapper.list2.run();$parent1.find('.list-toolbar-wrapper').prepend("");$parent2.find('.list-toolbar-wrapper').prepend("");} +/* + * erpnext/startup/js/toolbar.js + */ +wn.provide('erpnext.toolbar');erpnext.toolbar.setup=function(){erpnext.toolbar.add_modules();$('#toolbar-user').append('
  • Profile Settings
  • ');$('.navbar .pull-right').append('\ +
  • ');$('.navbar .pull-right').prepend('') +$('#toolbar-help').append('
  • \ + Documentation
  • ') +$('#toolbar-help').append('
  • \ + Forum
  • ') +$('#toolbar-help').append('
  • \ + Live Chat (Office Hours)
  • ') +erpnext.toolbar.set_new_comments();} +erpnext.toolbar.add_modules=function(){$('').prependTo('.navbar .nav:first');if(wn.boot.modules_list&&typeof(wn.boot.modules_list)=='string'){wn.boot.modules_list=JSON.parse(wn.boot.modules_list);} +else +wn.boot.modules_list=keys(erpnext.modules).sort();for(var i in wn.boot.modules_list){var m=wn.boot.modules_list[i] +if(m!='Setup'&&wn.boot.profile.allow_modules.indexOf(m)!=-1){args={module:m,module_page:erpnext.modules[m],module_label:m=='HR'?'Human Resources':m} +$('.navbar .modules').append(repl('
  • %(module_label)s
  • ',args));}} +if(user_roles.indexOf("Accounts Manager")!=-1){$('.navbar .modules').append('
  • Dashboard
  • ');} +if(user_roles.indexOf("System Manager")!=-1){$('.navbar .modules').append('
  • \ +
  • Setup
  • ');}} +erpnext.toolbar.set_new_comments=function(new_comments){var navbar_nc=$('.navbar-new-comments');if(new_comments&&new_comments.length>0){navbar_nc.text(new_comments.length);navbar_nc.addClass('navbar-new-comments-true') +$.each(new_comments,function(i,v){var msg='New Message: '+(v[1].length<=100?v[1]:(v[1].substr(0,100)+"..."));var id=v[0].replace('/','-');if(!$('#'+id)[0]){show_alert(msg,id);}})}else{navbar_nc.removeClass('navbar-new-comments-true');navbar_nc.text(0);}} +/* + * erpnext/startup/js/feature_setup.js + */ +pscript.feature_dict={'fs_projects':{'BOM':{'fields':['project_name']},'Delivery Note':{'fields':['project_name']},'Purchase Invoice':{'entries':['project_name']},'Production Order':{'fields':['project_name']},'Purchase Order':{'po_details':['project_name']},'Purchase Receipt':{'purchase_receipt_details':['project_name']},'Sales Invoice':{'fields':['project_name']},'Sales Order':{'fields':['project_name']},'Stock Entry':{'fields':['project_name']},'Timesheet':{'timesheet_details':['project_name']}},'fs_packing_details':{},'fs_discounts':{'Delivery Note':{'delivery_note_details':['adj_rate']},'Quotation':{'quotation_details':['adj_rate']},'Sales Invoice':{'entries':['adj_rate']},'Sales Order':{'sales_order_details':['adj_rate','ref_rate']}},'fs_purchase_discounts':{'Purchase Order':{'po_details':['purchase_ref_rate','discount_rate','import_ref_rate']},'Purchase Receipt':{'purchase_receipt_details':['purchase_ref_rate','discount_rate','import_ref_rate']},'Purchase Invoice':{'entries':['purchase_ref_rate','discount_rate','import_ref_rate']}},'fs_brands':{'Delivery Note':{'delivery_note_details':['brand']},'Purchase Request':{'indent_details':['brand']},'Item':{'fields':['brand']},'Purchase Order':{'po_details':['brand']},'Purchase Invoice':{'entries':['brand']},'Quotation':{'quotation_details':['brand']},'Sales Invoice':{'entries':['brand']},'Sales BOM':{'fields':['new_item_brand']},'Sales Order':{'sales_order_details':['brand']},'Serial No':{'fields':['brand']}},'fs_after_sales_installations':{'Delivery Note':{'fields':['installation_status','per_installed'],'delivery_note_details':['installed_qty']}},'fs_item_batch_nos':{'Delivery Note':{'delivery_note_details':['batch_no']},'Item':{'fields':['has_batch_no']},'Purchase Receipt':{'purchase_receipt_details':['batch_no']},'Quality Inspection':{'fields':['batch_no']},'Sales and Pruchase Return Wizard':{'return_details':['batch_no']},'Sales Invoice':{'entries':['batch_no']},'Stock Entry':{'mtn_details':['batch_no']},'Stock Ledger Entry':{'fields':['batch_no']}},'fs_item_serial_nos':{'Customer Issue':{'fields':['serial_no']},'Delivery Note':{'delivery_note_details':['serial_no'],'packing_details':['serial_no']},'Installation Note':{'installed_item_details':['serial_no']},'Item':{'fields':['has_serial_no']},'Maintenance Schedule':{'item_maintenance_detail':['serial_no'],'maintenance_schedule_detail':['serial_no']},'Maintenance Visit':{'maintenance_visit_details':['serial_no']},'Purchase Receipt':{'purchase_receipt_details':['serial_no']},'Quality Inspection':{'fields':['item_serial_no']},'Sales and Pruchase Return Wizard':{'return_details':['serial_no']},'Sales Invoice':{'entries':['serial_no']},'Stock Entry':{'mtn_details':['serial_no']},'Stock Ledger Entry':{'fields':['serial_no']}},'fs_item_barcode':{'Item':{'fields':['barcode']},'Delivery Note':{'delivery_note_details':['barcode']},'Sales Invoice':{'entries':['barcode']}},'fs_item_group_in_details':{'Delivery Note':{'delivery_note_details':['item_group']},'Opportunity':{'enquiry_details':['item_group']},'Purchase Request':{'indent_details':['item_group']},'Item':{'fields':['item_group']},'Global Defaults':{'fields':['default_item_group']},'Purchase Order':{'po_details':['item_group']},'Purchase Receipt':{'purchase_receipt_details':['item_group']},'Purchase Voucher':{'entries':['item_group']},'Quotation':{'quotation_details':['item_group']},'Sales Invoice':{'entries':['item_group']},'Sales BOM':{'fields':['serial_no']},'Sales Order':{'sales_order_details':['item_group']},'Serial No':{'fields':['item_group']},'Sales Partner':{'partner_target_details':['item_group']},'Sales Person':{'target_details':['item_group']},'Territory':{'target_details':['item_group']}},'fs_page_break':{'Delivery Note':{'delivery_note_details':['page_break'],'packing_details':['page_break']},'Purchase Request':{'indent_details':['page_break']},'Purchase Order':{'po_details':['page_break']},'Purchase Receipt':{'purchase_receipt_details':['page_break']},'Purchase Voucher':{'entries':['page_break']},'Quotation':{'quotation_details':['page_break']},'Sales Invoice':{'entries':['page_break']},'Sales Order':{'sales_order_details':['page_break']}},'fs_exports':{'Delivery Note':{'fields':['Note','conversion_rate','currency','grand_total_export','in_words_export','rounded_total_export'],'delivery_note_details':['base_ref_rate','amount','basic_rate']},'POS Setting':{'fields':['conversion_rate','currency']},'Quotation':{'fields':['Note HTML','OT Notes','conversion_rate','currency','grand_total_export','in_words_export','rounded_total_export'],'quotation_details':['base_ref_rate','amount','basic_rate']},'Sales Invoice':{'fields':['conversion_rate','currency','grand_total_export','in_words_export','rounded_total_export'],'entries':['base_ref_rate','amount','basic_rate']},'Item':{'ref_rate_details':['ref_currency']},'Sales BOM':{'fields':['currency']},'Sales Order':{'fields':['Note1','OT Notes','conversion_rate','currency','grand_total_export','in_words_export','rounded_total_export'],'sales_order_details':['base_ref_rate','amount','basic_rate']}},'fs_imports':{'Purchase Invoice':{'fields':['conversion_rate','currency','grand_total_import','in_words_import','net_total_import','other_charges_added_import','other_charges_deducted_import'],'entries':['purchase_ref_rate','amount','rate']},'Purchase Order':{'fields':['Note HTML','conversion_rate','currency','grand_total_import','in_words_import','net_total_import','other_charges_added_import','other_charges_deducted_import'],'po_details':['purchase_ref_rate','amount','purchase_rate']},'Purchase Receipt':{'fields':['conversion_rate','currency','grand_total_import','in_words_import','net_total_import','other_charges_added_import','other_charges_deducted_import'],'purchase_receipt_details':['purchase_ref_rate','amount','purchase_rate']},'Supplier Quotation':{'fields':['conversion_rate','currency']}},'fs_item_advanced':{'Item':{'fields':['item_customer_details']}},'fs_sales_extras':{'Address':{'fields':['sales_partner']},'Contact':{'fields':['sales_partner']},'Customer':{'fields':['sales_team']},'Delivery Note':{'fields':['sales_team','Packing List']},'Item':{'fields':['item_customer_details']},'Sales Invoice':{'fields':['sales_team']},'Sales Order':{'fields':['sales_team','Packing List']}},'fs_more_info':{'Delivery Note':{'fields':['More Info']},'Opportunity':{'fields':['More Info']},'Purchase Request':{'fields':['More Info']},'Lead':{'fields':['More Info']},'Purchase Invoice':{'fields':['More Info']},'Purchase Order':{'fields':['More Info']},'Purchase Receipt':{'fields':['More Info']},'Quotation':{'fields':['More Info']},'Sales Invoice':{'fields':['More Info']},'Sales Order':{'fields':['More Info']},},'fs_quality':{'Item':{'fields':['Item Inspection Criteria','inspection_required']},'Purchase Receipt':{'purchase_receipt_details':['qa_no']}},'fs_manufacturing':{'Item':{'fields':['Manufacturing']}},'fs_pos':{'Sales Invoice':{'fields':['is_pos']}},'fs_recurring_invoice':{'Sales Invoice':{'fields':['Recurring Invoice']}}} +$(document).bind('form_refresh',function(){for(sys_feat in sys_defaults) +{if(sys_defaults[sys_feat]=='0'&&(sys_feat in pscript.feature_dict)) +{if(cur_frm.doc.doctype in pscript.feature_dict[sys_feat]) +{for(fort in pscript.feature_dict[sys_feat][cur_frm.doc.doctype]) +{if(fort=='fields') +hide_field(pscript.feature_dict[sys_feat][cur_frm.doc.doctype][fort]);else if(cur_frm.fields_dict[fort]) +{for(grid_field in pscript.feature_dict[sys_feat][cur_frm.doc.doctype][fort]) +cur_frm.fields_dict[fort].grid.set_column_disp(pscript.feature_dict[sys_feat][cur_frm.doc.doctype][fort][grid_field],false);} +else +msgprint('Grid "'+fort+'" does not exists');}}}}}) +/* + * conf.js + */ +wn.provide('erpnext');erpnext.set_about=function(){wn.provide('wn.app');$.extend(wn.app,{name:'ERPNext',license:'GNU/GPL - Usage Condition: All "erpnext" branding must be kept as it is',source:'https://github.com/webnotes/erpnext',publisher:'Web Notes Technologies Pvt Ltd, Mumbai',copyright:'© Web Notes Technologies Pvt Ltd',version:'2'});} +wn.modules_path='erpnext';$(document).bind('toolbar_setup',function(){$('.brand').html((wn.boot.website_settings.brand_html||'erpnext')+' ').css('max-width','200px').css('overflow','hidden').hover(function(){$(this).find('.icon-home').addClass('navbar-icon-home-hover');},function(){$(this).find('.icon-home').removeClass('navbar-icon-home-hover');});}); \ No newline at end of file diff --git a/setup/doctype/company/company.py b/setup/doctype/company/company.py index bd50340f80..8e08fed84e 100644 --- a/setup/doctype/company/company.py +++ b/setup/doctype/company/company.py @@ -31,9 +31,6 @@ get_value = webnotes.conn.get_value in_transaction = webnotes.conn.in_transaction convert_to_lists = webnotes.conn.convert_to_lists -# ----------------------------------------------------------------------------------------- - - class DocType: def __init__(self,d,dl): self.doc, self.doclist = d,dl @@ -235,9 +232,6 @@ class DocType: # delete gl entry sql("delete from `tabGL Entry` where company = %s", self.doc.name) - #delete tabAccount Balance - sql("delete ab.* from `tabAccount Balance` ab, `tabAccount` a where ab.account = a.name and a.company = %s", self.doc.name) - #delete tabAccount sql("delete from `tabAccount` where company = %s order by lft desc, rgt desc", self.doc.name) diff --git a/setup/doctype/global_defaults/global_defaults.py b/setup/doctype/global_defaults/global_defaults.py index 26590fea70..13a42ed766 100644 --- a/setup/doctype/global_defaults/global_defaults.py +++ b/setup/doctype/global_defaults/global_defaults.py @@ -42,8 +42,8 @@ keydict = { class DocType: def __init__(self, d, dl): - self.doc, self.doclist = d, dl - + self.doc, self.doclist = d, dl + def on_update(self): """update defaults""" diff --git a/setup/doctype/period/__init__.py b/setup/doctype/period/__init__.py deleted file mode 100644 index baffc48825..0000000000 --- a/setup/doctype/period/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from __future__ import unicode_literals diff --git a/setup/doctype/period/period.js b/setup/doctype/period/period.js deleted file mode 100644 index 3cad9447a9..0000000000 --- a/setup/doctype/period/period.js +++ /dev/null @@ -1,26 +0,0 @@ -// ERPNext - web based ERP (http://erpnext.com) -// Copyright (C) 2012 Web Notes Technologies Pvt Ltd -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - - - -//--------- ONLOAD ------------- -cur_frm.cscript.onload = function(doc, cdt, cdn) { - -} - -cur_frm.cscript.refresh = function(doc, cdt, cdn) { - -} \ No newline at end of file diff --git a/setup/doctype/period/period.txt b/setup/doctype/period/period.txt deleted file mode 100644 index 77ee019cc2..0000000000 --- a/setup/doctype/period/period.txt +++ /dev/null @@ -1,115 +0,0 @@ -# DocType, Period -[ - - # These values are common in all dictionaries - { - 'creation': '2012-03-27 14:36:22', - 'docstatus': 0, - 'modified': '2012-03-27 14:36:22', - 'modified_by': u'Administrator', - 'owner': u'nabin@webnotestech.com' - }, - - # These values are common for all DocType - { - 'autoname': u'field:period_name', - 'colour': u'White:FFF', - 'doctype': 'DocType', - 'document_type': u'Master', - 'in_create': 1, - 'module': u'Setup', - 'name': '__common__', - 'section_style': u'Simple', - 'server_code_error': u' ', - 'version': 5 - }, - - # These values are common for all DocField - { - 'doctype': u'DocField', - 'name': '__common__', - 'parent': u'Period', - 'parentfield': u'fields', - 'parenttype': u'DocType', - 'permlevel': 0 - }, - - # These values are common for all DocPerm - { - 'doctype': u'DocPerm', - 'name': '__common__', - 'parent': u'Period', - 'parentfield': u'permissions', - 'parenttype': u'DocType', - 'permlevel': 0, - 'read': 1, - 'role': u'System Manager', - 'write': 0 - }, - - # DocType, Period - { - 'doctype': 'DocType', - 'name': u'Period' - }, - - # DocPerm - { - 'doctype': u'DocPerm' - }, - - # DocPerm - { - 'doctype': u'DocPerm' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'period_name', - 'fieldtype': u'Data', - 'label': u'Period Name', - 'oldfieldname': u'period_name', - 'oldfieldtype': u'Data' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'start_date', - 'fieldtype': u'Date', - 'label': u'Start Date', - 'oldfieldname': u'start_date', - 'oldfieldtype': u'Date' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'end_date', - 'fieldtype': u'Date', - 'label': u'End Date', - 'oldfieldname': u'end_date', - 'oldfieldtype': u'Date' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'period_type', - 'fieldtype': u'Data', - 'label': u'Period Type', - 'oldfieldname': u'period_type', - 'oldfieldtype': u'Data' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'fiscal_year', - 'fieldtype': u'Data', - 'label': u'Fiscal Year', - 'oldfieldname': u'fiscal_year', - 'oldfieldtype': u'Data' - } -] \ No newline at end of file diff --git a/setup/doctype/period_control/__init__.py b/setup/doctype/period_control/__init__.py deleted file mode 100644 index baffc48825..0000000000 --- a/setup/doctype/period_control/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from __future__ import unicode_literals diff --git a/setup/doctype/period_control/period_control.py b/setup/doctype/period_control/period_control.py deleted file mode 100644 index a8fb4e83ce..0000000000 --- a/setup/doctype/period_control/period_control.py +++ /dev/null @@ -1,78 +0,0 @@ -# ERPNext - web based ERP (http://erpnext.com) -# Copyright (C) 2012 Web Notes Technologies Pvt Ltd -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Please edit this list and import only required elements -from __future__ import unicode_literals -import webnotes - -from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, 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, msgprint, errprint - -set = webnotes.conn.set -sql = webnotes.conn.sql -get_value = webnotes.conn.get_value -in_transaction = webnotes.conn.in_transaction -convert_to_lists = webnotes.conn.convert_to_lists - -# ----------------------------------------------------------------------------------------- - - -class DocType: - def __init__(self,d,dl): - self.doc, self.doclist = d, dl - - # Generate Periods - #------------------ - def generate_periods(self, fy): - ml = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec') - - import webnotes.utils - from dateutil.relativedelta import relativedelta - - - if not sql("select name from `tabPeriod` where fiscal_year = '%s'" % fy): - ysd = sql("select year_start_date from `tabFiscal Year` where name = '%s'"%fy)[0][0] - - #create period as fiscal year record name - #---------------------------------------------- - arg = {'pn':fy,'sd':ysd,'ed':webnotes.utils.get_last_day(ysd + relativedelta(months=11)).strftime('%Y-%m-%d'),'pt':'Year','fy':fy} - self.create_period(arg) - - for i in range(12): - msd = ysd + relativedelta(months=i) - - arg = {'pn':ml[cint(msd.strftime('%m'))-1] + ' ' + msd.strftime('%Y'),'sd':msd.strftime('%Y-%m-%d'),'ed':webnotes.utils.get_last_day(msd).strftime('%Y-%m-%d'),'pt':'Month','fy':fy} - self.create_period(arg) - - #--------------------------------------------------------- - #create period common function - def create_period(self,arg): - p = Document('Period') - p.period_name = arg['pn'] - p.start_date = arg['sd'] - p.end_date = arg['ed'] - p.period_type = arg['pt'] - p.fiscal_year = arg['fy'] - - try: - p.save(1) - except NameError, e: - msgprint('Period %s already exists' % p.period_name) - raise Exception \ No newline at end of file diff --git a/setup/doctype/period_control/period_control.txt b/setup/doctype/period_control/period_control.txt deleted file mode 100644 index 420b319630..0000000000 --- a/setup/doctype/period_control/period_control.txt +++ /dev/null @@ -1,32 +0,0 @@ -# DocType, Period Control -[ - - # These values are common in all dictionaries - { - 'creation': '2012-03-27 14:36:22', - 'docstatus': 0, - 'modified': '2012-03-27 14:36:22', - 'modified_by': u'Administrator', - 'owner': u'nabin@webnotestech.com' - }, - - # These values are common for all DocType - { - 'colour': u'White:FFF', - 'doctype': 'DocType', - 'in_create': 1, - 'issingle': 1, - 'module': u'Setup', - 'name': '__common__', - 'read_only': 1, - 'section_style': u'Simple', - 'server_code_error': u' ', - 'version': 36 - }, - - # DocType, Period Control - { - 'doctype': 'DocType', - 'name': u'Period Control' - } -] \ No newline at end of file diff --git a/startup/event_handlers.py b/startup/event_handlers.py index ffbf11373b..9b9c03019f 100644 --- a/startup/event_handlers.py +++ b/startup/event_handlers.py @@ -118,22 +118,17 @@ def check_if_expired(): # if expired, stop user from logging in from webnotes.utils import formatdate + msg = """Oops! Your subscription expired on %s. +
    Nothing catastrophic.
    """ % formatdate(conf.expires_on) + if 'System Manager' in webnotes.user.roles: - webnotes.response['server_messages'] = """Oops! \ - Your subscription expired on %s. - - Nothing catastrophic. - - Just drop in a mail at support@erpnext.com and \ - we will guide you to get your account re-activated.""" % formatdate(conf.expires_on) + msg += """Just drop in a mail at support@erpnext.com and + we will guide you to get your account re-activated.""" else: - webnotes.response['server_messages'] = """Oops! \ - Your subscription expired on %s. - - Nothing catastrophic. - - Just ask your System Manager to drop in a mail at support@erpnext.com and \ - we will guide him to get your account re-activated.""" % formatdate(conf.expires_on) + msg += """Just ask your System Manager to drop in a mail at support@erpnext.com and + we will guide him to get your account re-activated.""" + + webnotes.msgprint(msg) webnotes.response['message'] = 'Account Expired' raise webnotes.AuthenticationError diff --git a/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.js b/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.js index 30242d4222..d57ff5dd77 100644 --- a/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.js +++ b/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.js @@ -191,7 +191,7 @@ cur_frm.cscript.make_credit_note = function(doc) { var doclist = make_doclist(doc.doctype, doc.name); $c('accounts.get_new_jv_details', { doclist: JSON.stringify(doclist), - fiscal_year: sys_defaults.fiscal_year + fiscal_year: sys_defaults.fiscal_year, }, function(r, rt) { if(!r.exc) { cur_frm.cscript.make_jv(doc, 'Credit Note', r.message); @@ -210,7 +210,7 @@ cur_frm.cscript.make_jv = function(doc, dr_or_cr, children) { jv.company = sys_defaults.company; jv.fiscal_year = sys_defaults.fiscal_year; jv.is_opening = 'No'; - jv.posting_date = dateutil.obj_to_str(new Date()); + jv.posting_date = doc.return_date; jv.voucher_date = dateutil.obj_to_str(new Date()); // Add children @@ -218,6 +218,7 @@ cur_frm.cscript.make_jv = function(doc, dr_or_cr, children) { for(var i=0; i. - -var bin_list = []; -var msg = []; -var binidx = 0; - -cur_frm.cscript.repost_bin = function(doc,cdt,cdn) { - args = {'check': 'Bin'}; - $c_obj('Reposting Tool','get_count_for_reposting', docstring(args), function(r,rt) { - bin_list = r.message; - repair_bin(); - }); -} - -function repair_single_bin(){ - $c_obj('Reposting Tool', 'repair_bin', cstr(bin_list[binidx]), function(r,rt) { - for(i = 0; i < r.message.length ; i++){ - msg.push(r.message[i]); - } - repair_bin(); - }); -} - -function repair_bin(){ - if(binidx >= 10) { - args = {'msg': msg, 'subject': 'Item Quantity'}; - $c_obj('Reposting Tool', 'send_mail', docstring(args)); - alert('Completed'); - return; - } - repair_single_bin(); - binidx ++; -} - -// Batch for Account Balances -//====================================================== -var acc_list = []; -var accidx = 0; -cur_frm.cscript.repost_account_balances = function(doc,cdt,cdn) { - args = {'check': 'Account Balance'}; - $c_obj('Reposting Tool','get_count_for_reposting', docstring(args), function(r,rt) { - acc_list = r.message; - repair_acc_bal(); - }); -} - -function repair_single_acc_bal(){ - $c_obj('Reposting Tool', 'repair_acc_bal', cstr(acc_list[accidx]), function(r,rt) { - for(i = 0; i < r.message.length; i++){ - msg.push(r.message[i]); - } - repair_acc_bal(); - }); -} - -function repair_acc_bal(){ - if(accidx >= 15) { - args = {'msg' : msg, 'subject': 'Account Balance'}; - $c_obj('Reposting Tool', 'send_mail', docstring(args)); - alert('Completed'); - return; - } - repair_single_acc_bal(); - accidx ++; -} \ No newline at end of file diff --git a/utilities/doctype/reposting_tool/reposting_tool.py b/utilities/doctype/reposting_tool/reposting_tool.py deleted file mode 100644 index 3d53b69319..0000000000 --- a/utilities/doctype/reposting_tool/reposting_tool.py +++ /dev/null @@ -1,211 +0,0 @@ -# ERPNext - web based ERP (http://erpnext.com) -# Copyright (C) 2012 Web Notes Technologies Pvt Ltd -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Please edit this list and import only required elements -from __future__ import unicode_literals -import webnotes - -from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, 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, 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 - self.msg = [] - - - # ============================================================================= - def get_count_for_reposting(self, args): - args = eval(args) - if args['check'] == 'Bin': - return [d[0] for d in sql("select name from `tabBin` where item_code = 'Repost Item' " )] - - if args['check'] == 'Account Balance': - # message - if not self.doc.past_year: - msgprint('
    Warning: Opening balances were not imported
    ') - - # do not repost from same year - if self.doc.past_year == self.doc.name: - msgprint("Cannot import from the current year") - - return [d[0] for d in sql("select name from `tabAccount` ")] - - # ============================================================================= - def get_bin_qty(self, wh, item): - # get actual_qty - act_qty = sql("select sum(actual_qty) from `tabStock Ledger Entry` where warehouse = '%s' and item_code = '%s' and ifnull(is_cancelled, 'No') = 'No'" % (wh, item)) - act_qty = act_qty and flt(act_qty[0][0]) or 0 - - # get indented_qty - ind_qty = sql("select sum(if( ifnull(t2.qty, 0) > ifnull(t2.ordered_qty, 0), ifnull(t2.qty, 0) - ifnull(t2.ordered_qty, 0), 0) ) from `tabPurchase Request` t1, `tabPurchase Request Item`t2 where t1.name = t2.parent and t1.docstatus = 1 and t2.warehouse = '%s' and t2.item_code = '%s' and status != 'Stopped'" % (wh, item)) - ind_qty = ind_qty and flt(ind_qty[0][0]) or 0 - - # get ordered_qty - ord_qty = sql("select sum(if ( ifnull(t2.qty, 0) > ifnull(t2.received_qty, 0), (ifnull(t2.qty, 0) - ifnull(t2.received_qty, 0)) * ifnull(t2.conversion_factor, 0) , 0) ) from `tabPurchase Order` t1, `tabPurchase Order Item` t2 where t1.name = t2.parent and t1.docstatus = 1 and t2.warehouse = '%s' and t2.item_code = '%s' and status != 'Stopped'" % (wh, item)) - ord_qty = ord_qty and flt(ord_qty[0][0]) or 0 - - - # get reserved_qty - res_qty =sql("select sum(if ( ifnull(t2.qty, 0) > ifnull(t2.delivered_qty, 0), ifnull(t2.qty, 0) - ifnull(t2.delivered_qty, 0) , 0) ) from `tabSales Order` t1, `tabSales Order Item` t2 where t1.name = t2.parent and t1.docstatus = 1 and t2.reserved_warehouse = '%s' and t2.item_code = '%s' and status != 'Stopped'" % (wh, item)) - res_qty = res_qty and flt(res_qty[0][0]) or 0 - - # get planned_qty - plan_qty = sql("select sum(if ( ifnull(qty, 0) > ifnull(produced_qty,0), ifnull(qty, 0) - ifnull(produced_qty, 0), 0) ) from `tabProduction Order` where fg_warehouse = '%s' and production_item = '%s' and docstatus = 1" % (wh, item)) - plan_qty = plan_qty and flt(plan_qty[0][0]) or 0 - - return {'actual_qty': act_qty, 'indented_qty': ind_qty, 'ordered_qty': ord_qty, 'reserved_qty': res_qty, 'planned_qty': plan_qty } - - # ============================================================================= - def check_bin_qty(self, bin_obj, qty_dict): - label_dict = {'actual_qty': 'Actual Qty', 'indented_qty': 'Quantity Requested for Purchase', 'ordered_qty': 'Ordered Qty', 'reserved_qty': 'Reserved Qty', 'planned_qty': 'Planned Qty'} - for f in qty_dict: - if flt(bin_obj.doc.fields[f]) != qty_dict[f]: - msgprint('
    Difference found in %s for Item:= %s and Warehouse:= %s (Before : %s; After : %s)
    ' % (label_dict[f], bin_obj.doc.item_code, bin_obj.doc.warehouse, cstr(bin_obj.doc.fields[f]), cstr(qty_dict[f]))) - self.msg.append('
    Difference found in %s for Item:= %s and Warehouse:= %s (Before : %s; After : %s)
    ' % (label_dict[f], bin_obj.doc.item_code, bin_obj.doc.warehouse, cstr(bin_obj.doc.fields[f]), cstr(qty_dict[f]))) - - # Check projected qty - projected_qty = flt(qty_dict['actual_qty']) + flt(qty_dict['indented_qty']) + flt(qty_dict['ordered_qty']) + flt(qty_dict['planned_qty']) - flt(qty_dict['reserved_qty']) - if flt(projected_qty) != flt(bin_obj.doc.projected_qty): - msgprint('
    Difference found in Projected Qty for Item:= %s and Warehouse:= %s (Before : %s; After : %s)
    ' % (bin_obj.doc.item_code, bin_obj.doc.warehouse, bin_obj.doc.projected_qty, cstr(projected_qty))) - self.msg.append('
    Difference found in Projected Qty for Item:= %s and Warehouse:= %s (Before : %s; After : %s)
    ' % (bin_obj.doc.item_code, bin_obj.doc.warehouse, bin_obj.doc.projected_qty, cstr(projected_qty))) - - - # ============================================================================= - def repair_bin(self, bin): - import webnotes - bin_obj = get_obj('Bin',bin) - bin_act_qty = flt(bin_obj.doc.actual_qty) - try: - # udpate actual qty and item valuation - bin_obj.update_entries_after('0000-00-00', '00:00') - # get bin qty - qty_dict = self.get_bin_qty(bin_obj.doc.warehouse, bin_obj.doc.item_code) - - # check bin qty - self.check_bin_qty(bin_obj, qty_dict) - - projected_qty = flt(qty_dict['indented_qty']) + flt(qty_dict['ordered_qty']) - flt(qty_dict['reserved_qty']) + flt(qty_dict['planned_qty']) + flt(qty_dict['actual_qty']) - # update indented_qty, ordered_qty, reserved_qty, planned_qty - sql("update `tabBin` set indented_qty = '%s', ordered_qty = '%s', reserved_qty = '%s', planned_qty = '%s', projected_qty = '%s' where warehouse = '%s' and item_code = '%s'" % ( flt(qty_dict['indented_qty']), flt(qty_dict['ordered_qty']), flt(qty_dict['reserved_qty']), flt(qty_dict['planned_qty']), projected_qty, bin_obj.doc.warehouse, bin_obj.doc.item_code)) - - # update projected_qty - sql("update `tabBin` set projected_qty = ifnull(indented_qty, 0) + ifnull(ordered_qty,0) + ifnull(actual_qty, 0) + ifnull(planned_qty, 0) - ifnull(reserved_qty,0) where warehouse = '%s' and item_code = '%s' " % (bin_obj.doc.warehouse, bin_obj.doc.item_code)) - if not self.msg: - msgprint('
    Reposting of Stock for Item %s and Warehouse %s completed Successfully.
    ' % (bin_obj.doc.item_code, bin_obj.doc.warehouse)) - except Exception: - msgprint('
    Handle Item %s and Warehouse %s seprately.
    ERROR: %s
    ' % (bin_obj.doc.item_code, bin_obj.doc.warehouse, str(webnotes.utils.getTraceback()))) - self.msg.append('
    ERROR: %s
    ' % (str(webnotes.utils.getTraceback()))) - - # ============================================================================= - def repair_all_bins(self): - bins = sql("select name from tabBin") - cnt = 0 - for bin in bins: - if cnt % 20 == 0: - sql("commit") - sql("start transaction") - cnt += 1 - - self.repair_bin(bin[0]) - - # ============================================================================= - def repair_bins_for_illegal_cancelled(self, after_date = '2011-01-01'): - bins = sql("select name from tabBin where modified >= %s", after_date) - cnt = 0 - for bin in bins: - if cnt % 20 == 0: - sql("commit") - sql("start transaction") - cnt += 1 - - self.repair_bin(bin[0]) - # ============================================================================= - def repair_opening_bal(self, d, acc_obj, past_yr, fiscal_yr): - # check opening balance - opbal = sql("select balance from `tabAccount Balance` where account=%s and period = %s", (acc_obj.doc.name, past_yr)) - if flt(d.opening) != flt(opbal and flt(opbal[0][0]) or 0): - msgprint('
    Difference found in Opening of Account %s for Period %s in Fiscal Year %s (Before : %s; After : %s)
    ' % (acc_obj.doc.name, d.period, fiscal_yr, flt(d.opening), opbal and flt(opbal[0][0]) or 0)) - self.msg.append('
    Difference found in Opening of Account %s for Period %s in Fiscal Year %s (Before : %s; After : %s)
    ' % (acc_obj.doc.name, d.period, fiscal_yr, flt(d.opening), opbal and flt(opbal[0][0]) or 0)) - sql("update `tabAccount Balance` set opening = '%s' where period = '%s' and account = '%s' " % (opbal and flt(opbal[0][0]) or 0, fiscal_yr, acc_obj.doc.name)) - - - # ============================================================================= - def repair_bal(self, d, acc_obj, fiscal_yr): - # check balances - ysd = get_value('Fiscal Year', fiscal_yr, 'year_start_date') - bal = get_obj('GL Control').get_as_on_balance(acc_obj.doc.name, fiscal_yr, d.end_date, acc_obj.doc.debit_or_credit, acc_obj.doc.is_pl_account, acc_obj.doc.lft, acc_obj.doc.rgt, ysd) - if flt(d.balance) != flt(bal): - msgprint('
    Difference found in Balance of Account %s for Period %s in Fiscal Year %s (Before : %s; After : %s)
    ' % (acc_obj.doc.name, d.period, fiscal_yr, flt(d.balance), flt(bal))) - self.msg.append('
    Difference found in Balance of Account %s for Period %s in Fiscal Year %s (Before : %s; After : %s)
    ' % (acc_obj.doc.name, d.period, fiscal_yr, flt(d.balance), flt(bal))) - sql("update `tabAccount Balance` set balance = '%s' where period = '%s' and account = '%s' " % (bal, d.period, acc_obj.doc.name)) - - - # ============================================================================= - def repair_acc_bal(self, acc, past_yr = '' , fiscal_yr = ''): - # get account obj - acc_obj = get_obj('Account', acc, with_children = 1) - - # get fiscal yr & past yr - if not fiscal_yr: - import webnotes.utils - fiscal_yr = webnotes.utils.get_defaults()['fiscal_year'] - if not past_yr: past_yr = get_value('Fiscal Year', fiscal_yr, 'past_year') - - # Repair Opening and Balance For Account Balances - for d in getlist(acc_obj.doclist, 'account_balances'): - if d.fiscal_year == fiscal_yr: - if past_yr and (past_yr != fiscal_yr) and d.period == fiscal_yr: - self.repair_opening_bal(d, acc_obj, past_yr, fiscal_yr) - else: - self.repair_bal(d, acc_obj, fiscal_yr) - - # Acknowledge USer - if not self.msg: - msgprint('
    Openings & Balances of Account %s for Fiscal Year %s updated successfully.
    ' % ( acc_obj.doc.name, fiscal_yr)) - - return self.msg - - - # ============================================================================= - def send_mail(self, args): - args = eval(args) - self.msg, subject = args['msg'], args['subject'] - msgprint(self.msg) - if self.msg: - email_msg = """ Dear Administrator, - -In Account := %s User := %s has Reposted %s and following was found:- - -%s - -""" % (get_value('Control Panel', None,'account_id'), session['user'], subject, '\n'.join(self.msg)) - - sendmail(['support@iwebnotes.com'], subject='Repair of ' + cstr(subject), parts = [('text/plain', email_msg)]) diff --git a/utilities/doctype/reposting_tool/reposting_tool.txt b/utilities/doctype/reposting_tool/reposting_tool.txt deleted file mode 100644 index 453902bdc3..0000000000 --- a/utilities/doctype/reposting_tool/reposting_tool.txt +++ /dev/null @@ -1,94 +0,0 @@ -# DocType, Reposting Tool -[ - - # These values are common in all dictionaries - { - 'creation': '2012-03-27 14:36:47', - 'docstatus': 0, - 'modified': '2012-03-27 14:36:47', - 'modified_by': u'Administrator', - 'owner': u'Administrator' - }, - - # These values are common for all DocType - { - 'allow_copy': 1, - 'allow_email': 1, - 'allow_print': 1, - 'colour': u'Light Blue:DEF', - 'default_print_format': u'Standard', - 'doctype': 'DocType', - 'hide_toolbar': 1, - 'in_create': 0, - 'issingle': 1, - 'module': u'Utilities', - 'name': '__common__', - 'read_only': 1, - 'section_style': u'Simple', - 'server_code_error': u' ', - 'show_in_menu': 1, - 'version': 173 - }, - - # These values are common for all DocField - { - 'doctype': u'DocField', - 'name': '__common__', - 'parent': u'Reposting Tool', - 'parentfield': u'fields', - 'parenttype': u'DocType', - 'permlevel': 0 - }, - - # These values are common for all DocPerm - { - 'create': 1, - 'doctype': u'DocPerm', - 'name': '__common__', - 'parent': u'Reposting Tool', - 'parentfield': u'permissions', - 'parenttype': u'DocType', - 'permlevel': 0, - 'read': 1, - 'role': u'System Manager', - 'write': 1 - }, - - # DocType, Reposting Tool - { - 'doctype': 'DocType', - 'name': u'Reposting Tool' - }, - - # DocPerm - { - 'doctype': u'DocPerm' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'recalculate_mar_&_actual_qty', - 'fieldtype': u'Data', - 'label': u'Recalculate MAR & Actual Qty' - }, - - # DocField - { - 'colour': u'White:FFF', - 'doctype': u'DocField', - 'fieldname': u'repost_bin', - 'fieldtype': u'Button', - 'label': u'Repost Bin', - 'trigger': u'Client' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'repost_account_balances', - 'fieldtype': u'Button', - 'label': u'Repost Account Balances', - 'trigger': u'Client' - } -] \ No newline at end of file