Merge pull request #3640 from anandpdoshi/anand-july-13

Fixes to Issues
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 7a43823..9ef50d1 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,5 +1,9 @@
 # Contributing to Frappe / ERPNext
 
+## Questions
+
+If you have questions on how to use ERPNext or want help in customization or debugging of your scripts, please post on https://discuss.frappe.io. This is only for bug reports and feature requests.
+
 ## Reporting issues
 
 We only accept issues that are bug reports or feature requests. Bugs must be isolated and reproducible problems. Please read the following guidelines before opening any issue.
diff --git a/erpnext/__version__.py b/erpnext/__version__.py
index 2c86e6c..ef61354 100644
--- a/erpnext/__version__.py
+++ b/erpnext/__version__.py
@@ -1,2 +1,2 @@
 from __future__ import unicode_literals
-__version__ = '5.1.4'
+__version__ = '5.1.6'
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index 3bb9aa0..5b2f348 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -369,15 +369,15 @@
 }
 
 cur_frm.cscript.income_account = function(doc, cdt, cdn) {
-	cur_frm.cscript.copy_account_in_all_row(doc, cdt, cdn, "income_account");
+	erpnext.utils.copy_value_in_all_row(doc, cdt, cdn, "items", "income_account");
 }
 
 cur_frm.cscript.expense_account = function(doc, cdt, cdn) {
-	cur_frm.cscript.copy_account_in_all_row(doc, cdt, cdn, "expense_account");
+	erpnext.utils.copy_value_in_all_row(doc, cdt, cdn, "items", "expense_account");
 }
 
 cur_frm.cscript.cost_center = function(doc, cdt, cdn) {
-	cur_frm.cscript.copy_account_in_all_row(doc, cdt, cdn, "cost_center");
+	erpnext.utils.copy_value_in_all_row(doc, cdt, cdn, "items", "cost_center");
 }
 
 cur_frm.cscript.on_submit = function(doc, cdt, cdn) {
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index 809e352..25dd398 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -322,9 +322,9 @@
    "read_only": 0
   }, 
   {
-   "fieldname": "sales_bom_help", 
+   "fieldname": "product_bundle_help", 
    "fieldtype": "HTML", 
-   "label": "Sales BOM Help", 
+   "label": "Product Bundle Help", 
    "permlevel": 0, 
    "print_hide": 1, 
    "read_only": 0
@@ -1252,7 +1252,7 @@
  ], 
  "icon": "icon-file-text", 
  "idx": 1, 
- "is_submittable": 1, 
+ "is_submittable": 1,
  "modified": "2015-07-09 17:33:28.583808", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index 5de43a0..250286c 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -74,9 +74,17 @@
 		{party_type.lower(): party.name, "is_primary_contact":1}, "name")
 
 	if not out.contact_person:
-		return
-
-	out.update(get_contact_details(out.contact_person))
+		out.update({
+			"contact_person": None,
+			"contact_display": None,
+			"contact_email": None,
+			"contact_mobile": None,
+			"contact_phone": None,
+			"contact_designation": None,
+			"contact_department": None
+		})
+	else:
+		out.update(get_contact_details(out.contact_person))
 
 def set_other_values(out, party, party_type):
 	# copy
diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py
index 9b68810..8153912 100644
--- a/erpnext/accounts/report/gross_profit/gross_profit.py
+++ b/erpnext/accounts/report/gross_profit/gross_profit.py
@@ -86,23 +86,23 @@
 		self.filters = frappe._dict(filters)
 		self.load_invoice_items()
 		self.load_stock_ledger_entries()
-		self.load_sales_bom()
+		self.load_product_bundle()
 		self.load_non_stock_items()
 		self.process()
 
 	def process(self):
 		self.grouped = {}
 		for row in self.si_list:
-			if self.skip_row(row, self.sales_boms):
+			if self.skip_row(row, self.product_bundles):
 				continue
 
 			row.base_amount = flt(row.base_net_amount)
 
-			sales_boms = self.sales_boms.get(row.parenttype, {}).get(row.parent, frappe._dict())
+			product_bundles = self.product_bundles.get(row.parenttype, {}).get(row.parent, frappe._dict())
 
 			# get buying amount
-			if row.item_code in sales_boms:
-				row.buying_amount = self.get_buying_amount_from_sales_bom(row, sales_boms[row.item_code])
+			if row.item_code in product_bundles:
+				row.buying_amount = self.get_buying_amount_from_product_bundle(row, product_bundles[row.item_code])
 			else:
 				row.buying_amount = self.get_buying_amount(row, row.item_code)
 
@@ -152,13 +152,13 @@
 
 			self.grouped_data.append(new_row)
 
-	def skip_row(self, row, sales_boms):
+	def skip_row(self, row, product_bundles):
 		if self.filters.get("group_by") != "Invoice" and not row.get(scrub(self.filters.get("group_by"))):
 			return True
 
-	def get_buying_amount_from_sales_bom(self, row, sales_bom):
+	def get_buying_amount_from_product_bundle(self, row, product_bundle):
 		buying_amount = 0.0
-		for bom_item in sales_bom:
+		for bom_item in product_bundle:
 			if bom_item.get("parent_detail_docname")==row.item_row:
 				buying_amount += self.get_buying_amount(row, bom_item.item_code)
 
@@ -246,13 +246,13 @@
 
 			self.sle[(r.item_code, r.warehouse)].append(r)
 
-	def load_sales_bom(self):
-		self.sales_boms = {}
+	def load_product_bundle(self):
+		self.product_bundles = {}
 
 		for d in frappe.db.sql("""select parenttype, parent, parent_item,
 			item_code, warehouse, -1*qty as total_qty, parent_detail_docname
 			from `tabPacked Item` where docstatus=1""", as_dict=True):
-			self.sales_boms.setdefault(d.parenttype, frappe._dict()).setdefault(d.parent,
+			self.product_bundles.setdefault(d.parenttype, frappe._dict()).setdefault(d.parent,
 				frappe._dict()).setdefault(d.parent_item, []).append(d)
 
 	def load_non_stock_items(self):
diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.js b/erpnext/buying/doctype/purchase_common/purchase_common.js
index 6e27401..1b7d20a 100644
--- a/erpnext/buying/doctype/purchase_common/purchase_common.js
+++ b/erpnext/buying/doctype/purchase_common/purchase_common.js
@@ -70,10 +70,6 @@
 		erpnext.utils.get_address_display(this.frm);
 	},
 
-	contact_person: function() {
-		erpnext.utils.get_contact_details(this.frm);
-	},
-
 	buying_price_list: function() {
 		this.apply_price_list();
 	},
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index c4c28e4..20edbca 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -249,7 +249,7 @@
 
 
 cur_frm.cscript.schedule_date = function(doc, cdt, cdn) {
-	cur_frm.cscript.copy_account_in_all_row(doc, cdt, cdn, "schedule_date");
+	erpnext.utils.copy_value_in_all_row(doc, cdt, cdn, "items", "schedule_date");
 }
 
 frappe.provide("erpnext.buying");
