Merge branch 'develop' into iff-invoicing
diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
index 52a5be0..f6d76e5 100644
--- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
+++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
@@ -1,5 +1,4 @@
 {
- "actions": [],
  "autoname": "hash",
  "creation": "2013-05-22 12:43:10",
  "doctype": "DocType",
@@ -82,6 +81,7 @@
   "item_tax_rate",
   "bom",
   "include_exploded_items",
+  "purchase_invoice_item",
   "col_break6",
   "purchase_order",
   "po_detail",
@@ -769,12 +769,21 @@
    "collapsible": 1,
    "fieldname": "col_break7",
    "fieldtype": "Column Break"
+  },
+  {
+   "depends_on": "eval:parent.update_stock == 1",
+   "fieldname": "purchase_invoice_item",
+   "fieldtype": "Data",
+   "ignore_user_permissions": 1,
+   "label": "Purchase Invoice Item",
+   "no_copy": 1,
+   "print_hide": 1,
+   "read_only": 1
   }
  ],
  "idx": 1,
  "istable": 1,
- "links": [],
- "modified": "2020-04-22 10:37:35.103176",
+ "modified": "2020-08-20 11:48:01.398356",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Purchase Invoice Item",
diff --git a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
index 004d358..fb3dd6a 100644
--- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
+++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
@@ -1,5 +1,4 @@
 {
- "actions": [],
  "autoname": "hash",
  "creation": "2013-06-04 11:02:19",
  "doctype": "DocType",
@@ -87,6 +86,7 @@
   "edit_references",
   "sales_order",
   "so_detail",
+  "sales_invoice_item",
   "column_break_74",
   "delivery_note",
   "dn_detail",
@@ -790,12 +790,22 @@
    "fieldtype": "Link",
    "label": "Project",
    "options": "Project"
-  }
+  },
+  {
+    "depends_on": "eval:parent.update_stock == 1",
+    "fieldname": "sales_invoice_item",
+    "fieldtype": "Data",
+    "ignore_user_permissions": 1,
+    "label": "Sales Invoice Item",
+    "no_copy": 1,
+    "print_hide": 1,
+    "read_only": 1
+   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2020-07-18 12:24:41.749986",
+ "modified": "2020-08-20 11:24:41.749986",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Sales Invoice Item",
diff --git a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
index c2c7207..219871b 100644
--- a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
+++ b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
@@ -378,7 +378,7 @@
 		if filters and filters.get('presentation_currency') != d.default_currency:
 			currency_info['company'] = d.name
 			currency_info['company_currency'] = d.default_currency
-			convert_to_presentation_currency(gl_entries, currency_info)
+			convert_to_presentation_currency(gl_entries, currency_info, filters.get('company'))
 
 		for entry in gl_entries:
 			key = entry.account_number or entry.account_name
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index d5b8cdb..1b65a31 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -423,7 +423,7 @@
 				distributed_cost_center_query=distributed_cost_center_query), gl_filters, as_dict=True) #nosec
 
 		if filters and filters.get('presentation_currency'):
-			convert_to_presentation_currency(gl_entries, get_currency(filters))
+			convert_to_presentation_currency(gl_entries, get_currency(filters), filters.get('company'))
 
 		for entry in gl_entries:
 			gl_entries_by_account.setdefault(entry.account, []).append(entry)
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py
index fcd36e4..0a72f6a 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.py
+++ b/erpnext/accounts/report/general_ledger/general_ledger.py
@@ -180,7 +180,7 @@
 		filters, as_dict=1)
 
 	if filters.get('presentation_currency'):
-		return convert_to_presentation_currency(gl_entries, currency_map)
+		return convert_to_presentation_currency(gl_entries, currency_map, filters.get('company'))
 	else:
 		return gl_entries
 
diff --git a/erpnext/accounts/report/utils.py b/erpnext/accounts/report/utils.py
index 4a9af49..9de8d19 100644
--- a/erpnext/accounts/report/utils.py
+++ b/erpnext/accounts/report/utils.py
@@ -6,10 +6,6 @@
 from frappe.utils import cint, get_datetime_str, formatdate, flt
 
 __exchange_rates = {}
