Merge pull request #21280 from anupamvs/opportunity-calendar

Adding Opportunity Calendar View
diff --git a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
index b6f5396..fa4d40e 100644
--- a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
+++ b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
@@ -164,7 +164,7 @@
 	error_messages = []
 
 	for i in data:
-		account_name, _, account_number, is_group, account_type, root_type = i
+		account_name, dummy, account_number, is_group, account_type, root_type = i
 
 		if not account_name:
 			error_messages.append("Row {0}: Please enter Account Name".format(line_no))
diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py
index 2ffa27f..100bb1d 100644
--- a/erpnext/accounts/doctype/pricing_rule/utils.py
+++ b/erpnext/accounts/doctype/pricing_rule/utils.py
@@ -178,7 +178,8 @@
 
 		if pricing_rules[0].mixed_conditions and doc:
 			stock_qty, amount, items = get_qty_and_rate_for_mixed_conditions(doc, pr_doc, args)
-			pricing_rules[0].apply_rule_on_other_items = items
+			for pricing_rule_args in pricing_rules:
+				pricing_rule_args.apply_rule_on_other_items = items
 
 		elif pricing_rules[0].is_cumulative:
 			items = [args.get(frappe.scrub(pr_doc.get('apply_on')))]
@@ -329,9 +330,9 @@
 			if pr_doc.mixed_conditions:
 				amt = args.get('qty') * args.get("price_list_rate")
 				if args.get("item_code") != row.get("item_code"):
-					amt = row.get('qty') * row.get("price_list_rate")
+					amt = row.get('qty') * (row.get("price_list_rate") or args.get("rate"))
 
