Merge pull request #2266 from ankitjavalkarwork/fix1387

Add Customer Credit Balance Report
diff --git a/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.json b/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.json
index dd7c8e4..178c077 100644
--- a/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.json
+++ b/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.json
@@ -2,7 +2,7 @@
  "allow_import": 1, 
  "allow_rename": 1, 
  "autoname": "field:title", 
- "creation": "2013-01-10 16:34:08.000000", 
+ "creation": "2013-01-10 16:34:08", 
  "description": "Standard tax template that can be applied to all Purchase Transactions. This template can contain list of tax heads and also other expense heads like \"Shipping\", \"Insurance\", \"Handling\" etc.\n\n#### Note\n\nThe tax rate you define here will be the standard tax rate for all **Items**. If there are **Items** that have different rates, they must be added in the **Item Tax** table in the **Item** master.\n\n#### Description of Columns\n\n1. Calculation Type: \n    - This can be on **Net Total** (that is the sum of basic amount).\n    - **On Previous Row Total / Amount** (for cumulative taxes or charges). If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total.\n    - **Actual** (as mentioned).\n2. Account Head: The Account ledger under which this tax will be booked\n3. Cost Center: If the tax / charge is an income (like shipping) or expense it needs to be booked against a Cost Center.\n4. Description: Description of the tax (that will be printed in invoices / quotes).\n5. Rate: Tax rate.\n6. Amount: Tax amount.\n7. Total: Cumulative total to this point.\n8. Enter Row: If based on \"Previous Row Total\" you can select the row number which will be taken as a base for this calculation (default is the previous row).\n9. Consider Tax or Charge for: In this section you can specify if the tax / charge is only for valuation (not a part of total) or only for total (does not add value to the item) or for both.\n10. Add or Deduct: Whether you want to add or deduct the tax.", 
  "docstatus": 0, 
  "doctype": "DocType", 
@@ -12,6 +12,7 @@
    "fieldname": "title", 
    "fieldtype": "Data", 
    "in_filter": 1, 
+   "in_list_view": 1, 
    "label": "Title", 
    "oldfieldname": "title", 
    "oldfieldtype": "Data", 
@@ -22,19 +23,43 @@
   {
    "fieldname": "is_default", 
    "fieldtype": "Check", 
+   "in_list_view": 1, 
    "label": "Default", 
    "permlevel": 0
   }, 
   {
+   "fieldname": "disabled", 
+   "fieldtype": "Check", 
+   "in_list_view": 1, 
+   "label": "Disabled", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
+   "fieldname": "column_break4", 
+   "fieldtype": "Column Break", 
+   "label": "", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
    "fieldname": "company", 
    "fieldtype": "Link", 
    "in_filter": 1, 
+   "in_list_view": 1, 
    "label": "Company", 
    "options": "Company", 
    "permlevel": 0, 
    "reqd": 1
   }, 
   {
+   "fieldname": "section_break6", 
+   "fieldtype": "Section Break", 
+   "label": "", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
    "fieldname": "other_charges", 
    "fieldtype": "Table", 
    "label": "Purchase Taxes and Charges", 
@@ -46,7 +71,7 @@
  ], 
  "icon": "icon-money", 
  "idx": 1, 
- "modified": "2014-01-29 12:26:38.000000", 
+ "modified": "2014-10-07 12:40:17.165882", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Purchase Taxes and Charges Master", 
diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.json b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.json
index 47d385b..12d425c 100644
--- a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.json
+++ b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.json
@@ -28,6 +28,14 @@
    "permlevel": 0
   }, 
   {
+   "fieldname": "disabled", 
+   "fieldtype": "Check", 
+   "in_list_view": 0, 
+   "label": "Disabled", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
    "fieldname": "column_break_3", 
    "fieldtype": "Column Break", 
    "permlevel": 0
@@ -72,7 +80,7 @@
  ], 
  "icon": "icon-money", 
  "idx": 1, 
- "modified": "2014-05-27 03:49:19.023941", 
+ "modified": "2014-10-06 13:11:18.616789", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Sales Taxes and Charges Master", 
diff --git a/erpnext/accounts/report/accounts_payable/accounts_payable.js b/erpnext/accounts/report/accounts_payable/accounts_payable.js
index 281f29f..f1812de 100644
--- a/erpnext/accounts/report/accounts_payable/accounts_payable.js
+++ b/erpnext/accounts/report/accounts_payable/accounts_payable.js
@@ -28,6 +28,30 @@
 			"fieldtype": "Select",
 			"options": 'Posting Date' + NEWLINE + 'Due Date',
 			"default": "Posting Date"