-P_OR_L_ACCOUNTS = list(
-	sum(frappe.get_list('Account', fields=['name'], or_filters=[{'root_type': 'Income'}, {'root_type': 'Expense'}], as_list=True), ())
-)
-
 
 def get_currency(filters):
 	"""
@@ -73,18 +69,7 @@
 
 	return rate
 
-
-def is_p_or_l_account(account_name):
-	"""
-	Check if the given `account name` is an `Account` with `root_type` of either 'Income'
-	or 'Expense'.
-	:param account_name:
-	:return: Boolean
-	"""
-	return account_name in P_OR_L_ACCOUNTS
-
-
-def convert_to_presentation_currency(gl_entries, currency_info):
+def convert_to_presentation_currency(gl_entries, currency_info, company):
 	"""
 	Take a list of GL Entries and change the 'debit' and 'credit' values to currencies
 	in `currency_info`.
@@ -96,6 +81,9 @@
 	presentation_currency = currency_info['presentation_currency']
 	company_currency = currency_info['company_currency']
 
+	pl_accounts = [d.name for d in frappe.get_list('Account',
+		filters={'report_type': 'Profit and Loss', 'company': company})]
+
 	for entry in gl_entries:
 		account = entry['account']
 		debit = flt(entry['debit'])
@@ -107,7 +95,7 @@
 		if account_currency != presentation_currency:
 			value = debit or credit
 
-			date = currency_info['report_date'] if not is_p_or_l_account(account) else entry['posting_date']
+			date = entry['posting_date'] if account in pl_accounts else currency_info['report_date']
 			converted_value = convert(value, presentation_currency, company_currency, date)
 
 			if entry.get('debit'):
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 89b48f0..f982700 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -559,9 +559,19 @@
 						"serial_no": cstr(d.serial_no).strip()
 					})
 					if self.is_return:
-						original_incoming_rate = frappe.db.get_value("Stock Ledger Entry",
-							{"voucher_type": "Purchase Receipt", "voucher_no": self.return_against,
-							"item_code": d.item_code}, "incoming_rate")
+						filters = {
+							"voucher_type": self.doctype,
+							"voucher_no": self.return_against,
+							"item_code": d.item_code
+						}
+
+						if (self.doctype == "Purchase Invoice" and self.update_stock
+							and d.get("purchase_invoice_item")):
+							filters["voucher_detail_no"] = d.purchase_invoice_item
+						elif self.doctype == "Purchase Receipt" and d.get("purchase_receipt_item"):
+							filters["voucher_detail_no"] = d.purchase_receipt_item
+
+						original_incoming_rate = frappe.db.get_value("Stock Ledger Entry", filters, "incoming_rate")
 
 						sle.update({
 							"outgoing_rate": original_incoming_rate
diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py
index 3f127a2..a03dee1 100644
--- a/erpnext/controllers/sales_and_purchase_return.py
+++ b/erpnext/controllers/sales_and_purchase_return.py
@@ -281,6 +281,8 @@
 			target_doc.rejected_warehouse = source_doc.rejected_warehouse
 			target_doc.po_detail = source_doc.po_detail
 			target_doc.pr_detail = source_doc.pr_detail
+			target_doc.purchase_invoice_item = source_doc.name
+
 		elif doctype == "Delivery Note":
 			target_doc.against_sales_order = source_doc.against_sales_order
 			target_doc.against_sales_invoice = source_doc.against_sales_invoice
@@ -296,6 +298,7 @@
 			target_doc.so_detail = source_doc.so_detail
 			target_doc.dn_detail = source_doc.dn_detail
 			target_doc.expense_account = source_doc.expense_account
+			target_doc.sales_invoice_item = source_doc.name
 			if default_warehouse_for_sales_return:
 				target_doc.warehouse = default_warehouse_for_sales_return
 
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index b696ac3..17f3ae5 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -217,7 +217,9 @@
 							'target_warehouse': p.target_warehouse,
 							'company': self.company,
 							'voucher_type': self.doctype,
-							'allow_zero_valuation': d.allow_zero_valuation_rate
+							'allow_zero_valuation': d.allow_zero_valuation_rate,
+							'sales_invoice_item': d.get("sales_invoice_item"),
+							'delivery_note_item': d.get("dn_detail")
 						}))
 			else:
 				il.append(frappe._dict({
@@ -233,7 +235,9 @@
 					'target_warehouse': d.target_warehouse,
 					'company': self.company,
 					'voucher_type': self.doctype,
-					'allow_zero_valuation': d.allow_zero_valuation_rate
+					'allow_zero_valuation': d.allow_zero_valuation_rate,
+					'sales_invoice_item': d.get("sales_invoice_item"),
+					'delivery_note_item': d.get("dn_detail")
 				}))
 		return il
 