diff --git a/erpnext/change_log/v5/v5_1_5.md b/erpnext/change_log/v5/v5_1_5.md
new file mode 100644
index 0000000..9ebe28b
--- /dev/null
+++ b/erpnext/change_log/v5/v5_1_5.md
@@ -0,0 +1,8 @@
+- Customer's credit days based on fixed days / last day of the next month **[Sponsored by McLean Images](http://www.mcleans.net.au)**
+- Production Order is not allowed against Item Template (for Variants)
+- Currency symbol fixed for outstanding amount and advance amount field in Sales Invoice
+- A Contact can be linked to Customer, Supplier and Sales partner at the same time
+- Validation added to prevent task being closed with open dependent tasks
+- Blocked stock transactions against an expired batch
+- Added Employees in Newsletter List
+- Link Address to Customer / Supplier / Lead, based on logged-in user, if created in portal
diff --git a/erpnext/config/hr.py b/erpnext/config/hr.py
index 2e60061..72fe8dd 100644
--- a/erpnext/config/hr.py
+++ b/erpnext/config/hr.py
@@ -60,7 +60,7 @@
 			"items": [
 				{
 					"type": "doctype",
-					"name": "Salary Manager",
+					"name": "Process Payroll",
 					"label": _("Process Payroll"),
 					"description":_("Generate Salary Slips"),
 					"hide_count": True
diff --git a/erpnext/config/selling.py b/erpnext/config/selling.py
index 78c73d8..5433964 100644
--- a/erpnext/config/selling.py
+++ b/erpnext/config/selling.py
@@ -144,7 +144,7 @@
 				},
 				{
 					"type": "doctype",
-					"name": "Sales BOM",
+					"name": "Product Bundle",
 					"description": _("Bundle items at time of sale."),
 				},
 				{
diff --git a/erpnext/config/stock.py b/erpnext/config/stock.py
index 70bb258..f4ec6f0 100644
--- a/erpnext/config/stock.py
+++ b/erpnext/config/stock.py
@@ -83,6 +83,11 @@
 					"name": "Stock UOM Replace Utility",
 					"description": _("Change UOM for an Item."),
 				},
+				{
+					"type": "doctype",
+					"name": "Manage Variants",
+					"description": _("Manage Item Variants."),
+				},
 			]
 		},
 		{
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index 9a2da96..c709326 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -172,7 +172,7 @@
 
 			if self.doctype == "Sales Order":
 				if (frappe.db.get_value("Item", d.item_code, "is_stock_item") == 'Yes' or
-					self.has_sales_bom(d.item_code)) and not d.warehouse:
+					self.has_product_bundle(d.item_code)) and not d.warehouse:
 						frappe.throw(_("Reserved Warehouse required for stock Item {0} in row {1}").format(d.item_code, d.idx))
 				reserved_warehouse = d.warehouse
 				if flt(d.qty) > flt(d.delivered_qty):
@@ -191,7 +191,7 @@
 				else:
 					reserved_qty_for_main_item = -flt(d.qty)
 
-			if self.has_sales_bom(d.item_code):
+			if self.has_product_bundle(d.item_code):
 				for p in self.get("packed_items"):
 					if p.parent_detail_docname == d.name and p.parent_item == d.item_code:
 						# the packing details table's qty is already multiplied with parent's qty
@@ -221,8 +221,8 @@
 				}))
 		return il
 
-	def has_sales_bom(self, item_code):
-		return frappe.db.sql("""select name from `tabSales BOM`
+	def has_product_bundle(self, item_code):
+		return frappe.db.sql("""select name from `tabProduct Bundle`
 			where new_item_code=%s and docstatus != 2""", item_code)
 
 	def get_already_delivered_qty(self, dn, so, so_detail):
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index ef1afa3..30032f8 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -5,7 +5,7 @@
 app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations"
 app_icon = "icon-th"
 app_color = "#e74c3c"
-app_version = "5.1.4"
+app_version = "5.1.6"
 
 error_report_email = "support@erpnext.com"
 
diff --git a/erpnext/hr/doctype/process_payroll/__init__.py b/erpnext/hr/doctype/process_payroll/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hr/doctype/process_payroll/__init__.py
diff --git a/erpnext/hr/doctype/salary_manager/salary_manager.js b/erpnext/hr/doctype/process_payroll/process_payroll.js
similarity index 95%
rename from erpnext/hr/doctype/salary_manager/salary_manager.js
rename to erpnext/hr/doctype/process_payroll/process_payroll.js
index ca70226..d882349 100644
--- a/erpnext/hr/doctype/salary_manager/salary_manager.js
+++ b/erpnext/hr/doctype/process_payroll/process_payroll.js
@@ -59,6 +59,6 @@
 }
 
 
-frappe.ui.form.on("Salary Manager", "refresh", function(frm) {
+frappe.ui.form.on("Process Payroll", "refresh", function(frm) {
 	frm.disable_save();
 });
diff --git a/erpnext/hr/doctype/salary_manager/salary_manager.json b/erpnext/hr/doctype/process_payroll/process_payroll.json
similarity index 97%
rename from erpnext/hr/doctype/salary_manager/salary_manager.json
rename to erpnext/hr/doctype/process_payroll/process_payroll.json
index 93ee138..36e858c 100644
--- a/erpnext/hr/doctype/salary_manager/salary_manager.json
+++ b/erpnext/hr/doctype/process_payroll/process_payroll.json
@@ -154,10 +154,10 @@
  "icon": "icon-cog", 
  "idx": 1, 
  "issingle": 1, 
- "modified": "2015-06-05 11:33:00.152362", 
+ "modified": "2015-07-07 07:16:02.380839", 
  "modified_by": "Administrator", 
  "module": "HR", 
- "name": "Salary Manager", 
+ "name": "Process Payroll", 
  "owner": "Administrator", 
  "permissions": [
   {
diff --git a/erpnext/hr/doctype/salary_manager/salary_manager.py b/erpnext/hr/doctype/process_payroll/process_payroll.py
similarity index 98%
rename from erpnext/hr/doctype/salary_manager/salary_manager.py
rename to erpnext/hr/doctype/process_payroll/process_payroll.py
index 3e0b53e..4900bd0 100644
--- a/erpnext/hr/doctype/salary_manager/salary_manager.py
+++ b/erpnext/hr/doctype/process_payroll/process_payroll.py
@@ -8,7 +8,7 @@
 
 from frappe.model.document import Document
 
-class SalaryManager(Document):
+class ProcessPayroll(Document):
 
 	def get_emp_list(self):
 		"""
diff --git a/erpnext/hr/doctype/salary_manager/README.md b/erpnext/hr/doctype/salary_manager/README.md
deleted file mode 100644
index 040d038..0000000
--- a/erpnext/hr/doctype/salary_manager/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Tool to issue monthly Salary Slips to all Employees.
\ No newline at end of file
diff --git a/erpnext/hr/doctype/salary_manager/__init__.py b/erpnext/hr/doctype/salary_manager/__init__.py
deleted file mode 100644
index f24df48..0000000
--- a/erpnext/hr/doctype/salary_manager/__init__.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# ERPNext - web based ERP (http://erpnext.com)
-# Copyright (C) 2012 Frappe Technologies Pvt Ltd
-# 
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-# 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-from __future__ import unicode_literals
-from frappe import ValidationError
-
-class SalarySlipExistsError(ValidationError): pass
-
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py
index dd54490..24079c1 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -49,7 +49,7 @@
 		if not self.month:
 			self.month = "%02d" % getdate(nowdate()).month
 
-		m = frappe.get_doc('Salary Manager').get_month_details(self.fiscal_year, self.month)
+		m = frappe.get_doc('Process Payroll').get_month_details(self.fiscal_year, self.month)
 		holidays = self.get_holidays_for_employee(m)
 
 		if not cint(frappe.db.get_value("HR Settings", "HR Settings",
diff --git a/erpnext/hr/doctype/salary_slip_deduction/salary_slip_deduction.json b/erpnext/hr/doctype/salary_slip_deduction/salary_slip_deduction.json
index 4b4e59c..b8079f3 100644
--- a/erpnext/hr/doctype/salary_slip_deduction/salary_slip_deduction.json
+++ b/erpnext/hr/doctype/salary_slip_deduction/salary_slip_deduction.json
@@ -31,7 +31,7 @@
    "fieldname": "d_depends_on_lwp", 
    "fieldtype": "Check", 
    "in_list_view": 0, 
-   "label": "Depends on LWP", 
+   "label": "Depends on Leave Without Pay", 
    "permlevel": 0, 
    "print_hide": 1
   }, 
@@ -46,7 +46,7 @@
  ], 
  "idx": 1, 
  "istable": 1, 
- "modified": "2015-03-03 12:41:04.505378", 
+ "modified": "2015-07-07 07:13:11.919941", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Salary Slip Deduction", 
diff --git a/erpnext/hr/doctype/salary_slip_earning/salary_slip_earning.json b/erpnext/hr/doctype/salary_slip_earning/salary_slip_earning.json
index 4359905..a0804e2 100644
--- a/erpnext/hr/doctype/salary_slip_earning/salary_slip_earning.json
+++ b/erpnext/hr/doctype/salary_slip_earning/salary_slip_earning.json
@@ -31,7 +31,7 @@
    "fieldname": "e_depends_on_lwp", 
    "fieldtype": "Check", 
    "in_list_view": 0, 
-   "label": "Depends on LWP", 
+   "label": "Depends on Leave Without Pay", 
    "permlevel": 0, 
    "print_hide": 1
   }, 
