Merge pull request #7139 from rohitwaghchaure/customer_billing_amount_issue

[Fix] Currecny symbol for customer's total annual billing, total unpaid amount
diff --git a/erpnext/hr/doctype/salary_slip/test_salary_slip.py b/erpnext/hr/doctype/salary_slip/test_salary_slip.py
index 8cf0688..57a3711 100644
--- a/erpnext/hr/doctype/salary_slip/test_salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/test_salary_slip.py
@@ -55,8 +55,8 @@
 		ss = frappe.get_doc("Salary Slip",
 			self.make_employee_salary_slip("test_employee@salary.com"))
 
-		self.assertEquals(ss.total_days_in_month, 27)
-		self.assertEquals(ss.payment_days, 27)
+		self.assertEquals(ss.total_days_in_month, 28)
+		self.assertEquals(ss.payment_days, 28)
 		self.assertEquals(ss.earnings[0].amount, 5000)
 		self.assertEquals(ss.earnings[0].default_amount, 5000)
 		self.assertEquals(ss.earnings[1].amount, 3000)
@@ -76,23 +76,23 @@
 		ss = frappe.get_doc("Salary Slip",
 			self.make_employee_salary_slip("test_employee@salary.com"))
 
-		self.assertEquals(ss.total_days_in_month, 27)
-		self.assertEquals(ss.payment_days, 27)
+		self.assertEquals(ss.total_days_in_month, 28)
+		self.assertEquals(ss.payment_days, 28)
 
 		# set relieving date in the same month
 		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", "12-12-2016")
 		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Left")
 		
-		self.assertEquals(ss.total_days_in_month, 27)
-		self.assertEquals(ss.payment_days, 27)
+		self.assertEquals(ss.total_days_in_month, 28)
+		self.assertEquals(ss.payment_days, 28)
 		ss.save()
 		
 		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
 		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Active")
 		# Holidays included in working days
 		frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 1)	
-		self.assertEquals(ss.total_days_in_month, 27)
-		self.assertEquals(ss.payment_days, 27)
+		self.assertEquals(ss.total_days_in_month, 28)
+		self.assertEquals(ss.payment_days, 28)
 		ss.save()
 				#
 		# frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "date_of_joining", "2001-01-11")