@@ -302,7 +306,11 @@
 					d.conversion_factor = get_conversion_factor(d.item_code, d.uom).get("conversion_factor") or 1.0
 				return_rate = 0
 				if cint(self.is_return) and self.return_against and self.docstatus==1:
-					return_rate = self.get_incoming_rate_for_return(d.item_code, self.return_against)
+					against_document_no = (d.get("sales_invoice_item")
+						if self.doctype == "Sales Invoice" else d.get("delivery_note_item"))
+
+					return_rate = self.get_incoming_rate_for_return(d.item_code,
+						self.return_against, against_document_no)
 
 				# On cancellation or if return entry submission, make stock ledger entry for
 				# target warehouse first, to update serial no values properly
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index e8483da..394883d 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -301,14 +301,19 @@
 
 		return serialized_items
 
-	def get_incoming_rate_for_return(self, item_code, against_document):
+	def get_incoming_rate_for_return(self, item_code, against_document, against_document_no=None):
 		incoming_rate = 0.0
+		cond = ''
 		if against_document and item_code:
+			if against_document_no:
+				cond = " and voucher_detail_no = %s" %(frappe.db.escape(against_document_no))
+
 			incoming_rate = frappe.db.sql("""select abs(stock_value_difference / actual_qty)
 				from `tabStock Ledger Entry`
 				where voucher_type = %s and voucher_no = %s
-					and item_code = %s limit 1""",
+					and item_code = %s {0} limit 1""".format(cond),
 				(self.doctype, against_document, item_code))
+
 			incoming_rate = incoming_rate[0][0] if incoming_rate else 0.0
 
 		return incoming_rate
diff --git a/erpnext/crm/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py
index e152850..6096053 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.py
+++ b/erpnext/crm/doctype/opportunity/opportunity.py
@@ -325,7 +325,7 @@
 		doc.save()
 
 @frappe.whitelist()
-def make_opportunity_from_communication(communication, ignore_communication_links=False):
+def make_opportunity_from_communication(communication, company, ignore_communication_links=False):
 	from erpnext.crm.doctype.lead.lead import make_lead_from_communication
 	doc = frappe.get_doc("Communication", communication)
 
@@ -337,6 +337,7 @@
 
 	opportunity = frappe.get_doc({
 		"doctype": "Opportunity",
+		"company": company,
 		"opportunity_from": opportunity_from,
 		"party_name": lead
 	}).insert(ignore_permissions=True)
diff --git a/erpnext/hr/doctype/job_offer/job_offer.py b/erpnext/hr/doctype/job_offer/job_offer.py
index 3d68bc8..c397a3f 100644
--- a/erpnext/hr/doctype/job_offer/job_offer.py
+++ b/erpnext/hr/doctype/job_offer/job_offer.py
@@ -3,6 +3,7 @@
 
 from __future__ import unicode_literals
 import frappe
+from frappe.utils import cint
 from frappe.model.document import Document
 from frappe.model.mapper import get_mapped_doc
 from frappe import _
@@ -24,8 +25,7 @@
 		check_vacancies = frappe.get_single("HR Settings").check_vacancies
 		if staffing_plan and check_vacancies:
 			job_offers = self.get_job_offer(staffing_plan.from_date, staffing_plan.to_date)
-
-			if not staffing_plan.get("vacancies") or staffing_plan.vacancies - len(job_offers) <= 0:
+			if not staffing_plan.get("vacancies") or cint(staffing_plan.vacancies) - len(job_offers) <= 0:
 				error_variable = 'for ' + frappe.bold(self.designation)
 				if staffing_plan.get("parent"):
 					error_variable = frappe.bold(get_link_to_form("Staffing Plan", staffing_plan.parent))
@@ -65,7 +65,7 @@
 			AND %s between sp.from_date and sp.to_date
 	""", (designation, company, offer_date), as_dict=1)
 