@@ -46,7 +46,7 @@
  ], 
  "idx": 1, 
  "istable": 1, 
- "modified": "2015-03-03 12:42:49.087748", 
+ "modified": "2015-07-07 07:13:24.833881", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Salary Slip Earning", 
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.js b/erpnext/manufacturing/doctype/production_order/production_order.js
index 6d16cd4..17fa202 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.js
+++ b/erpnext/manufacturing/doctype/production_order/production_order.js
@@ -186,15 +186,26 @@
 	},
 
 	bom_no: function() {
-		return this.frm.call({
-			doc: this.frm.doc,
-			method: "set_production_order_operations"
-		});
+		if (this.frm.doc.track_operations) {
+			return this.frm.call({
+				doc: this.frm.doc,
+				method: "set_production_order_operations"
+			});
+		}
 	},
 	
 	qty: function() {
 		frappe.ui.form.trigger("Production Order", 'bom_no')
 	},
+	
+	track_operations: function(doc) {
+		if (doc.track_operations) {
+			frappe.ui.form.trigger("Production Order", 'bom_no')
+		}
+		else {
+			doc.operations =[];
+		}
+	},
 
 	show_time_logs: function(doc, cdt, cdn) {
 		var child = locals[cdt][cdn]
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.json b/erpnext/manufacturing/doctype/production_order/production_order.json
index 07cc5c6..ccf3f68 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.json
+++ b/erpnext/manufacturing/doctype/production_order/production_order.json
@@ -74,6 +74,14 @@
    "permlevel": 0
   }, 
   {
+   "default": "1", 
+   "fieldname": "track_operations", 
+   "fieldtype": "Check", 
+   "label": "Track Operations", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
    "fieldname": "column_break1", 
    "fieldtype": "Column Break", 
    "oldfieldtype": "Column Break", 
@@ -207,7 +215,7 @@
    "read_only": 1
   }, 
   {
-   "depends_on": "", 
+   "depends_on": "track_operations", 
    "fieldname": "operations_section", 
    "fieldtype": "Section Break", 
    "label": "Operations", 
@@ -216,6 +224,7 @@
    "precision": ""
   }, 
   {
+   "depends_on": "", 
    "fieldname": "operations", 
    "fieldtype": "Table", 
    "label": "Operations", 
@@ -225,6 +234,7 @@
    "read_only": 1
   }, 
   {
+   "depends_on": "track_operations", 
    "fieldname": "section_break_22", 
    "fieldtype": "Section Break", 
    "label": "Operation Cost", 
@@ -358,7 +368,7 @@
  "idx": 1, 
  "in_create": 0, 
  "is_submittable": 1, 
- "modified": "2015-04-13 02:44:17.319988", 
+ "modified": "2015-07-09 03:31:01.291811", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "Production Order", 
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index 0f805d0..26af40a 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -174,13 +174,17 @@
 
 	def set_production_order_operations(self):
 		"""Fetch operations from BOM and set in 'Production Order'"""
-
+		if not self.bom_no:
+			return
 		self.set('operations', [])
-
 		operations = frappe.db.sql("""select operation, description, workstation, idx,
 			hour_rate, time_in_mins, "Pending" as status from `tabBOM Operation`
 			where parent = %s order by idx""", self.bom_no, as_dict=1)
-
+		if operations:
+			self.track_operations=1
+		else:
+			self.track_operations=0
+			frappe.msgprint(_("Cannot 'track operations' as selected BOM does not have Operations."))
 		self.set('operations', operations)
 		self.calculate_time()
 
@@ -219,14 +223,12 @@
 		for i, d in enumerate(self.operations):
 			self.set_operation_start_end_time(i, d)
 
-			if not d.workstation:
-				continue
-
 			time_log = make_time_log(self.name, d.operation, d.planned_start_time, d.planned_end_time,
 				flt(self.qty) - flt(d.completed_qty), self.project_name, d.workstation, operation_id=d.name)
 
-			# validate operating hours if workstation [not mandatory] is specified
-			self.check_operation_fits_in_working_hours(d)
+			if d.workstation:
+				# validate operating hours if workstation [not mandatory] is specified
+				self.check_operation_fits_in_working_hours(d)
 
 			original_start_time = time_log.from_time
 			while True:
@@ -315,7 +317,7 @@
 	def validate_delivery_date(self):
 		if self.planned_start_date and self.expected_delivery_date \
 			and getdate(self.expected_delivery_date) < getdate(self.planned_start_date):
-				frappe.throw(_("Expected Delivery Date must be greater than Planned Start Date."))
+				frappe.msgprint(_("Expected Delivery Date is lesser than Planned Start Date."))
 
 	def delete_time_logs(self):
 		for time_log in frappe.get_all("Time Log", ["name"], {"production_order": self.name}):
@@ -391,7 +393,7 @@
 	return data
 
 @frappe.whitelist()
-def make_time_log(name, operation, from_time, to_time, qty=None,  project=None, workstation=None, operation_id=None):
+def make_time_log(name, operation, from_time=None, to_time=None, qty=None,  project=None, workstation=None, operation_id=None):
 	time_log =  frappe.new_doc("Time Log")
 	time_log.for_manufacturing = 1
 	time_log.from_time = from_time
diff --git a/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json b/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json
index 7134938..2c56569 100644
--- a/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json
+++ b/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json
@@ -43,6 +43,15 @@
    "width": "100px"
   }, 
   {
+   "default": "", 
+   "fieldname": "planned_start_date", 
+   "fieldtype": "Datetime", 
+   "label": "Planned Start Date", 
+   "permlevel": 0, 
+   "precision": "", 
+   "reqd": 1
+  }, 
+  {
    "fieldname": "sales_order", 
    "fieldtype": "Link", 
    "in_list_view": 1, 
@@ -104,7 +113,7 @@
  ], 
  "idx": 1, 
  "istable": 1, 
- "modified": "2015-02-19 01:07:00.936590", 
+ "modified": "2015-07-08 07:12:11.211808", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "Production Plan Item", 
diff --git a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js
index 4f77132..f3b918d 100644
--- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js
+++ b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js
@@ -1,6 +1,8 @@
 // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
