Multiple fixes related to payment terms (#12115)

diff --git a/erpnext/accounts/doctype/payment_schedule/payment_schedule.json b/erpnext/accounts/doctype/payment_schedule/payment_schedule.json
index 854def0..2fcd44f 100644
--- a/erpnext/accounts/doctype/payment_schedule/payment_schedule.json
+++ b/erpnext/accounts/doctype/payment_schedule/payment_schedule.json
@@ -67,7 +67,7 @@
    "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
-   "read_only": 1, 
+   "read_only": 0, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -98,7 +98,7 @@
    "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
-   "read_only": 1, 
+   "read_only": 0, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 1, 
@@ -160,7 +160,7 @@
    "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
-   "read_only": 1, 
+   "read_only": 0, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 1, 
@@ -179,8 +179,8 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2017-11-23 12:39:02.013040", 
- "modified_by": "Administrator", 
+ "modified": "2017-12-19 16:20:33.546984", 
+ "modified_by": "nabinhait@gmail.com", 
  "module": "Accounts", 
  "name": "Payment Schedule", 
  "name_case": "", 
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
index 59b7c96..f282afe 100755
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
@@ -192,7 +192,7 @@
    "oldfieldname": "due_date", 
    "oldfieldtype": "Date", 
    "permlevel": 0, 
-   "print_hide": 1, 
+   "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "remember_last_selected_value": 0, 
@@ -3117,7 +3117,7 @@
    "options": "Payment Schedule", 
    "permlevel": 0, 
    "precision": "", 
-   "print_hide": 0, 
+   "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "remember_last_selected_value": 0, 
@@ -3914,7 +3914,7 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2017-12-15 17:49:51.230092", 
+ "modified": "2017-12-20 17:49:51.230092", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Purchase Invoice", 
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index b85c623..d1e64bc 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -503,7 +503,7 @@
    "oldfieldname": "due_date",
    "oldfieldtype": "Date",
    "permlevel": 0,
-   "print_hide": 1,
+   "print_hide": 0,
    "print_hide_if_no_value": 0,
    "read_only": 0,
    "remember_last_selected_value": 0,
@@ -2864,7 +2864,7 @@
    "options": "Payment Schedule",
    "permlevel": 0,
    "precision": "",
-   "print_hide": 0,
+   "print_hide": 1,
    "print_hide_if_no_value": 0,
    "read_only": 0,
    "remember_last_selected_value": 0,
@@ -4563,7 +4563,7 @@
  "istable": 0,
  "max_attachments": 0,
  "menu_index": 0,
- "modified": "2017-11-29 17:36:05.216046",
+ "modified": "2017-12-20 17:36:05.216046",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Sales Invoice",
diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json
index ee6b12c..45c9a65 100644
--- a/erpnext/assets/doctype/asset/asset.json
+++ b/erpnext/assets/doctype/asset/asset.json
@@ -193,7 +193,7 @@
    "read_only": 0, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
-   "reqd": 1, 
+   "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
    "unique": 0
@@ -1221,7 +1221,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-12-08 12:58:44.137460", 
+ "modified": "2017-12-19 12:58:44.137460", 
  "modified_by": "Administrator", 
  "module": "Assets", 
  "name": "Asset", 
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json
index fffc5ab..2191a55 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.json
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.json
@@ -2552,7 +2552,7 @@
    "options": "Payment Schedule", 
    "permlevel": 0, 
    "precision": "", 
-   "print_hide": 0, 
+   "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "remember_last_selected_value": 0, 
@@ -3261,8 +3261,8 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-11-29 14:06:33.636401", 
- "modified_by": "Administrator", 
+ "modified": "2017-12-19 14:53:03.986840", 
+ "modified_by": "nabinhait@gmail.com", 
  "module": "Buying", 
  "name": "Purchase Order", 
  "owner": "Administrator", 
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 0c36c6a..a27a21b 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -64,16 +64,14 @@
 	def validate_invoice_documents_schedule(self):
 		self.validate_payment_schedule_dates()
 		self.set_due_date()
-		self.validate_invoice_portion()
 		self.set_payment_schedule()
 		self.validate_payment_schedule_amount()
 		self.validate_due_date()
 		self.validate_advance_entries()
 
 	def validate_non_invoice_documents_schedule(self):
-		self.validate_payment_schedule_dates()
-		self.validate_invoice_portion()
 		self.set_payment_schedule()
+		self.validate_payment_schedule_dates()
 		self.validate_payment_schedule_amount()
 
 	def validate_all_documents_schedule(self):
@@ -652,6 +650,8 @@
 		date = self.get("due_date")
 		due_date = date or posting_date
 		grand_total = self.get("rounded_total") or self.grand_total
+		if self.doctype in ("Sales Invoice", "Purchase Invoice"):
+			grand_total = grand_total - flt(self.write_off_amount)
 
 		if not self.get("payment_schedule"):
 			if self.get("payment_terms_template"):
@@ -663,7 +663,8 @@
 				self.append("payment_schedule", data)
 		else:
 			for d in self.get("payment_schedule"):
-				d.payment_amount = grand_total * flt(d.invoice_portion) / 100
+				if d.invoice_portion:
+					d.payment_amount = grand_total * flt(d.invoice_portion) / 100
 
 	def set_due_date(self):
 		due_dates = [d.due_date for d in self.get("payment_schedule") if d.due_date]
@@ -673,12 +674,9 @@
 	def validate_payment_schedule_dates(self):
 		dates = []
 		li = []
-		if self.get('posting_date'):
-			if self.due_date and getdate(self.due_date) < getdate(self.posting_date):
-				frappe.throw(_("Due Date cannot be before posting date"))
 
 		for d in self.get("payment_schedule"):
-			if self.get('posting_date') and getdate(d.due_date) < getdate(self.posting_date):
+			if self.doctype == "Sales Order" and getdate(d.due_date) < getdate(self.transaction_date):
 				frappe.throw(_("Row {0}: Due Date cannot be before posting date").format(d.idx))
 			elif d.due_date in dates:
 				li.append('{0} in row {1}'.format(d.due_date, d.idx))
@@ -700,15 +698,6 @@
 			if total != grand_total:
 				frappe.throw(_("Total Payment Amount in Payment Schedule must be equal to Grand / Rounded Total"))
 
-	def validate_invoice_portion(self):
-		if self.get("payment_schedule"):
-			total_portion = 0
-			for term in self.payment_schedule:
-				total_portion += flt(term.get('invoice_portion', 0))
-
-			if flt(total_portion, 2) != 100.00:
-				frappe.msgprint(_('Combined invoice portion must equal 100%'), indicator='red', raise_exception=1)
-
 	def is_rounded_total_disabled(self):
 		if self.meta.get_field("disable_rounded_total"):
 			return self.disable_rounded_total
diff --git a/erpnext/selling/doctype/quotation/quotation.json b/erpnext/selling/doctype/quotation/quotation.json
index 1fec2ed..1c40ec3 100644
--- a/erpnext/selling/doctype/quotation/quotation.json
+++ b/erpnext/selling/doctype/quotation/quotation.json
@@ -2266,7 +2266,7 @@
    "options": "Payment Schedule", 
    "permlevel": 0, 
    "precision": "", 
-   "print_hide": 0, 
+   "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "remember_last_selected_value": 0, 
@@ -2881,8 +2881,8 @@
  "istable": 0, 
  "max_attachments": 1, 
  "menu_index": 0, 
- "modified": "2017-11-29 14:10:44.067669", 
- "modified_by": "Administrator", 
+ "modified": "2017-12-19 14:52:28.966139", 
+ "modified_by": "nabinhait@gmail.com", 
  "module": "Selling", 
  "name": "Quotation", 
  "owner": "Administrator", 
diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json
index cdd27ff..7c23687 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.json
+++ b/erpnext/selling/doctype/sales_order/sales_order.json
@@ -2445,7 +2445,7 @@
    "options": "Payment Schedule", 
    "permlevel": 0, 
    "precision": "", 
-   "print_hide": 0, 
+   "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "remember_last_selected_value": 0, 
@@ -3529,8 +3529,8 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-11-29 13:43:33.076893", 
- "modified_by": "Administrator", 
+ "modified": "2017-12-19 14:51:52.710612", 
+ "modified_by": "nabinhait@gmail.com", 
  "module": "Selling", 
  "name": "Sales Order", 
  "owner": "Administrator", 
diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.json b/erpnext/stock/doctype/delivery_trip/delivery_trip.json
index 50e4999..98aaa1c 100644
--- a/erpnext/stock/doctype/delivery_trip/delivery_trip.json
+++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.json
@@ -539,8 +539,8 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-11-13 03:56:09.885801", 
- "modified_by": "Administrator", 
+ "modified": "2017-12-19 12:00:49.226226", 
+ "modified_by": "nabinhait@gmail.com", 
  "module": "Stock", 
  "name": "Delivery Trip", 
  "name_case": "", 
@@ -565,6 +565,26 @@
    "share": 1, 
    "submit": 1, 
    "write": 1
+  }, 
+  {
+   "amend": 1, 
+   "apply_user_permissions": 0, 
+   "cancel": 1, 
+   "create": 1, 
+   "delete": 1, 
+   "email": 1, 
+   "export": 1, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "Stock User", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 1, 
+   "write": 1
   }
  ], 
  "quick_entry": 0, 
diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
index 551ad9f2..b590822 100644
--- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
@@ -496,10 +496,10 @@
 		frappe.get_doc("User", "test2@example.com")\
 			.add_roles("Sales User", "Sales Manager", "Stock User", "Stock Manager")
 
-		frappe.set_user("test@example.com")
 		st1 = frappe.copy_doc(test_records[0])
 		st1.company = "_Test Company 1"
 		set_perpetual_inventory(0, st1.company)
+		frappe.set_user("test@example.com")
 		st1.get("items")[0].t_warehouse="_Test Warehouse 2 - _TC1"
 		self.assertRaises(frappe.PermissionError, st1.insert)