fix(pos): incorrect grand_total in case of inclusive taxes on item
diff --git a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py
index 0720d9b..f372dd6 100644
--- a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py
+++ b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py
@@ -84,12 +84,21 @@
 		sales_invoice.set_posting_time = 1
 		sales_invoice.posting_date = getdate(self.posting_date)
 		sales_invoice.save()
+		self.write_off_fractional_amount(sales_invoice, data)
 		sales_invoice.submit()
 
 		self.consolidated_invoice = sales_invoice.name
 
 		return sales_invoice.name
 
+	def write_off_fractional_amount(self, invoice, data):
+		pos_invoice_grand_total = sum(d.grand_total for d in data)
+
+		if abs(pos_invoice_grand_total - invoice.grand_total) < 1:
+
+			invoice.write_off_amount += -1 * (pos_invoice_grand_total - invoice.grand_total)
+			invoice.save()
+
 	def process_merging_into_credit_note(self, data):
 		credit_note = self.get_new_sales_invoice()
 		credit_note.is_return = 1
@@ -102,6 +111,7 @@
 		# TODO: return could be against multiple sales invoice which could also have been consolidated?
 		# credit_note.return_against = self.consolidated_invoice
 		credit_note.save()
+		self.write_off_fractional_amount(credit_note, data)
 		credit_note.submit()
 
 		self.consolidated_credit_note = credit_note.name
@@ -135,9 +145,15 @@
 						i.uom == item.uom and i.net_rate == item.net_rate and i.warehouse == item.warehouse):
 						found = True
 						i.qty = i.qty + item.qty
+						i.amount = i.amount + item.net_amount
+						i.net_amount = i.amount
+						i.base_amount = i.base_amount + item.base_net_amount
+						i.base_net_amount = i.base_amount
 
 				if not found:
 					item.rate = item.net_rate
+					item.amount = item.net_amount
+					item.base_amount = item.base_net_amount
 					item.price_list_rate = 0
 					si_item = map_child_doc(item, invoice, {"doctype": "Sales Invoice Item"})
 					items.append(si_item)
@@ -169,10 +185,12 @@
 						found = True
 				if not found:
 					payments.append(payment)
-			rounding_adjustment += doc.rounding_adjustment
-			rounded_total += doc.rounded_total
-			base_rounding_adjustment += doc.base_rounding_adjustment
-			base_rounded_total += doc.base_rounded_total
+
+			if doc.rounding_adjustment or doc.base_rounding_adjustment:
+				rounding_adjustment += doc.rounding_adjustment
+				rounded_total += doc.rounded_total
+				base_rounding_adjustment += doc.base_rounding_adjustment
+				base_rounded_total += doc.base_rounded_total
 
 
 		if loyalty_points_sum:
diff --git a/erpnext/accounts/doctype/pos_invoice_merge_log/test_pos_invoice_merge_log.py b/erpnext/accounts/doctype/pos_invoice_merge_log/test_pos_invoice_merge_log.py
index 3555da8..928d266 100644
--- a/erpnext/accounts/doctype/pos_invoice_merge_log/test_pos_invoice_merge_log.py
+++ b/erpnext/accounts/doctype/pos_invoice_merge_log/test_pos_invoice_merge_log.py
@@ -150,3 +150,118 @@
 			frappe.set_user("Administrator")
 			frappe.db.sql("delete from `tabPOS Profile`")
 			frappe.db.sql("delete from `tabPOS Invoice`")