+frappe.require("assets/erpnext/js/utils.js");
+
 cur_frm.cscript.onload = function(doc, cdt, cdn) {
 	cur_frm.set_value("company", frappe.defaults.get_user_default("company"))
 	cur_frm.set_value("use_multi_level_bom", 1)
@@ -72,3 +74,7 @@
 
 cur_frm.fields_dict.sales_orders.grid.get_field("customer").get_query =
 	cur_frm.fields_dict.customer.get_query;
+
+cur_frm.cscript.planned_start_date = function(doc, cdt, cdn) {
+	erpnext.utils.copy_value_in_all_row(doc, cdt, cdn, "items", "planned_start_date");
+}
diff --git a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py
index f5c951f..86a14d8 100644
--- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py
+++ b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py
@@ -3,7 +3,7 @@
 
 from __future__ import unicode_literals
 import frappe
-from frappe.utils import cstr, flt, cint, nowdate, now, add_days, comma_and
+from frappe.utils import cstr, flt, cint, nowdate, add_days, comma_and
 
 from frappe import msgprint, _
 
@@ -211,8 +211,6 @@
 		for key in items:
 			pro = frappe.new_doc("Production Order")
 			pro.update(items[key])
-
-			pro.planned_start_date = now()
 			pro.set_production_order_operations()
 
 			frappe.flags.mute_messages = True
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index f3282f7..26c1d7b 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -171,4 +171,7 @@
 erpnext.patches.v5_0.item_variants
 erpnext.patches.v5_0.update_item_desc_in_invoice
 erpnext.patches.v5_1.fix_against_account
-erpnext.patches.v5_1.fix_credit_days_based_on
\ No newline at end of file
+erpnext.patches.v5_1.fix_credit_days_based_on
+erpnext.patches.v5_1.track_operations
+erpnext.patches.v5_1.sales_bom_rename
+execute:frappe.rename_doc("DocType", "Salary Manager", "Process Payroll", force=True)
diff --git a/erpnext/patches/v5_1/sales_bom_rename.py b/erpnext/patches/v5_1/sales_bom_rename.py
new file mode 100644
index 0000000..e06012f
--- /dev/null
+++ b/erpnext/patches/v5_1/sales_bom_rename.py
@@ -0,0 +1,12 @@
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+	tables = frappe.db.sql_list("show tables")
+	for old_dt, new_dt in [["Sales BOM Item", "Product Bundle Item"],
+		["Sales BOM", "Product Bundle"]]:
+			if "tab"+new_dt not in tables:
+				frappe.rename_doc("DocType", old_dt, new_dt, force=True)
diff --git a/erpnext/patches/v5_1/track_operations.py b/erpnext/patches/v5_1/track_operations.py
new file mode 100644
index 0000000..0a12142
--- /dev/null
+++ b/erpnext/patches/v5_1/track_operations.py
@@ -0,0 +1,8 @@
+from __future__ import unicode_literals
+
+import frappe
+
+def execute():
+	frappe.reload_doctype("Production Order")
+	frappe.db.sql("""Update `tabProduction Order` as po set track_operations=1 where 
+		exists(select name from `tabProduction Order Operation` as po_operation where po_operation.parent = po.name )""")
\ No newline at end of file
diff --git a/erpnext/projects/doctype/time_log/time_log_calendar.js b/erpnext/projects/doctype/time_log/time_log_calendar.js
index 3ed092a..61229d6 100644
--- a/erpnext/projects/doctype/time_log/time_log_calendar.js
+++ b/erpnext/projects/doctype/time_log/time_log_calendar.js
@@ -17,6 +17,12 @@
 			"options": "Workstation",
 			"label": __("Workstation")
 		},
+		{
+			"fieldtype": "Link",
+			"fieldname": "employee",
+			"options": "Employee",
+			"label": __("Employee")
+		},
 	],
 	get_events_method: "erpnext.projects.doctype.time_log.time_log.get_events"
-}
\ No newline at end of file
+}
diff --git a/erpnext/public/js/controllers/stock_controller.js b/erpnext/public/js/controllers/stock_controller.js
index 1d62b3a..c5cad95 100644
--- a/erpnext/public/js/controllers/stock_controller.js
+++ b/erpnext/public/js/controllers/stock_controller.js
@@ -70,16 +70,5 @@
 				frappe.set_route("query-report", "General Ledger");
 			}, "icon-table");
 		}
-	},
-
-	copy_account_in_all_row: function(doc, dt, dn, fieldname) {
-		var d = locals[dt][dn];
-		if(d[fieldname]){
-			var cl = doc["items"] || [];
-			for(var i = 0; i < cl.length; i++) {
-				if(!cl[i][fieldname]) cl[i][fieldname] = d[fieldname];
-			}
-		}
-		refresh_field("items");
 	}
 });
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 953800d..0a75dad 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -282,6 +282,10 @@
 	get_company_currency: function() {
 		return erpnext.get_currency(this.frm.doc.company);
 	},
+	
+	contact_person: function() {
+		erpnext.utils.get_contact_details(this.frm);
+	},
 
 	currency: function() {
 		var me = this;
diff --git a/erpnext/public/js/feature_setup.js b/erpnext/public/js/feature_setup.js
index 664da66..d43ffc5 100644
--- a/erpnext/public/js/feature_setup.js
+++ b/erpnext/public/js/feature_setup.js
@@ -46,7 +46,7 @@
 		'Purchase Invoice': {'items':['brand']},
 		'Quotation': {'items':['brand']},
 		'Sales Invoice': {'items':['brand']},
-		'Sales BOM': {'fields':['new_item_brand']},
+		'Product Bundle': {'fields':['new_item_brand']},
 		'Sales Order': {'items':['brand']},
 		'Serial No': {'fields':['brand']}
 	},
@@ -95,7 +95,7 @@
 		'Purchase Voucher': {'items':['item_group']},
 		'Quotation': {'items':['item_group']},
 		'Sales Invoice': {'items':['item_group']},
-		'Sales BOM': {'fields':['serial_no']},
+		'Product Bundle': {'fields':['serial_no']},
 		'Sales Order': {'items':['item_group']},
 		'Serial No': {'fields':['item_group']},
 		'Sales Partner': {'targets':['item_group']},
@@ -129,7 +129,7 @@
 				'base_total', 'base_net_total', 'base_discount_amount', 'base_total_taxes_and_charges'],
 			'items': ['base_price_list_rate','base_amount','base_rate', 'base_net_rate', 'base_net_amount']
 		},
-		'Sales BOM': {'fields':['currency']},
+		'Product Bundle': {'fields':['currency']},
 		'Sales Order': {
 			'fields': ['conversion_rate','currency','base_grand_total','base_in_words','base_rounded_total',
 				'base_total', 'base_net_total', 'base_discount_amount', 'base_total_taxes_and_charges'],
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index dc74a3a..5b38559 100644
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -131,6 +131,17 @@
 				}
 			);
 		}
+	}, 
+	
+	copy_value_in_all_row: function(doc, dt, dn, table_fieldname, fieldname) {
+		var d = locals[dt][dn];
+		if(d[fieldname]){
+			var cl = doc[table_fieldname] || [];
+			for(var i = 0; i < cl.length; i++) {
+				if(!cl[i][fieldname]) cl[i][fieldname] = d[fieldname];
+			}
+		}
+		refresh_field(table_fieldname);
 	}
 });
 