+		},
+		{
+			"fieldtype": "Break",
+		},
+		{
+			"fieldname":"range1",
+			"label": __("Ageing Range 1"),
+			"fieldtype": "Int",
+			"default": "30",
+			"reqd": 1
+		},
+		{
+			"fieldname":"range2",
+			"label": __("Ageing Range 2"),
+			"fieldtype": "Int",
+			"default": "60",
+			"reqd": 1
+		},
+		{
+			"fieldname":"range3",
+			"label": __("Ageing Range 3"),
+			"fieldtype": "Int",
+			"default": "90",
+			"reqd": 1
 		}
 	]
 }
diff --git a/erpnext/accounts/report/accounts_payable/accounts_payable.py b/erpnext/accounts/report/accounts_payable/accounts_payable.py
index 1e1f1eac..bc42033 100644
--- a/erpnext/accounts/report/accounts_payable/accounts_payable.py
+++ b/erpnext/accounts/report/accounts_payable/accounts_payable.py
@@ -3,14 +3,14 @@
 
 from __future__ import unicode_literals
 import frappe
-from frappe import _
-from frappe.utils import getdate, nowdate, flt, cstr
+from frappe.utils import getdate, nowdate, flt, cstr, cint
+from frappe import msgprint, _
 from erpnext.accounts.report.accounts_receivable.accounts_receivable import get_ageing_data
 
 def execute(filters=None):
 	if not filters: filters = {}
 	supplier_naming_by = frappe.db.get_value("Buying Settings", None, "supp_master_name")
-	columns = get_columns(supplier_naming_by)
+	columns = get_columns(filters, supplier_naming_by)
 	entries = get_gl_entries(filters)
 
 	entries_after_report_date = [[gle.voucher_type, gle.voucher_no]
@@ -50,7 +50,8 @@
 				else:
 					ageing_based_on_date = gle.posting_date
 
-				row += get_ageing_data(age_on, ageing_based_on_date, outstanding_amount) + \
+				row += get_ageing_data(cint(filters.get("range1")), cint(filters.get("range2")), \
+					cint(filters.get("range3")), age_on, ageing_based_on_date, outstanding_amount) + \
 					[supplier_details.get(gle.party).supplier_type, gle.remarks]
 
 				data.append(row)
@@ -70,8 +71,11 @@
 	columns +=[_("Voucher Type") + "::110", _("Voucher No") + ":Dynamic Link/Voucher Type:120",
 		_("Due Date") + ":Date:80", _("Bill No") + "::80", _("Bill Date") + ":Date:80",
 		_("Invoiced Amount") + ":Currency:100", _("Paid Amount") + ":Currency:100",
-		_("Outstanding Amount") + ":Currency:100", _("Age") + ":Int:50", "0-30:Currency:100",
-		"30-60:Currency:100", "60-90:Currency:100", _("90-Above") + ":Currency:100",
+		_("Outstanding Amount") + ":Currency:100", _("Age") + ":Int:50", 
+		"0-" + filters.get("range1") + ":Currency:100",
+		filters.get("range1") + "-" + filters.get("range2") + ":Currency:100", 
+		filters.get("range2") + "-" + filters.get("range3") + ":Currency:100", 
+		filters.get("range3") + _("-Above") + ":Currency:100",
 		_("Supplier Type") + ":Link/Supplier Type:150", _("Remarks") + "::150"
 	]
 
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
index 708f63b..aa7d175 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
@@ -28,6 +28,30 @@
 			"fieldtype": "Select",
 			"options": 'Posting Date' + NEWLINE + 'Due Date',
 			"default": "Posting Date"
+		},
+		{
+			"fieldtype": "Break",
+		},
+		{
+			"fieldname":"range1",
+			"label": __("Ageing Range 1"),
+			"fieldtype": "Int",
+			"default": "30",
+			"reqd": 1
+		},
+		{
+			"fieldname":"range2",
+			"label": __("Ageing Range 2"),
+			"fieldtype": "Int",
+			"default": "60",
+			"reqd": 1
+		},
+		{
+			"fieldname":"range3",
+			"label": __("Ageing Range 3"),
+			"fieldtype": "Int",
+			"default": "90",
+			"reqd": 1
 		}
 	]
 }
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
index 069391a..b239289 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
@@ -4,7 +4,7 @@
 from __future__ import unicode_literals
 import frappe
 from frappe import _