-	return frappe._dict(detail[0]) if detail else None
+	return frappe._dict(detail[0]) if (detail and detail[0].parent) else None
 
 @frappe.whitelist()
 def make_employee(source_name, target_doc=None):
diff --git a/erpnext/public/js/communication.js b/erpnext/public/js/communication.js
index 9432d42..26e5ab8 100644
--- a/erpnext/public/js/communication.js
+++ b/erpnext/public/js/communication.js
@@ -7,7 +7,7 @@
 	},
 
 	setup_custom_buttons: (frm) => {
-		let confirm_msg = "Are you sure you want to create {0} from this email";
+		let confirm_msg = "Are you sure you want to create {0} from this email?";
 		if(frm.doc.reference_doctype !== "Issue") {
 			frm.add_custom_button(__("Issue"), () => {
 				frappe.confirm(__(confirm_msg, [__("Issue")]), () => {
@@ -62,17 +62,36 @@
 	},
 
 	make_opportunity_from_communication: (frm) => {
-		return frappe.call({
-			method: "erpnext.crm.doctype.opportunity.opportunity.make_opportunity_from_communication",
-			args: {
-				communication: frm.doc.name
-			},
-			freeze: true,
-			callback: (r) => {
-				if(r.message) {
-					frm.reload_doc()
+		const fields = [{
+			fieldtype: 'Link',
+			label: __('Select a Company'),
+			fieldname: 'company',
+			options: 'Company',
+			reqd: 1,
+			default: frappe.defaults.get_user_default("Company")
+		}];
+
+		frappe.prompt(fields, data => {
+			frappe.call({
+				method: "erpnext.crm.doctype.opportunity.opportunity.make_opportunity_from_communication",
+				args: {
+					communication: frm.doc.name,
+					company: data.company
+				},
+				freeze: true,
+				callback: (r) => {
+					if(r.message) {
+						frm.reload_doc();
+						frappe.show_alert({
+							message: __("Opportunity {0} created",
+								['<a href="#Form/Opportunity/'+r.message+'">' + r.message + '</a>']),
+							indicator: 'green'
+						});
+					}
 				}
-			}
-		})
+			});
+		},
+		'Create an Opportunity',
+		'Create');
 	}
-});
\ No newline at end of file
+});
diff --git a/erpnext/public/less/products.less b/erpnext/public/less/products.less
index 79f57b3..5e744ce 100644
--- a/erpnext/public/less/products.less
+++ b/erpnext/public/less/products.less
@@ -22,6 +22,8 @@
 }
 
 .filter-options {
+	margin-left: -5px;
+	padding-left: 5px;
 	max-height: 300px;
 	overflow: auto;
 }
diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py
index 844e34b..69e47a4 100644
--- a/erpnext/regional/india/utils.py
+++ b/erpnext/regional/india/utils.py
@@ -726,9 +726,6 @@
 	if country != 'India':
 		return gl_entries
 
-	if not doc.total_taxes_and_charges:
-		return gl_entries
-
 	if doc.reverse_charge == 'Y':
 		gst_accounts = get_gst_accounts(doc.company)
 		gst_account_list = gst_accounts.get('cgst_account') + gst_accounts.get('sgst_account') \
@@ -738,6 +735,7 @@
 			if tax.category not in ("Total", "Valuation and Total"):
 				continue
 
+			dr_or_cr = "credit" if tax.add_deduct_tax == "Add" else "debit"
 			if flt(tax.base_tax_amount_after_discount_amount) and tax.account_head in gst_account_list:
 				account_currency = get_account_currency(tax.account_head)
 
@@ -747,8 +745,8 @@
 						"cost_center": tax.cost_center,
 						"posting_date": doc.posting_date,
 						"against": doc.supplier,
-						"credit": tax.base_tax_amount_after_discount_amount,
-						"credits_in_account_currency": tax.base_tax_amount_after_discount_amount \
+						dr_or_cr: tax.base_tax_amount_after_discount_amount,
+						dr_or_cr + "_in_account_currency": tax.base_tax_amount_after_discount_amount \
 							if account_currency==doc.company_currency \
 							else tax.tax_amount_after_discount_amount
 					}, account_currency, item=tax)
