diff --git a/erpnext/accounts/page/general_ledger/general_ledger.js b/erpnext/accounts/page/general_ledger/general_ledger.js index cbe88fb4e2..eca9dea97a 100644 --- a/erpnext/accounts/page/general_ledger/general_ledger.js +++ b/erpnext/accounts/page/general_ledger/general_ledger.js @@ -21,179 +21,218 @@ wn.pages['general-ledger'].onload = function(wrapper) { single_column: true }); - erpnext.general_ledger = new wn.views.GridReport({ - title: "General Ledger", - page: wrapper, - parent: $(wrapper).find('.layout-main'), - appframe: wrapper.appframe, - doctypes: ["Company", "Account", "GL Entry", "Cost Center"], - - setup_columns: function() { - this.columns = [ - {id: "posting_date", name: "Posting Date", field: "posting_date", width: 100, - formatter: this.date_formatter}, - {id: "account", name: "Account", field: "account", width: 240, - link_formatter: { - filter_input: "account", - open_btn: true, - }}, - {id: "debit", name: "Debit", field: "debit", width: 100, - formatter: this.currency_formatter}, - {id: "credit", name: "Credit", field: "credit", width: 100, - formatter: this.currency_formatter}, - {id: "voucher_type", name: "Voucher Type", field: "voucher_type", width: 120}, - {id: "voucher_no", name: "Voucher No", field: "voucher_no", width: 160, - link_formatter: { - filter_input: "voucher_no", - open_btn: true, - doctype: "dataContext.voucher_type" - }}, - {id: "remarks", name: "Remarks", field: "remarks", width: 200, - formatter: this.text_formatter}, - - ]; - }, - filters: [ - {fieldtype:"Select", label: "Company", link:"Company", default_value: "Select Company...", - filter: function(val, item, opts) { - return item.company == val || val == opts.default_value; - }}, - {fieldtype:"Select", label: "Account", link:"Account", default_value: "Select Account...", - filter: function(val, item, opts, me) { - if(val == opts.default_value) { - return true; - } else { - // true if GL Entry belongs to selected - // account ledger or group - return me.is_child_account(val, item.account); - } - }}, - {fieldtype:"Data", label: "Voucher No", - filter: function(val, item, opts) { - if(!val) return true; - return (item.voucher_no && item.voucher_no.indexOf(val)!=-1); - }}, - {fieldtype:"Date", label: "From Date", filter: function(val, item) { - return dateutil.str_to_obj(val) <= dateutil.str_to_obj(item.posting_date); - }}, - {fieldtype:"Label", label: "To"}, - {fieldtype:"Date", label: "To Date", filter: function(val, item) { - return dateutil.str_to_obj(val) >= dateutil.str_to_obj(item.posting_date); - }}, - {fieldtype:"Button", label: "Refresh", icon:"icon-refresh icon-white", cssClass:"btn-info"}, - {fieldtype:"Button", label: "Reset Filters"} - ], - is_child_account: function(account, item_account) { - account = this.account_by_name[account]; - item_account = this.account_by_name[item_account]; - - return (item_account.lft >= account.lft && item_account.rgt <= account.rgt) - }, - prepare_data: function() { - // add Opening, Closing, Totals rows - // if filtered by account and / or voucher - var data = wn.report_dump.data["GL Entry"]; - var out = []; - - if(!this.account_by_name) - this.account_by_name = this.make_name_map(wn.report_dump.data["Account"]); - - var me = this; - - var from_date = dateutil.str_to_obj(this.from_date); - var to_date = dateutil.str_to_obj(this.to_date); - - if(to_date < from_date) { - msgprint("From Date must be before To Date"); - return; - } - - var opening = { - account: "Opening", debit: 0.0, credit: 0.0, - id:"_opening", _show: true, _style: "font-weight: bold" - } - var totals = { - account: "Totals", debit: 0.0, credit: 0.0, - id:"_totals", _show: true, _style: "font-weight: bold" - } - - $.each(data, function(i, item) { - if((!me.is_default("account") ? me.is_child_account(me.account, item.account) : true) && - (me.voucher_no ? item.voucher_no==me.voucher_no : true)) { - - var date = dateutil.str_to_obj(item.posting_date); - - if(date < from_date) { - opening.debit += item.debit; - opening.credit += item.credit; - } else if(date <= to_date) { - totals.debit += item.debit; - totals.credit += item.credit; - } - - if(me.apply_filters(item)) { - out.push(item); - } - } - }) - - var closing = { - account: "Closing (Opening + Totals)", debit: opening.debit + totals.debit, - credit: opening.credit + totals.credit, - id:"_closing", _show: true, _style: "font-weight: bold" - } - - - if(!me.is_default("account")) { - if(me.account_by_name[me.account].debit_or_credit == "Debit") { - opening.debit -= opening.credit; opening.credit = 0; - closing.debit -= closing.credit; closing.credit = 0; - } else { - opening.credit -= opening.debit; opening.debit = 0; - closing.credit -= closing.debit; closing.debit = 0; - } - var out = [opening].concat(out).concat([totals, closing]); - } else { - var out = out.concat([totals]); - } - - this.data = out; - }, - get_plot_data: function() { - var data = []; - var me = this; - if(me.is_default("account") || me.voucher_no) return false; - var debit_or_credit = me.account_by_name[me.account].debit_or_credit; - var balance = debit_or_credit=="Debit" ? me.data[0].debit : me.data[0].credit; - data.push({ - label: me.account, - data: [[dateutil.str_to_obj(me.from_date).getTime(), balance]] - .concat($.map(me.data, function(col, idx) { - if (col.posting_date) { - var diff = (debit_or_credit == "Debit" ? 1 : -1) * (flt(col.debit) - flt(col.credit)); - balance += diff; - return [[dateutil.str_to_obj(col.posting_date).getTime(), balance - diff], - [dateutil.str_to_obj(col.posting_date).getTime(), balance]] - } - return null; - })).concat([ - // closing - [dateutil.str_to_obj(me.to_date).getTime(), balance] - ]), - points: {show: true}, - lines: {show: true, fill: true}, - }); - return data; - }, - get_plot_options: function() { - return { - grid: { hoverable: true, clickable: true }, - xaxis: { mode: "time", - min: dateutil.str_to_obj(this.from_date).getTime(), - max: dateutil.str_to_obj(this.to_date).getTime() } - } - }, - }); + erpnext.general_ledger = new erpnext.GeneralLedger(wrapper); } +erpnext.GeneralLedger = wn.views.GridReport.extend({ + init: function(wrapper) { + this._super({ + title: "General Ledger", + page: wrapper, + parent: $(wrapper).find('.layout-main'), + appframe: wrapper.appframe, + doctypes: ["Company", "Account", "GL Entry", "Cost Center"], + }); + }, + setup_columns: function() { + this.columns = [ + {id: "posting_date", name: "Posting Date", field: "posting_date", width: 100, + formatter: this.date_formatter}, + {id: "account", name: "Account", field: "account", width: 240, + link_formatter: { + filter_input: "account", + open_btn: true, + }}, + {id: "debit", name: "Debit", field: "debit", width: 100, + formatter: this.currency_formatter}, + {id: "credit", name: "Credit", field: "credit", width: 100, + formatter: this.currency_formatter}, + {id: "voucher_type", name: "Voucher Type", field: "voucher_type", width: 120}, + {id: "voucher_no", name: "Voucher No", field: "voucher_no", width: 160, + link_formatter: { + filter_input: "voucher_no", + open_btn: true, + doctype: "dataContext.voucher_type" + }}, + {id: "remarks", name: "Remarks", field: "remarks", width: 200, + formatter: this.text_formatter}, + + ]; + }, + filters: [ + {fieldtype:"Select", label: "Company", link:"Company", default_value: "Select Company...", + filter: function(val, item, opts) { + return item.company == val || val == opts.default_value; + }}, + {fieldtype:"Select", label: "Account", link:"Account", default_value: "Select Account...", + filter: function(val, item, opts, me) { + if(val == opts.default_value) { + return true; + } else { + // true if GL Entry belongs to selected + // account ledger or group + return me.is_child_account(val, item.account); + } + }}, + {fieldtype:"Data", label: "Voucher No", + filter: function(val, item, opts) { + if(!val) return true; + return (item.voucher_no && item.voucher_no.indexOf(val)!=-1); + }}, + {fieldtype:"Date", label: "From Date", filter: function(val, item) { + return dateutil.str_to_obj(val) <= dateutil.str_to_obj(item.posting_date); + }}, + {fieldtype:"Label", label: "To"}, + {fieldtype:"Date", label: "To Date", filter: function(val, item) { + return dateutil.str_to_obj(val) >= dateutil.str_to_obj(item.posting_date); + }}, + {fieldtype:"Button", label: "Refresh", icon:"icon-refresh icon-white", cssClass:"btn-info"}, + {fieldtype:"Button", label: "Reset Filters"} + ], + setup_filters: function() { + this._super(); + var me = this; + + // filter accounts options by company + var accounts_by_company = this.make_accounts_by_company(); + this.filter_inputs.company && this.filter_inputs.company.change(function() { + var $filter = me.filter_inputs.account; + var company = $(this).val(); + var default_company = me.filter_inputs.company.get(0).opts.default_value; + $filter.empty().add_options([$filter.get(0).opts.default_value].concat( + $.map(wn.report_dump.data["Account"], function(ac) { + return (accounts_by_company[company].indexOf(ac.name)!=-1 || + company===default_company) ? ac.name : null; + }))); + me.filter_inputs.refresh.click(); + }); + + this.filter_inputs.account && this.filter_inputs.account.change(function() { + me.filter_inputs.refresh.click(); + }); + }, + init_filter_values: function() { + this._super(); + this.filter_inputs.company.change(); + }, + make_accounts_by_company: function() { + var accounts_by_company = {}; + var me = this; + $.each(wn.report_dump.data["Account"], function(i, ac) { + if(!accounts_by_company[ac.company]) accounts_by_company[ac.company] = []; + accounts_by_company[ac.company].push(ac.name); + }); + return accounts_by_company; + }, + is_child_account: function(account, item_account) { + account = this.account_by_name[account]; + item_account = this.account_by_name[item_account]; + + return (item_account.lft >= account.lft && item_account.rgt <= account.rgt) + }, + prepare_data: function() { + // add Opening, Closing, Totals rows + // if filtered by account and / or voucher + var data = wn.report_dump.data["GL Entry"]; + var out = []; + + if(!this.account_by_name) + this.account_by_name = this.make_name_map(wn.report_dump.data["Account"]); + + var me = this; + + var from_date = dateutil.str_to_obj(this.from_date); + var to_date = dateutil.str_to_obj(this.to_date); + + if(to_date < from_date) { + msgprint("From Date must be before To Date"); + return; + } + + var opening = { + account: "Opening", debit: 0.0, credit: 0.0, + id:"_opening", _show: true, _style: "font-weight: bold" + } + var totals = { + account: "Totals", debit: 0.0, credit: 0.0, + id:"_totals", _show: true, _style: "font-weight: bold" + } + + $.each(data, function(i, item) { + if((me.is_default("company") ? true : me.apply_filter(item, "company")) && + (!me.is_default("account") ? me.is_child_account(me.account, item.account) + : true) && (me.voucher_no ? item.voucher_no==me.voucher_no : true)) { + var date = dateutil.str_to_obj(item.posting_date); + + if(date < from_date) { + opening.debit += item.debit; + opening.credit += item.credit; + } else if(date <= to_date) { + totals.debit += item.debit; + totals.credit += item.credit; + } + + if(me.apply_filters(item)) { + out.push(item); + } + } + }) + + var closing = { + account: "Closing (Opening + Totals)", debit: opening.debit + totals.debit, + credit: opening.credit + totals.credit, + id:"_closing", _show: true, _style: "font-weight: bold" + } + + + if(!me.is_default("account")) { + if(me.account_by_name[me.account].debit_or_credit == "Debit") { + opening.debit -= opening.credit; opening.credit = 0; + closing.debit -= closing.credit; closing.credit = 0; + } else { + opening.credit -= opening.debit; opening.debit = 0; + closing.credit -= closing.debit; closing.debit = 0; + } + var out = [opening].concat(out).concat([totals, closing]); + } else { + var out = out.concat([totals]); + } + + this.data = out; + }, + get_plot_data: function() { + var data = []; + var me = this; + if(me.is_default("account") || me.voucher_no) return false; + var debit_or_credit = me.account_by_name[me.account].debit_or_credit; + var balance = debit_or_credit=="Debit" ? me.data[0].debit : me.data[0].credit; + data.push({ + label: me.account, + data: [[dateutil.str_to_obj(me.from_date).getTime(), balance]] + .concat($.map(me.data, function(col, idx) { + if (col.posting_date) { + var diff = (debit_or_credit == "Debit" ? 1 : -1) * (flt(col.debit) - flt(col.credit)); + balance += diff; + return [[dateutil.str_to_obj(col.posting_date).getTime(), balance - diff], + [dateutil.str_to_obj(col.posting_date).getTime(), balance]] + } + return null; + })).concat([ + // closing + [dateutil.str_to_obj(me.to_date).getTime(), balance] + ]), + points: {show: true}, + lines: {show: true, fill: true}, + }); + return data; + }, + get_plot_options: function() { + return { + grid: { hoverable: true, clickable: true }, + xaxis: { mode: "time", + min: dateutil.str_to_obj(this.from_date).getTime(), + max: dateutil.str_to_obj(this.to_date).getTime() } + } + }, +}); \ No newline at end of file diff --git a/erpnext/startup/report_data_map.py b/erpnext/startup/report_data_map.py index b2be566565..a098e33ef3 100644 --- a/erpnext/startup/report_data_map.py +++ b/erpnext/startup/report_data_map.py @@ -31,8 +31,8 @@ data_map = { # Accounts "Account": { - "columns": ["name", "parent_account", "lft", "rgt", "debit_or_credit", "is_pl_account", - "company"], + "columns": ["name", "parent_account", "lft", "rgt", "debit_or_credit", + "is_pl_account", "company"], "order_by": "lft" }, "Cost Center": { diff --git a/erpnext/stock/doctype/bin/bin.py b/erpnext/stock/doctype/bin/bin.py index fc2c75e87a..6f25496efa 100644 --- a/erpnext/stock/doctype/bin/bin.py +++ b/erpnext/stock/doctype/bin/bin.py @@ -373,7 +373,7 @@ class DocType: indent_obj.validate() set(indent_obj.doc,'docstatus',1) indent_obj.on_submit() - msgprint("""Item: is to be re-ordered. Purchase Request %s raised. + msgprint("""Item: %s is to be re-ordered. Purchase Request %s raised. It was generated from %s %s""" % (self.doc.item_code, indent.name,doc_type, doc_name )) if(i['email_notify']): diff --git a/erpnext/stock/page/stock_ledger/stock_ledger.js b/erpnext/stock/page/stock_ledger/stock_ledger.js index f3b7a66ea8..3a9020f12a 100644 --- a/erpnext/stock/page/stock_ledger/stock_ledger.js +++ b/erpnext/stock/page/stock_ledger/stock_ledger.js @@ -175,8 +175,8 @@ erpnext.StockLedger = erpnext.StockGridReport.extend({ if(me.item_code != me.item_code_default && !me.voucher_no) { var closing = { item_code: "On " + dateutil.str_to_user(this.to_date), - balance: (out ? out[out.length-1].balance : 0), qty: 0, - balance_value: (out ? out[out.length-1].balance_value : 0), + balance: (out.length ? out[out.length-1].balance : 0), qty: 0, + balance_value: (out.length ? out[out.length-1].balance_value : 0), id:"_closing", _show: true, _style: "font-weight: bold" }; total_out.balance_value = -total_out.balance_value; diff --git a/public/js/all-app.js b/public/js/all-app.js index c43d8f2855..2126b37e0e 100644 --- a/public/js/all-app.js +++ b/public/js/all-app.js @@ -1088,7 +1088,7 @@ me.filter_inputs[v.fieldname]=input;});},make_waiting:function(){this.waiting=$(
\
').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