Merge pull request #17998 from netchampfaris/app-logo-url

fix: App logo URL
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index 41205ae..c06856a 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -390,8 +390,8 @@
 	if filters:
 		if filters.get("project"):
 			if not isinstance(filters.get("project"), list):
-				projects = frappe.safe_encode(filters.get("project"))
-				filters.project = [d.strip() for d in projects.strip().split(',') if d]
+				filters.project = frappe.parse_json(filters.get("project"))
+
 			additional_conditions.append("project in %(project)s")
 
 		if filters.get("cost_center"):
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.js b/erpnext/accounts/report/general_ledger/general_ledger.js
index 4235b7f..5c98b24 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.js
+++ b/erpnext/accounts/report/general_ledger/general_ledger.js
@@ -72,46 +72,25 @@
 		{
 			"fieldname":"party",
 			"label": __("Party"),
-			"fieldtype": "MultiSelect",
-			get_data: function() {
+			"fieldtype": "MultiSelectList",
+			get_data: function(txt) {
 				if (!frappe.query_report.filters) return;
-				var party_type = frappe.query_report.get_filter_value('party_type');
-				var parties = frappe.query_report.get_filter_value('party');
-				if(!party_type) return;
 
-				const values = parties.split(/\s*,\s*/).filter(d => d);
-				const txt = parties.match(/[^,\s*]*$/)[0] || '';
-				let data = [];
+				let party_type = frappe.query_report.get_filter_value('party_type');
+				if (!party_type) return;
 
-				frappe.call({
-					type: "GET",
-					method:'frappe.desk.search.search_link',
-					async: false,
-					no_spinner: true,
-					args: {
-						doctype: frappe.query_report.get_filter_value('party_type'),
-						txt: txt,
-						filters: {
-							"name": ["not in", values]
-						}
-					},
-					callback: function(r) {
-						data = r.results;
-					}
-				});
-				return data;
+				return frappe.db.get_link_options(party_type, txt);
 			},
 			on_change: function() {
 				var party_type = frappe.query_report.get_filter_value('party_type');
 				var parties = frappe.query_report.get_filter_value('party');
-				const values = parties.split(/\s*,\s*/).filter(d => d);
 
-				if(!party_type || !parties || values.length>1) {
+				if(!party_type || parties.length === 0 || parties.length > 1) {
 					frappe.query_report.set_filter_value('party_name', "");
 					frappe.query_report.set_filter_value('tax_id', "");
 					return;
 				} else {
-					var party = values[0];
+					var party = parties[0];
 					var fieldname = erpnext.utils.get_party_name(party_type) || "name";
 					frappe.db.get_value(party_type, party, fieldname, function(value) {
 						frappe.query_report.set_filter_value('party_name', value[fieldname]);
@@ -154,62 +133,17 @@
 		{
 			"fieldname":"cost_center",
 			"label": __("Cost Center"),
-			"fieldtype": "MultiSelect",
-			get_data: function() {
-				var cost_centers = frappe.query_report.get_filter_value("cost_center") || "";
-
-				const values = cost_centers.split(/\s*,\s*/).filter(d => d);
-				const txt = cost_centers.match(/[^,\s*]*$/)[0] || '';
-				let data = [];
-
-				frappe.call({
-					type: "GET",
-					method:'frappe.desk.search.search_link',
-					async: false,
-					no_spinner: true,
-					args: {
-						doctype: "Cost Center",
-						txt: txt,
-						filters: {
-							"company": frappe.query_report.get_filter_value("company"),
-							"name": ["not in", values]
-						}
-					},
-					callback: function(r) {
-						data = r.results;
-					}
-				});
-				return data;
+			"fieldtype": "MultiSelectList",
+			get_data: function(txt) {
+				return frappe.db.get_link_options('Cost Center', txt);
 			}
 		},
 		{
 			"fieldname":"project",
 			"label": __("Project"),
-			"fieldtype": "MultiSelect",
-			get_data: function() {
-				var projects = frappe.query_report.get_filter_value("project") || "";
-
-				const values = projects.split(/\s*,\s*/).filter(d => d);
-				const txt = projects.match(/[^,\s*]*$/)[0] || '';
-				let data = [];
-
-				frappe.call({
-					type: "GET",
-					method:'frappe.desk.search.search_link',
-					async: false,
-					no_spinner: true,
-					args: {
-						doctype: "Project",
-						txt: txt,
-						filters: {
-							"name": ["not in", values]
-						}
-					},
-					callback: function(r) {
-						data = r.results;
-					}
-				});
-				return data;
+			"fieldtype": "MultiSelectList",
+			get_data: function(txt) {
+				return frappe.db.get_link_options('Project', txt);
 			}
 		},
 		{
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py
index d9f395b..1c5e089 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.py
+++ b/erpnext/accounts/report/general_ledger/general_ledger.py
@@ -26,8 +26,7 @@
 		account_details.setdefault(acc.name, acc)
 
 	if filters.get('party'):
-		parties = cstr(filters.get("party")).strip()
-		filters.party = [d.strip() for d in parties.split(',') if d]
+		filters.party = frappe.parse_json(filters.get("party"))
 
 	validate_filters(filters, account_details)
 
@@ -61,12 +60,10 @@
 		frappe.throw(_("From Date must be before To Date"))
 
 	if filters.get('project'):
-		projects = cstr(filters.get("project")).strip()
-		filters.project = [d.strip() for d in projects.split(',') if d]
+		filters.project = frappe.parse_json(filters.get('project'))
 
 	if filters.get('cost_center'):
-		cost_centers = cstr(filters.get("cost_center")).strip()
-		filters.cost_center = [d.strip() for d in cost_centers.split(',') if d]
+		filters.cost_center = frappe.parse_json(filters.get('cost_center'))
 
 
 def validate_party(filters):
diff --git a/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js
index 63ac281..8dc5ab3 100644
--- a/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js
+++ b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js
@@ -13,33 +13,11 @@
 
 	frappe.query_reports["Gross and Net Profit Report"]["filters"].push(
 		{
-			"fieldname":"project",
+			"fieldname": "project",
 			"label": __("Project"),
-			"fieldtype": "MultiSelect",
-			get_data: function() {
-				var projects = frappe.query_report.get_filter_value("project") || "";
-
-				const values = projects.split(/\s*,\s*/).filter(d => d);
-				const txt = projects.match(/[^,\s*]*$/)[0] || '';
-				let data = [];
-
-				frappe.call({
-					type: "GET",
-					method:'frappe.desk.search.search_link',
-					async: false,
-					no_spinner: true,
-					args: {
-						doctype: "Project",
-						txt: txt,
-						filters: {
-							"name": ["not in", values]
-						}
-					},
-					callback: function(r) {
-						data = r.results;
-					}
-				});
-				return data;
+			"fieldtype": "MultiSelectList",
+			get_data: function(txt) {
+				return frappe.db.get_link_options('Project', txt);
 			}
 		},
 		{
diff --git a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
index 250e516..df5c982 100644
--- a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
+++ b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
@@ -8,33 +8,11 @@
 
 	frappe.query_reports["Profit and Loss Statement"]["filters"].push(
 		{
-			"fieldname":"project",
+			"fieldname": "project",
 			"label": __("Project"),
-			"fieldtype": "MultiSelect",
-			get_data: function() {
-				var projects = frappe.query_report.get_filter_value("project") || "";
-
-				const values = projects.split(/\s*,\s*/).filter(d => d);
-				const txt = projects.match(/[^,\s*]*$/)[0] || '';
-				let data = [];
-
-				frappe.call({
-					type: "GET",
-					method:'frappe.desk.search.search_link',
-					async: false,
-					no_spinner: true,
-					args: {
-						doctype: "Project",
-						txt: txt,
-						filters: {
-							"name": ["not in", values]
-						}
-					},
-					callback: function(r) {
-						data = r.results;
-					}
-				});
-				return data;
+			"fieldtype": "MultiSelectList",
+			get_data: function(txt) {
+				return frappe.db.get_link_options('Project', txt);
 			}
 		},
 		{
diff --git a/erpnext/assets/doctype/location/test_location.py b/erpnext/assets/doctype/location/test_location.py
index 22d25b5..c98b0b0 100644
--- a/erpnext/assets/doctype/location/test_location.py
+++ b/erpnext/assets/doctype/location/test_location.py
@@ -25,9 +25,12 @@
 			temp['features'][0]['properties']['feature_of'] = location
 			formatted_locations.extend(temp['features'])
 
-		formatted_location_string = str(formatted_locations)
 		test_location = frappe.get_doc('Location', 'Test Location Area')
 		test_location.save()
 
-		self.assertEqual(formatted_location_string, str(json.loads(test_location.get('location'))['features']))
+		test_location_features = json.loads(test_location.get('location'))['features']
+		ordered_test_location_features = sorted(test_location_features, key=lambda x: x['properties']['feature_of'])
+		ordered_formatted_locations = sorted(formatted_locations, key=lambda x: x['properties']['feature_of'])
+
+		self.assertEqual(ordered_formatted_locations, ordered_test_location_features)
 		self.assertEqual(area, test_location.get('area'))
diff --git a/erpnext/crm/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py
index 4d45936..adac8f5 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.py
+++ b/erpnext/crm/doctype/opportunity/opportunity.py
@@ -342,7 +342,7 @@
 	elif doc.lead:
 		assign_user = frappe.db.get_value('Lead', doc.lead, 'lead_owner')
 
-	if assign_user and assign_user != 'Administrator':
+	if assign_user and assign_user not in ['Administrator', 'Guest']:
 		if not assign_to.get(dict(doctype = doc.doctype, name = doc.name)):
 			assign_to.add({
 				"assign_to": assign_user,
diff --git a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js
index e71ce12..b73dcf8 100644
--- a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js
+++ b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js
@@ -2,20 +2,8 @@
 // For license information, please see license.txt
 
 frappe.ui.form.on('Employee Benefit Application', {
-	setup: function(frm) {
-		if(!frm.doc.employee || !frm.doc.date) {
-			frappe.throw(__("Please select Employee and Date first"));
-		} else {
-			frm.set_query("earning_component", "employee_benefits", function() {
-				return {
-					query : "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_earning_components",
-					filters: {date: frm.doc.date, employee: frm.doc.employee}
-				};
-			});
-		}
-	},
-
 	employee: function(frm) {
+		frm.trigger('set_earning_component');
 		var method, args;
 		if(frm.doc.employee && frm.doc.date && frm.doc.payroll_period){
 			method = "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_max_benefits_remaining";
@@ -35,6 +23,21 @@
 			get_max_benefits(frm, method, args);
 		}
 	},
+
+	date: function(frm) {
+		frm.trigger('set_earning_component');
+	},
+
+	set_earning_component: function(frm) {
+		if(!frm.doc.employee && !frm.doc.date) return;
+		frm.set_query("earning_component", "employee_benefits", function() {
+			return {
+				query : "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_earning_components",
+				filters: {date: frm.doc.date, employee: frm.doc.employee}
+			};
+		});
+	},
+
 	payroll_period: function(frm) {
 		var method, args;
 		if(frm.doc.employee && frm.doc.date && frm.doc.payroll_period){
diff --git a/erpnext/projects/doctype/timesheet/test_timesheet.py b/erpnext/projects/doctype/timesheet/test_timesheet.py
index f117903..32f0428 100644
--- a/erpnext/projects/doctype/timesheet/test_timesheet.py
+++ b/erpnext/projects/doctype/timesheet/test_timesheet.py
@@ -103,8 +103,8 @@
 			{
 				"billable": 1,
 				"activity_type": "_Test Activity Type",
-				"from_type": now_datetime(),
-				"hours": 3,
+				"from_time": now_datetime(),
+				"to_time": now_datetime() + datetime.timedelta(hours=3),
 				"company": "_Test Company"
 			}
 		)
@@ -113,8 +113,8 @@
 			{
 				"billable": 1,
 				"activity_type": "_Test Activity Type",
-				"from_type": now_datetime(),
-				"hours": 3,
+				"from_time": now_datetime(),
+				"to_time": now_datetime() + datetime.timedelta(hours=3),
 				"company": "_Test Company"
 			}
 		)
diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js
index 7e61f03..97c823d 100644
--- a/erpnext/public/js/controllers/buying.js
+++ b/erpnext/public/js/controllers/buying.js
@@ -144,7 +144,9 @@
 			item.discount_amount = flt(item_rate) * flt(item.discount_percentage) / 100;
 		}
 
-		item.rate = flt((item.price_list_rate) - (item.discount_amount), precision('rate', item));
+		if (item.discount_amount) {
+			item.rate = flt((item.price_list_rate) - (item.discount_amount), precision('rate', item));
+		}
 
 		this.calculate_taxes_and_totals();
 	},
diff --git a/erpnext/public/js/financial_statements.js b/erpnext/public/js/financial_statements.js
index 73e04c0..d1113a4 100644
--- a/erpnext/public/js/financial_statements.js
+++ b/erpnext/public/js/financial_statements.js
@@ -118,34 +118,13 @@
 			"options": erpnext.get_presentation_currency_list()
 		},
 		{
-			"fieldname":"cost_center",
+			"fieldname": "cost_center",
 			"label": __("Cost Center"),
-			"fieldtype": "MultiSelect",
-			get_data: function() {
-				var cost_centers = frappe.query_report.get_filter_value("cost_center") || "";
-
-				const values = cost_centers.split(/\s*,\s*/).filter(d => d);
-				const txt = cost_centers.match(/[^,\s*]*$/)[0] || '';
-				let data = [];
-
-				frappe.call({
-					type: "GET",
-					method:'frappe.desk.search.search_link',
-					async: false,
-					no_spinner: true,
-					args: {
-						doctype: "Cost Center",
-						txt: txt,
-						filters: {
-							"company": frappe.query_report.get_filter_value("company"),
-							"name": ["not in", values]
-						}
-					},
-					callback: function(r) {
-						data = r.results;
-					}
+			"fieldtype": "MultiSelectList",
+			get_data: function(txt) {
+				return frappe.db.get_link_options('Cost Center', txt, {
+					company: frappe.query_report.get_filter_value("company")
 				});
-				return data;
 			}
 		}
 	]
diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py
index 9d8fa2a..3a8149d 100644
--- a/erpnext/regional/report/gstr_1/gstr_1.py
+++ b/erpnext/regional/report/gstr_1/gstr_1.py
@@ -60,11 +60,8 @@
 		else:
 			for inv, items_based_on_rate in self.items_based_on_tax_rate.items():
 				invoice_details = self.invoices.get(inv)
-				for key, items in items_based_on_rate.items():
-					rate = key[0]
-					account = key[1]
-
-					row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, account, items)
+				for rate, items in items_based_on_rate.items():
+					row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, items)
 
 					if self.filters.get("type_of_business") ==  "CDNR":
 						row.append("Y" if invoice_details.posting_date <= date(2017, 7, 1) else "N")
@@ -103,7 +100,7 @@
 		for key, value in iteritems(b2cs_output):
 			self.data.append(value)
 
-	def get_row_data_for_invoice(self, invoice, invoice_details, tax_rate, account, items):
+	def get_row_data_for_invoice(self, invoice, invoice_details, tax_rate, items):
 		row = []
 		for fieldname in self.invoice_fields:
 			if self.filters.get("type_of_business") ==  "CDNR" and fieldname == "invoice_value":
@@ -120,10 +117,8 @@
 		taxable_value = 0
 		for item_code, net_amount in self.invoice_items.get(invoice).items():
 				if item_code in items:
-					if self.item_tax_rate.get(invoice) and self.item_tax_rate.get(invoice, {}).get(item_code):
-						item_tax_rate = self.item_tax_rate.get(invoice, {}).get(item_code)
-						if account in item_tax_rate and tax_rate == item_tax_rate.get(account):
-							taxable_value += abs(net_amount)
+					if self.item_tax_rate.get(invoice) and tax_rate in self.item_tax_rate.get(invoice, {}).get(item_code):
+						taxable_value += abs(net_amount)
 					elif not self.item_tax_rate.get(invoice):
 						taxable_value += abs(net_amount)
 
@@ -214,8 +209,9 @@
 				if d.item_tax_rate:
 					item_tax_rate = json.loads(d.item_tax_rate)
 
-				if item_tax_rate:
-					self.item_tax_rate.setdefault(d.parent, {}).setdefault(d.item_code, item_tax_rate)
+					for account, rate in item_tax_rate.items():
+						tax_rate_dict = self.item_tax_rate.setdefault(d.parent, {}).setdefault(d.item_code, [])
+						tax_rate_dict.append(rate)
 
 	def get_items_based_on_tax_rate(self):
 		self.tax_details = frappe.db.sql("""
@@ -255,7 +251,7 @@
 								tax_rate *= 2
 
 							rate_based_dict = self.items_based_on_tax_rate\
-								.setdefault(parent, {}).setdefault((tax_rate, account), [])
+								.setdefault(parent, {}).setdefault(tax_rate, [])
 							if item_code not in rate_based_dict:
 								rate_based_dict.append(item_code)
 					except ValueError:
diff --git a/erpnext/regional/report/gstr_2/gstr_2.py b/erpnext/regional/report/gstr_2/gstr_2.py
index d9cab63..a362269 100644
--- a/erpnext/regional/report/gstr_2/gstr_2.py
+++ b/erpnext/regional/report/gstr_2/gstr_2.py
@@ -43,11 +43,8 @@
 		self.get_igst_invoices()
 		for inv, items_based_on_rate in self.items_based_on_tax_rate.items():
 			invoice_details = self.invoices.get(inv)
-			for key, items in items_based_on_rate.items():
-				rate = key[0]
-				account = key[1]
-
-				row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, account, items)
+			for rate, items in items_based_on_rate.items():
+				row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, items)
 				tax_amount = taxable_value * rate / 100
 				if inv in self.igst_invoices:
 					row += [tax_amount, 0, 0]
diff --git a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js
index dcb81cb..dfdf9dc 100644
--- a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js
+++ b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js
@@ -29,7 +29,20 @@
 			"placeholder":"Company GSTIN",
 			"options": [""],
 			"width": "80"
-		}
+		},
+		{
+			"fieldname":"from_date",
+			"label": __("From Date"),
+			"fieldtype": "Date",
+			"width": "80"
+		},
+		{
+			"fieldname":"to_date",
+			"label": __("To Date"),
+			"fieldtype": "Date",
+			"width": "80"
+		},
+
 	],
 	onload: (report) => {
 		fetch_gstins(report);
diff --git a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py
index e938e29..222dfa1 100644
--- a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py
+++ b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py
@@ -88,7 +88,9 @@
 
 	for opts in (("company", " and company=%(company)s"),
 		("gst_hsn_code", " and gst_hsn_code=%(gst_hsn_code)s"),
-		("company_gstin", " and company_gstin=%(company_gstin)s")):
+		("company_gstin", " and company_gstin=%(company_gstin)s"),
+		("from_date", " and posting_date >= %(from_date)s"),
+		("to_date", "and posting_date <= %(to_date)s")):
 			if filters.get(opts[0]):
 				conditions += opts[1]
 
diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.py b/erpnext/stock/doctype/delivery_trip/delivery_trip.py
index 01b4734..bc8c749 100644
--- a/erpnext/stock/doctype/delivery_trip/delivery_trip.py
+++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.py
@@ -20,8 +20,7 @@
 		# Google Maps returns distances in meters by default
 		self.default_distance_uom = frappe.db.get_single_value("Global Defaults", "default_distance_unit") or "Meter"
 		self.uom_conversion_factor = frappe.db.get_value("UOM Conversion Factor",
-														{"from_uom": "Meter", "to_uom": self.default_distance_uom},
-														"value")
+			{"from_uom": "Meter", "to_uom": self.default_distance_uom}, "value")
 
 	def validate(self):
 		self.validate_stop_addresses()
@@ -139,7 +138,7 @@
 				# Include last leg in the final distance calculation
 				self.uom = self.default_distance_uom
 				total_distance = sum([leg.get("distance", {}).get("value", 0.0)
-											for leg in directions.get("legs")])  # in meters
+					for leg in directions.get("legs")])  # in meters
 				self.total_distance = total_distance * self.uom_conversion_factor
 			else:
 				idx += len(route) - 1
@@ -358,8 +357,12 @@
 	email_recipients = []
 
 	for stop in delivery_trip.delivery_stops:
-		contact_info = frappe.db.get_value("Contact", stop.contact,
-											["first_name", "last_name", "email_id", "gender"], as_dict=1)
+		contact_info = frappe.db.get_value("Contact", stop.contact, ["first_name", "last_name", "email_id"], as_dict=1)
+
+		context.update({"items": []})
+		if stop.delivery_note:
+			items = frappe.get_all("Delivery Note Item", filters={"parent": stop.delivery_note, "docstatus": 1}, fields=["*"])
+			context.update({"items": items})
 
 		if contact_info and contact_info.email_id:
 			context.update(stop.as_dict())
@@ -369,9 +372,9 @@
 			dispatch_template = frappe.get_doc("Email Template", dispatch_template_name)
 
 			frappe.sendmail(recipients=contact_info.email_id,
-							subject=dispatch_template.subject,
-							message=frappe.render_template(dispatch_template.response, context),
-							attachments=get_attachments(stop))
+				subject=dispatch_template.subject,
+				message=frappe.render_template(dispatch_template.response, context),
+				attachments=get_attachments(stop))
 
 			stop.db_set("email_sent_to", contact_info.email_id)
 			email_recipients.append(contact_info.email_id)
@@ -388,9 +391,7 @@
 		return []
 
 	dispatch_attachment = frappe.db.get_single_value("Delivery Settings", "dispatch_attachment")
-	attachments = frappe.attach_print("Delivery Note",
-										delivery_stop.delivery_note,
-										file_name="Delivery Note",
-										print_format=dispatch_attachment)
+	attachments = frappe.attach_print("Delivery Note", delivery_stop.delivery_note,
+		file_name="Delivery Note", print_format=dispatch_attachment)
 
 	return [attachments]
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 4869335..1a88473 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -67,8 +67,6 @@
 				from frappe.model.naming import set_name_by_naming_series
 				set_name_by_naming_series(self)
 				self.item_code = self.name
-		elif not self.item_code:
-			msgprint(_("Item Code is mandatory because Item is not automatically numbered"), raise_exception=1)
 
 		self.item_code = strip(self.item_code)
 		self.name = self.item_code