diff --git a/erpnext/selling/desk_page/retail/retail.json b/erpnext/selling/desk_page/retail/retail.json
index 7b30af2..581e14c 100644
--- a/erpnext/selling/desk_page/retail/retail.json
+++ b/erpnext/selling/desk_page/retail/retail.json
@@ -3,7 +3,7 @@
   {
    "hidden": 0,
    "label": "Retail Operations",
-   "links": "[\n    {\n        \"description\": \"Setup default values for POS Invoices\",\n        \"label\": \"Point-of-Sale Profile\",\n        \"name\": \"POS Profile\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"dependencies\": [\n            \"POS Profile\"\n        ],\n        \"description\": \"Point of Sale\",\n        \"label\": \"POS\",\n        \"name\": \"pos\",\n        \"onboard\": 1,\n        \"type\": \"page\"\n    },\n    {\n        \"description\": \"Cashier Closing\",\n        \"label\": \"Cashier Closing\",\n        \"name\": \"Cashier Closing\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Setup mode of POS (Online / Offline)\",\n        \"label\": \"POS Settings\",\n        \"name\": \"POS Settings\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"To make Customer based incentive schemes.\",\n        \"label\": \"Loyalty Program\",\n        \"name\": \"Loyalty Program\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"To view logs of Loyalty Points assigned to a Customer.\",\n        \"label\": \"Loyalty Point Entry\",\n        \"name\": \"Loyalty Point Entry\",\n        \"type\": \"doctype\"\n    }\n]"
+   "links": "[\n    {\n        \"description\": \"Setup default values for POS Invoices\",\n        \"label\": \"Point of Sale Profile\",\n        \"name\": \"POS Profile\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"dependencies\": [\n            \"POS Profile\"\n        ],\n        \"description\": \"Point of Sale\",\n        \"label\": \"Point of Sale\",\n        \"name\": \"point-of-sale\",\n        \"onboard\": 1,\n        \"type\": \"page\"\n    },\n    {\n        \"description\": \"Setup mode of POS (Online / Offline)\",\n        \"label\": \"POS Settings\",\n        \"name\": \"POS Settings\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Cashier Closing\",\n        \"label\": \"Cashier Closing\",\n        \"name\": \"Cashier Closing\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"To make Customer based incentive schemes.\",\n        \"label\": \"Loyalty Program\",\n        \"name\": \"Loyalty Program\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"To view logs of Loyalty Points assigned to a Customer.\",\n        \"label\": \"Loyalty Point Entry\",\n        \"name\": \"Loyalty Point Entry\",\n        \"type\": \"doctype\"\n    }\n]"
   }
  ],
  "category": "Domains",
@@ -14,10 +14,11 @@
  "docstatus": 0,
  "doctype": "Desk Page",
  "extends_another_page": 0,
+ "hide_custom": 0,
  "idx": 0,
  "is_standard": 1,
  "label": "Retail",
- "modified": "2020-04-26 22:42:39.346750",
+ "modified": "2020-08-20 18:00:07.515691",
  "modified_by": "Administrator",
  "module": "Selling",
  "name": "Retail",