-				sum_qty += row.get("stock_qty") or args.get("stock_qty")
+				sum_qty += row.get("stock_qty") or args.get("stock_qty") or args.get("qty")
 				sum_amt += amt
 
 		if pr_doc.is_cumulative:
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 9c97426..db3f72a 100644
--- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
+++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
@@ -754,8 +754,7 @@
   {
    "fieldname": "manufacturer_part_no",
    "fieldtype": "Data",
-   "label": "Manufacturer Part Number",
-   "read_only": 1
+   "label": "Manufacturer Part Number"
   },
   {
    "depends_on": "is_fixed_asset",
@@ -777,7 +776,7 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2020-04-01 14:20:17.297284",
+ "modified": "2020-04-07 18:34:35.104178",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Purchase Invoice Item",
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index 4cfeb25..47dfa09 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -162,8 +162,9 @@
 def set_price_list(party_details, party, party_type, given_price_list, pos=None):
 	# price list
 	price_list = get_permitted_documents('Price List')
-
-	if price_list:
+	
+	# if there is only one permitted document based on user permissions, set it
+	if price_list and len(price_list) == 1:
 		price_list = price_list[0]
 	elif pos and party_type == 'Customer':
 		customer_price_list = frappe.get_value('Customer', party.name, 'default_price_list')
@@ -635,4 +636,4 @@
 		except:
 			return None
 	else:
-		return None
\ No newline at end of file
+		return None
diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
index 6768dfa..e37e1dd 100644
--- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
+++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
@@ -702,8 +702,7 @@
   {
    "fieldname": "manufacturer_part_no",
    "fieldtype": "Data",
-   "label": "Manufacturer Part Number",
-   "read_only": 1
+   "label": "Manufacturer Part Number"
   },
   {
    "default": "0",
@@ -723,7 +722,7 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2019-12-06 13:17:12.142799",
+ "modified": "2020-04-07 18:35:17.558928",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Purchase Order Item",
diff --git a/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json b/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json
index 7d7d6f4..b50e834 100644
--- a/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json
+++ b/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json
@@ -1,4 +1,5 @@
 {
+ "actions": [],
  "autoname": "hash",
  "creation": "2013-05-22 12:43:10",
  "doctype": "DocType",
@@ -522,8 +523,7 @@
   {
    "fieldname": "manufacturer_part_no",
    "fieldtype": "Data",
-   "label": "Manufacturer Part Number",
-   "read_only": 1
+   "label": "Manufacturer Part Number"
   },
   {
    "fieldname": "column_break_15",
@@ -532,7 +532,8 @@
  ],
  "idx": 1,
  "istable": 1,
- "modified": "2019-06-02 05:32:46.019237",
+ "links": [],
+ "modified": "2020-04-07 18:35:51.175947",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Supplier Quotation Item",
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index 95e661a..4e568e2 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -667,8 +667,7 @@
 			itemised_tax=itemised_tax,
 			itemised_taxable_amount=itemised_taxable_amount,
 			tax_accounts=tax_accounts,
-			conversion_rate=doc.conversion_rate,
-			currency=doc.currency
+			doc=doc
 		)
 	)
 
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 2f07e15..6b6d1e2 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -347,6 +347,8 @@
 
 payment_gateway_enabled = "erpnext.accounts.utils.create_payment_gateway_account"
 
+communication_doctypes = ["Customer", "Supplier"]
+
 regional_overrides = {
 	'France': {
 		'erpnext.tests.test_regional.test_method': 'erpnext.regional.france.utils.test_method'
diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py
index afd52de..c441751 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.py
+++ b/erpnext/hr/doctype/leave_application/leave_application.py
@@ -580,19 +580,22 @@
 	return leave_days
 
 def skip_expiry_leaves(leave_entry, date):
-	''' Checks whether the expired leaves coincide with the to_date of leave balance check '''
+	''' Checks whether the expired leaves coincide with the to_date of leave balance check.
+		This allows backdated leave entry creation for non carry forwarded allocation '''
 	end_date = frappe.db.get_value("Leave Allocation", {'name': leave_entry.transaction_name}, ['to_date'])
 	return True if end_date == date and not leave_entry.is_carry_forward else False
 
 def get_leave_entries(employee, leave_type, from_date, to_date):
-	''' Returns leave entries between from_date and to_date '''
+	''' Returns leave entries between from_date and to_date. '''
 	return frappe.db.sql("""
 		SELECT
 			employee, leave_type, from_date, to_date, leaves, transaction_name, transaction_type,
 			is_carry_forward, is_expired
 		FROM `tabLeave Ledger Entry`
 		WHERE employee=%(employee)s AND leave_type=%(leave_type)s
-			AND docstatus=1 AND leaves<0
+			AND docstatus=1 
+			AND (leaves<0
+				OR is_expired=1)
 			AND (from_date between %(from_date)s AND %(to_date)s
 				OR to_date between %(from_date)s AND %(to_date)s
 				OR (from_date < %(from_date)s AND to_date > %(to_date)s))
diff --git a/erpnext/hr/doctype/leave_encashment/leave_encashment.py b/erpnext/hr/doctype/leave_encashment/leave_encashment.py
index ad2cc02..7d6fd42 100644
--- a/erpnext/hr/doctype/leave_encashment/leave_encashment.py
+++ b/erpnext/hr/doctype/leave_encashment/leave_encashment.py
@@ -8,7 +8,6 @@
 from frappe.model.document import Document
 from frappe.utils import getdate, nowdate, flt
 from erpnext.hr.utils import set_employee_name
-from erpnext.hr.doctype.leave_application.leave_application import get_leave_balance_on
 from erpnext.hr.doctype.salary_structure_assignment.salary_structure_assignment import get_assigned_salary_structure
 from erpnext.hr.doctype.leave_ledger_entry.leave_ledger_entry import create_leave_ledger_entry
 from erpnext.hr.doctype.leave_allocation.leave_allocation import get_unused_leaves
diff --git a/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.py b/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.py
index bfc6d95..9ed58c9 100644
--- a/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.py
+++ b/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.py
@@ -141,6 +141,7 @@
 	leaves = get_remaining_leaves(allocation)
 	expiry_date = expiry_date if expiry_date else allocation.to_date
 
+	# allows expired leaves entry to be created/reverted
 	if leaves:
 		args = dict(
 			leaves=flt(leaves) * -1,
@@ -160,6 +161,8 @@
 	from erpnext.hr.doctype.leave_application.leave_application import get_leaves_for_period
 	leaves_taken = get_leaves_for_period(allocation.employee, allocation.leave_type, allocation.from_date, allocation.to_date)
 	leaves = flt(allocation.leaves) + flt(leaves_taken)
+
+	# allow expired leaves entry to be created
 	if leaves > 0:
 		args = frappe._dict(
 			transaction_name=allocation.name,
diff --git a/erpnext/loan_management/doctype/loan_disbursement/test_loan_disbursement.py b/erpnext/loan_management/doctype/loan_disbursement/test_loan_disbursement.py
index 189b2f5..0c1578f 100644
--- a/erpnext/loan_management/doctype/loan_disbursement/test_loan_disbursement.py
+++ b/erpnext/loan_management/doctype/loan_disbursement/test_loan_disbursement.py
@@ -58,18 +58,16 @@
 
 		process_loan_interest_accrual_for_demand_loans(posting_date=add_days(last_date, 1))
 
-		# Paid 511095.89 amount includes 5,00,000 principal amount and 11095.89 interest amount
+		# Should not be able to create loan disbursement entry before repayment
+		self.assertRaises(frappe.ValidationError, make_loan_disbursement_entry, loan.name,
+			500000, first_date)
+
 		repayment_entry = create_repayment_entry(loan.name, self.applicant, add_days(get_last_day(nowdate()), 5),
 			"Regular Payment", 611095.89)
-		repayment_entry.submit()
 
+		repayment_entry.submit()
 		loan.reload()
 
+		# After repayment loan disbursement entry should go through
 		make_loan_disbursement_entry(loan.name, 500000, disbursement_date=add_days(last_date, 16))
 
-		total_principal_paid = loan.total_principal_paid
-
-		loan.reload()
-
-		# Loan Topup will result in decreasing the Total Principal Paid
-		self.assertEqual(flt(loan.total_principal_paid, 2), flt(total_principal_paid - 500000, 2))
diff --git a/erpnext/loan_management/doctype/loan_type/loan_type.json b/erpnext/loan_management/doctype/loan_type/loan_type.json
index a3525db..51c5cb9 100644
--- a/erpnext/loan_management/doctype/loan_type/loan_type.json
+++ b/erpnext/loan_management/doctype/loan_type/loan_type.json
@@ -119,6 +119,7 @@
    "label": "Penalty Interest Rate (%) Per Day"
   },
   {
+   "description": "No. of days from due date until which penalty won't be charged in case of delay in loan repayment",
    "fieldname": "grace_period_in_days",
    "fieldtype": "Int",
    "label": "Grace Period in Days"
@@ -142,7 +143,7 @@
  ],
  "is_submittable": 1,
  "links": [],
- "modified": "2020-02-03 05:03:00.334813",
+ "modified": "2020-04-15 00:24:43.259963",
  "modified_by": "Administrator",
  "module": "Loan Management",
  "name": "Loan Type",
diff --git a/erpnext/patches/v12_0/update_healthcare_refactored_changes.py b/erpnext/patches/v12_0/update_healthcare_refactored_changes.py
index 02378e0..d06c571 100644
--- a/erpnext/patches/v12_0/update_healthcare_refactored_changes.py
+++ b/erpnext/patches/v12_0/update_healthcare_refactored_changes.py
@@ -100,7 +100,7 @@
 
 		for entry in encounter_details:
 			doc = frappe.get_doc('Patient Encounter', entry.name)
-			symptoms = entry.symptoms.split('\n')
+			symptoms = entry.symptoms.split('\n') if entry.symptoms else []
 			for symptom in symptoms:
 				if not frappe.db.exists('Complaint', symptom):
 					frappe.get_doc({
@@ -112,7 +112,7 @@
 				})
 				row.db_update()
 
-			diagnosis = entry.diagnosis.split('\n')
+			diagnosis = entry.diagnosis.split('\n') if entry.diagnosis else []
 			for d in diagnosis:
 				if not frappe.db.exists('Diagnosis', d):
 					frappe.get_doc({
diff --git a/erpnext/projects/doctype/project/project.json b/erpnext/projects/doctype/project/project.json
index 7d47db3..49abab1 100644
--- a/erpnext/projects/doctype/project/project.json
+++ b/erpnext/projects/doctype/project/project.json
@@ -1,4 +1,5 @@
 {
+ "actions": [],
  "allow_import": 1,
  "allow_rename": 1,
  "autoname": "field:project_name",
@@ -435,16 +436,18 @@
   },
   {
    "depends_on": "collect_progress",
-   "description": "Message will sent to users to get their status on the project",
+   "description": "Message will be sent to the users to get their status on the Project",
    "fieldname": "message",
    "fieldtype": "Text",
-   "label": "Message"
+   "label": "Message",
+   "mandatory_depends_on": "collect_progress"
   }
  ],
  "icon": "fa fa-puzzle-piece",
  "idx": 29,
+ "links": [],
  "max_attachments": 4,
- "modified": "2019-09-24 15:02:50.208301",
+ "modified": "2020-04-08 22:11:14.552615",
  "modified_by": "Administrator",
  "module": "Projects",
  "name": "Project",
@@ -487,4 +490,4 @@
  "sort_order": "DESC",
  "timeline_field": "customer",
  "track_seen": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js
index 27a9de9..afbdbc6 100644
--- a/erpnext/public/js/controllers/buying.js
+++ b/erpnext/public/js/controllers/buying.js
@@ -379,7 +379,31 @@
 				}
 			});
 		}
-	}
+	},
+
+	manufacturer_part_no: function(doc, cdt, cdn) {
+		const row = locals[cdt][cdn];
+
+		if (row.manufacturer_part_no) {
+			frappe.model.get_value('Item Manufacturer',
+				{
+					'item_code': row.item_code,
+					'manufacturer': row.manufacturer,
+					'manufacturer_part_no': row.manufacturer_part_no
+				},
+				'name',
+				function(data) {
+					if (!data) {
+						let msg = {
+							message: __("Manufacturer Part Number <b>{0}</b> is invalid", [row.manufacturer_part_no]),
+							title: __("Invalid Part Number")
+						}
+						frappe.throw(msg);
+					}
+				});
+
+			}
+		}
 });
 
 cur_frm.add_fetch('project', 'cost_center', 'cost_center');
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 0c63c33..8e8c48f 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -559,7 +559,13 @@
 									}
 								},
 								() => me.conversion_factor(doc, cdt, cdn, true),
-								() => me.remove_pricing_rule(item)
+								() => me.remove_pricing_rule(item),
+								() => {
+									if (item.apply_rule_on_other_items) {
+										let key = item.name;
+										me.apply_rule_on_other_items({key: item});
+									}
+								}
 							]);
 						}
 					}
@@ -1394,20 +1400,22 @@
 
 	apply_rule_on_other_items: function(args) {
 		const me = this;
-		const fields = ["discount_percentage", "discount_amount", "rate"];
+		const fields = ["discount_percentage", "pricing_rules", "discount_amount", "rate"];
 
 		for(var k in args) {
 			let data = args[k];
 
-			me.frm.doc.items.forEach(d => {
-				if (in_list(data.apply_rule_on_other_items, d[data.apply_rule_on])) {
-					for(var k in data) {
-						if (in_list(fields, k)) {
-							frappe.model.set_value(d.doctype, d.name, k, data[k]);
+			if (data && data.apply_rule_on_other_items) {
+				me.frm.doc.items.forEach(d => {
+					if (in_list(data.apply_rule_on_other_items, d[data.apply_rule_on])) {
+						for(var k in data) {
+							if (in_list(fields, k) && data[k]) {
+								frappe.model.set_value(d.doctype, d.name, k, data[k]);
+							}
 						}
 					}
-				}
-			});
+				});
+			}
 		}
 	},
 
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index 02667e8..50e719f 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -150,7 +150,7 @@
 						contact.save()
 
 			else:
-				lead.lead_name = lead.lead_name.split(" ")
+				lead.lead_name = lead.lead_name.lstrip().split(" ")
 				lead.first_name = lead.lead_name[0]
 				lead.last_name = " ".join(lead.lead_name[1:])
 
diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.js b/erpnext/selling/page/point_of_sale/point_of_sale.js
index df48783..f175687 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.js
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.js
@@ -1176,7 +1176,7 @@
 
 		return `
 			<div class="list-item indicator ${indicator_class}" data-item-code="${escape(item.item_code)}"
-				data-batch-no="${batch_no}" title="Item: ${item.item_name}  Available Qty: ${item.actual_qty}">
+				data-batch-no="${batch_no}" title="Item: ${item.item_name}  Available Qty: ${item.actual_qty} ${item.stock_uom}">
 				<div class="item-name list-item__content list-item__content--flex-1.5 ellipsis">
 					${item.item_name}
 				</div>
diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.py b/erpnext/selling/page/point_of_sale/point_of_sale.py
index 17136e0..dfa0f7f 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.py
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.py
@@ -37,20 +37,33 @@
 	lft, rgt = frappe.db.get_value('Item Group', item_group, ['lft', 'rgt'])
 	# locate function is used to sort by closest match from the beginning of the value
 
-
 	result = []
 
-	items_data = frappe.db.sql(""" SELECT name as item_code,
-			item_name, image as item_image, idx as idx,is_stock_item
+	items_data = frappe.db.sql("""
+		SELECT
+			name AS item_code,
+			item_name,
+			stock_uom,
+			image AS item_image,
+			idx AS idx,
+			is_stock_item
 		FROM
 			`tabItem`
 		WHERE
-			disabled = 0 and has_variants = 0 and is_sales_item = 1
-			and item_group in (select name from `tabItem Group` where lft >= {lft} and rgt <= {rgt})
-			and {condition} order by idx desc limit {start}, {page_length}"""
+			disabled = 0
+				AND has_variants = 0
+				AND is_sales_item = 1
+				AND item_group in (SELECT name FROM `tabItem Group` WHERE lft >= {lft} AND rgt <= {rgt})
+				AND {condition}
+		ORDER BY
+			idx desc
+		LIMIT
+			{start}, {page_length}"""
 		.format(
-			start=start, page_length=page_length,
-			lft=lft, rgt=rgt,
+			start=start,
+			page_length=page_length,
+			lft=lft,
+			rgt=rgt,
 			condition=condition
 		), as_dict=1)
 
diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json
index aa6b2fe..7d2e311 100644
--- a/erpnext/stock/doctype/item/item.json
+++ b/erpnext/stock/doctype/item/item.json
@@ -114,6 +114,8 @@
   "is_sub_contracted_item",
   "column_break_74",
   "customer_code",
+  "default_item_manufacturer",
+  "default_manufacturer_part_no",
   "website_section",
   "show_in_website",
   "show_variant_in_website",
@@ -1038,6 +1040,18 @@
    "fieldname": "auto_create_assets",
    "fieldtype": "Check",
    "label": "Auto Create Assets on Purchase"
+  },
+  {
+   "fieldname": "default_item_manufacturer",
+   "fieldtype": "Data",
+   "label": "Default Item Manufacturer",
+   "read_only": 1
+  },
+  {
+   "fieldname": "default_manufacturer_part_no",
+   "fieldtype": "Data",
+   "label": "Default Manufacturer Part No",
+   "read_only": 1
   }
  ],
  "has_web_view": 1,
@@ -1046,7 +1060,7 @@
  "image_field": "image",
  "links": [],
  "max_attachments": 1,
- "modified": "2020-03-24 16:14:36.950677",
+ "modified": "2020-04-07 15:56:06.195722",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Item",
diff --git a/erpnext/stock/doctype/item_manufacturer/item_manufacturer.json b/erpnext/stock/doctype/item_manufacturer/item_manufacturer.json
index 956c92e..0cef6ea 100644
--- a/erpnext/stock/doctype/item_manufacturer/item_manufacturer.json
+++ b/erpnext/stock/doctype/item_manufacturer/item_manufacturer.json
@@ -1,4 +1,5 @@
 {
+ "actions": [],
  "allow_import": 1,
  "creation": "2019-06-02 04:41:37.332911",
  "doctype": "DocType",
@@ -10,7 +11,8 @@
   "manufacturer_part_no",
   "column_break_3",
   "item_name",
-  "description"
+  "description",
+  "is_default"
  ],
  "fields": [
   {
@@ -52,9 +54,17 @@
    "fieldtype": "Small Text",
    "label": "Description",
    "read_only": 1
+  },
+  {
+   "default": "0",
+   "fieldname": "is_default",
+   "fieldtype": "Check",
+   "in_list_view": 1,
+   "label": "Is Default"
   }
  ],
- "modified": "2019-06-06 19:07:31.175919",
+ "links": [],
+ "modified": "2020-04-07 20:25:55.507905",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Item Manufacturer",
diff --git a/erpnext/stock/doctype/item_manufacturer/item_manufacturer.py b/erpnext/stock/doctype/item_manufacturer/item_manufacturer.py
index 67eab82..c27d1be 100644
--- a/erpnext/stock/doctype/item_manufacturer/item_manufacturer.py
+++ b/erpnext/stock/doctype/item_manufacturer/item_manufacturer.py
@@ -11,6 +11,10 @@
 class ItemManufacturer(Document):
 	def validate(self):
 		self.validate_duplicate_entry()
+		self.manage_default_item_manufacturer()
+
+	def on_trash(self):
+		self.manage_default_item_manufacturer(delete=True)
 
 	def validate_duplicate_entry(self):
 		if self.is_new():
@@ -24,6 +28,40 @@
 				frappe.throw(_("Duplicate entry against the item code {0} and manufacturer {1}")
 					.format(self.item_code, self.manufacturer))
 
+	def manage_default_item_manufacturer(self, delete=False):
+		from frappe.model.utils import set_default
+
+		item = frappe.get_doc("Item", self.item_code)
+		default_manufacturer = item.default_item_manufacturer
+		default_part_no = item.default_manufacturer_part_no
+
+		if not self.is_default:
+			# if unchecked and default in Item master, clear it.
+			if default_manufacturer == self.manufacturer and default_part_no == self.manufacturer_part_no:
+				frappe.db.set_value("Item", item.name,
+					{
+						"default_item_manufacturer": None,
+						"default_manufacturer_part_no": None
+					})
+
+		elif self.is_default:
+			set_default(self, "item_code")
+			manufacturer, manufacturer_part_no = default_manufacturer, default_part_no
+
+			if delete:
+				manufacturer, manufacturer_part_no = None, None
+
+			elif (default_manufacturer != self.manufacturer) or \
+				(default_manufacturer == self.manufacturer and default_part_no != self.manufacturer_part_no):
+				manufacturer = self.manufacturer
+				manufacturer_part_no = self.manufacturer_part_no
+
+			frappe.db.set_value("Item", item.name,
+					{
+						"default_item_manufacturer": manufacturer,
+						"default_manufacturer_part_no": manufacturer_part_no
+					})
+
 @frappe.whitelist()
 def get_item_manufacturer_part_no(item_code, manufacturer):
 	return frappe.db.get_value("Item Manufacturer",
diff --git a/erpnext/stock/doctype/material_request_item/material_request_item.json b/erpnext/stock/doctype/material_request_item/material_request_item.json
index 9d1dafb..30206b6 100644
--- a/erpnext/stock/doctype/material_request_item/material_request_item.json
+++ b/erpnext/stock/doctype/material_request_item/material_request_item.json
@@ -404,14 +404,13 @@
   {
    "fieldname": "manufacturer_part_no",
    "fieldtype": "Data",
-   "label": "Manufacturer Part Number",
-   "read_only": 1
+   "label": "Manufacturer Part Number"
   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2020-02-25 03:09:10.698967",
+ "modified": "2020-04-07 18:37:54.495112",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Material Request Item",
diff --git a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
index a8b9c81..b15f23c 100644
--- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
+++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
@@ -801,8 +801,7 @@
   {
    "fieldname": "manufacturer_part_no",
    "fieldtype": "Data",
-   "label": "Manufacturer Part Number",
-   "read_only": 1
+   "label": "Manufacturer Part Number"
   },
   {
    "depends_on": "is_fixed_asset",
@@ -832,7 +831,7 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2020-03-11 14:19:48.799370",
+ "modified": "2020-04-07 18:38:21.141558",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Purchase Receipt Item",
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index b1bfc90..61429cc 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -341,6 +341,9 @@
 		else:
 			out["manufacturer_part_no"] = None
 			out["manufacturer"] = None
+	else:
+		out["manufacturer"], out["manufacturer_part_no"] = frappe.get_value("Item", item.name,
+			["default_item_manufacturer", "default_manufacturer_part_no"] )
 
 	child_doctype = args.doctype + ' Item'
 	meta = frappe.get_meta(child_doctype)
diff --git a/erpnext/templates/includes/itemised_tax_breakup.html b/erpnext/templates/includes/itemised_tax_breakup.html
index c27e4ce..c2f1353 100644
--- a/erpnext/templates/includes/itemised_tax_breakup.html
+++ b/erpnext/templates/includes/itemised_tax_breakup.html
@@ -16,7 +16,11 @@
 				<tr>
 					<td>{{ item }}</td>
 					<td class='text-right'>
-						{{ frappe.utils.fmt_money(itemised_taxable_amount.get(item, 0), None, currency) }}
+						{% if doc.get('is_return') %}
+							{{ frappe.utils.fmt_money((itemised_taxable_amount.get(item, 0))|abs, None, doc.currency) }}
+						{% else %}
+							{{ frappe.utils.fmt_money(itemised_taxable_amount.get(item, 0), None, doc.currency) }}
+						{% endif %}
 					</td>
 					{% for tax_account in tax_accounts %}
 						{% set tax_details = taxes.get(tax_account) %}
@@ -25,7 +29,11 @@
 								{% if tax_details.tax_rate or not tax_details.tax_amount %}
 									({{ tax_details.tax_rate }}%)
 								{% endif %}
-								{{ frappe.utils.fmt_money(tax_details.tax_amount / conversion_rate, None, currency) }}
+								{% if doc.get('is_return') %}
+									{{ frappe.utils.fmt_money((tax_details.tax_amount / doc.conversion_rate)|abs, None, doc.currency) }}
+								{% else %}
+									{{ frappe.utils.fmt_money(tax_details.tax_amount / doc.conversion_rate, None, doc.currency) }}
+								{% endif %}
 							</td>
 						{% else %}
 							<td></td>