-from frappe.utils import getdate, nowdate, flt
+from frappe.utils import getdate, nowdate, flt, cint
 
 class AccountsReceivableReport(object):
 	def __init__(self, filters=None):
@@ -27,8 +27,10 @@
 		columns += [_("Voucher Type") + "::110", _("Voucher No") + ":Dynamic Link/Voucher Type:120",
 			_("Due Date") + ":Date:80", _("Invoiced Amount") + ":Currency:100",
 			_("Payment Received") + ":Currency:100", _("Outstanding Amount") + ":Currency:100",
-			_("Age") + ":Int:50", "0-30:Currency:100", "30-60:Currency:100",
-			"60-90:Currency:100", _("90-Above") + ":Currency:100",
+			_("Age") + ":Int:50", "0-" + self.filters.range1 + ":Currency:100",
+			self.filters.range1 + "-" + self.filters.range2 + ":Currency:100", 
+			self.filters.range2 + "-" + self.filters.range3 + ":Currency:100", 
+			self.filters.range3 + _("-Above") + ":Currency:100",
 			_("Territory") + ":Link/Territory:80", _("Remarks") + "::200"
 		]
 
@@ -56,7 +58,8 @@
 						payment_received, outstanding_amount]
 
 					entry_date = due_date if self.filters.ageing_based_on == "Due Date" else gle.posting_date
-					row += get_ageing_data(self.age_as_on, entry_date, outstanding_amount) + \
+					row += get_ageing_data(cint(self.filters.range1), cint(self.filters.range2), \
+						cint(self.filters.range3), self.age_as_on, entry_date, outstanding_amount) + \
 						[self.get_territory(gle.account), gle.remarks]
 
 					data.append(row)
@@ -155,15 +158,16 @@
 def execute(filters=None):
 	return AccountsReceivableReport(filters).run()
 
-def get_ageing_data(age_as_on, entry_date, outstanding_amount):
+def get_ageing_data(first_range, second_range, third_range, age_as_on, entry_date, outstanding_amount):
 	# [0-30, 30-60, 60-90, 90-above]
 	outstanding_range = [0.0, 0.0, 0.0, 0.0]
+
 	if not (age_as_on and entry_date):
 		return [0] + outstanding_range
 
 	age = (getdate(age_as_on) - getdate(entry_date)).days or 0
 	index = None
-	for i, days in enumerate([30, 60, 90]):
+	for i, days in enumerate([first_range, second_range, third_range]):
 		if age <= days:
 			index = i
 			break
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index b7e68d3..7a0b51a 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -26,6 +26,9 @@
 		if self.meta.get_field("is_recurring"):
 			validate_recurring_document(self)
 
+		if self.meta.get_field("taxes_and_charges"):
+			self.validate_enabled_taxes_and_charges()
+
 	def on_submit(self):
 		if self.meta.get_field("is_recurring"):
 			convert_to_recurring(self, self.get("posting_date") or self.get("transaction_date"))
@@ -342,6 +345,11 @@
 			self.precision(base_field, item))
 		item.set(base_field, value_in_company_currency)
 
+	def validate_enabled_taxes_and_charges(self):
+		taxes_and_charges_doctype = self.meta.get_options("taxes_and_charges")
+		if frappe.db.get_value(taxes_and_charges_doctype, self.taxes_and_charges, "disabled"):
+			frappe.throw(_("{0} '{1}' is disabled").format(taxes_and_charges_doctype, self.taxes_and_charges))
+
 	def calculate_total_advance(self, parenttype, advance_parentfield):
 		if self.doctype == parenttype and self.docstatus < 2:
 			sum_of_allocated_amount = sum([flt(adv.allocated_amount, self.precision("allocated_amount", adv))
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 9826132..52dd66c 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -82,5 +82,5 @@
 erpnext.patches.v4_2.update_sales_order_invoice_field_name
 erpnext.patches.v4_2.cost_of_production_cycle
 erpnext.patches.v4_2.seprate_manufacture_and_repack
+erpnext.patches.v4_2.party_model
 erpnext.patches.v5_0.update_frozen_accounts_permission_role
-erpnext.patches.v5_0.party_model