Merge pull request #5925 from rohitwaghchaure/bcornwellmott-1

PPT looks at default MR type in Item to set MR type.
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index b284619..f055140 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -87,15 +87,6 @@
 	def before_save(self):
 		set_account_for_mode_of_payment(self)
 
-	def update_change_amount(self):
-		self.base_paid_amount = 0.0
-		if self.paid_amount:
-			self.base_paid_amount = flt(self.paid_amount * self.conversion_rate, self.precision("base_paid_amount"))
-			self.change_amount = self.base_change_amount = 0.0
-			if self.paid_amount > self.grand_total:
-				self.change_amount = flt(self.paid_amount - self.grand_total, self.precision("change_amount"))
-				self.base_change_amount = flt(self.change_amount * self.conversion_rate, self.precision("base_change_amount"))
-
 	def on_submit(self):
 		if not self.recurring_id:
 			frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
@@ -110,6 +101,7 @@
 		self.update_status_updater_args()
 		self.update_prevdoc_status()
 		self.update_billing_status_in_dn()
+		self.clear_unallocated_mode_of_payments()
 
 		# Updating stock ledger should always be called after updating prevdoc status,
 		# because updating reserved qty in bin depends upon updated delivered qty in SO
@@ -296,6 +288,12 @@
 			frappe.throw(_("Debit To account must be a Receivable account"))
 
 		self.party_account_currency = account.account_currency
+		
+	def clear_unallocated_mode_of_payments(self):
+		self.set("payments", self.get("payments", {"amount": ["not in", [0, None, ""]]}))
+
+		frappe.db.sql("""delete from `tabSales Invoice Payment` where parent = %s
+			and amount = 0""", self.name)
 
 	def validate_with_previous_doc(self):
 		super(SalesInvoice, self).validate_with_previous_doc({
@@ -504,6 +502,7 @@
 		gl_entries = merge_similar_entries(gl_entries)
 
 		self.make_pos_gl_entries(gl_entries)
+		self.make_gle_for_change(gl_entries)
 
 		self.make_write_off_gl_entry(gl_entries)
 
@@ -578,27 +577,24 @@
 
 	def make_pos_gl_entries(self, gl_entries):
 		if cint(self.is_pos) and self.paid_amount:
-			# POS, make payment entries
-			gl_entries.append(
-				self.get_gl_dict({
-					"account": self.debit_to,
-					"party_type": "Customer",
-					"party": self.customer,
-					"against": self.cash_bank_account,
-					"credit": flt(self.base_paid_amount - self.base_change_amount),
-					"credit_in_account_currency": flt(self.base_paid_amount - self.base_change_amount) \
-						if self.party_account_currency==self.company_currency else flt(self.paid_amount - self.change_amount),
-					"against_voucher": self.return_against if cint(self.is_return) else self.name,
-					"against_voucher_type": self.doctype,
-				}, self.party_account_currency)
-			)
-
-			cash_account = ''
 			for payment_mode in self.payments:
-				if payment_mode.type == 'Cash':
-					cash_account = payment_mode.account
-
 				if payment_mode.base_amount > 0:
+					# POS, make payment entries
+					gl_entries.append(
+						self.get_gl_dict({
+							"account": self.debit_to,
+							"party_type": "Customer",
+							"party": self.customer,
+							"against": payment_mode.account,
+							"credit": payment_mode.base_amount,
+							"credit_in_account_currency": payment_mode.base_amount \
+								if self.party_account_currency==self.company_currency \
+								else payment_mode.amount,
+							"against_voucher": self.return_against if cint(self.is_return) else self.name,
+							"against_voucher_type": self.doctype,
+						}, self.party_account_currency)
+					)
+					
 					payment_mode_account_currency = get_account_currency(payment_mode.account)
 					gl_entries.append(
 						self.get_gl_dict({
@@ -609,20 +605,44 @@
 								if payment_mode_account_currency==self.company_currency else payment_mode.amount
 						}, payment_mode_account_currency)
 					)
-
-			if self.change_amount:
-				cash_account = cash_account or self.payments[0].account
-				cash_account_currency = get_account_currency(cash_account)
+				
+	def make_gle_for_change(self, gl_entries):
+		if cint(self.is_pos) and self.change_amount:
+			cash_account = self.get_cash_account()
+			if cash_account:
+				gl_entries.append(
+					self.get_gl_dict({
+						"account": self.debit_to,
+						"party_type": "Customer",
+						"party": self.customer,
+						"against": cash_account,
+						"debit": flt(self.base_change_amount),
+						"debit_in_account_currency": flt(self.base_change_amount) \
+							if self.party_account_currency==self.company_currency else flt(self.change_amount),
+						"against_voucher": self.return_against if cint(self.is_return) else self.name,
+						"against_voucher_type": self.doctype
+					}, self.party_account_currency)
+				)
+				
 				gl_entries.append(
 					self.get_gl_dict({
 						"account": cash_account,
 						"against": self.customer,
-						"credit": self.base_change_amount,
-						"credit_in_account_currency": self.base_change_amount \
-							if payment_mode_account_currency==self.company_currency else self.change_amount
-					}, payment_mode_account_currency)
+						"credit": self.base_change_amount
+					})
 				)