@@ -25,5 +26,27 @@
  "pin_to_bottom": 0,
  "pin_to_top": 0,
  "restrict_to_domain": "Retail",
- "shortcuts": []
+ "shortcuts": [
+  {
+   "color": "#9deca2",
+   "doc_view": "",
+   "format": "{} Active",
+   "label": "Point of Sale Profile",
+   "link_to": "POS Profile",
+   "stats_filter": "{\n    \"disabled\": 0\n}",
+   "type": "DocType"
+  },
+  {
+   "doc_view": "",
+   "label": "Point of Sale",
+   "link_to": "point-of-sale",
+   "type": "Page"
+  },
+  {
+   "doc_view": "",
+   "label": "POS Settings",
+   "link_to": "POS Settings",
+   "type": "DocType"
+  }
+ ]
 }
\ No newline at end of file
diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py
index aa9fbc0..50f9d84 100644
--- a/erpnext/setup/install.py
+++ b/erpnext/setup/install.py
@@ -7,6 +7,7 @@
 from erpnext.accounts.doctype.cash_flow_mapper.default_cash_flow_mapper import DEFAULT_MAPPERS
 from .default_success_action import get_default_success_action
 from frappe import _
+from frappe.utils import cint
 from frappe.desk.page.setup_wizard.setup_wizard import add_all_roles_to
 from frappe.custom.doctype.custom_field.custom_field import create_custom_field
 from erpnext.setup.default_energy_point_rules import get_default_energy_point_rules
@@ -29,8 +30,8 @@
 
 
 def check_setup_wizard_not_completed():
-	if frappe.db.get_default('desktop:home_page') != 'setup-wizard':
-		message = """ERPNext can only be installed on a fresh site where the setup wizard is not completed. 
+	if cint(frappe.db.get_single_value('System Settings', 'setup_complete') or 0):
+		message = """ERPNext can only be installed on a fresh site where the setup wizard is not completed.
 You can reinstall this site (after saving your data) using: bench --site [sitename] reinstall"""
 		frappe.throw(message)
 
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index d97b9e8..52e5e55 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -18,6 +18,28 @@
 		set_perpetual_inventory(0)
 		frappe.db.set_value("Buying Settings", None, "allow_multiple_items", 1)
 
+	def test_reverse_purchase_receipt_sle(self):
+
+		frappe.db.set_value('UOM', '_Test UOM', 'must_be_whole_number', 0)
+
+		pr = make_purchase_receipt(qty=0.5)
+
+		sl_entry = frappe.db.get_all("Stock Ledger Entry", {"voucher_type": "Purchase Receipt",
+			"voucher_no": pr.name}, ['actual_qty'])
+
+		self.assertEqual(len(sl_entry), 1)
+		self.assertEqual(sl_entry[0].actual_qty, 0.5)
+
+		pr.cancel()
+
+		sl_entry_cancelled = frappe.db.get_all("Stock Ledger Entry", {"voucher_type": "Purchase Receipt",
+			"voucher_no": pr.name}, ['actual_qty'], order_by='creation')
+
+		self.assertEqual(len(sl_entry_cancelled), 2)
+		self.assertEqual(sl_entry_cancelled[1].actual_qty, -0.5)
+
+		frappe.db.set_value('UOM', '_Test UOM', 'must_be_whole_number', 1)
+
 	def test_make_purchase_invoice(self):
 		pr = make_purchase_receipt(do_not_save=True)
 		self.assertRaises(frappe.ValidationError, make_purchase_invoice, pr.name)
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index e1b3730..f4490f1 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -31,7 +31,7 @@
 				sle['posting_time'] = now_datetime().strftime('%H:%M:%S.%f')
 
 				if cancel:
-					sle['actual_qty'] = -flt(sle.get('actual_qty'), 0)
+					sle['actual_qty'] = -flt(sle.get('actual_qty'))
 
 					if sle['actual_qty'] < 0 and not sle.get('outgoing_rate'):
 						sle['outgoing_rate'] = get_incoming_outgoing_rate_for_cancel(sle.item_code,