+
+
+	def test_consolidation_round_off_error_1(self):
+		'''
+		Test case for bug:
+		Round off error in consolidated invoice creation if POS Invoice has inclusive tax
+		'''
+		frappe.db.sql("delete from `tabPOS Invoice`")
+
+		try:
+			init_user_and_profile()
+
+			inv = create_pos_invoice(qty=3, rate=10000, do_not_save=True)
+			inv.append("taxes", {
+				"account_head": "_Test Account VAT - _TC",
+				"charge_type": "On Net Total",
+				"cost_center": "_Test Cost Center - _TC",
+				"description": "VAT",
+				"doctype": "Sales Taxes and Charges",
+				"rate": 7.5,
+				"included_in_print_rate": 1
+			})
+			inv.append('payments', {
+				'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 30000
+			})
+			inv.insert()
+			inv.submit()
+
+			inv2 = create_pos_invoice(qty=3, rate=10000, do_not_save=True)
+			inv2.append("taxes", {
+				"account_head": "_Test Account VAT - _TC",
+				"charge_type": "On Net Total",
+				"cost_center": "_Test Cost Center - _TC",
+				"description": "VAT",
+				"doctype": "Sales Taxes and Charges",
+				"rate": 7.5,
+				"included_in_print_rate": 1
+			})
+			inv2.append('payments', {
+				'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 30000
+			})
+			inv2.insert()
+			inv2.submit()
+
+			consolidate_pos_invoices()
+
+			inv.load_from_db()
+			consolidated_invoice = frappe.get_doc('Sales Invoice', inv.consolidated_invoice)
+			self.assertEqual(consolidated_invoice.outstanding_amount, 0)
+			self.assertEqual(consolidated_invoice.status, 'Paid')
+
+		finally:
+			frappe.set_user("Administrator")
+			frappe.db.sql("delete from `tabPOS Profile`")
+			frappe.db.sql("delete from `tabPOS Invoice`")
+
+	def test_consolidation_round_off_error_2(self):
+		'''
+		Test the same case as above but with an Unpaid POS Invoice
+		'''
+		frappe.db.sql("delete from `tabPOS Invoice`")
+
+		try:
+			init_user_and_profile()
+
+			inv = create_pos_invoice(qty=6, rate=10000, do_not_save=True)
+			inv.append("taxes", {
+				"account_head": "_Test Account VAT - _TC",
+				"charge_type": "On Net Total",
+				"cost_center": "_Test Cost Center - _TC",
+				"description": "VAT",
+				"doctype": "Sales Taxes and Charges",
+				"rate": 7.5,
+				"included_in_print_rate": 1
+			})
+			inv.append('payments', {
+				'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 60000
+			})
+			inv.insert()
+			inv.submit()
+
+			inv2 = create_pos_invoice(qty=6, rate=10000, do_not_save=True)
+			inv2.append("taxes", {
+				"account_head": "_Test Account VAT - _TC",
+				"charge_type": "On Net Total",
+				"cost_center": "_Test Cost Center - _TC",
+				"description": "VAT",
+				"doctype": "Sales Taxes and Charges",
+				"rate": 7.5,
+				"included_in_print_rate": 1
+			})
+			inv2.append('payments', {
+				'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 60000
+			})
+			inv2.insert()
+			inv2.submit()
+
+			inv3 = create_pos_invoice(qty=3, rate=600, do_not_save=True)
+			inv3.append('payments', {
+				'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 1000
+			})
+			inv3.insert()
+			inv3.submit()
+
+			consolidate_pos_invoices()
+
+			inv.load_from_db()
+			consolidated_invoice = frappe.get_doc('Sales Invoice', inv.consolidated_invoice)
+			self.assertEqual(consolidated_invoice.outstanding_amount, 800)
+			self.assertEqual(consolidated_invoice.status, 'Unpaid')
+
+		finally:
+			frappe.set_user("Administrator")
+			frappe.db.sql("delete from `tabPOS Profile`")
+			frappe.db.sql("delete from `tabPOS Invoice`")
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index 075e3e3..5d1856c 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -106,6 +106,9 @@
 		self.doc.conversion_rate = flt(self.doc.conversion_rate)
 
 	def calculate_item_values(self):
+		if self.doc.get('is_consolidated'):
+			return
+
 		if not self.discount_amount_applied:
 			for item in self.doc.get("items"):
 				self.doc.round_floats_in(item)