diff --git a/erpnext/selling/doctype/product_bundle/__init__.py b/erpnext/selling/doctype/product_bundle/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/selling/doctype/product_bundle/__init__.py
diff --git a/erpnext/selling/doctype/sales_bom/sales_bom.js b/erpnext/selling/doctype/product_bundle/product_bundle.js
similarity index 82%
rename from erpnext/selling/doctype/sales_bom/sales_bom.js
rename to erpnext/selling/doctype/product_bundle/product_bundle.js
index 0b64a5f..2849be5 100644
--- a/erpnext/selling/doctype/sales_bom/sales_bom.js
+++ b/erpnext/selling/doctype/product_bundle/product_bundle.js
@@ -7,10 +7,10 @@
 
 cur_frm.fields_dict.new_item_code.get_query = function() {
 	return{
-		query: "erpnext.selling.doctype.sales_bom.sales_bom.get_new_item_code"
+		query: "erpnext.selling.doctype.product_bundle.product_bundle.get_new_item_code"
 	}
 }
-cur_frm.fields_dict.new_item_code.query_description = __('Please select Item where "Is Stock Item" is "No" and "Is Sales Item" is "Yes" and there is no other Sales BOM');
+cur_frm.fields_dict.new_item_code.query_description = __('Please select Item where "Is Stock Item" is "No" and "Is Sales Item" is "Yes" and there is no other Product Bundle');
 
 cur_frm.cscript.item_code = function(doc, dt, dn) {
 	var d = locals[dt][dn];
diff --git a/erpnext/selling/doctype/sales_bom/sales_bom.json b/erpnext/selling/doctype/product_bundle/product_bundle.json
similarity index 91%
rename from erpnext/selling/doctype/sales_bom/sales_bom.json
rename to erpnext/selling/doctype/product_bundle/product_bundle.json
index bf366f7..c998b23 100644
--- a/erpnext/selling/doctype/sales_bom/sales_bom.json
+++ b/erpnext/selling/doctype/product_bundle/product_bundle.json
@@ -1,7 +1,7 @@
 {
  "allow_import": 1, 
  "creation": "2013-06-20 11:53:21", 
- "description": "Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**. \n\nThe package **Item** will have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\".\n\nFor Example: If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Sales BOM Item.\n\nNote: BOM = Bill of Materials", 
+ "description": "Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**. \n\nThe package **Item** will have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\".\n\nFor Example: If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Product Bundle Item.\n\nNote: BOM = Bill of Materials", 
  "docstatus": 0, 
  "doctype": "DocType", 
  "document_type": "Master", 
@@ -38,7 +38,7 @@
    "label": "Items", 
    "oldfieldname": "sales_bom_items", 
    "oldfieldtype": "Table", 
-   "options": "Sales BOM Item", 
+   "options": "Product Bundle Item", 
    "permlevel": 0, 
    "reqd": 1
   }
@@ -46,10 +46,10 @@
  "icon": "icon-sitemap", 
  "idx": 1, 
  "is_submittable": 0, 
- "modified": "2015-02-20 05:05:03.719573", 
+ "modified": "2015-07-06 06:11:10.534423", 
  "modified_by": "Administrator", 
  "module": "Selling", 
- "name": "Sales BOM", 
+ "name": "Product Bundle", 
  "owner": "Administrator", 
  "permissions": [
   {
diff --git a/erpnext/selling/doctype/sales_bom/sales_bom.py b/erpnext/selling/doctype/product_bundle/product_bundle.py
similarity index 92%
rename from erpnext/selling/doctype/sales_bom/sales_bom.py
rename to erpnext/selling/doctype/product_bundle/product_bundle.py
index ddb955f..796b4b4 100644
--- a/erpnext/selling/doctype/sales_bom/sales_bom.py
+++ b/erpnext/selling/doctype/product_bundle/product_bundle.py
@@ -8,9 +8,7 @@
 
 from frappe.model.document import Document
 
-class SalesBOM(Document):
-
-
+class ProductBundle(Document):
 	def autoname(self):
 		self.name = self.new_item_code
 
@@ -39,7 +37,7 @@
 
 	return frappe.db.sql("""select name, item_name, description from tabItem
 		where is_stock_item="No" and is_sales_item="Yes"
-		and name not in (select name from `tabSales BOM`) and %s like %s
+		and name not in (select name from `tabProduct Bundle`) and %s like %s
 		%s limit %s, %s""" % (searchfield, "%s",
 		get_match_cond(doctype),"%s", "%s"),
 		("%%%s%%" % txt, start, page_len))
diff --git a/erpnext/selling/doctype/sales_bom/test_sales_bom.py b/erpnext/selling/doctype/product_bundle/test_product_bundle.py
similarity index 75%
rename from erpnext/selling/doctype/sales_bom/test_sales_bom.py
rename to erpnext/selling/doctype/product_bundle/test_product_bundle.py
index ad9e22b..8c5fe12 100644
--- a/erpnext/selling/doctype/sales_bom/test_sales_bom.py
+++ b/erpnext/selling/doctype/product_bundle/test_product_bundle.py
@@ -1,7 +1,8 @@
+
 # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 from __future__ import unicode_literals
 
 
 import frappe
-test_records = frappe.get_test_records('Sales BOM')
+test_records = frappe.get_test_records('Product Bundle')
\ No newline at end of file
diff --git a/erpnext/selling/doctype/product_bundle/test_records.json b/erpnext/selling/doctype/product_bundle/test_records.json
new file mode 100644
index 0000000..b92892f
--- /dev/null
+++ b/erpnext/selling/doctype/product_bundle/test_records.json
@@ -0,0 +1,20 @@
+[
+ {
+  "doctype": "Product Bundle", 
+  "new_item_code": "_Test Product Bundle Item", 
+  "items": [
+   {
+    "doctype": "Product Bundle Item", 
+    "item_code": "_Test Item", 
+    "parentfield": "items", 
+    "qty": 5.0
+   }, 
+   {
+    "doctype": "Product Bundle Item", 
+    "item_code": "_Test Item Home Desktop 100", 
+    "parentfield": "items", 
+    "qty": 2.0
+   }
+  ]
+ }
+]
\ No newline at end of file
diff --git a/erpnext/selling/doctype/product_bundle_item/__init__.py b/erpnext/selling/doctype/product_bundle_item/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/selling/doctype/product_bundle_item/__init__.py
diff --git a/erpnext/selling/doctype/sales_bom_item/sales_bom_item.json b/erpnext/selling/doctype/product_bundle_item/product_bundle_item.json
similarity index 88%
rename from erpnext/selling/doctype/sales_bom_item/sales_bom_item.json
rename to erpnext/selling/doctype/product_bundle_item/product_bundle_item.json
index c48debd..d219125 100644
--- a/erpnext/selling/doctype/sales_bom_item/sales_bom_item.json
+++ b/erpnext/selling/doctype/product_bundle_item/product_bundle_item.json
@@ -1,5 +1,5 @@
 {
- "creation": "2013-05-23 16:55:51.000000", 
+ "creation": "2013-05-23 16:55:51", 
  "docstatus": 0, 
  "doctype": "DocType", 
  "fields": [
@@ -60,9 +60,10 @@
  ], 
  "idx": 1, 
  "istable": 1, 
- "modified": "2013-12-20 19:21:38.000000", 
+ "modified": "2015-07-06 06:05:18.854360", 
  "modified_by": "Administrator", 
  "module": "Selling", 
- "name": "Sales BOM Item", 
- "owner": "Administrator"
+ "name": "Product Bundle Item", 
+ "owner": "Administrator", 
+ "permissions": []
 }
\ No newline at end of file
diff --git a/erpnext/selling/doctype/product_bundle_item/product_bundle_item.py b/erpnext/selling/doctype/product_bundle_item/product_bundle_item.py
new file mode 100644
index 0000000..8721bfa
--- /dev/null
+++ b/erpnext/selling/doctype/product_bundle_item/product_bundle_item.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class ProductBundleItem(Document):
+	pass
diff --git a/erpnext/selling/doctype/quotation/test_quotation.py b/erpnext/selling/doctype/quotation/test_quotation.py
index 7496429..3f30d05 100644
--- a/erpnext/selling/doctype/quotation/test_quotation.py
+++ b/erpnext/selling/doctype/quotation/test_quotation.py
@@ -6,7 +6,7 @@
 from frappe.utils import flt
 import unittest
 
-test_dependencies = ["Sales BOM"]
+test_dependencies = ["Product Bundle"]
 
 class TestQuotation(unittest.TestCase):
 	def test_make_sales_order(self):
diff --git a/erpnext/selling/doctype/sales_bom/__init__.py b/erpnext/selling/doctype/sales_bom/__init__.py
deleted file mode 100644
index baffc48..0000000
--- a/erpnext/selling/doctype/sales_bom/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from __future__ import unicode_literals
diff --git a/erpnext/selling/doctype/sales_bom/test_records.json b/erpnext/selling/doctype/sales_bom/test_records.json
deleted file mode 100644
index a19bc1a..0000000
--- a/erpnext/selling/doctype/sales_bom/test_records.json
+++ /dev/null
@@ -1,20 +0,0 @@
-[
- {
-  "doctype": "Sales BOM", 
-  "new_item_code": "_Test Sales BOM Item", 
-  "items": [
-   {
-    "doctype": "Sales BOM Item", 
-    "item_code": "_Test Item", 
-    "parentfield": "items", 
-    "qty": 5.0
-   }, 
-   {
-    "doctype": "Sales BOM Item", 
-    "item_code": "_Test Item Home Desktop 100", 
-    "parentfield": "items", 
-    "qty": 2.0
-   }
-  ]
- }
-]
\ No newline at end of file
diff --git a/erpnext/selling/doctype/sales_bom_item/__init__.py b/erpnext/selling/doctype/sales_bom_item/__init__.py
deleted file mode 100644
index baffc48..0000000
--- a/erpnext/selling/doctype/sales_bom_item/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from __future__ import unicode_literals
diff --git a/erpnext/selling/doctype/sales_bom_item/sales_bom_item.py b/erpnext/selling/doctype/sales_bom_item/sales_bom_item.py
deleted file mode 100644
index 27d515b..0000000
--- a/erpnext/selling/doctype/sales_bom_item/sales_bom_item.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-from __future__ import unicode_literals
-import frappe
-
-from frappe.model.document import Document
-
-class SalesBOMItem(Document):
-	pass
\ No newline at end of file
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index feffc4f..e8a772a 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -39,8 +39,8 @@
 		for d in self.get('items'):
 			check_list.append(cstr(d.item_code))
 
-			if frappe.db.get_value("Item", d.item_code, "is_stock_item") == 'Yes':
-				if not d.warehouse:
+			if (frappe.db.get_value("Item", d.item_code, "is_stock_item") == 'Yes' or
+				self.has_product_bundle(d.item_code)) and not d.warehouse:
 					frappe.throw(_("Reserved warehouse required for stock item {0}").format(d.item_code))
 
 			# used for production plan
diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py
index 0565341..91daa3f 100644
--- a/erpnext/selling/doctype/sales_order/test_sales_order.py
+++ b/erpnext/selling/doctype/sales_order/test_sales_order.py
@@ -125,7 +125,7 @@
 		existing_reserved_qty_item1 = get_reserved_qty("_Test Item")
 		existing_reserved_qty_item2 = get_reserved_qty("_Test Item Home Desktop 100")
 		
-		so = make_sales_order(item_code="_Test Sales BOM Item")
+		so = make_sales_order(item_code="_Test Product Bundle Item")
 		
 		self.assertEqual(get_reserved_qty("_Test Item"), existing_reserved_qty_item1 + 50)
 		self.assertEqual(get_reserved_qty("_Test Item Home Desktop 100"), 
@@ -164,12 +164,12 @@
 
 	def test_reserved_qty_for_over_delivery_with_packing_list(self):
 		# set over-delivery tolerance
-		frappe.db.set_value('Item', "_Test Sales BOM Item", 'tolerance', 50)
+		frappe.db.set_value('Item', "_Test Product Bundle Item", 'tolerance', 50)
 		
 		existing_reserved_qty_item1 = get_reserved_qty("_Test Item")
 		existing_reserved_qty_item2 = get_reserved_qty("_Test Item Home Desktop 100")
 		
-		so = make_sales_order(item_code="_Test Sales BOM Item")
+		so = make_sales_order(item_code="_Test Product Bundle Item")
 		
 		self.assertEqual(get_reserved_qty("_Test Item"), existing_reserved_qty_item1 + 50)
 		self.assertEqual(get_reserved_qty("_Test Item Home Desktop 100"), 
diff --git a/erpnext/selling/report/available_stock_for_packing_items/available_stock_for_packing_items.json b/erpnext/selling/report/available_stock_for_packing_items/available_stock_for_packing_items.json
index 30b5d84..52da750 100644
--- a/erpnext/selling/report/available_stock_for_packing_items/available_stock_for_packing_items.json
+++ b/erpnext/selling/report/available_stock_for_packing_items/available_stock_for_packing_items.json
@@ -5,12 +5,12 @@
  "doctype": "Report", 
  "idx": 1, 
  "is_standard": "Yes", 
- "modified": "2014-06-03 07:18:16.914298", 
+ "modified": "2015-07-06 06:11:10.534423", 
  "modified_by": "Administrator", 
  "module": "Selling", 
  "name": "Available Stock for Packing Items", 
  "owner": "Administrator", 
- "ref_doctype": "Sales BOM", 
+ "ref_doctype": "Product Bundle", 
  "report_name": "Available Stock for Packing Items", 
  "report_type": "Script Report"
 }
\ No newline at end of file
diff --git a/erpnext/selling/report/available_stock_for_packing_items/available_stock_for_packing_items.py b/erpnext/selling/report/available_stock_for_packing_items/available_stock_for_packing_items.py
index f1633e7..40ed20c 100644
--- a/erpnext/selling/report/available_stock_for_packing_items/available_stock_for_packing_items.py
+++ b/erpnext/selling/report/available_stock_for_packing_items/available_stock_for_packing_items.py
@@ -39,9 +39,9 @@
 
 	return columns
 
-def get_sales_bom_items():
+def get_product_bundle_items():
 	sbom_item_map = {}
-	for sbom in frappe.db.sql("""select parent, item_code, qty from `tabSales BOM Item` 
+	for sbom in frappe.db.sql("""select parent, item_code, qty from `tabProduct Bundle Item` 
 		where docstatus < 2""", as_dict=1):
 			sbom_item_map.setdefault(sbom.parent, {}).setdefault(sbom.item_code, sbom.qty)
 			
@@ -67,7 +67,7 @@
 def get_item_warehouse_quantity_map():
 	sbom_map = {}
 	iwq_map = get_item_warehouse_quantity()
-	sbom_item_map = get_sales_bom_items()
+	sbom_item_map = get_product_bundle_items()
 	
 	for sbom, sbom_items in sbom_item_map.items():
 		for item, child_qty in sbom_items.items():
diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js
index cd65d18..f3cd8a7 100644
--- a/erpnext/selling/sales_common.js
+++ b/erpnext/selling/sales_common.js
@@ -112,10 +112,6 @@
 		erpnext.utils.get_address_display(this.frm, "shipping_address_name", "shipping_address");
 	},
 
-	contact_person: function() {
-		erpnext.utils.get_contact_details(this.frm);
-	},
-
 	sales_partner: function() {
 		this.apply_pricing_rule();
 	},
@@ -295,27 +291,27 @@
 
 	set_dynamic_labels: function() {
 		this._super();
-		this.set_sales_bom_help(this.frm.doc);
+		this.set_product_bundle_help(this.frm.doc);
 	},
 
-	set_sales_bom_help: function(doc) {
+	set_product_bundle_help: function(doc) {
 		if(!cur_frm.fields_dict.packing_list) return;
 		if ((doc.packed_items || []).length) {
 			$(cur_frm.fields_dict.packing_list.row.wrapper).toggle(true);
 
 			if (inList(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
 				help_msg = "<div class='alert alert-warning'>" +
-					__("For 'Sales BOM' items, Warehouse, Serial No and Batch No will be considered from the 'Packing List' table. If Warehouse and Batch No are same for all packing items for any 'Sales BOM' item, those values can be entered in the main Item table, values will be copied to 'Packing List' table.")+
+					__("For 'Product Bundle' items, Warehouse, Serial No and Batch No will be considered from the 'Packing List' table. If Warehouse and Batch No are same for all packing items for any 'Product Bundle' item, those values can be entered in the main Item table, values will be copied to 'Packing List' table.")+
 				"</div>";
-				frappe.meta.get_docfield(doc.doctype, 'sales_bom_help', doc.name).options = help_msg;
+				frappe.meta.get_docfield(doc.doctype, 'product_bundle_help', doc.name).options = help_msg;
 			}
 		} else {
 			$(cur_frm.fields_dict.packing_list.row.wrapper).toggle(false);
 			if (inList(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
-				frappe.meta.get_docfield(doc.doctype, 'sales_bom_help', doc.name).options = '';
+				frappe.meta.get_docfield(doc.doctype, 'product_bundle_help', doc.name).options = '';
 			}
 		}
-		refresh_field('sales_bom_help');
+		refresh_field('product_bundle_help');
 	}
 });
 
diff --git a/erpnext/setup/doctype/features_setup/features_setup.json b/erpnext/setup/doctype/features_setup/features_setup.json
index 590a73e..edc88e2 100644
--- a/erpnext/setup/doctype/features_setup/features_setup.json
+++ b/erpnext/setup/doctype/features_setup/features_setup.json
@@ -26,7 +26,7 @@
    "permlevel": 0
   }, 
   {
-   "description": "To track brand name in the following documents Delivery Note, Opportunity, Material Request, Item, Purchase Order, Purchase Voucher, Purchaser Receipt, Quotation, Sales Invoice, Sales BOM, Sales Order, Serial No", 
+   "description": "To track brand name in the following documents Delivery Note, Opportunity, Material Request, Item, Purchase Order, Purchase Voucher, Purchaser Receipt, Quotation, Sales Invoice, Product Bundle, Sales Order, Serial No", 
    "fieldname": "fs_brands", 
    "fieldtype": "Check", 
    "in_list_view": 1, 
@@ -205,7 +205,7 @@
  "icon": "icon-glass", 
  "idx": 1, 
  "issingle": 1, 
- "modified": "2015-02-05 05:11:38.842809", 
+ "modified": "2015-07-06 06:11:10.534423", 
  "modified_by": "Administrator", 
  "module": "Setup", 
  "name": "Features Setup", 
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.json b/erpnext/stock/doctype/delivery_note/delivery_note.json
index d356912..3859d63 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.json
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.json
@@ -331,9 +331,9 @@
    "read_only": 1
   }, 
   {
-   "fieldname": "sales_bom_help", 
+   "fieldname": "product_bundle_help", 
    "fieldtype": "HTML", 
-   "label": "Sales BOM Help", 
+   "label": "Product Bundle Help", 
    "permlevel": 0, 
    "print_hide": 1, 
    "read_only": 0
@@ -1070,7 +1070,7 @@
  "idx": 1, 
  "in_create": 0, 
  "is_submittable": 1, 
- "modified": "2015-06-15 15:37:54.699371", 
+ "modified": "2015-07-07 02:37:08.064584", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Delivery Note", 
diff --git a/erpnext/stock/doctype/delivery_note/test_delivery_note.py b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
index 4d397e7..978e968 100644
--- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
@@ -112,7 +112,7 @@
 		stock_in_hand_account = frappe.db.get_value("Account", {"warehouse": "_Test Warehouse - _TC"})
 		prev_bal = get_balance_on(stock_in_hand_account)
 
-		dn = create_delivery_note(item_code="_Test Sales BOM Item")
+		dn = create_delivery_note(item_code="_Test Product Bundle Item")
 
 		stock_value_diff_rm1 = abs(frappe.db.get_value("Stock Ledger Entry",
 			{"voucher_type": "Delivery Note", "voucher_no": dn.name, "item_code": "_Test Item"},
@@ -208,4 +208,4 @@
 			dn.submit()
 	return dn
 
-test_dependencies = ["Sales BOM"]
+test_dependencies = ["Product Bundle"]
diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json
index 45606b0..8fdb52b 100644
--- a/erpnext/stock/doctype/item/item.json
+++ b/erpnext/stock/doctype/item/item.json
@@ -181,6 +181,7 @@
    "fieldname": "has_variants", 
    "fieldtype": "Check", 
    "label": "Has Variants", 
+   "no_copy": 1, 
    "options": "", 
    "permlevel": 0, 
    "precision": "", 
diff --git a/erpnext/stock/doctype/item/test_records.json b/erpnext/stock/doctype/item/test_records.json
index 5a02c6b..86d581d 100644
--- a/erpnext/stock/doctype/item/test_records.json
+++ b/erpnext/stock/doctype/item/test_records.json
@@ -109,7 +109,7 @@
   "stock_uom": "_Test UOM 1"
  },
  {
-  "description": "_Test Sales BOM Item 5",
+  "description": "_Test Product Bundle Item 5",
   "doctype": "Item",
   "expense_account": "_Test Account Cost for Goods Sold - _TC",
   "cost_center": "_Test Cost Center - _TC",
@@ -124,9 +124,9 @@
   "is_service_item": "No",
   "is_stock_item": "No",
   "is_sub_contracted_item": "No",
-  "item_code": "_Test Sales BOM Item",
+  "item_code": "_Test Product Bundle Item",
   "item_group": "_Test Item Group Desktops",
-  "item_name": "_Test Sales BOM Item",
+  "item_name": "_Test Product Bundle Item",
   "stock_uom": "_Test UOM"
  },
  {
diff --git a/erpnext/stock/doctype/packed_item/packed_item.py b/erpnext/stock/doctype/packed_item/packed_item.py
index 647ef2e..e7a75fe 100644
--- a/erpnext/stock/doctype/packed_item/packed_item.py
+++ b/erpnext/stock/doctype/packed_item/packed_item.py
@@ -13,9 +13,9 @@
 class PackedItem(Document):
 	pass
 
-def get_sales_bom_items(item_code):
+def get_product_bundle_items(item_code):
 	return frappe.db.sql("""select t1.item_code, t1.qty, t1.uom
-		from `tabSales BOM Item` t1, `tabSales BOM` t2
+		from `tabProduct Bundle Item` t1, `tabProduct Bundle` t2
 		where t2.new_item_code=%s and t1.parent = t2.name""", item_code, as_dict=1)
 
 def get_packing_item_details(item):
@@ -58,14 +58,14 @@
 
 
 def make_packing_list(obj, item_table_fieldname):
-	"""make packing list for sales bom item"""
+	"""make packing list for Product Bundle item"""
 
 	if obj.get("_action") and obj._action == "update_after_submit": return
 
 	parent_items = []
 	for d in obj.get(item_table_fieldname):
-		if frappe.db.get_value("Sales BOM", {"new_item_code": d.item_code}):
-			for i in get_sales_bom_items(d.item_code):
+		if frappe.db.get_value("Product Bundle", {"new_item_code": d.item_code}):
+			for i in get_product_bundle_items(d.item_code):
 				update_packing_list_item(obj, i['item_code'], flt(i['qty'])*flt(d.qty), d.warehouse, d)
 
 			if [d.item_code, d.name] not in parent_items:
diff --git a/erpnext/stock/doctype/sales_bom_item/README.md b/erpnext/stock/doctype/sales_bom_item/README.md
index 1e5c8a2..3dad9d9 100644
--- a/erpnext/stock/doctype/sales_bom_item/README.md
+++ b/erpnext/stock/doctype/sales_bom_item/README.md
@@ -1 +1 @@
-Child Item grouped in parent Sales BOM.
\ No newline at end of file
+Child Item grouped in parent Product Bundle.
\ No newline at end of file
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index 465b641..6958ea0 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -519,11 +519,11 @@
 }
 
 cur_frm.cscript.expense_account = function(doc, cdt, cdn) {
-	cur_frm.cscript.copy_account_in_all_row(doc, cdt, cdn, "expense_account");
+	erpnext.utils.copy_value_in_all_row(doc, cdt, cdn, "items", "expense_account");
 }
 
 cur_frm.cscript.cost_center = function(doc, cdt, cdn) {
-	cur_frm.cscript.copy_account_in_all_row(doc, cdt, cdn, "cost_center");
+	erpnext.utils.copy_value_in_all_row(doc, cdt, cdn, "items", "cost_center");
 }
 
 cur_frm.fields_dict.customer.get_query = function(doc, cdt, cdn) {
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index c3597e3..fb1ec3d 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -201,6 +201,9 @@
 	def check_if_operations_completed(self):
 		"""Check if Time Logs are completed against before manufacturing to capture operating costs."""
 		prod_order = frappe.get_doc("Production Order", self.production_order)
+		if not prod_order.track_operations:
+			return
+			
 		for d in prod_order.get("operations"):
 			total_completed_qty = flt(self.fg_completed_qty) + flt(prod_order.produced_qty)
 			if total_completed_qty > flt(d.completed_qty):
diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
index 589f1ed..81c07fb 100644
--- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
@@ -346,7 +346,7 @@
 		self._test_sales_invoice_return("_Test Item", 5, 2)
 
 	def test_sales_invoice_return_of_packing_item(self):
-		self._test_sales_invoice_return("_Test Sales BOM Item", 25, 20)
+		self._test_sales_invoice_return("_Test Product Bundle Item", 25, 20)
 
 	def _test_delivery_note_return(self, item_code, delivered_qty, returned_qty):
 		from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
@@ -381,7 +381,7 @@
 		self._test_delivery_note_return("_Test Item", 5, 2)
 
 	def test_delivery_note_return_of_packing_item(self):
-		self._test_delivery_note_return("_Test Sales BOM Item", 25, 20)
+		self._test_delivery_note_return("_Test Product Bundle Item", 25, 20)
 
 	def _test_sales_return_jv(self, se):
 		jv = make_return_jv(se.name)
@@ -399,7 +399,7 @@
 		self._test_sales_return_jv(se)
 
 	def test_make_return_jv_for_sales_invoice_packing_item(self):
-		se = self._test_sales_invoice_return("_Test Sales BOM Item", 25, 20)
+		se = self._test_sales_invoice_return("_Test Product Bundle Item", 25, 20)
 		self._test_sales_return_jv(se)
 
 	def test_make_return_jv_for_delivery_note_non_packing_item(self):
@@ -410,10 +410,10 @@
 		self._test_sales_return_jv(se)
 
 	def test_make_return_jv_for_delivery_note_packing_item(self):
-		se = self._test_delivery_note_return("_Test Sales BOM Item", 25, 20)
+		se = self._test_delivery_note_return("_Test Product Bundle Item", 25, 20)
 		self._test_sales_return_jv(se)
 
-		se = self._test_delivery_note_return_against_sales_order("_Test Sales BOM Item", 25, 20)
+		se = self._test_delivery_note_return_against_sales_order("_Test Product Bundle Item", 25, 20)
 		self._test_sales_return_jv(se)
 
 	def _test_delivery_note_return_against_sales_order(self, item_code, delivered_qty, returned_qty):
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json
index 763680f..db09565 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json
@@ -67,7 +67,8 @@
    "label": "Items", 
    "options": "Stock Reconciliation Item", 
    "permlevel": 0, 
-   "precision": ""
+   "precision": "", 
+   "reqd": 1
   }, 
   {
    "fieldname": "get_items", 
@@ -148,7 +149,7 @@
  "idx": 1, 
  "is_submittable": 1, 
  "max_attachments": 1, 
- "modified": "2015-02-20 04:39:46.585018", 
+ "modified": "2015-07-06 03:13:52.054017", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Stock Reconciliation", 
diff --git a/erpnext/stock/report/bom_search/bom_search.py b/erpnext/stock/report/bom_search/bom_search.py
index b8a7b78..828ae16 100644
--- a/erpnext/stock/report/bom_search/bom_search.py
+++ b/erpnext/stock/report/bom_search/bom_search.py
@@ -7,12 +7,12 @@
 def execute(filters=None):
 	data = []
 	parents = {
-		"Sales BOM Item": "Sales BOM",
+		"Product Bundle Item": "Product Bundle",
 		"BOM Explosion Item": "BOM",
 		"BOM Item": "BOM"
 	}
 
-	for doctype in ("Sales BOM Item",
+	for doctype in ("Product Bundle Item",
 		"BOM Explosion Item" if filters.search_sub_assemblies else "BOM Item"):
 		all_boms = {}
 		for d in frappe.get_all(doctype, fields=["parent", "item_code"]):
diff --git a/erpnext/utilities/doctype/contact/contact.py b/erpnext/utilities/doctype/contact/contact.py
index 4158d75..314014f 100644
--- a/erpnext/utilities/doctype/contact/contact.py
+++ b/erpnext/utilities/doctype/contact/contact.py
@@ -66,5 +66,4 @@
 		"contact_designation": contact.get("designation"),
 		"contact_department": contact.get("department")
 	}
-
 	return out
diff --git a/setup.py b/setup.py
index 7154899..e7702e4 100644
--- a/setup.py
+++ b/setup.py
@@ -1,6 +1,6 @@
 from setuptools import setup, find_packages
 
-version = "5.1.4"
+version = "5.1.6"
 
 with open("requirements.txt", "r") as f:
 	install_requires = f.readlines()
diff --git a/sponsors.md b/sponsors.md
new file mode 100644
index 0000000..74f67f8
--- /dev/null
+++ b/sponsors.md
@@ -0,0 +1,25 @@
+## Sponsors
+
+
+#### General
+
+- [CWT (connector & wire technology GmbH)](http://www.cwt-assembly.com/) (2013)
+- [Pinnacle GIS](http://pinnaclegis.com.au/) (2014)
+- [Rohit Industries](www.rigpl.com) (2014)
+
+
+#### Features
+
+<table>
+	<tbody>
+		<tr>
+			<td style="width: 30%">
+				<a href="http://www.mcleans.net.au">McLean Images</a>
+			</td>
+			<td>
+				For credit period setting options
+				for Customer <a href="https://github.com/frappe/erpnext/issues/3451">#3451</a>
+			</td>
+		</tr>
+	</tbody>
+</table>