diff --git a/erpnext/hr/report/employee_information/employee_information.json b/erpnext/hr/report/employee_information/employee_information.json
index 93b8cd2..51963d4 100644
--- a/erpnext/hr/report/employee_information/employee_information.json
+++ b/erpnext/hr/report/employee_information/employee_information.json
@@ -1,12 +1,14 @@
 {
+ "add_total_row": 0, 
  "apply_user_permissions": 1, 
  "creation": "2013-05-06 18:43:53", 
+ "disabled": 0, 
  "docstatus": 0, 
  "doctype": "Report", 
  "idx": 1, 
  "is_standard": "Yes", 
- "json": "{\"filters\":[],\"columns\":[[\"name\",\"Employee\"],[\"employee_number\",\"Employee\"],[\"date_of_joining\",\"Employee\"],[\"branch\",\"Employee\"],[\"department\",\"Employee\"],[\"designation\",\"Employee\"],[\"gender\",\"Employee\"],[\"status\",\"Employee\"],[\"company\",\"Employee\"],[\"employment_type\",\"Employee\"],[\"reports_to\",\"Employee\"],[\"company_email\",\"Employee\"]],\"sort_by\":\"Employee.bank_ac_no\",\"sort_order\":\"desc\",\"sort_by_next\":\"\",\"sort_order_next\":\"desc\"}", 
- "modified": "2015-03-02 07:42:02.352823", 
+ "json": "{\"add_total_row\": 0, \"sort_by\": \"Employee.bank_ac_no\", \"sort_order\": \"desc\", \"sort_by_next\": \"\", \"filters\": [], \"sort_order_next\": \"desc\", \"columns\": [[\"name\", \"Employee\"], [\"employee_number\", \"Employee\"], [\"date_of_joining\", \"Employee\"], [\"branch\", \"Employee\"], [\"department\", \"Employee\"], [\"designation\", \"Employee\"], [\"gender\", \"Employee\"], [\"status\", \"Employee\"], [\"company\", \"Employee\"], [\"employment_type\", \"Employee\"], [\"reports_to\", \"Employee\"], [\"company_email\", \"Employee\"]]}", 
+ "modified": "2016-12-05 18:49:34.782552", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Employee Information", 
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 30e8e03..b578ac2 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -349,4 +349,5 @@
 erpnext.patches.v7_1.update_invoice_status
 erpnext.patches.v7_0.po_status_issue_for_pr_return
 erpnext.patches.v7_1.update_missing_salary_component_type
-erpnext.patches.v7_0.update_autoname_field
\ No newline at end of file
+erpnext.patches.v7_0.update_autoname_field
+erpnext.patches.v7_0.update_status_of_po_so
\ No newline at end of file
diff --git a/erpnext/patches/v7_0/update_status_of_po_so.py b/erpnext/patches/v7_0/update_status_of_po_so.py
new file mode 100644
index 0000000..0e2dd74
--- /dev/null
+++ b/erpnext/patches/v7_0/update_status_of_po_so.py
@@ -0,0 +1,62 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.utils import cint, flt
+
+def execute():
+	update_po_per_received_per_billed()
+	update_so_per_delivered_per_billed()
+	update_status()
+
+def update_po_per_received_per_billed():
+	frappe.db.sql(""" 
+		update
+			`tabPurchase Order`
+		set
+			`tabPurchase Order`.per_received = round((select sum(if(qty > ifnull(received_qty, 0),
+					ifnull(received_qty, 0), qty)) / sum(qty) *100 from `tabPurchase Order Item`
+					where parent = `tabPurchase Order`.name), 2),
+			`tabPurchase Order`.per_billed = round((select sum( if(amount > ifnull(billed_amt, 0),
+					ifnull(billed_amt, 0), amount)) / sum(amount) *100 from `tabPurchase Order Item`
+					where parent = `tabPurchase Order`.name), 2)""")
+
+def update_so_per_delivered_per_billed():
+	frappe.db.sql(""" 
+		update
+			`tabSales Order`
+		set 
+			`tabSales Order`.per_delivered = round((select sum( if(qty > ifnull(delivered_qty, 0),
+					ifnull(delivered_qty, 0), qty)) / sum(qty) *100 from `tabSales Order Item` 
+					where parent = `tabSales Order`.name), 2), 
+			`tabSales Order`.per_billed = round((select sum( if(amount > ifnull(billed_amt, 0),
+					ifnull(billed_amt, 0), amount)) / sum(amount) *100 from `tabSales Order Item`
+					where parent = `tabSales Order`.name), 2)""")
+
+def update_status():
+	frappe.db.sql("""
+		update
+			`tabSales Order`
+		set status = (Case when status = 'Closed' then 'Closed'
+			When per_delivered < 100 and per_billed < 100 and docstatus = 1 then 'To Deliver and Bill'
+			when per_delivered = 100 and per_billed < 100 and docstatus = 1 then 'To Bill'
+			when per_delivered < 100 and per_billed = 100 and docstatus = 1 then 'To Deliver'
+			when per_delivered = 100 and per_billed = 100 and docstatus = 1 then 'Completed'
+			when order_type = 'Maintenance' and per_billed = 100 and docstatus = 1 then 'Completed'
+			when docstatus = 2 then 'Cancelled'
+			else 'Draft'
+		End)""")
+
+	frappe.db.sql("""
+		update 
+			`tabPurchase Order` 
+		set status = (Case when status = 'Closed' then 'Closed'
+			when status = 'Delivered' then 'Delivered'
+			When per_received < 100 and per_billed < 100 and docstatus = 1 then 'To Receive and Bill'
+			when per_received = 100 and per_billed < 100 and docstatus = 1 then 'To Bill'
+			when per_received < 100 and per_billed = 100 and docstatus = 1 then 'To Receive'
+			when per_received = 100 and per_billed = 100 and docstatus = 1 then 'Completed'
+			when docstatus = 2 then 'Cancelled'
+			else 'Draft'
+		End)""")
\ No newline at end of file
diff --git a/erpnext/selling/doctype/customer/test_customer.py b/erpnext/selling/doctype/customer/test_customer.py
index 36e4819..23df503 100644
--- a/erpnext/selling/doctype/customer/test_customer.py
+++ b/erpnext/selling/doctype/customer/test_customer.py
@@ -16,6 +16,9 @@
 test_records = frappe.get_test_records('Customer')
 
 class TestCustomer(unittest.TestCase):
+	def tearDown(self):
+		frappe.db.set_value("Customer", '_Test Customer', 'credit_limit', 0.0)
+
 	def test_party_details(self):
 		from erpnext.accounts.party import get_party_details
 
diff --git a/erpnext/setup/doctype/email_digest/email_digest.py b/erpnext/setup/doctype/email_digest/email_digest.py
index ac999ed..a7dfa7c 100644
--- a/erpnext/setup/doctype/email_digest/email_digest.py
+++ b/erpnext/setup/doctype/email_digest/email_digest.py
@@ -233,7 +233,7 @@
 			 "new_quotations","pending_quotations","sales_order","purchase_order","pending_sales_orders","pending_purchase_orders",
 			"invoiced_amount", "payables", "bank_balance", "credit_balance"):
 			if self.get(key):