-
+		
+				
+	def get_cash_account(self):
+		cash_account = [d.account for d in self.payments if d.type=="Cash"]
+		if cash_account:
+			cash_account = cash_account[0]
+		else:
+			cash_account = frappe.db.get_value("Account", 
+				filters={"company": self.company, "account_type": "Cash", "is_group": 0})
+				
+		return cash_account
+		
 	def make_write_off_gl_entry(self, gl_entries):
 		# write off entries, applicable if only pos
 		if self.write_off_account and self.write_off_amount:
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index e7eee5f..dd28059 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -503,7 +503,8 @@
 			[pos["taxes"][1]["account_head"], 0.0, 50.0],
 			[stock_in_hand, 0.0, abs(sle.stock_value_difference)],
 			[pos["items"][0]["expense_account"], abs(sle.stock_value_difference), 0.0],
-			[si.debit_to, 0.0, si.paid_amount],
+			[si.debit_to, 0.0, 300.0],
+			[si.debit_to, 0.0, cash_amount],
 			["_Test Bank - _TC", 300.0, 0.0],
 			["Cash - _TC", cash_amount, 0.0]
 		])
diff --git a/erpnext/config/accounts.py b/erpnext/config/accounts.py
index a0fcb63..419d83f 100644
--- a/erpnext/config/accounts.py
+++ b/erpnext/config/accounts.py
@@ -27,6 +27,12 @@
 					"description": _("Bank/Cash transactions against party or for internal transfer")
 				},
 				{
+					"type": "page",
+					"name": "pos",
+					"label": _("POS"),
+					"description": _("Point of Sale")
+				},
+				{
 					"type": "report",
 					"name": "Accounts Receivable",
 					"doctype": "Sales Invoice",	
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index eb75dee..28b2f7c 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -440,33 +440,32 @@
 			paid_amount = self.doc.paid_amount \
 				if self.doc.party_account_currency == self.doc.currency else self.doc.base_paid_amount
 
-			self.doc.outstanding_amount = 0
-			if total_amount_to_pay > paid_amount:
-				self.doc.outstanding_amount = flt(total_amount_to_pay - flt(paid_amount),
-					self.doc.precision("outstanding_amount"))
-			self.change_amount()
+			self.calculate_change_amount()
 
+			self.doc.outstanding_amount = flt(total_amount_to_pay - flt(paid_amount) +
+				flt(self.doc.change_amount), self.doc.precision("outstanding_amount"))
+					
 		elif self.doc.doctype == "Purchase Invoice":
 			self.doc.outstanding_amount = flt(total_amount_to_pay, self.doc.precision("outstanding_amount"))
 		
 	def calculate_paid_amount(self):
 		paid_amount = base_paid_amount = 0.0
 		for payment in self.doc.get('payments'):
-			payment.base_amount = flt(payment.amount * self.doc.conversion_rate)
-			paid_amount += payment.amount
-			base_paid_amount += payment.base_amount
+			if flt(payment.amount) > 0:
+				payment.base_amount = flt(payment.amount * self.doc.conversion_rate)
+				paid_amount += payment.amount
+				base_paid_amount += payment.base_amount
 
 		self.doc.paid_amount = flt(paid_amount, self.doc.precision("paid_amount"))
 		self.doc.base_paid_amount = flt(base_paid_amount, self.doc.precision("base_paid_amount"))
 
-	def change_amount(self):
-		change_amount = 0.0
+	def calculate_change_amount(self):
+		self.doc.change_amount = 0.0
 		if self.doc.paid_amount > self.doc.grand_total:
-			change_amount = flt(self.doc.paid_amount - self.doc.grand_total, 
-				self.doc.precision("change_amount"))
+			self.doc.change_amount = flt(self.doc.paid_amount - self.doc.grand_total + 
+				self.doc.write_off_amount, self.doc.precision("change_amount"))
 
-		self.doc.change_amount = change_amount;
-		self.doc.base_change_amount = flt(change_amount * self.doc.conversion_rate, 
+		self.doc.base_change_amount = flt(self.doc.change_amount * self.doc.conversion_rate, 
 			self.doc.precision("base_change_amount"))
 
 	def calculate_margin(self, item):
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index 2b173bf..0f6dae6 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -540,7 +540,7 @@
 	po = frappe.get_doc('Production Order', source_name)
 	ts = po.make_time_logs(open_new=True)
 
-	if not ts.get('time_logs'):
+	if not ts or not ts.get('time_logs'):
 		frappe.throw(_("Already completed"))
 
 	return ts
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index 34c4557..576bc71 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -561,22 +561,18 @@
 				this.calculate_paid_amount()
 			}
 
+			this.calculate_change_amount()
 			var outstanding_amount = 0.0
 
 			var paid_amount = (this.frm.doc.party_account_currency == this.frm.doc.currency) ?
 				this.frm.doc.paid_amount : this.frm.doc.base_paid_amount;
 
-			if (total_amount_to_pay > paid_amount){
-				outstanding_amount =  flt(total_amount_to_pay - flt(paid_amount),
-					precision("outstanding_amount"));
-			}
+			this.frm.doc.outstanding_amount =  flt(total_amount_to_pay - flt(paid_amount) + 
+				flt(this.frm.doc.change_amount), precision("outstanding_amount"));
 
 		} else if(this.frm.doc.doctype == "Purchase Invoice") {
-			var outstanding_amount = flt(total_amount_to_pay, precision("outstanding_amount"));
-		}
-
-		this.frm.doc.outstanding_amount = outstanding_amount;
-		this.calculate_change_amount()
+			this.frm.doc.outstanding_amount = flt(total_amount_to_pay, precision("outstanding_amount"));
+		}		
 	},
 
 	set_default_payment: function(total_amount_to_pay, update_paid_amount){
@@ -610,15 +606,13 @@
 	},
 
 	calculate_change_amount: function(){
-		var change_amount = 0.0;
+		this.frm.doc.change_amount = 0.0;
 		if(this.frm.doc.paid_amount > this.frm.doc.grand_total){
-			change_amount = flt(this.frm.doc.paid_amount - this.frm.doc.grand_total,
-				precision("change_amount"))
+			this.frm.doc.change_amount = flt(this.frm.doc.paid_amount - this.frm.doc.grand_total + 
+				this.frm.doc.write_off_amount, precision("change_amount"));
 		}
 
-		this.frm.doc.change_amount = flt(change_amount,
-			precision("change_amount"))
-		this.frm.doc.base_change_amount = flt(change_amount * this.frm.doc.conversion_rate,
-			precision("base_change_amount"))
+		this.frm.doc.base_change_amount = flt(this.frm.doc.change_amount * this.frm.doc.conversion_rate,
+			precision("base_change_amount"));
 	},
 })