Merge branch 'develop'
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index ce9a142..6902417 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -2,7 +2,7 @@
 from __future__ import unicode_literals
 import frappe
 
-__version__ = '8.0.3'
+__version__ = '8.0.4'
 
 def get_default_company(user=None):
 	'''Get default company for user'''
@@ -25,6 +25,14 @@
 	if company:
 		return frappe.db.get_value('Company', company, 'default_currency')
 
+def get_company_currency(company):
+	'''Returns the default company currency'''
+	if not frappe.flags.company_currency:
+		frappe.flags.company_currency = {}
+	if not company in frappe.flags.company_currency:
+		frappe.flags.company_currency[company] = frappe.db.get_value('Company', company, 'default_currency')
+	return frappe.flags.company_currency[company]
+
 def set_perpetual_inventory(enable=1):
 	accounts_settings = frappe.get_doc("Accounts Settings")
 	accounts_settings.auto_accounting_for_stock = enable
diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py
index ce60298..304af37 100644
--- a/erpnext/accounts/doctype/gl_entry/gl_entry.py
+++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py
@@ -2,13 +2,12 @@
 # License: GNU General Public License v3. See license.txt
 
 from __future__ import unicode_literals
-import frappe
+import frappe, erpnext
 from frappe import _
 from frappe.utils import flt, fmt_money, getdate, formatdate
 from frappe.model.document import Document
 from erpnext.accounts.party import validate_party_gle_currency, validate_party_frozen_disabled
 from erpnext.accounts.utils import get_account_currency
-from erpnext.setup.doctype.company.company import get_company_currency
 from erpnext.accounts.utils import get_fiscal_year
 from erpnext.exceptions import InvalidAccountCurrency
 
@@ -19,7 +18,7 @@
 		self.flags.ignore_submit_comment = True
 		self.check_mandatory()
 		self.validate_and_set_fiscal_year()
-		
+
 		if not self.flags.from_repost:
 			self.pl_must_have_cost_center()
 			self.check_pl_account()
@@ -32,7 +31,7 @@
 		if not from_repost:
 			self.validate_account_details(adv_adj)
 			check_freezing_date(self.posting_date, adv_adj)
-			
+
 		validate_frozen_account(self.account, adv_adj)
 		validate_balance_type(self.account, adv_adj)
 
@@ -56,7 +55,7 @@
 			elif account_type == "Payable":
 				frappe.throw(_("{0} {1}: Supplier is required against Payable account {2}")
 					.format(self.voucher_type, self.voucher_no, self.account))