-				cache_key = "email_digest:card:{0}:{1}".format(self.company, key)
+				cache_key = "email_digest:card:{0}:{1}:{2}".format(self.company, self.frequency, key)
 				card = cache.get(cache_key)
 
 				if card:
diff --git a/erpnext/stock/report/item_shortage_report/item_shortage_report.json b/erpnext/stock/report/item_shortage_report/item_shortage_report.json
index b87a415..3abdead 100644
--- a/erpnext/stock/report/item_shortage_report/item_shortage_report.json
+++ b/erpnext/stock/report/item_shortage_report/item_shortage_report.json
@@ -1,12 +1,14 @@
 {
+ "add_total_row": 0, 
  "apply_user_permissions": 1, 
  "creation": "2013-08-20 13:43:30", 
+ "disabled": 0, 
  "docstatus": 0, 
  "doctype": "Report", 
  "idx": 1, 
  "is_standard": "Yes", 
- "json": "{\"filters\":[[\"Bin\",\"projected_qty\",\"<\",\"0\"]],\"columns\":[[\"warehouse\",\"Bin\"],[\"item_code\",\"Bin\"],[\"actual_qty\",\"Bin\"],[\"ordered_qty\",\"Bin\"],[\"planned_qty\",\"Bin\"],[\"reserved_qty\",\"Bin\"],[\"projected_qty\",\"Bin\"]],\"sort_by\":\"Bin.projected_qty\",\"sort_order\":\"asc\",\"sort_by_next\":\"\",\"sort_order_next\":\"desc\"}", 
- "modified": "2014-06-03 07:18:17.092713", 
+ "json": "{\"add_total_row\": 0, \"sort_by\": \"Bin.projected_qty\", \"sort_order\": \"asc\", \"sort_by_next\": \"\", \"filters\": [[\"Bin\", \"projected_qty\", \"<\", \"0\"]], \"sort_order_next\": \"desc\", \"columns\": [[\"warehouse\", \"Bin\"], [\"item_code\", \"Bin\"], [\"actual_qty\", \"Bin\"], [\"ordered_qty\", \"Bin\"], [\"planned_qty\", \"Bin\"], [\"reserved_qty\", \"Bin\"], [\"projected_qty\", \"Bin\"]]}", 
+ "modified": "2016-12-05 18:49:41.909411", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Item Shortage Report", 
diff --git a/erpnext/stock/report/item_wise_price_list_rate/item_wise_price_list_rate.json b/erpnext/stock/report/item_wise_price_list_rate/item_wise_price_list_rate.json
index 6a8ddc3..bcca0b4 100644
--- a/erpnext/stock/report/item_wise_price_list_rate/item_wise_price_list_rate.json
+++ b/erpnext/stock/report/item_wise_price_list_rate/item_wise_price_list_rate.json
@@ -7,8 +7,8 @@
  "doctype": "Report", 
  "idx": 1, 
  "is_standard": "Yes", 
- "json": "{\"filters\":[],\"columns\":[[\"name\",\"Item Price\"],[\"price_list\",\"Item Price\"],[\"item_code\",\"Item Price\"],[\"item_name\",\"Item Price\"],[\"item_description\",\"Item Price\"],[\"price_list_rate\",\"Item Price\"],[\"buying\",\"Item Price\"],[\"selling\",\"Item Price\"],[\"currency\",\"Item Price\"]],\"sort_by\":\"Item Price.modified\",\"sort_order\":\"desc\",\"sort_by_next\":null,\"sort_order_next\":\"desc\"}", 
- "modified": "2016-02-01 14:31:04.075909", 
+ "json": "{\"add_total_row\": 0, \"sort_by\": \"Item Price.modified\", \"sort_order\": \"desc\", \"sort_by_next\": null, \"filters\": [], \"sort_order_next\": \"desc\", \"columns\": [[\"name\", \"Item Price\"], [\"price_list\", \"Item Price\"], [\"item_code\", \"Item Price\"], [\"item_name\", \"Item Price\"], [\"item_description\", \"Item Price\"], [\"price_list_rate\", \"Item Price\"], [\"buying\", \"Item Price\"], [\"selling\", \"Item Price\"], [\"currency\", \"Item Price\"]]}", 
+ "modified": "2016-12-05 18:49:15.693076", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Item-wise Price List Rate", 
diff --git a/erpnext/stock/report/serial_no_service_contract_expiry/serial_no_service_contract_expiry.json b/erpnext/stock/report/serial_no_service_contract_expiry/serial_no_service_contract_expiry.json
index 5ab5e64..2879d98 100644
--- a/erpnext/stock/report/serial_no_service_contract_expiry/serial_no_service_contract_expiry.json
+++ b/erpnext/stock/report/serial_no_service_contract_expiry/serial_no_service_contract_expiry.json
@@ -7,8 +7,8 @@
  "doctype": "Report", 
  "idx": 1, 
  "is_standard": "Yes", 
- "json": "{\"filters\":[[\"Serial No\",\"delivery_document_type\",\"in\",[\"Delivery Note\",\"Sales Invoice\"]],[\"Serial No\",\"warehouse\",\"=\",\"\"]],\"columns\":[[\"name\",\"Serial No\"],[\"item_code\",\"Serial No\"],[\"amc_expiry_date\",\"Serial No\"],[\"maintenance_status\",\"Serial No\"],[\"delivery_document_no\",\"Serial No\"],[\"customer\",\"Serial No\"],[\"customer_name\",\"Serial No\"],[\"item_name\",\"Serial No\"],[\"description\",\"Serial No\"],[\"item_group\",\"Serial No\"],[\"brand\",\"Serial No\"]],\"sort_by\":\"Serial No.modified\",\"sort_order\":\"desc\",\"sort_by_next\":null,\"sort_order_next\":\"desc\"}", 
- "modified": "2015-10-22 14:53:45.192497", 
+ "json": "{\"add_total_row\": 0, \"sort_by\": \"Serial No.modified\", \"sort_order\": \"desc\", \"sort_by_next\": null, \"filters\": [[\"Serial No\", \"delivery_document_type\", \"in\", [\"Delivery Note\", \"Sales Invoice\"]], [\"Serial No\", \"warehouse\", \"=\", \"\"]], \"sort_order_next\": \"desc\", \"columns\": [[\"name\", \"Serial No\"], [\"item_code\", \"Serial No\"], [\"amc_expiry_date\", \"Serial No\"], [\"maintenance_status\", \"Serial No\"], [\"delivery_document_no\", \"Serial No\"], [\"customer\", \"Serial No\"], [\"customer_name\", \"Serial No\"], [\"item_name\", \"Serial No\"], [\"description\", \"Serial No\"], [\"item_group\", \"Serial No\"], [\"brand\", \"Serial No\"]]}", 
+ "modified": "2016-12-05 18:49:22.748446", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Serial No Service Contract Expiry", 
diff --git a/erpnext/stock/report/serial_no_status/serial_no_status.json b/erpnext/stock/report/serial_no_status/serial_no_status.json
index dfc7afc..cb4e70d 100644
--- a/erpnext/stock/report/serial_no_status/serial_no_status.json
+++ b/erpnext/stock/report/serial_no_status/serial_no_status.json
@@ -7,8 +7,8 @@
  "doctype": "Report", 
  "idx": 1, 
  "is_standard": "Yes", 
- "json": "{\"filters\":[],\"columns\":[[\"name\",\"Serial No\"],[\"item_code\",\"Serial No\"],[\"warehouse\",\"Serial No\"],[\"item_name\",\"Serial No\"],[\"description\",\"Serial No\"],[\"item_group\",\"Serial No\"],[\"brand\",\"Serial No\"],[\"purchase_document_no\",\"Serial No\"],[\"purchase_date\",\"Serial No\"],[\"customer\",\"Serial No\"],[\"customer_name\",\"Serial No\"],[\"purchase_rate\",\"Serial No\"],[\"delivery_document_no\",\"Serial No\"],[\"delivery_date\",\"Serial No\"],[\"supplier\",\"Serial No\"],[\"supplier_name\",\"Serial No\"]],\"sort_by\":\"Serial No.name\",\"sort_order\":\"desc\",\"sort_by_next\":null,\"sort_order_next\":\"desc\"}", 
- "modified": "2015-10-22 14:49:29.491790", 
+ "json": "{\"add_total_row\": 0, \"sort_by\": \"Serial No.name\", \"sort_order\": \"desc\", \"sort_by_next\": null, \"filters\": [], \"sort_order_next\": \"desc\", \"columns\": [[\"name\", \"Serial No\"], [\"item_code\", \"Serial No\"], [\"warehouse\", \"Serial No\"], [\"item_name\", \"Serial No\"], [\"description\", \"Serial No\"], [\"item_group\", \"Serial No\"], [\"brand\", \"Serial No\"], [\"purchase_document_no\", \"Serial No\"], [\"purchase_date\", \"Serial No\"], [\"customer\", \"Serial No\"], [\"customer_name\", \"Serial No\"], [\"purchase_rate\", \"Serial No\"], [\"delivery_document_no\", \"Serial No\"], [\"delivery_date\", \"Serial No\"], [\"supplier\", \"Serial No\"], [\"supplier_name\", \"Serial No\"]]}", 
+ "modified": "2016-12-05 18:49:31.424300", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Serial No Status", 
diff --git a/erpnext/stock/report/serial_no_warranty_expiry/serial_no_warranty_expiry.json b/erpnext/stock/report/serial_no_warranty_expiry/serial_no_warranty_expiry.json
index 2a919af..6905671 100644
--- a/erpnext/stock/report/serial_no_warranty_expiry/serial_no_warranty_expiry.json
+++ b/erpnext/stock/report/serial_no_warranty_expiry/serial_no_warranty_expiry.json
@@ -7,8 +7,8 @@
  "doctype": "Report", 
  "idx": 1, 
  "is_standard": "Yes", 
- "json": "{\"filters\":[[\"Serial No\",\"delivery_document_type\",\"in\",[\"Delivery Note\",\"Sales Invoice\"]],[\"Serial No\",\"warehouse\",\"=\",\"\"]],\"columns\":[[\"name\",\"Serial No\"],[\"item_code\",\"Serial No\"],[\"warranty_expiry_date\",\"Serial No\"],[\"warranty_period\",\"Serial No\"],[\"maintenance_status\",\"Serial No\"],[\"purchase_document_no\",\"Serial No\"],[\"purchase_date\",\"Serial No\"],[\"supplier\",\"Serial No\"],[\"supplier_name\",\"Serial No\"],[\"delivery_document_no\",\"Serial No\"],[\"delivery_date\",\"Serial No\"],[\"customer\",\"Serial No\"],[\"customer_name\",\"Serial No\"],[\"item_name\",\"Serial No\"],[\"description\",\"Serial No\"],[\"item_group\",\"Serial No\"],[\"brand\",\"Serial No\"]],\"sort_by\":\"Serial No.modified\",\"sort_order\":\"desc\",\"sort_by_next\":null,\"sort_order_next\":\"desc\"}", 
- "modified": "2015-10-22 14:53:12.575608", 
+ "json": "{\"add_total_row\": 0, \"sort_by\": \"Serial No.modified\", \"sort_order\": \"desc\", \"sort_by_next\": null, \"filters\": [[\"Serial No\", \"delivery_document_type\", \"in\", [\"Delivery Note\", \"Sales Invoice\"]], [\"Serial No\", \"warehouse\", \"=\", \"\"]], \"sort_order_next\": \"desc\", \"columns\": [[\"name\", \"Serial No\"], [\"item_code\", \"Serial No\"], [\"warranty_expiry_date\", \"Serial No\"], [\"warranty_period\", \"Serial No\"], [\"maintenance_status\", \"Serial No\"], [\"purchase_document_no\", \"Serial No\"], [\"purchase_date\", \"Serial No\"], [\"supplier\", \"Serial No\"], [\"supplier_name\", \"Serial No\"], [\"delivery_document_no\", \"Serial No\"], [\"delivery_date\", \"Serial No\"], [\"customer\", \"Serial No\"], [\"customer_name\", \"Serial No\"], [\"item_name\", \"Serial No\"], [\"description\", \"Serial No\"], [\"item_group\", \"Serial No\"], [\"brand\", \"Serial No\"]]}", 
+ "modified": "2016-12-05 18:49:26.761364", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Serial No Warranty Expiry",