-				
+
 		# Zero value transaction is not allowed
 		if not (flt(self.debit) or flt(self.credit)):
 			frappe.throw(_("{0} {1}: Either debit or credit amount is required for {2}")
@@ -116,7 +115,7 @@
 		validate_party_frozen_disabled(self.party_type, self.party)
 
 	def validate_currency(self):
-		company_currency = get_company_currency(self.company)
+		company_currency = erpnext.get_company_currency(self.company)
 		account_currency = get_account_currency(self.account)
 
 		if not self.account_currency:
@@ -124,7 +123,7 @@
 
 		if account_currency != self.account_currency:
 			frappe.throw(_("{0} {1}: Accounting Entry for {2} can only be made in currency: {3}")
-				.format(self.voucher_type, self.voucher_no, self.account, 
+				.format(self.voucher_type, self.voucher_no, self.account,
 				(account_currency or company_currency)), InvalidAccountCurrency)
 
 		if self.party_type and self.party:
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index 06724b1..a471c48 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -2,12 +2,11 @@
 # License: GNU General Public License v3. See license.txt
 
 from __future__ import unicode_literals
-import frappe, json
+import frappe, erpnext, json
 from frappe.utils import cstr, flt, fmt_money, formatdate
 from frappe import msgprint, _, scrub
 from erpnext.controllers.accounts_controller import AccountsController
 from erpnext.accounts.utils import get_balance_on, get_account_currency
-from erpnext.setup.utils import get_company_currency
 from erpnext.accounts.party import get_party_account
 from erpnext.hr.doctype.expense_claim.expense_claim import update_reimbursed_amount
 from erpnext.hr.doctype.employee_loan.employee_loan import update_disbursement_status
@@ -325,11 +324,11 @@
 			if d.account_currency == self.company_currency:
 				d.exchange_rate = 1
 			elif not d.exchange_rate or d.exchange_rate == 1 or \
-				(d.reference_type in ("Sales Invoice", "Purchase Invoice") 
+				(d.reference_type in ("Sales Invoice", "Purchase Invoice")
 				and d.reference_name and self.posting_date):
-				
+
 					# Modified to include the posting date for which to retreive the exchange rate
-					d.exchange_rate = get_exchange_rate(self.posting_date, d.account, d.account_currency, 
+					d.exchange_rate = get_exchange_rate(self.posting_date, d.account, d.account_currency,
 						self.company, d.reference_type, d.reference_name, d.debit, d.credit, d.exchange_rate)
 
 			if not d.exchange_rate:
@@ -656,7 +655,7 @@
 	if args.get("party_account"):
 		# Modified to include the posting date for which the exchange rate is required.
 		# Assumed to be the posting date in the reference document
-		exchange_rate = get_exchange_rate(ref_doc.get("posting_date") or ref_doc.get("transaction_date"), 
+		exchange_rate = get_exchange_rate(ref_doc.get("posting_date") or ref_doc.get("transaction_date"),
 			args.get("party_account"), args.get("party_account_currency"),
 			ref_doc.company, ref_doc.doctype, ref_doc.name)
 
@@ -692,8 +691,8 @@
 		bank_row.update(bank_account)
 		# Modified to include the posting date for which the exchange rate is required.
 		# Assumed to be the posting date of the reference date
-		bank_row.exchange_rate = get_exchange_rate(ref_doc.get("posting_date") 
-			or ref_doc.get("transaction_date"), bank_account["account"], 
+		bank_row.exchange_rate = get_exchange_rate(ref_doc.get("posting_date")
+			or ref_doc.get("transaction_date"), bank_account["account"],
 			bank_account["account_currency"], ref_doc.company)
 
 	bank_row.cost_center = cost_center
@@ -746,7 +745,7 @@
 	if isinstance(args, basestring):
 		args = json.loads(args)
 
-	company_currency = get_company_currency(args.get("company"))
+	company_currency = erpnext.get_company_currency(args.get("company"))
 
 	if args.get("doctype") == "Journal Entry":
 		condition = " and party=%(party)s" if args.get("party") else ""
@@ -805,7 +804,7 @@
 	if not frappe.has_permission("Account"):
 		frappe.msgprint(_("No Permission"), raise_exception=1)
 
-	company_currency = get_company_currency(company)
+	company_currency = erpnext.get_company_currency(company)
 	account_details = frappe.db.get_value("Account", account, ["account_type", "account_currency"], as_dict=1)
 
 	if not account_details:
@@ -853,7 +852,7 @@
 	if not account_currency:
 		account_currency = account_details.account_currency
 
-	company_currency = get_company_currency(company)
+	company_currency = erpnext.get_company_currency(company)
 
 	if account_currency != company_currency:
 		if reference_type in ("Sales Invoice", "Purchase Invoice") and reference_name:
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index 6ee9e66..3762b48 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -2,8 +2,7 @@
 // License: GNU General Public License v3. See license.txt
 
 frappe.provide("erpnext.accounts");
-{% include 'erpnext/buying/doctype/purchase_common/purchase_common.js' %};
-
+{% include 'erpnext/public/js/controllers/buying.js' %};
 
 erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
 	setup: function(doc) {
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index dd3b4ba..1972cc9 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -2,10 +2,9 @@
 # License: GNU General Public License v3. See license.txt
 
 from __future__ import unicode_literals
-import frappe
+import frappe, erpnext
 from frappe.utils import cint, formatdate, flt, getdate
 from frappe import _, throw
-from erpnext.setup.utils import get_company_currency
 import frappe.defaults
 
 from erpnext.controllers.buying_controller import BuyingController
@@ -15,6 +14,7 @@
 from erpnext.controllers.stock_controller import get_warehouse_account
 from erpnext.accounts.general_ledger import make_gl_entries, merge_similar_entries, delete_gl_entries
 from erpnext.accounts.doctype.gl_entry.gl_entry import update_outstanding_amt
+from erpnext.buying.utils import check_for_closed_status
 
 form_grid_templates = {
 	"items": "templates/form_grid/item_grid.html"
@@ -93,7 +93,7 @@
 		super(PurchaseInvoice, self).set_missing_values(for_validate)
 
 	def check_conversion_rate(self):
-		default_currency = get_company_currency(self.company)
+		default_currency = erpnext.get_company_currency(self.company)
 		if not default_currency:
 			throw(_('Please enter default currency in Company Master'))
 		if (self.currency == default_currency and flt(self.conversion_rate) != 1.00) or not self.conversion_rate or (self.currency != default_currency and flt(self.conversion_rate) == 1.00):
@@ -113,12 +113,11 @@
 
 	def check_for_closed_status(self):
 		check_list = []
-		pc_obj = frappe.get_doc('Purchase Common')
 
 		for d in self.get('items'):
 			if d.purchase_order and not d.purchase_order in check_list and not d.purchase_receipt:
 				check_list.append(d.purchase_order)
-				pc_obj.check_for_closed_status('Purchase Order', d.purchase_order)
+				check_for_closed_status('Purchase Order', d.purchase_order)
 
 	def validate_with_previous_doc(self):
 		super(PurchaseInvoice, self).validate_with_previous_doc({
diff --git a/erpnext/accounts/doctype/shipping_rule/shipping_rule.py b/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
index 80e4fb7..7faaf11 100644
--- a/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
+++ b/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
@@ -4,11 +4,10 @@
 # For license information, please see license.txt
 
 from __future__ import unicode_literals
-import frappe
+import frappe, erpnext
 from frappe import _, msgprint, throw
 from frappe.utils import flt, fmt_money
 from frappe.model.document import Document
-from erpnext.setup.utils import get_company_currency
 
 class OverlappingConditionError(frappe.ValidationError): pass
 class FromGreaterThanToError(frappe.ValidationError): pass
@@ -77,7 +76,7 @@
 						overlaps.append([d1, d2])
 
 		if overlaps:
-			company_currency = get_company_currency(self.company)
+			company_currency = erpnext.get_company_currency(self.company)
 			msgprint(_("Overlapping conditions found between:"))
 			messages = []
 			for d1, d2 in overlaps:
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index 8aedf78..f4c5c4d 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -151,13 +151,6 @@
 	}
 	return out
 
-def get_company_currency():
-	company_currency = frappe._dict()
-	for d in frappe.get_all("Company", fields=["name", "default_currency"]):
-		company_currency.setdefault(d.name, d.default_currency)
-
-	return company_currency
-
 @frappe.whitelist()
 def get_party_account(party_type, party, company):
 	"""Returns the account for the given `party`.
diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py
index 48c6d9a..7dffd0a 100644
--- a/erpnext/accounts/report/gross_profit/gross_profit.py
+++ b/erpnext/accounts/report/gross_profit/gross_profit.py
@@ -12,7 +12,7 @@
 
 def execute(filters=None):
 	if not filters: filters = frappe._dict()
-	company_currency = frappe.db.get_value("Company", filters.company, "default_currency")
+	filters.currency = frappe.db.get_value("Company", filters.company, "default_currency")
 
 	gross_profit_data = GrossProfitGenerator(filters)
 
@@ -50,7 +50,7 @@
 		for col in group_wise_columns.get(scrub(filters.group_by)):
 			row.append(src.get(col))
 
-		row.append(company_currency)
+		row.append(filters.currency)
 		data.append(row)
 
 	return columns, data
@@ -224,8 +224,11 @@
 			else:
 				average_buying_rate = get_incoming_rate(row)
 				if not average_buying_rate:
-					average_buying_rate = get_valuation_rate(item_code, row.warehouse, allow_zero_rate=True)
-				self.average_buying_rate[item_code] =  average_buying_rate
+					average_buying_rate = get_valuation_rate(item_code, row.warehouse,
+            row.parenttype, row.parent, allow_zero_rate=True, 
+            currency=self.filters.currency)
+
+          self.average_buying_rate[item_code] =  average_buying_rate
 
 		return self.average_buying_rate[item_code]
 
@@ -235,7 +238,7 @@
 			select (a.base_rate / a.conversion_factor)
 			from `tabPurchase Invoice Item` a
 			where a.item_code = %s and a.docstatus=1
-			and modified <= %s 
+			and modified <= %s
 			order by a.modified desc limit 1""", (item_code,self.filters.to_date))
 		else:
 			last_purchase_rate = frappe.db.sql("""
@@ -253,7 +256,7 @@
 			conditions += " and posting_date >= %(from_date)s"
 		if self.filters.to_date:
 			conditions += " and posting_date <= %(to_date)s"
-					
+
 		if self.filters.group_by=="Sales Person":
 			sales_person_cols = ", sales.sales_person, sales.allocated_amount, sales.incentives"
 			sales_team_table = "left join `tabSales Team` sales on sales.parent = `tabSales Invoice`.name"
@@ -269,7 +272,7 @@
 				`tabSales Invoice Item`.dn_detail, `tabSales Invoice Item`.delivery_note, `tabSales Invoice Item`.stock_qty as qty,
 				`tabSales Invoice Item`.base_net_rate, `tabSales Invoice Item`.base_net_amount, `tabSales Invoice Item`.name as "item_row"
 				{sales_person_cols}
-			from 
+			from
 				`tabSales Invoice`
 				inner join `tabSales Invoice Item` on `tabSales Invoice Item`.parent = `tabSales Invoice`.name
 				{sales_team_table}
@@ -277,7 +280,7 @@
 				`tabSales Invoice`.docstatus = 1 and `tabSales Invoice`.is_return != 1 {conditions} {match_cond}
 			order by
 				`tabSales Invoice`.posting_date desc, `tabSales Invoice`.posting_time desc"""
-			.format(conditions=conditions, sales_person_cols=sales_person_cols, 
+			.format(conditions=conditions, sales_person_cols=sales_person_cols,
 				sales_team_table=sales_team_table, match_cond = get_match_cond('Sales Invoice')), self.filters, as_dict=1)
 
 	def load_stock_ledger_entries(self):
diff --git a/erpnext/buying/doctype/purchase_common/README.md b/erpnext/buying/doctype/purchase_common/README.md
deleted file mode 100644
index bedec2a..0000000
--- a/erpnext/buying/doctype/purchase_common/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Common scripts for purchase transactions.
\ No newline at end of file
diff --git a/erpnext/buying/doctype/purchase_common/__init__.py b/erpnext/buying/doctype/purchase_common/__init__.py
deleted file mode 100644
index baffc48..0000000
--- a/erpnext/buying/doctype/purchase_common/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from __future__ import unicode_literals
diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.json b/erpnext/buying/doctype/purchase_common/purchase_common.json
deleted file mode 100644
index fd08d08..0000000
--- a/erpnext/buying/doctype/purchase_common/purchase_common.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "allow_copy": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "creation": "2012-03-27 14:35:51", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "fields": [], 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 1, 
- "in_create": 0, 
- "in_dialog": 0, 
- "is_submittable": 0, 
- "issingle": 1, 
- "istable": 0, 
- "modified": "2013-12-20 19:23:27", 
- "modified_by": "Administrator", 
- "module": "Buying", 
- "name": "Purchase Common", 
- "owner": "Administrator", 
- "permissions": [], 
- "read_only": 0, 
- "read_only_onload": 0
-}
\ No newline at end of file
diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.py b/erpnext/buying/doctype/purchase_common/purchase_common.py
deleted file mode 100644
index 844a655..0000000
--- a/erpnext/buying/doctype/purchase_common/purchase_common.py
+++ /dev/null
@@ -1,105 +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, json
-from frappe.utils import flt, cstr, cint
-from frappe import _
-
-from erpnext.stock.doctype.item.item import get_last_purchase_details
-from erpnext.controllers.buying_controller import BuyingController
-
-class PurchaseCommon(BuyingController):
-	def update_last_purchase_rate(self, obj, is_submit):
-		"""updates last_purchase_rate in item table for each item"""
-
-		import frappe.utils
-		this_purchase_date = frappe.utils.getdate(obj.get('posting_date') or obj.get('transaction_date'))
-
-		for d in obj.get("items"):
-			# get last purchase details
-			last_purchase_details = get_last_purchase_details(d.item_code, obj.name)
-
-			# compare last purchase date and this transaction's date
-			last_purchase_rate = None
-			if last_purchase_details and \
-					(last_purchase_details.purchase_date > this_purchase_date):
-				last_purchase_rate = last_purchase_details['base_rate']
-			elif is_submit == 1:
-				# even if this transaction is the latest one, it should be submitted
-				# for it to be considered for latest purchase rate
-				if flt(d.conversion_factor):
-					last_purchase_rate = flt(d.base_rate) / flt(d.conversion_factor)
-				else:
-					frappe.throw(_("UOM Conversion factor is required in row {0}").format(d.idx))
-
-			# update last purchsae rate
-			if last_purchase_rate:
-				frappe.db.sql("""update `tabItem` set last_purchase_rate = %s where name = %s""",
-					(flt(last_purchase_rate), d.item_code))
-
-	def validate_for_items(self, obj):
-		items = []
-		for d in obj.get("items"):
-			if not d.qty:
-				if obj.doctype == "Purchase Receipt" and d.rejected_qty:
-					continue
-				frappe.throw(_("Please enter quantity for Item {0}").format(d.item_code))
-
-			# udpate with latest quantities
-			bin = frappe.db.sql("""select projected_qty from `tabBin` where
-				item_code = %s and warehouse = %s""", (d.item_code, d.warehouse), as_dict=1)
-
-			f_lst ={'projected_qty': bin and flt(bin[0]['projected_qty']) or 0, 'ordered_qty': 0, 'received_qty' : 0}
-			if d.doctype in ('Purchase Receipt Item', 'Purchase Invoice Item'):
-				f_lst.pop('received_qty')
-			for x in f_lst :
-				if d.meta.get_field(x):
-					d.set(x, f_lst[x])
-
-			item = frappe.db.sql("""select is_stock_item,
-				is_sub_contracted_item, end_of_life, disabled from `tabItem` where name=%s""",
-				d.item_code, as_dict=1)[0]
-
-			from erpnext.stock.doctype.item.item import validate_end_of_life
-			validate_end_of_life(d.item_code, item.end_of_life, item.disabled)
-
-			# validate stock item
-			if item.is_stock_item==1 and d.qty and not d.warehouse and not d.delivered_by_supplier:
-				frappe.throw(_("Warehouse is mandatory for stock Item {0} in row {1}").format(d.item_code, d.idx))
-
-			items.append(cstr(d.item_code))
-
-		if items and len(items) != len(set(items)) and \
-			not cint(frappe.db.get_single_value("Buying Settings", "allow_multiple_items") or 0):
-			frappe.throw(_("Same item cannot be entered multiple times."))
-
-	def check_for_closed_status(self, doctype, docname):
-		status = frappe.db.get_value(doctype, docname, "status")
-
-		if status == "Closed":
-			frappe.throw(_("{0} {1} status is {2}").format(doctype, docname, status), frappe.InvalidStatusError)
-			
-@frappe.whitelist()
-def get_linked_material_requests(items):
-	items = json.loads(items)
-	mr_list = []
-	for item in items:
-		material_request = frappe.db.sql("""SELECT distinct mr.name AS mr_name, 
-				(mr_item.qty - mr_item.ordered_qty) AS qty, 
-				mr_item.item_code AS item_code,
-				mr_item.name AS mr_item 
-			FROM `tabMaterial Request` mr, `tabMaterial Request Item` mr_item
-			WHERE mr.name = mr_item.parent
-				AND mr_item.item_code = %(item)s 
-				AND mr.material_request_type = 'Purchase'
-				AND mr.per_ordered < 99.99
-				AND mr.docstatus = 1
-				AND mr.status != 'Stopped'
-                        ORDER BY mr_item.item_code ASC""",{"item": item}, as_dict=1)
-		if material_request:
-			mr_list.append(material_request)
-	
-	return mr_list
-	
-	
\ No newline at end of file
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index 5b16cd6..85a6329 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -3,7 +3,7 @@
 
 frappe.provide("erpnext.buying");
 
-{% include 'erpnext/buying/doctype/purchase_common/purchase_common.js' %};
+{% include 'erpnext/public/js/controllers/buying.js' %};
 
 frappe.ui.form.on("Purchase Order", {
 	setup: function(frm) {
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 796e0f2..96351e3 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -11,6 +11,8 @@
 from erpnext.stock.doctype.item.item import get_last_purchase_details
 from erpnext.stock.stock_balance import update_bin_qty, get_ordered_qty
 from frappe.desk.notifications import clear_doctype_notifications
+from erpnext.buying.utils import (validate_for_items, check_for_closed_status,
+	update_last_purchase_rate)
 
 
 form_grid_templates = {
@@ -37,9 +39,8 @@
 		super(PurchaseOrder, self).validate()
 
 		self.set_status()
-		pc_obj = frappe.get_doc('Purchase Common')
-		pc_obj.validate_for_items(self)
-		self.check_for_closed_status(pc_obj)
+		validate_for_items(self)
+		self.check_for_closed_status()
 
 		self.validate_uom_is_integer("uom", "qty")
 		self.validate_uom_is_integer("stock_uom", ["qty", "required_qty"])
@@ -111,12 +112,12 @@
 							= d.rate = item_last_purchase_rate
 
 	# Check for Closed status
-	def check_for_closed_status(self, pc_obj):
+	def check_for_closed_status(self):
 		check_list =[]
 		for d in self.get('items'):
 			if d.meta.get_field('material_request') and d.material_request and d.material_request not in check_list:
 				check_list.append(d.material_request)
-				pc_obj.check_for_closed_status('Material Request', d.material_request)
+				check_for_closed_status('Material Request', d.material_request)
 
 	def update_requested_qty(self):
 		material_request_map = {}
@@ -155,7 +156,7 @@
 		if date_diff and date_diff[0][0]:
 			msgprint(_("{0} {1} has been modified. Please refresh.").format(self.doctype, self.name),
 				raise_exception=True)
-				
+
 	def update_status(self, status):
 		self.check_modified_date()
 		self.set_status(update=True, status=status)
@@ -168,8 +169,6 @@
 		if self.is_against_so():
 			self.update_status_updater()
 
-		purchase_controller = frappe.get_doc("Purchase Common")
-
 		self.update_prevdoc_status()
 		self.update_requested_qty()
 		self.update_ordered_qty()
@@ -177,7 +176,7 @@
 		frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
 			self.company, self.base_grand_total)
 
-		purchase_controller.update_last_purchase_rate(self, is_submit = 1)
+		update_last_purchase_rate(self, is_submit = 1)
 
 	def on_cancel(self):
 		if self.is_against_so():
@@ -186,8 +185,7 @@
 		if self.has_drop_ship_item():
 			self.update_delivered_qty_in_sales_order()
 
-		pc_obj = frappe.get_doc('Purchase Common')
-		self.check_for_closed_status(pc_obj)
+		self.check_for_closed_status()
 
 		frappe.db.set(self,'status','Cancelled')
 
@@ -197,7 +195,7 @@
 		self.update_requested_qty()
 		self.update_ordered_qty()
 
-		pc_obj.update_last_purchase_rate(self, is_submit = 0)
+		update_last_purchase_rate(self, is_submit = 0)
 
 	def on_update(self):
 		pass
@@ -303,7 +301,7 @@
 		target.amount = flt(obj.amount) - flt(obj.billed_amt)
 		target.base_amount = target.amount * flt(source_parent.conversion_rate)
 		target.qty = target.amount / flt(obj.rate) if (flt(obj.rate) and flt(obj.billed_amt)) else flt(obj.qty)
-		
+
 		item = frappe.db.get_value("Item", target.item_code, ["item_group", "buying_cost_center"], as_dict=1)
 		target.cost_center = frappe.db.get_value("Project", obj.project, "cost_center") \
 			or item.buying_cost_center \
diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js
index 59ad092..92600b7 100644
--- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js
+++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js
@@ -2,7 +2,7 @@
 // License: GNU General Public License v3. See license.txt
 
 
-{% include 'erpnext/buying/doctype/purchase_common/purchase_common.js' %};
+{% include 'erpnext/public/js/controllers/buying.js' %};
 
 cur_frm.add_fetch('contact', 'email_id', 'email_id')
 
diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
index ab9efae..9109239 100644
--- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
+++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
@@ -14,13 +14,14 @@
 from erpnext.accounts.party import get_party_account_currency, get_party_details
 from erpnext.stock.doctype.material_request.material_request import set_missing_values
 from erpnext.controllers.buying_controller import BuyingController
+from erpnext.buying.utils import validate_for_items
 
 STANDARD_USERS = ("Guest", "Administrator")
 
 class RequestforQuotation(BuyingController):
 	def validate(self):
 		self.validate_duplicate_supplier()
-		self.validate_common()
+		validate_for_items(self)
 		self.update_email_id()
 
 	def validate_duplicate_supplier(self):
@@ -28,10 +29,6 @@
 		if len(supplier_list) != len(set(supplier_list)):
 			frappe.throw(_("Same supplier has been entered multiple times"))
 
-	def validate_common(self):
-		pc = frappe.get_doc('Purchase Common')
-		pc.validate_for_items(self)
-
 	def update_email_id(self):
 		for rfq_supplier in self.suppliers:
 			if not rfq_supplier.email_id:
@@ -130,7 +127,7 @@
 		self.send_email(data, sender, subject, message, attachments)
 
 	def send_email(self, data, sender, subject, message, attachments):
-		make(subject = subject, content=message,recipients=data.email_id, 
+		make(subject = subject, content=message,recipients=data.email_id,
 			sender=sender,attachments = attachments, send_email=True,
 		     	doctype=self.doctype, name=self.name)["name"]
 
@@ -250,26 +247,26 @@
 		args = doc.get('suppliers')[cint(supplier_idx) - 1]
 		doc.update_supplier_part_no(args)
 		return doc
-		
+
 @frappe.whitelist()
 def get_item_from_material_requests_based_on_supplier(source_name, target_doc = None):
 	mr_items_list = frappe.db.sql("""
 		SELECT
 			mr.name, mr_item.item_code
 		FROM
-			`tabItem` as item, 
-			`tabItem Supplier` as item_supp, 
-			`tabMaterial Request Item` as mr_item, 
-			`tabMaterial Request`  as mr 
-		WHERE item_supp.supplier = %(supplier)s 
-			AND item.name = item_supp.parent 
-			AND mr_item.parent = mr.name 
-			AND mr_item.item_code = item.name 
-			AND mr.status != "Stopped" 
-			AND mr.material_request_type = "Purchase" 
-			AND mr.docstatus = 1 
+			`tabItem` as item,
+			`tabItem Supplier` as item_supp,
+			`tabMaterial Request Item` as mr_item,
+			`tabMaterial Request`  as mr
+		WHERE item_supp.supplier = %(supplier)s
+			AND item.name = item_supp.parent
+			AND mr_item.parent = mr.name
+			AND mr_item.item_code = item.name
+			AND mr.status != "Stopped"
+			AND mr.material_request_type = "Purchase"
+			AND mr.docstatus = 1
 			AND mr.per_ordered < 99.99""", {"supplier": source_name}, as_dict=1)
-	
+
 	material_requests = {}
 	for d in mr_items_list:
 		material_requests.setdefault(d.name, []).append(d.item_code)
@@ -293,5 +290,5 @@
 				]
 			}
 		}, target_doc)
-		
+
 	return target_doc
diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js
index 5ed210c..1e2379e 100644
--- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js
+++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js
@@ -2,7 +2,7 @@
 // License: GNU General Public License v3. See license.txt
 
 // attach required files
-{% include 'erpnext/buying/doctype/purchase_common/purchase_common.js' %};
+{% include 'erpnext/public/js/controllers/buying.js' %};
 
 frappe.ui.form.on('Suppier Quotation', {
 	setup: function() {
diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py
index 30899c8..1cb5a18 100644
--- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py
+++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py
@@ -8,6 +8,7 @@
 from frappe.model.mapper import get_mapped_doc
 
 from erpnext.controllers.buying_controller import BuyingController
+from erpnext.buying.utils import validate_for_items
 
 form_grid_templates = {
 	"items": "templates/form_grid/item_grid.html"
@@ -24,7 +25,7 @@
 		validate_status(self.status, ["Draft", "Submitted", "Stopped",
 			"Cancelled"])
 
-		self.validate_common()
+		validate_for_items(self)
 		self.validate_with_previous_doc()
 		self.validate_uom_is_integer("uom", "qty")
 
@@ -50,11 +51,6 @@
 			}
 		})
 
-
-	def validate_common(self):
-		pc = frappe.get_doc('Purchase Common')
-		pc.validate_for_items(self)
-
 def get_list_context(context=None):
 	from erpnext.controllers.website_list_for_contact import get_list_context
 	list_context = get_list_context(context)
diff --git a/erpnext/buying/utils.py b/erpnext/buying/utils.py
new file mode 100644
index 0000000..28c7579
--- /dev/null
+++ b/erpnext/buying/utils.py
@@ -0,0 +1,80 @@
+# 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.utils import flt, cstr, cint
+from frappe import _
+
+from erpnext.stock.doctype.item.item import get_last_purchase_details
+from erpnext.stock.doctype.item.item import validate_end_of_life
+
+def update_last_purchase_rate(doc, is_submit):
+	"""updates last_purchase_rate in item table for each item"""
+
+	import frappe.utils
+	this_purchase_date = frappe.utils.getdate(doc.get('posting_date') or doc.get('transaction_date'))
+
+	for d in doc.get("items"):
+		# get last purchase details
+		last_purchase_details = get_last_purchase_details(d.item_code, doc.name)
+
+		# compare last purchase date and this transaction's date
+		last_purchase_rate = None
+		if last_purchase_details and \
+				(last_purchase_details.purchase_date > this_purchase_date):
+			last_purchase_rate = last_purchase_details['base_rate']
+		elif is_submit == 1:
+			# even if this transaction is the latest one, it should be submitted
+			# for it to be considered for latest purchase rate
+			if flt(d.conversion_factor):
+				last_purchase_rate = flt(d.base_rate) / flt(d.conversion_factor)
+			else:
+				frappe.throw(_("UOM Conversion factor is required in row {0}").format(d.idx))
+
+		# update last purchsae rate
+		if last_purchase_rate:
+			frappe.db.sql("""update `tabItem` set last_purchase_rate = %s where name = %s""",
+				(flt(last_purchase_rate), d.item_code))
+
+def validate_for_items(doc):
+	items = []
+	for d in doc.get("items"):
+		if not d.qty:
+			if doc.doctype == "Purchase Receipt" and d.rejected_qty:
+				continue
+			frappe.throw(_("Please enter quantity for Item {0}").format(d.item_code))
+
+		# update with latest quantities
+		bin = frappe.db.sql("""select projected_qty from `tabBin` where
+			item_code = %s and warehouse = %s""", (d.item_code, d.warehouse), as_dict=1)
+
+		f_lst ={'projected_qty': bin and flt(bin[0]['projected_qty']) or 0, 'ordered_qty': 0, 'received_qty' : 0}
+		if d.doctype in ('Purchase Receipt Item', 'Purchase Invoice Item'):
+			f_lst.pop('received_qty')
+		for x in f_lst :
+			if d.meta.get_field(x):
+				d.set(x, f_lst[x])
+
+		item = frappe.db.sql("""select is_stock_item,
+			is_sub_contracted_item, end_of_life, disabled from `tabItem` where name=%s""",
+			d.item_code, as_dict=1)[0]
+
+		validate_end_of_life(d.item_code, item.end_of_life, item.disabled)
+
+		# validate stock item
+		if item.is_stock_item==1 and d.qty and not d.warehouse and not d.delivered_by_supplier:
+			frappe.throw(_("Warehouse is mandatory for stock Item {0} in row {1}").format(d.item_code, d.idx))
+
+		items.append(cstr(d.item_code))
+
+	if items and len(items) != len(set(items)) and \
+		not cint(frappe.db.get_single_value("Buying Settings", "allow_multiple_items") or 0):
+		frappe.throw(_("Same item cannot be entered multiple times."))
+
+def check_for_closed_status(doctype, docname):
+	status = frappe.db.get_value(doctype, docname, "status")
+
+	if status == "Closed":
+		frappe.throw(_("{0} {1} status is {2}").format(doctype, docname, status), frappe.InvalidStatusError)
+
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 518f686..910c19c 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -2,10 +2,10 @@
 # License: GNU General Public License v3. See license.txt
 
 from __future__ import unicode_literals
-import frappe
+import frappe, erpnext
 from frappe import _, throw
 from frappe.utils import today, flt, cint, fmt_money, formatdate, getdate
-from erpnext.setup.utils import get_company_currency, get_exchange_rate
+from erpnext.setup.utils import get_exchange_rate
 from erpnext.accounts.utils import get_fiscal_years, validate_fiscal_year, get_account_currency
 from erpnext.utilities.transaction_base import TransactionBase
 from erpnext.controllers.recurring_document import convert_to_recurring, validate_recurring_document
@@ -22,7 +22,7 @@
 	@property
 	def company_currency(self):
 		if not hasattr(self, "__company_currency"):
-			self.__company_currency = get_company_currency(self.company)
+			self.__company_currency = erpnext.get_company_currency(self.company)
 
 		return self.__company_currency
 
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index a1c7185..5bc8bb3 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -6,9 +6,10 @@
 from frappe import _, msgprint
 from frappe.utils import flt,cint, cstr
 
-from erpnext.setup.utils import get_company_currency
 from erpnext.accounts.party import get_party_details
 from erpnext.stock.get_item_details import get_conversion_factor
+from erpnext.buying.utils import validate_for_items
+from erpnext.stock.stock_ledger import get_valuation_rate
 
 from erpnext.controllers.stock_controller import StockController
 
@@ -40,9 +41,7 @@
 			# self.validate_purchase_return()
 			self.validate_rejected_warehouse()
 			self.validate_accepted_rejected_qty()
-
-			pc_obj = frappe.get_doc('Purchase Common')
-			pc_obj.validate_for_items(self)
+			validate_for_items(self)
 
 			#sub-contracting
 			self.validate_for_subcontracting()
@@ -88,9 +87,8 @@
 
 	def set_total_in_words(self):
 		from frappe.utils import money_in_words
-		company_currency = get_company_currency(self.company)
 		if self.meta.get_field("base_in_words"):
-			self.base_in_words = money_in_words(self.base_grand_total, company_currency)
+			self.base_in_words = money_in_words(self.base_grand_total, self.company_currency)
 		if self.meta.get_field("in_words"):
 			self.in_words = money_in_words(self.grand_total, self.currency)
 
@@ -225,9 +223,8 @@
 					"serial_no": rm.serial_no
 				})
 				if not rm.rate:
-					from erpnext.stock.stock_ledger import get_valuation_rate
-					rm.rate = get_valuation_rate(bom_item.item_code, self.supplier_warehouse, 
-						self.doctype, self.name)
+					rm.rate = get_valuation_rate(bom_item.item_code, self.supplier_warehouse,
+						self.doctype, self.name, currency=self.company_currency)
 			else:
 				rm.rate = bom_item.rate
 
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index 5f50ae3..c235d34 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -4,11 +4,9 @@
 from __future__ import unicode_literals
 import frappe
 from frappe.utils import cint, flt, cstr, comma_or
-from erpnext.setup.utils import get_company_currency
 from frappe import _, throw
 from erpnext.stock.get_item_details import get_bin_details
 from erpnext.stock.utils import get_incoming_rate
-from erpnext.stock.stock_ledger import get_valuation_rate
 from erpnext.stock.get_item_details import get_conversion_factor
 
 from erpnext.controllers.stock_controller import StockController
@@ -113,13 +111,11 @@
 
 	def set_total_in_words(self):
 		from frappe.utils import money_in_words
-		company_currency = get_company_currency(self.company)
-
 		disable_rounded_total = cint(frappe.db.get_value("Global Defaults", None, "disable_rounded_total"))
 
 		if self.meta.get_field("base_in_words"):
 			self.base_in_words = money_in_words(disable_rounded_total and
-				abs(self.base_grand_total) or abs(self.base_rounded_total), company_currency)
+				abs(self.base_grand_total) or abs(self.base_rounded_total), self.company_currency)
 		if self.meta.get_field("in_words"):
 			self.in_words = money_in_words(disable_rounded_total and
 				abs(self.grand_total) or abs(self.rounded_total), self.currency)
@@ -170,7 +166,7 @@
 			if d.meta.get_field("stock_qty"):
 				if not d.conversion_factor:
 					frappe.throw(_("Row {0}: Conversion Factor is mandatory").format(d.idx))
-				d.stock_qty = flt(d.qty) * flt(d.conversion_factor)			
+				d.stock_qty = flt(d.qty) * flt(d.conversion_factor)
 
 	def validate_selling_price(self):
 		def throw_message(item_name, rate, ref_rate_field):
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index add882c..9f05345 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -54,9 +54,9 @@
 
 						self.check_expense_account(item_row)
 
-						# If item is not a sample item 
+						# If item is not a sample item
 						# and ( valuation rate not mentioned in an incoming entry
-						# or incoming entry not found while delivering the item), 
+						# or incoming entry not found while delivering the item),
 						# try to pick valuation rate from previous sle or Item master and update in SLE
 						# Otherwise, throw an exception
 
@@ -96,25 +96,25 @@
 		return process_gl_map(gl_list)
 
 	def update_stock_ledger_entries(self, sle):
-		sle.valuation_rate = get_valuation_rate(sle.item_code, sle.warehouse, 
-			self.doctype, self.name)
+		sle.valuation_rate = get_valuation_rate(sle.item_code, sle.warehouse,
+			self.doctype, self.name, currency=self.company_currency)
 
 		sle.stock_value = flt(sle.qty_after_transaction) * flt(sle.valuation_rate)
 		sle.stock_value_difference = flt(sle.actual_qty) * flt(sle.valuation_rate)
-		
+
 		if sle.name:
 			frappe.db.sql("""
-				update 
-					`tabStock Ledger Entry` 
-				set 
+				update
+					`tabStock Ledger Entry`
+				set
 					stock_value = %(stock_value)s,
-					valuation_rate = %(valuation_rate)s, 
-					stock_value_difference = %(stock_value_difference)s 
-				where 
+					valuation_rate = %(valuation_rate)s,
+					stock_value_difference = %(stock_value_difference)s
+				where
 					name = %(name)s""", (sle))
-					
+
 		return sle
-					
+
 	def get_voucher_details(self, default_expense_account, default_cost_center, sle_map):
 		if self.doctype == "Stock Reconciliation":
 			return [frappe._dict({ "name": voucher_detail_no, "expense_account": default_expense_account,
@@ -163,9 +163,9 @@
 	def get_stock_ledger_details(self):
 		stock_ledger = {}
 		stock_ledger_entries = frappe.db.sql("""
-			select 
+			select
 				name, warehouse, stock_value_difference, valuation_rate,
-				voucher_detail_no, item_code, posting_date, posting_time, 
+				voucher_detail_no, item_code, posting_date, posting_time,
 				actual_qty, qty_after_transaction
 			from
 				`tabStock Ledger Entry`
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index 0e02df8..bec57f4 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -3,10 +3,9 @@
 
 from __future__ import unicode_literals
 import json
-import frappe
+import frappe, erpnext
 from frappe import _, scrub
 from frappe.utils import cint, flt, round_based_on_smallest_currency_fraction
-from erpnext.setup.utils import get_company_currency
 from erpnext.controllers.accounts_controller import validate_conversion_rate, \
 	validate_taxes_and_charges, validate_inclusive_tax
 
@@ -38,7 +37,7 @@
 
 	def validate_conversion_rate(self):
 		# validate conversion rate
-		company_currency = get_company_currency(self.doc.company)
+		company_currency = erpnext.get_company_currency(self.doc.company)
 		if not self.doc.currency or self.doc.currency == company_currency:
 			self.doc.currency = company_currency
 			self.doc.conversion_rate = 1.0
@@ -327,7 +326,7 @@
 			self.doc.rounded_total = round_based_on_smallest_currency_fraction(self.doc.grand_total,
 				self.doc.currency, self.doc.precision("rounded_total"))
 		if self.doc.meta.get_field("base_rounded_total"):
-			company_currency = get_company_currency(self.doc.company)
+			company_currency = erpnext.get_company_currency(self.doc.company)
 
 			self.doc.base_rounded_total = \
 				round_based_on_smallest_currency_fraction(self.doc.base_grand_total,
diff --git a/erpnext/crm/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py
index 913d2e4..3c553a5 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.py
+++ b/erpnext/crm/doctype/opportunity/opportunity.py
@@ -194,11 +194,12 @@
 				quotation.transaction_date)
 
 		quotation.conversion_rate = exchange_rate
-		
+
 		# get default taxes
 		taxes = get_default_taxes_and_charges("Sales Taxes and Charges Template")
-		quotation.extend("taxes", taxes)
-		
+		if taxes:
+			quotation.extend("taxes", taxes)
+
 		quotation.run_method("set_missing_values")
 		quotation.run_method("calculate_taxes_and_totals")
 
diff --git a/erpnext/demo/setup/setup_data.py b/erpnext/demo/setup/setup_data.py
index 400b076..c1a8bed 100644
--- a/erpnext/demo/setup/setup_data.py
+++ b/erpnext/demo/setup/setup_data.py
@@ -63,6 +63,10 @@
 			"language": "english"
 		})
 
+		company = erpnext.get_default_company()
+		company.db_set('default_payroll_payable_account',
+			frappe.db.get_value('Account', dict(account_name='Payroll Payable')))
+
 def setup_demo_page():
 	# home page should always be "start"
 	website_settings = frappe.get_doc("Website Settings", "Website Settings")
diff --git a/erpnext/demo/user/hr.py b/erpnext/demo/user/hr.py
index 2536602..0b644c4 100644
--- a/erpnext/demo/user/hr.py
+++ b/erpnext/demo/user/hr.py
@@ -34,14 +34,16 @@
 		process_payroll.salary_slip_based_on_timesheet = 0
 		process_payroll.create_salary_slips()
 		process_payroll.submit_salary_slips()
-		process_payroll.make_journal_entry(reference_date=frappe.flags.current_date,
-			reference_number=random_string(10))
+		process_payroll.make_accural_jv_entry()
+		# process_payroll.make_journal_entry(reference_date=frappe.flags.current_date,
+		# 	reference_number=random_string(10))
 
 		process_payroll.salary_slip_based_on_timesheet = 1
 		process_payroll.create_salary_slips()
 		process_payroll.submit_salary_slips()
-		process_payroll.make_journal_entry(reference_date=frappe.flags.current_date,
-			reference_number=random_string(10))
+		process_payroll.make_accural_jv_entry()
+		# process_payroll.make_journal_entry(reference_date=frappe.flags.current_date,
+		# 	reference_number=random_string(10))
 
 	if frappe.db.get_global('demo_hr_user'):
 		make_timesheet_records()
diff --git a/erpnext/docs/assets/img/accounts/pos-customer.png b/erpnext/docs/assets/img/accounts/pos-customer.png
index c3cbb8a..20bce38 100644
--- a/erpnext/docs/assets/img/accounts/pos-customer.png
+++ b/erpnext/docs/assets/img/accounts/pos-customer.png
Binary files differ
diff --git a/erpnext/docs/assets/img/accounts/pos-email.png b/erpnext/docs/assets/img/accounts/pos-email.png
new file mode 100644
index 0000000..31aa086
--- /dev/null
+++ b/erpnext/docs/assets/img/accounts/pos-email.png
Binary files differ
diff --git a/erpnext/docs/assets/img/taxes-and-charges.gif b/erpnext/docs/assets/img/selling/taxes-and-charges.gif
similarity index 100%
rename from erpnext/docs/assets/img/taxes-and-charges.gif
rename to erpnext/docs/assets/img/selling/taxes-and-charges.gif
Binary files differ
diff --git a/erpnext/docs/assets/img/users-and-permissions/reset-roles-permisison-for-page-report.png b/erpnext/docs/assets/img/users-and-permissions/reset-roles-permisison-for-page-report.png
new file mode 100644
index 0000000..aec9293
--- /dev/null
+++ b/erpnext/docs/assets/img/users-and-permissions/reset-roles-permisison-for-page-report.png
Binary files differ
diff --git a/erpnext/docs/assets/img/users-and-permissions/role-permission-for-page-and-report.png b/erpnext/docs/assets/img/users-and-permissions/role-permission-for-page-and-report.png
new file mode 100644
index 0000000..69b31d6
--- /dev/null
+++ b/erpnext/docs/assets/img/users-and-permissions/role-permission-for-page-and-report.png
Binary files differ
diff --git a/erpnext/docs/assets/img/users-and-permissions/roles-for-page.png b/erpnext/docs/assets/img/users-and-permissions/roles-for-page.png
new file mode 100644
index 0000000..f28c6d7
--- /dev/null
+++ b/erpnext/docs/assets/img/users-and-permissions/roles-for-page.png
Binary files differ
diff --git a/erpnext/docs/assets/img/users-and-permissions/roles-for-report.png b/erpnext/docs/assets/img/users-and-permissions/roles-for-report.png
new file mode 100644
index 0000000..1f8fd4e
--- /dev/null
+++ b/erpnext/docs/assets/img/users-and-permissions/roles-for-report.png
Binary files differ
diff --git a/erpnext/docs/user/manual/en/accounts/point-of-sale-pos-invoice.md b/erpnext/docs/user/manual/en/accounts/point-of-sale-pos-invoice.md
index 64fa22c..0c7e591 100644
--- a/erpnext/docs/user/manual/en/accounts/point-of-sale-pos-invoice.md
+++ b/erpnext/docs/user/manual/en/accounts/point-of-sale-pos-invoice.md
@@ -27,7 +27,7 @@
 
 ### Customer
 
-You can select one of the existing Customer from the Customer master. If Customer doesn't exist in the Customer master, enter Customer Name in the POS Invoice view itself. On creation of POS Invoice, Customer will be auto-created in the Customer master.
+In POS, user can select the existing customer during making an order or create the new customer. This features works in the offline mode also. User can also add the customer details like contact number, address details etc on the form. The customer which has been created from the POS will be synced when the internet connection is active.
 
 <img class="screenshot" alt="POS Customer" src="{{docs_base_url}}/assets/img/accounts/pos-customer.png">
 
@@ -105,4 +105,9 @@
 
 To see entries after “Submit”, click on “View Ledger”.
 
+### Email
+User can send email from the POS, after submission of an order, user has to click on menu > email
+<img class="screenshot" alt="POS Payment" src="{{docs_base_url}}/assets/img/accounts/pos-email.png">
+After sync of an order, email sent to the customer with the print of the bill in the attachment
+
 {next}
diff --git a/erpnext/docs/user/manual/en/setting-up/users-and-permissions/index.txt b/erpnext/docs/user/manual/en/setting-up/users-and-permissions/index.txt
index b00f32a..74243df 100644
--- a/erpnext/docs/user/manual/en/setting-up/users-and-permissions/index.txt
+++ b/erpnext/docs/user/manual/en/setting-up/users-and-permissions/index.txt
@@ -1,4 +1,5 @@
 adding-users
 role-based-permissions
 user-permissions
+role-permisison-for-page-and-report
 sharing
diff --git a/erpnext/docs/user/manual/en/setting-up/users-and-permissions/role-permisison-for-page-and-report.md b/erpnext/docs/user/manual/en/setting-up/users-and-permissions/role-permisison-for-page-and-report.md
new file mode 100644
index 0000000..3a26a32
--- /dev/null
+++ b/erpnext/docs/user/manual/en/setting-up/users-and-permissions/role-permisison-for-page-and-report.md
@@ -0,0 +1,25 @@
+# Role Permission for Page and Report
+
+In ERPNext, user can make his custom user interface using Page and the custom report using Report Builder or Query Report. ERPNext has role-based-permission system where user can assign roles to the user. And the same role can be assigned to the page and report, to access them.
+
+If user has enabled the developer mode, then they can add the roles directly in the page and report record. But in that case, the permissions will also be reflected in the json file for the page / report.
+
+### For Page
+<img alt="Assign roles to the page" class="screenshot" src="{{docs_base_url}}/assets/img/users-and-permissions/roles-for-page.png">
+
+### For Report
+<img alt="Assign roles to the report" class="screenshot" src="{{docs_base_url}}/assets/img/users-and-permissions/roles-for-report.png">
+
+## Tool for custom roles assignment
+
+If developer mode is disabled, then user can assign the roles to the page and report, using "Role Permission for Page and Report" page.
+
+To access, goto Setup > Permissions > Role Permission for Page and Report
+
+<img alt="Tools to assign custom roles to the page" class="screenshot" src="{{docs_base_url}}/assets/img/users-and-permissions/role-permission-for-page-and-report.png">
+
+### Reset to defaults
+
+Using "Reset to Default" button, user can remove the custom permissions applied on a page or report. Then default permissions will be applicable on that page or report.
+
+<img alt="Reset the default roles" class="screenshot" src="{{docs_base_url}}/assets/img/users-and-permissions/reset-roles-permisison-for-page-report.png">
diff --git a/erpnext/hr/doctype/salary_component/salary_component.py b/erpnext/hr/doctype/salary_component/salary_component.py
index c02d952..35d274c 100644
--- a/erpnext/hr/doctype/salary_component/salary_component.py
+++ b/erpnext/hr/doctype/salary_component/salary_component.py
@@ -5,7 +5,7 @@
 from __future__ import unicode_literals
 import frappe
 from frappe.model.document import Document
-from frappe import _
+from frappe.model.naming import append_number_if_name_exists
 
 class SalaryComponent(Document):
 	def validate(self):
@@ -13,12 +13,10 @@
 
 	def validate_abbr(self):
 		if not self.salary_component_abbr:
-			self.salary_component_abbr = ''.join([c[0] for c in self.salary_component.split()]).upper()
+			self.salary_component_abbr = ''.join([c[0] for c in
+				self.salary_component.split()]).upper()
 
 		self.salary_component_abbr = self.salary_component_abbr.strip()
 
-		if self.get('__islocal') and len(self.salary_component_abbr) > 5:
-			frappe.throw(_("Abbreviation cannot have more than 5 characters"))
-
-		if frappe.db.sql("select salary_component_abbr from `tabSalary Component` where name!=%s and salary_component_abbr=%s", (self.name, self.salary_component_abbr)):
-			frappe.throw(_("Abbreviation {0} already used for another salary component").format(self.salary_component_abbr))
\ No newline at end of file
+		self.salary_component_abbr = append_number_if_name_exists('Salary Component',
+			self.salary_component_abbr, 'salary_component_abbr', separator='_')
\ No newline at end of file
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py
index 34b729f..a4d6460 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -2,13 +2,12 @@
 # License: GNU General Public License v3. See license.txt
 
 from __future__ import unicode_literals
-import frappe
+import frappe, erpnext
 
 from frappe.utils import add_days, cint, cstr, flt, getdate, rounded, date_diff, money_in_words
 from frappe.model.naming import make_autoname
 
 from frappe import msgprint, _
-from erpnext.setup.utils import get_company_currency
 from erpnext.hr.doctype.process_payroll.process_payroll import get_start_end_dates
 from erpnext.hr.doctype.employee.employee import get_holiday_list_for_employee
 from erpnext.utilities.transaction_base import TransactionBase
@@ -33,7 +32,7 @@
 		# if self.salary_slip_based_on_timesheet or not self.net_pay:
 		self.calculate_net_pay()
 
-		company_currency = get_company_currency(self.company)
+		company_currency = erpnext.get_company_currency(self.company)
 		self.total_in_words = money_in_words(self.rounded_total, company_currency)
 
 		if frappe.db.get_single_value("HR Settings", "max_working_hours_against_timesheet"):
@@ -348,7 +347,7 @@
 
 		self.sum_components('earnings', 'gross_pay')
 		self.sum_components('deductions', 'total_deduction')
-		
+
 		self.set_loan_repayment()
 
 		self.net_pay = flt(self.gross_pay) - (flt(self.total_deduction) + flt(self.total_loan_repayment))
@@ -356,11 +355,11 @@
 			self.precision("net_pay") if disable_rounded_total else 0)
 
 	def set_loan_repayment(self):
-		employee_loan = frappe.db.sql("""select sum(principal_amount) as principal_amount, sum(interest_amount) as interest_amount, 
+		employee_loan = frappe.db.sql("""select sum(principal_amount) as principal_amount, sum(interest_amount) as interest_amount,
 						sum(total_payment) as total_loan_repayment from `tabRepayment Schedule`
 						where payment_date between %s and %s and parent in (select name from `tabEmployee Loan`
 						where employee = %s and repay_from_salary = 1 and docstatus = 1)""",
-						(self.start_date, self.end_date, self.employee), as_dict=True)				
+						(self.start_date, self.end_date, self.employee), as_dict=True)
 		if employee_loan:
 			self.principal_amount = employee_loan[0].principal_amount
 			self.interest_amount = employee_loan[0].interest_amount
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.js b/erpnext/manufacturing/doctype/production_order/production_order.js
index 1217790..6037397 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.js
+++ b/erpnext/manufacturing/doctype/production_order/production_order.js
@@ -218,7 +218,7 @@
 					project: doc.project
 					},
 			callback: function(r) {
-				$.each(["description", "stock_uom", "bom_no"], function(i, field) {
+				$.each(["description", "stock_uom", "project", "bom_no"], function(i, field) {
 					cur_frm.set_value(field, r.message[field]);
 				});
 
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index 2d9a067..b9b10c1 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -498,6 +498,7 @@
 			frappe.throw(_("Default BOM for {0} not found for Project {1}").format(item, project))
 		frappe.throw(_("Default BOM for {0} not found").format(item))
 
+	res['project'] = frappe.db.get_value('BOM', res['bom_no'], 'project')
 	res.update(check_if_scrap_warehouse_mandatory(res["bom_no"]))
 
 	return res
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index cb8ba03..3711bc8 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -381,4 +381,5 @@
 erpnext.patches.v7_2.make_all_assessment_group
 erpnext.patches.v8_0.manufacturer_childtable_migrate
 erpnext.patches.v8_0.repost_reserved_qty_for_multiple_sales_uom
-erpnext.patches.v8_0.addresses_linked_to_lead
\ No newline at end of file
+erpnext.patches.v8_0.addresses_linked_to_lead
+execute:frappe.delete_doc('DocType', 'Purchase Common')
\ No newline at end of file
diff --git a/erpnext/patches/v8_0/manufacturer_childtable_migrate.py b/erpnext/patches/v8_0/manufacturer_childtable_migrate.py
index 6d566b4..87a3431 100644
--- a/erpnext/patches/v8_0/manufacturer_childtable_migrate.py
+++ b/erpnext/patches/v8_0/manufacturer_childtable_migrate.py
@@ -6,20 +6,19 @@
 
 def execute():
 
-    # reading from json and writing it to mariadb
-    # reload_doc needed here with information because new table introduced
-    frappe.reload_doc('stock', 'doctype', 'item_manufacturer')
-    # reload_doctype is a simpler concept of reload_doc
-    frappe.reload_doctype('Item')
+	# reading from json and writing it to mariadb
+	# reload_doc needed here with information because new table introduced
+	frappe.reload_doc('stock', 'doctype', 'item_manufacturer')
+	# reload_doctype is a simpler concept of reload_doc
+	frappe.reload_doctype('Item')
 
-    item_manufacturers = frappe.get_all("Item", fields=["name", "manufacturer", "manufacturer_part_no"])
-    for item in item_manufacturers:
-        if item.manufacturer or item.manufacturer_part_no:
-            item_doc = frappe.get_doc("Item", item.name)
-            item_doc.append("manufacturers", {
-                "manufacturer": item.manufacturer,
-                "manufacturer_part_no": item.manufacturer_part_no
-            })
-            item_doc.flags.ignore_validate = True
-            item_doc.flags.ignore_mandatory = True
-            item_doc.save()
+	item_manufacturers = frappe.get_all("Item", fields=["name", "manufacturer", "manufacturer_part_no"])
+	for item in item_manufacturers:
+		if item.manufacturer or item.manufacturer_part_no:
+			item_doc = frappe.get_doc("Item", item.name)
+			item_doc.append("manufacturers", {
+				"manufacturer": item.manufacturer,
+				"manufacturer_part_no": item.manufacturer_part_no
+			})
+			
+			item_doc.get("manufacturers")[0].db_update()
\ No newline at end of file
diff --git a/erpnext/projects/doctype/project/project_list.js b/erpnext/projects/doctype/project/project_list.js
index 437bf60..0f715bf 100644
--- a/erpnext/projects/doctype/project/project_list.js
+++ b/erpnext/projects/doctype/project/project_list.js
@@ -1,5 +1,5 @@
 frappe.listview_settings['Project'] = {
-	add_fields: ["status", "priority", "is_active", "percent_complete", "expected_end_date"],
+	add_fields: ["status", "priority", "is_active", "percent_complete", "expected_end_date", "project_name"],
 	filters:[["status","=", "Open"]],
 	get_indicator: function(doc) {
 		if(doc.status=="Open" && doc.percent_complete) {
diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.js b/erpnext/public/js/controllers/buying.js
similarity index 97%
rename from erpnext/buying/doctype/purchase_common/purchase_common.js
rename to erpnext/public/js/controllers/buying.js
index 6867dd0..108aac1 100644
--- a/erpnext/buying/doctype/purchase_common/purchase_common.js
+++ b/erpnext/public/js/controllers/buying.js
@@ -113,7 +113,7 @@
 			frappe.model.round_floats_in(item, ["qty", "received_qty"]);
 
 			if(!doc.is_return && this.validate_negative_quantity(cdt, cdn, item, ["qty", "received_qty"])){ return }
-			
+
 			if(!item.rejected_qty && item.qty) {
 				item.received_qty = item.qty;
 			}
@@ -138,14 +138,14 @@
 		frappe.model.round_floats_in(item, ["received_qty", "rejected_qty"]);
 
 		if(!doc.is_return && this.validate_negative_quantity(cdt, cdn, item, ["received_qty", "rejected_qty"])){ return }
-		
+
 		item.qty = flt(item.received_qty - item.rejected_qty, precision("qty", item));
 		this.qty(doc, cdt, cdn);
 	},
 
 	validate_negative_quantity: function(cdt, cdn, item, fieldnames){
 		if(!item || !fieldnames) { return }
-		
+
 		var is_negative_qty = false;
 		for(var i = 0; i<fieldnames.length; i++) {
 			if(item[fieldnames[i]] < 0){
@@ -219,12 +219,12 @@
 						my_items.push(cur_frm.doc.items[i].item_code);
 					}
 				}
-				frappe.call({	
+				frappe.call({
 					method: "erpnext.buying.doctype.purchase_common.purchase_common.get_linked_material_requests",
 					args:{
-						items: my_items						
-					}, 
-					callback: function(r) { 
+						items: my_items
+					},
+					callback: function(r) {
 						var i = 0;
 						var item_length = cur_frm.doc.items.length;
 						while (i < item_length) {
@@ -239,32 +239,32 @@
 									d.qty = d.qty  - my_qty;
 									cur_frm.doc.items[i].stock_qty = my_qty*cur_frm.doc.items[i].conversion_factor;
 									cur_frm.doc.items[i].qty = my_qty;
-									
+
 									frappe.msgprint("Assigning " + d.mr_name + " to " + d.item_code + " (row " + cur_frm.doc.items[i].idx + ")");
 									if (qty > 0)
 									{
 										frappe.msgprint("Splitting " + qty + " units of " + d.item_code);
 										var newrow = frappe.model.add_child(cur_frm.doc, cur_frm.doc.items[i].doctype, "items");
 										item_length++;
-										
+
 										for (key in cur_frm.doc.items[i])
 										{
 											newrow[key] = cur_frm.doc.items[i][key];
 										}
-										
+
 										newrow.idx = item_length;
 										newrow["stock_qty"] = newrow.conversion_factor*qty;
 										newrow["qty"] = qty;
-										
+
 										newrow["material_request"] = "";
 										newrow["material_request_item"] = "";
-										
+
 									}
-									
-									
-									
+
+
+
 								}
-							
+
 							});
 							i++;
 						}
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 1c9c0ab..7e0dccc 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -97,7 +97,7 @@
 			});
 
 			if(this.frm.doc.company && !this.frm.doc.amended_from) {
-				this.frm.script_manager.trigger("company");
+				this.frm.trigger("company");
 			}
 		}
 
@@ -295,7 +295,7 @@
 
 		if (item.serial_no) {
 			if (!item.item_code) {
-				this.frm.script_manager.trigger("item_code", cdt, cdn);
+				this.frm.trigger("item_code", cdt, cdn);
 			}
 			else {
 				var sr_no = [];
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index dd7bca9..26298bc 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -123,7 +123,7 @@
 			{"company": self.name, "account_type": "Receivable", "is_group": 0}))
 		frappe.db.set(self, "default_payable_account", frappe.db.get_value("Account",
 			{"company": self.name, "account_type": "Payable", "is_group": 0}))
-			
+
 	def validate_coa_input(self):
 		if self.create_chart_of_accounts_based_on == "Existing Company":
 			self.chart_of_accounts = None
@@ -294,7 +294,3 @@
 		parts.append(company_abbr)
 
 	return " - ".join(parts)
-
-def get_company_currency(company):
-	return frappe.local_cache("company_currency", company,
-		lambda: frappe.db.get_value("Company", company, "default_currency"))
diff --git a/erpnext/setup/setup_wizard/setup_wizard.py b/erpnext/setup/setup_wizard/setup_wizard.py
index 26509ed..922479c 100644
--- a/erpnext/setup/setup_wizard/setup_wizard.py
+++ b/erpnext/setup/setup_wizard/setup_wizard.py
@@ -177,6 +177,7 @@
 	selling_settings.cust_master_name = "Customer Name"
 	selling_settings.so_required = "No"
 	selling_settings.dn_required = "No"
+	selling_settings.allow_multiple_items = 1
 	selling_settings.save()
 
 	buying_settings = frappe.get_doc("Buying Settings")
@@ -184,6 +185,7 @@
 	buying_settings.po_required = "No"
 	buying_settings.pr_required = "No"
 	buying_settings.maintain_same_rate = 1
+	buying_settings.allow_multiple_items = 1
 	buying_settings.save()
 
 	notification_control = frappe.get_doc("Notification Control")
diff --git a/erpnext/setup/utils.py b/erpnext/setup/utils.py
index cb63837..55a0fd3 100644
--- a/erpnext/setup/utils.py
+++ b/erpnext/setup/utils.py
@@ -3,19 +3,10 @@
 
 from __future__ import unicode_literals
 import frappe
-from frappe import _, throw
+from frappe import _
 from frappe.utils import flt
 from frappe.utils import get_datetime_str, nowdate
 
-def get_company_currency(company):
-	currency = frappe.db.get_value("Company", company, "default_currency", cache=True)
-	if not currency:
-		currency = frappe.db.get_default("currency")
-	if not currency:
-		throw(_('Please specify Default Currency in Company Master and Global Defaults'))
-
-	return currency
-
 def get_root_of(doctype):
 	"""Get root element of a DocType with a tree structure"""
 	result = frappe.db.sql_list("""select name from `tab%s`
diff --git a/erpnext/stock/doctype/material_request/material_request.js b/erpnext/stock/doctype/material_request/material_request.js
index 3a5a351..be0b4c2 100644
--- a/erpnext/stock/doctype/material_request/material_request.js
+++ b/erpnext/stock/doctype/material_request/material_request.js
@@ -1,7 +1,7 @@
 // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
-{% include 'erpnext/buying/doctype/purchase_common/purchase_common.js' %};
+{% include 'erpnext/public/js/controllers/buying.js' %};
 
 frappe.ui.form.on('Material Request', {
 	setup: function(frm) {
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index ca25414..82c4c19 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -13,7 +13,7 @@
 from erpnext.stock.stock_balance import update_bin_qty, get_indented_qty
 from erpnext.controllers.buying_controller import BuyingController
 from erpnext.manufacturing.doctype.production_order.production_order import get_item_details
-
+from erpnext.buying.utils import check_for_closed_status, validate_for_items
 
 form_grid_templates = {
 	"items": "templates/form_grid/material_request_grid.html"
@@ -72,12 +72,9 @@
 		from erpnext.controllers.status_updater import validate_status
 		validate_status(self.status, ["Draft", "Submitted", "Stopped", "Cancelled"])
 
-		pc_obj = frappe.get_doc('Purchase Common')
-		pc_obj.validate_for_items(self)
+		validate_for_items(self)
 
 		# self.set_title()
-
-
 		# self.validate_qty_against_so()
 		# NOTE: Since Item BOM and FG quantities are combined, using current data, it cannot be validated
 		# Though the creation of Material Request from a Production Plan can be rethought to fix this
@@ -112,9 +109,7 @@
 		self.update_requested_qty()
 
 	def on_cancel(self):
-		pc_obj = frappe.get_doc('Purchase Common')
-
-		pc_obj.check_for_closed_status(self.doctype, self.name)
+		check_for_closed_status(self.doctype, self.name)
 
 		self.update_requested_qty()
 
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
index f9370b4..383de01 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
@@ -1,7 +1,7 @@
 // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
-{% include 'erpnext/buying/doctype/purchase_common/purchase_common.js' %};
+{% include 'erpnext/public/js/controllers/buying.js' %};
 
 frappe.provide("erpnext.stock");
 
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index b89987c..1f8fd8d 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -12,6 +12,7 @@
 from erpnext.controllers.buying_controller import BuyingController
 from erpnext.accounts.utils import get_account_currency
 from frappe.desk.notifications import clear_doctype_notifications
+from erpnext.buying.utils import check_for_closed_status, update_last_purchase_rate
 
 form_grid_templates = {
 	"items": "templates/form_grid/item_grid.html"
@@ -56,8 +57,7 @@
 		self.validate_uom_is_integer("uom", ["qty", "received_qty"])
 		self.validate_uom_is_integer("stock_uom", "stock_qty")
 
-		pc_obj = frappe.get_doc('Purchase Common')
-		self.check_for_closed_status(pc_obj)
+		self.check_for_closed_status()
 
 		if getdate(self.posting_date) > getdate(nowdate()):
 			throw(_("Posting Date cannot be future date"))
@@ -98,17 +98,16 @@
 		return po_qty, po_warehouse
 
 	# Check for Closed status
-	def check_for_closed_status(self, pc_obj):
+	def check_for_closed_status(self):
 		check_list =[]
 		for d in self.get('items'):
-			if d.meta.get_field('purchase_order') and d.purchase_order and d.purchase_order not in check_list:
+			if (d.meta.get_field('purchase_order') and d.purchase_order
+				and d.purchase_order not in check_list):
 				check_list.append(d.purchase_order)
-				pc_obj.check_for_closed_status('Purchase Order', d.purchase_order)
+				check_for_closed_status('Purchase Order', d.purchase_order)
 
 	# on submit
 	def on_submit(self):
-		purchase_controller = frappe.get_doc("Purchase Common")
-
 		# Check for Approving Authority
 		frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
 			self.company, self.base_grand_total)
@@ -120,7 +119,7 @@
 		self.update_billing_status()
 
 		if not self.is_return:
-			purchase_controller.update_last_purchase_rate(self, 1)
+			update_last_purchase_rate(self, 1)
 
 		# Updating stock ledger should always be called after updating prevdoc status,
 		# because updating ordered qty in bin depends upon updated ordered qty in PO
@@ -140,9 +139,7 @@
 			frappe.throw(_("Purchase Invoice {0} is already submitted").format(self.submit_rv[0][0]))
 
 	def on_cancel(self):
-		pc_obj = frappe.get_doc('Purchase Common')
-
-		self.check_for_closed_status(pc_obj)
+		self.check_for_closed_status()
 		# Check if Purchase Invoice has been submitted against current Purchase Order
 		submitted = frappe.db.sql("""select t1.name
 			from `tabPurchase Invoice` t1,`tabPurchase Invoice Item` t2
@@ -157,7 +154,7 @@
 		self.update_billing_status()
 
 		if not self.is_return:
-			pc_obj.update_last_purchase_rate(self, 0)
+			update_last_purchase_rate(self, 0)
 
 		# Updating stock ledger should always be called after updating prevdoc status,
 		# because updating ordered qty in bin depends upon updated ordered qty in PO
@@ -170,9 +167,6 @@
 				bin = frappe.db.sql("select actual_qty from `tabBin` where item_code = %s and warehouse = %s", (d.rm_item_code, self.supplier_warehouse), as_dict = 1)
 				d.current_stock = bin and flt(bin[0]['actual_qty']) or 0
 
-	def get_rate(self,arg):
-		return frappe.get_doc('Purchase Common').get_rate(arg,self)
-
 	def get_gl_entries(self, warehouse_account=None):
 		from erpnext.accounts.general_ledger import process_gl_map
 
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index 948a626..82f9bf1 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -2,7 +2,7 @@
 # License: GNU General Public License v3. See license.txt
 from __future__ import unicode_literals
 
-import frappe
+import frappe, erpnext
 from frappe import _
 from frappe.utils import cint, flt, cstr, now
 from erpnext.stock.utils import get_valuation_method
@@ -258,14 +258,15 @@
 
 			if not self.valuation_rate and actual_qty > 0:
 				self.valuation_rate = sle.incoming_rate
-				
+
 			# Get valuation rate from previous SLE or Item master, if item is not a sample item
 			if not self.valuation_rate and sle.voucher_detail_no:
 				is_sample_item = self.check_if_sample_item(sle.voucher_type, sle.voucher_detail_no)
 				if not is_sample_item:
-					self.valuation_rate = get_valuation_rate(sle.item_code, sle.warehouse, 
-						sle.voucher_type, sle.voucher_no, self.allow_zero_rate)
-		
+					self.valuation_rate = get_valuation_rate(sle.item_code, sle.warehouse,
+						sle.voucher_type, sle.voucher_no, self.allow_zero_rate,
+						currency=erpnext.get_company_currency(sle.company))
+
 	def get_fifo_values(self, sle):
 		incoming_rate = flt(sle.incoming_rate)
 		actual_qty = flt(sle.actual_qty)
@@ -291,11 +292,12 @@
 					# Get valuation rate from last sle if exists or from valuation rate field in item master
 					is_sample_item = self.check_if_sample_item(sle.voucher_type, sle.voucher_detail_no)
 					if not is_sample_item:
-						_rate = get_valuation_rate(sle.item_code, sle.warehouse, 
-							sle.voucher_type, sle.voucher_no, self.allow_zero_rate)
+						_rate = get_valuation_rate(sle.item_code, sle.warehouse,
+							sle.voucher_type, sle.voucher_no, self.allow_zero_rate,
+							currency=erpnext.get_company_currency(sle.company))
 					else:
 						_rate = 0
-						
+
 					self.stock_queue.append([0, _rate])
 
 				index = None
@@ -341,11 +343,11 @@
 
 		if not self.stock_queue:
 			self.stock_queue.append([0, sle.incoming_rate or sle.outgoing_rate or self.valuation_rate])
-			
+
 	def check_if_sample_item(self, voucher_type, voucher_detail_no):
 		ref_item_dt = voucher_type + (" Detail" if voucher_type == "Stock Entry" else " Item")
 		return frappe.db.get_value(ref_item_dt, voucher_detail_no, "is_sample_item")
-		
+
 	def get_sle_before_datetime(self):
 		"""get previous stock ledger entry before current time-bucket"""
 		return get_stock_ledger_entries(self.args, "<", "desc", "limit 1", for_update=False)
@@ -419,7 +421,8 @@
 			"order": order
 		}, previous_sle, as_dict=1, debug=debug)
 
-def get_valuation_rate(item_code, warehouse, voucher_type, voucher_no, allow_zero_rate=False):
+def get_valuation_rate(item_code, warehouse, voucher_type, voucher_no,
+	allow_zero_rate=False, currency=None):
 	# Get valuation rate from last sle for the same item and warehouse
 	last_valuation_rate = frappe.db.sql("""select valuation_rate
 		from `tabStock Ledger Entry`
@@ -441,6 +444,11 @@
 		# syste does not found any SLE, then take valuation rate from Item
 		valuation_rate = frappe.db.get_value("Item", item_code, "valuation_rate")
 
+	if not valuation_rate:
+		# try in price list
+		valuation_rate = frappe.db.get_value('Item Price',
+			dict(item_code=item_code, buying=1, currency=currency), 'price_list_rate')
+
 	if not allow_zero_rate and not valuation_rate \
 			and cint(frappe.db.get_value("Accounts Settings", None, "auto_accounting_for_stock")):
 		frappe.local.message_log = []