Merge pull request #5230 from vjFaLk/gh-templates

[Fix] Added Discuss link in Issue Template
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index 32ad6d2..5af3e82 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -4,6 +4,7 @@
 frappe.provide("erpnext.accounts");
 {% include 'buying/doctype/purchase_common/purchase_common.js' %};
 
+
 erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
 	onload: function() {
 		this._super();
@@ -18,50 +19,58 @@
 
 	refresh: function(doc) {
 		this._super();
+		
+		hide_fields(this.frm.doc);
 
 		// Show / Hide button
 		this.show_general_ledger();
+		
+		if(doc.update_stock==1 && doc.docstatus==1) {
+			this.show_stock_ledger();
+		}
 
-		if(!doc.is_return) {
-			if(doc.docstatus==1) {
-				if(doc.outstanding_amount > 0) {
-					this.frm.add_custom_button(__('Payment'), this.make_bank_entry, __("Make"));
-					cur_frm.page.set_inner_btn_group_as_primary(__("Make"));
-				}
-				if(doc.outstanding_amount >= 0 || Math.abs(flt(doc.outstanding_amount)) < flt(doc.grand_total)) {
-					cur_frm.add_custom_button(__('Debit Note'), this.make_debit_note, __("Make"));
-				}
+		if(!doc.is_return && doc.docstatus==1) {
+			if(doc.outstanding_amount > 0) {
+				this.frm.add_custom_button(__('Payment'), this.make_bank_entry, __("Make"));
+				cur_frm.page.set_inner_btn_group_as_primary(__("Make"));
 			}
-
-			if(doc.docstatus===0) {
-				cur_frm.add_custom_button(__('Purchase Order'), function() {
-					frappe.model.map_current_doc({
-						method: "erpnext.buying.doctype.purchase_order.purchase_order.make_purchase_invoice",
-						source_doctype: "Purchase Order",
-						get_query_filters: {
-							supplier: cur_frm.doc.supplier || undefined,
-							docstatus: 1,
-							status: ["!=", "Closed"],
-							per_billed: ["<", 99.99],
-							company: cur_frm.doc.company
-						}
-					})
-				}, __("Get items from"));
-
-				cur_frm.add_custom_button(__('Purchase Receipt'), function() {
-					frappe.model.map_current_doc({
-						method: "erpnext.stock.doctype.purchase_receipt.purchase_receipt.make_purchase_invoice",
-						source_doctype: "Purchase Receipt",
-						get_query_filters: {
-							supplier: cur_frm.doc.supplier || undefined,
-							docstatus: 1,
-							status: ["!=", "Closed"],
-							company: cur_frm.doc.company
-						}
-					})
-				}, __("Get items from"));
+			
+			if(doc.outstanding_amount >= 0 || Math.abs(flt(doc.outstanding_amount)) < flt(doc.grand_total)) {
+				cur_frm.add_custom_button(doc.update_stock ? __('Purchase Return') : __('Debit Note'), 
+					this.make_debit_note, __("Make"));
 			}
 		}
+		
+		if(doc.docstatus===0) {
+			cur_frm.add_custom_button(__('Purchase Order'), function() {
+				frappe.model.map_current_doc({
+					method: "erpnext.buying.doctype.purchase_order.purchase_order.make_purchase_invoice",
+					source_doctype: "Purchase Order",
+					get_query_filters: {
+						supplier: cur_frm.doc.supplier || undefined,
+						docstatus: 1,
+						status: ["!=", "Closed"],
+						per_billed: ["<", 99.99],
+						company: cur_frm.doc.company
+					}
+				})
+			}, __("Get items from"));
+
+			cur_frm.add_custom_button(__('Purchase Receipt'), function() {
+				frappe.model.map_current_doc({
+					method: "erpnext.stock.doctype.purchase_receipt.purchase_receipt.make_purchase_invoice",
+					source_doctype: "Purchase Receipt",
+					get_query_filters: {
+						supplier: cur_frm.doc.supplier || undefined,
+						docstatus: 1,
+						status: ["!=", "Closed"],
+						company: cur_frm.doc.company
+					}
+				})
+			}, __("Get items from"));
+		}
+		
+		this.frm.toggle_reqd("supplier_warehouse", this.frm.doc.is_subcontracted==="Yes");
 	},
 
 	supplier: function() {
@@ -100,19 +109,33 @@
 		}
 	},
 
+	is_paid: function() {
+		hide_fields(this.frm.doc);
+		if(cint(this.frm.doc.is_paid)) {
+			if(!this.frm.doc.company) {
+				cur_frm.set_value("is_paid", 0)
+				msgprint(__("Please specify Company to proceed"));
+			}
+		}
+		this.calculate_outstanding_amount();
+		this.frm.refresh_fields();
+	},
+
 	write_off_amount: function() {
 		this.set_in_company_currency(this.frm.doc, ["write_off_amount"]);
 		this.calculate_outstanding_amount();
 		this.frm.refresh_fields();
 	},
 
-	allocated_amount: function() {
-		this.calculate_total_advance();
+	paid_amount: function() {
+		this.set_in_company_currency(this.frm.doc, ["paid_amount"]);
+		this.write_off_outstanding_amount();
 		this.frm.refresh_fields();
 	},
 
-	tc_name: function() {
-		this.get_terms();
+	allocated_amount: function() {
+		this.calculate_total_advance();
+		this.frm.refresh_fields();
 	},
 
 	items_add: function(doc, cdt, cdn) {
@@ -137,6 +160,44 @@
 
 cur_frm.script_manager.make(erpnext.accounts.PurchaseInvoice);
 
+// Hide Fields
+// ------------
+function hide_fields(doc) {
+	parent_fields = ['due_date', 'is_opening', 'advances_section', 'from_date', 'to_date'];
+
+	if(cint(doc.is_paid) == 1) {
+		hide_field(parent_fields);
+	} else {
+		for (i in parent_fields) {
+			var docfield = frappe.meta.docfield_map[doc.doctype][parent_fields[i]];
+			if(!docfield.hidden) unhide_field(parent_fields[i]);
+		}
+	
+	}
+
+	item_fields_stock = ['warehouse_section', 'received_qty', 'rejected_qty'];
+
+	cur_frm.fields_dict['items'].grid.set_column_disp(item_fields_stock,
+		(cint(doc.update_stock)==1 ? true : false));	
+
+	cur_frm.refresh_fields();
+}
+
+cur_frm.cscript.update_stock = function(doc, dt, dn) {
+	hide_fields(doc, dt, dn);
+}
+
+cur_frm.fields_dict.cash_bank_account.get_query = function(doc) {
+	return {
+		filters: [
+			["Account", "account_type", "in", ["Cash", "Bank"]],
+			["Account", "root_type", "=", "Asset"],
+			["Account", "is_group", "=",0],
+			["Account", "company", "=", doc.company]
+		]
+	}
+}
+
 cur_frm.cscript.make_bank_entry = function() {
 	return frappe.call({
 		method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_payment_entry_against_invoice",
@@ -267,3 +328,29 @@
 	else
 		cur_frm.pformat.print_heading = __("Purchase Invoice");
 }
+
+frappe.ui.form.on("Purchase Invoice", {
+	onload: function(frm) {
+		$.each(["warehouse", "rejected_warehouse"], function(i, field) {
+			frm.set_query(field, "items", function() {
+				return {
+					filters: [["Warehouse", "company", "in", ["", cstr(frm.doc.company)]]]
+				}
+			})
+		})
+
+		frm.set_query("supplier_warehouse", function() {
+			return {
+				filters: [["Warehouse", "company", "in", ["", cstr(frm.doc.company)]]]
+			}
+		})
+	},
+	
+	is_subcontracted: function(frm) {
+		if (frm.doc.is_subcontracted === "Yes") {
+			erpnext.buying.get_default_bom(frm);
+		}
+		frm.toggle_reqd("supplier_warehouse", frm.doc.is_subcontracted==="Yes");
+	}
+})
+	
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
index bba4a4a..90a0053 100755
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
@@ -120,6 +120,31 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "fieldname": "is_paid", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Is Paid", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
    "fieldname": "column_break1", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -262,8 +287,6 @@
    "label": "Company", 
    "length": 0, 
    "no_copy": 0, 
-   "oldfieldname": "company", 
-   "oldfieldtype": "Link", 
    "options": "Company", 
    "permlevel": 0, 
    "print_hide": 1, 
@@ -279,6 +302,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "default": "0", 
    "fieldname": "is_return", 
    "fieldtype": "Check", 
    "hidden": 0, 
@@ -807,6 +831,32 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "default": "0", 
+   "fieldname": "update_stock", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Update Stock", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
    "fieldname": "items", 
    "fieldtype": "Table", 
    "hidden": 0, 
@@ -1667,6 +1717,162 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 1, 
+   "collapsible_depends_on": "paid_amount", 
+   "depends_on": "eval:doc.is_paid===1||(doc.advances && doc.advances.length>0)", 
+   "fieldname": "payments_section", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Payments", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "mode_of_payment", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Mode of Payment", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Mode of Payment", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "cash_bank_account", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Cash/Bank Account", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Account", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "col_br_payments", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "is_paid", 
+   "fieldname": "paid_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Paid Amount", 
+   "length": 0, 
+   "no_copy": 1, 
+   "options": "currency", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "base_paid_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Paid Amount (Company Currency)", 
+   "length": 0, 
+   "no_copy": 1, 
+   "options": "Company:company:default_currency", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 1, 
    "collapsible_depends_on": "write_off_amount", 
    "depends_on": "grand_total", 
    "fieldname": "write_off", 
@@ -1975,15 +2181,15 @@
   {
    "allow_on_submit": 0, 
    "bold": 0, 
-   "collapsible": 1, 
-   "fieldname": "printing_settings", 
+   "collapsible": 0, 
+   "fieldname": "raw_materials_supplied", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "Printing Settings", 
+   "label": "Raw Materials Supplied", 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -2001,21 +2207,102 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "language", 
-   "fieldtype": "Data", 
+   "default": "No", 
+   "fieldname": "is_subcontracted", 
+   "fieldtype": "Select", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "Print Language", 
+   "label": "Raw Materials Supplied", 
    "length": 0, 
    "no_copy": 0, 
+   "options": "No\nYes", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
-   "read_only": 1, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "supplier_warehouse", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Supplier Warehouse", 
+   "length": 0, 
+   "no_copy": 1, 
+   "options": "Warehouse", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "print_width": "50px", 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0, 
+   "width": "50px"
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "supplied_items", 
+   "fieldtype": "Table", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Supplied Items", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Purchase Receipt Item Supplied", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 1, 
+   "fieldname": "printing_settings", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Printing Settings", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -2263,28 +2550,28 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "mode_of_payment", 
-   "fieldtype": "Link", 
+   "fieldname": "posting_time", 
+   "fieldtype": "Time", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "Mode of Payment", 
+   "label": "Posting Time", 
    "length": 0, 
-   "no_copy": 0, 
-   "oldfieldname": "mode_of_payment", 
-   "oldfieldtype": "Select", 
-   "options": "Mode of Payment", 
+   "no_copy": 1, 
    "permlevel": 0, 
-   "print_hide": 0, 
+   "precision": "", 
+   "print_hide": 1, 
    "print_hide_if_no_value": 0, 
+   "print_width": "100px", 
    "read_only": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "unique": 0
+   "unique": 0, 
+   "width": "100px"
   }, 
   {
    "allow_on_submit": 0, 
@@ -2315,6 +2602,33 @@
   {
    "allow_on_submit": 0, 
    "bold": 0, 
+   "collapsible": 0, 
+   "description": "Warehouse where you are maintaining stock of rejected items", 
+   "fieldname": "rejected_warehouse", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Rejected Warehouse", 
+   "length": 0, 
+   "no_copy": 1, 
+   "options": "Warehouse", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
    "collapsible": 1, 
    "collapsible_depends_on": "is_recurring", 
    "depends_on": "eval:doc.docstatus<2", 
@@ -2369,35 +2683,8 @@
    "allow_on_submit": 1, 
    "bold": 0, 
    "collapsible": 0, 
-   "depends_on": "is_recurring", 
-   "description": "", 
-   "fieldname": "recurring_id", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "label": "Reference Document", 
-   "length": 0, 
-   "no_copy": 1, 
-   "options": "Purchase Invoice", 
-   "permlevel": 0, 
-   "print_hide": 1, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_on_submit": 1, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name", 
-   "description": "", 
+   "depends_on": "eval:doc.is_recurring==1", 
+   "description": "Select the period when the invoice will be generated automatically", 
    "fieldname": "recurring_type", 
    "fieldtype": "Select", 
    "hidden": 0, 
@@ -2405,7 +2692,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "Frequency", 
+   "label": "Recurring Type", 
    "length": 0, 
    "no_copy": 1, 
    "options": "Monthly\nQuarterly\nHalf-yearly\nYearly", 
@@ -2423,16 +2710,16 @@
    "allow_on_submit": 1, 
    "bold": 0, 
    "collapsible": 0, 
-   "depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name", 
-   "description": "", 
-   "fieldname": "repeat_on_day_of_month", 
-   "fieldtype": "Int", 
+   "depends_on": "eval:doc.is_recurring==1", 
+   "description": "Start date of current invoice's period", 
+   "fieldname": "from_date", 
+   "fieldtype": "Date", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "Repeat on Day of Month", 
+   "label": "From Date", 
    "length": 0, 
    "no_copy": 1, 
    "permlevel": 0, 
@@ -2449,16 +2736,16 @@
    "allow_on_submit": 1, 
    "bold": 0, 
    "collapsible": 0, 
-   "depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name", 
-   "description": "", 
-   "fieldname": "end_date", 
+   "depends_on": "eval:doc.is_recurring==1", 
+   "description": "End date of current invoice's period", 
+   "fieldname": "to_date", 
    "fieldtype": "Date", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "Recurring Ends On", 
+   "label": "To Date", 
    "length": 0, 
    "no_copy": 1, 
    "permlevel": 0, 
@@ -2528,19 +2815,18 @@
    "allow_on_submit": 1, 
    "bold": 0, 
    "collapsible": 0, 
-   "depends_on": "eval:doc.is_recurring && doc.notify_by_email && doc.recurring_id === doc.name", 
-   "description": "", 
-   "fieldname": "notification_email_address", 
-   "fieldtype": "Code", 
+   "depends_on": "eval:doc.is_recurring==1", 
+   "description": "The day of the month on which auto invoice will be generated e.g. 05, 28 etc", 
+   "fieldname": "repeat_on_day_of_month", 
+   "fieldtype": "Int", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "Notification Email Address", 
+   "label": "Repeat on Day of Month", 
    "length": 0, 
    "no_copy": 1, 
-   "options": "Email", 
    "permlevel": 0, 
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
@@ -2552,24 +2838,23 @@
    "unique": 0
   }, 
   {
-   "allow_on_submit": 0, 
+   "allow_on_submit": 1, 
    "bold": 0, 
    "collapsible": 0, 
-   "depends_on": "eval:doc.is_recurring && doc.notify_by_email && doc.recurring_id === doc.name", 
-   "fieldname": "recurring_print_format", 
-   "fieldtype": "Link", 
+   "depends_on": "eval:doc.is_recurring==1", 
+   "description": "The date on which recurring invoice will be stop", 
+   "fieldname": "end_date", 
+   "fieldtype": "Date", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "Recurring Print Format", 
+   "label": "End Date", 
    "length": 0, 
-   "no_copy": 0, 
-   "options": "Print Format", 
+   "no_copy": 1, 
    "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
+   "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "report_hide": 0, 
@@ -2603,25 +2888,51 @@
    "width": "50%"
   }, 
   {
-   "allow_on_submit": 1, 
+   "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "depends_on": "is_recurring", 
-   "description": "", 
-   "fieldname": "from_date", 
+   "depends_on": "eval:doc.is_recurring==1", 
+   "description": "The date on which next invoice will be generated. It is generated on submit.", 
+   "fieldname": "next_date", 
    "fieldtype": "Date", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "From Date", 
+   "label": "Next Date", 
    "length": 0, 
    "no_copy": 1, 
    "permlevel": 0, 
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
-   "read_only": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "eval:doc.is_recurring==1", 
+   "description": "The unique id for tracking all recurring invoices. It is generated on submit.", 
+   "fieldname": "recurring_id", 
+   "fieldtype": "Data", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Recurring Id", 
+   "length": 0, 
+   "no_copy": 1, 
+   "permlevel": 0, 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -2632,16 +2943,16 @@
    "allow_on_submit": 1, 
    "bold": 0, 
    "collapsible": 0, 
-   "depends_on": "is_recurring", 
-   "description": "", 
-   "fieldname": "to_date", 
-   "fieldtype": "Date", 
+   "depends_on": "eval:doc.is_recurring==1", 
+   "description": "Enter email id separated by commas, invoice will be mailed automatically on particular date", 
+   "fieldname": "notification_email_address", 
+   "fieldtype": "Small Text", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "To Date", 
+   "label": "Notification Email Address", 
    "length": 0, 
    "no_copy": 1, 
    "permlevel": 0, 
@@ -2658,20 +2969,21 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "depends_on": "is_recurring", 
-   "description": "", 
-   "fieldname": "next_date", 
-   "fieldtype": "Date", 
+   "depends_on": "eval:doc.is_recurring==1", 
+   "fieldname": "recurring_print_format", 
+   "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "Next Date", 
+   "label": "Recurring Print Format", 
    "length": 0, 
-   "no_copy": 1, 
+   "no_copy": 0, 
+   "options": "Print Format", 
    "permlevel": 0, 
-   "print_hide": 1, 
+   "precision": "", 
+   "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "report_hide": 0, 
@@ -2692,7 +3004,7 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2016-04-06 05:39:45.475873", 
+ "modified": "2016-04-11 14:37:27.243253", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Purchase Invoice", 
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 427e040..43d14ed 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -4,7 +4,7 @@
 from __future__ import unicode_literals
 import frappe
 from frappe.utils import cint, formatdate, flt, getdate
-from frappe import msgprint, _, throw
+from frappe import _, throw
 from erpnext.setup.utils import get_company_currency
 import frappe.defaults
 
@@ -12,6 +12,9 @@
 from erpnext.accounts.party import get_party_account, get_due_date
 from erpnext.accounts.utils import get_account_currency, get_fiscal_year
 from erpnext.stock.doctype.purchase_receipt.purchase_receipt import update_billed_amount_based_on_po
+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
 
 form_grid_templates = {
 	"items": "templates/form_grid/item_grid.html"
@@ -45,19 +48,31 @@
 			self.validate_supplier_invoice()
 			self.validate_advance_jv("Purchase Order")
 
+		# validate cash purchase
+		if (self.is_paid == 1):
+			self.validate_cash()
+
 		self.check_conversion_rate()
 		self.validate_credit_to_acc()
 		self.clear_unallocated_advances("Purchase Invoice Advance", "advances")
 		self.check_for_closed_status()
 		self.validate_with_previous_doc()
 		self.validate_uom_is_integer("uom", "qty")
+		self.set_expense_account()
 		self.set_against_expense_account()
 		self.validate_write_off_account()
-		self.update_valuation_rate("items")
 		self.validate_multiple_billing("Purchase Receipt", "pr_detail", "amount", "items")
 		self.validate_fixed_asset_account()
 		self.create_remarks()
 
+	def validate_cash(self):
+		if not self.cash_bank_account and flt(self.paid_amount):
+			frappe.throw(_("Cash or Bank Account is mandatory for making payment entry"))
+
+		if flt(self.paid_amount) + flt(self.write_off_amount) \
+				- flt(self.base_grand_total) > 1/(10**(self.precision("base_grand_total") + 1)):
+			frappe.throw(_("""Paid amount + Write Off Amount can not be greater than Grand Total"""))
+
 	def create_remarks(self):
 		if not self.remarks:
 			if self.bill_no and self.bill_date:
@@ -135,52 +150,55 @@
 				["Purchase Order", "purchase_order", "po_detail"],
 				["Purchase Receipt", "purchase_receipt", "pr_detail"]
 			])
-
-	def set_against_expense_account(self):
+			
+	def set_expense_account(self):
 		auto_accounting_for_stock = cint(frappe.defaults.get_global_default("auto_accounting_for_stock"))
 
 		if auto_accounting_for_stock:
 			stock_not_billed_account = self.get_company_default("stock_received_but_not_billed")
-
-		against_accounts = []
-		stock_items = self.get_stock_items()
+			stock_items = self.get_stock_items()
+			
+		if self.update_stock:
+			warehouse_account = get_warehouse_account()
+		
 		for item in self.get("items"):
 			# in case of auto inventory accounting,
 			# expense account is always "Stock Received But Not Billed" for a stock item 
 			# except epening entry, drop-ship entry and fixed asset items
 
-			if auto_accounting_for_stock and item.item_code in stock_items and self.is_opening == 'No' \
-				and (not item.po_detail 
-					or not frappe.db.get_value("Purchase Order Item", item.po_detail, "delivered_by_supplier")
-					or not frappe.db.get_value("Item", item.item_code, "is_fixed_asset")):
+			if auto_accounting_for_stock and self.is_opening == 'No' \
+				and item.item_code in stock_items and ((not item.po_detail 
+				or not frappe.db.get_value("Purchase Order Item", item.po_detail, "delivered_by_supplier"))
+				or not frappe.db.get_value("Item", item.item_code, "is_fixed_asset")):
 
-				item.expense_account = stock_not_billed_account
-				item.cost_center = None
-
-				if stock_not_billed_account not in against_accounts:
-					against_accounts.append(stock_not_billed_account)
-
+				if self.update_stock:
+					item.expense_account = warehouse_account[item.warehouse]["name"]
+				else:
+					item.expense_account = stock_not_billed_account
+					
 			elif not item.expense_account:
 				throw(_("Expense account is mandatory for item {0}").format(item.item_code or item.item_name))
 
-			elif item.expense_account not in against_accounts:
-				# if no auto_accounting_for_stock or not a stock item
+	def set_against_expense_account(self):
+		against_accounts = []
+		for item in self.get("items"):
+			if item.expense_account not in against_accounts:
 				against_accounts.append(item.expense_account)
 
 		self.against_expense_account = ",".join(against_accounts)
 
 	def po_required(self):
 		if frappe.db.get_value("Buying Settings", None, "po_required") == 'Yes':
-			 for d in self.get('items'):
-				 if not d.purchase_order:
-					 throw(_("Purchse Order number required for Item {0}").format(d.item_code))
+			for d in self.get('items'):
+				if not d.purchase_order:
+					throw(_("Purchse Order number required for Item {0}").format(d.item_code))
 
 	def pr_required(self):
 		stock_items = self.get_stock_items()
 		if frappe.db.get_value("Buying Settings", None, "pr_required") == 'Yes':
-			 for d in self.get('items'):
-				 if not d.purchase_receipt and d.item_code in stock_items:
-					 throw(_("Purchase Receipt number required for Item {0}").format(d.item_code))
+			for d in self.get('items'):
+				if not d.purchase_receipt and d.item_code in stock_items:
+					throw(_("Purchase Receipt number required for Item {0}").format(d.item_code))
 
 	def validate_write_off_account(self):
 		if self.write_off_amount and not self.write_off_account:
@@ -228,21 +246,71 @@
 			from erpnext.accounts.utils import reconcile_against_document
 			reconcile_against_document(lst)
 
+	def update_status_updater_args(self):
+		if cint(self.update_stock):
+			self.status_updater.extend([{
+				'source_dt': 'Purchase Invoice Item',
+				'target_dt': 'Purchase Order Item',
+				'join_field': 'po_detail',
+				'target_field': 'received_qty',
+				'target_parent_dt': 'Purchase Order',
+				'target_parent_field': 'per_received',
+				'target_ref_field': 'qty',
+				'source_field': 'qty',
+				'percent_join_field':'purchase_order',
+				# 'percent_join_field': 'prevdoc_docname',
+				'overflow_type': 'receipt',
+				'extra_cond': """ and exists(select name from `tabPurchase Invoice`
+					where name=`tabPurchase Invoice Item`.parent and update_stock = 1)"""
+			},
+			{
+				'source_dt': 'Purchase Invoice Item',
+				'target_dt': 'Purchase Order Item',
+				'join_field': 'po_detail',
+				'target_field': 'returned_qty',
+				'target_parent_dt': 'Purchase Order',
+				# 'target_parent_field': 'per_received',
+				# 'target_ref_field': 'qty',
+				'source_field': '-1 * qty',
+				# 'percent_join_field': 'prevdoc_docname',
+				# 'overflow_type': 'receipt',
+				'extra_cond': """ and exists (select name from `tabPurchase Invoice`
+					where name=`tabPurchase Invoice Item`.parent and update_stock=1 and is_return=1)"""
+			}
+		])
+	
+	def validate_purchase_receipt_if_update_stock(self):
+		if self.update_stock:
+			for item in self.get("items"):
+				if item.purchase_receipt:
+					frappe.throw(_("Stock cannot be updated against Purchase Receipt {0}")
+						.format(item.purchase_receipt))
+
 	def on_submit(self):
 		self.check_prev_docstatus()
+		self.update_status_updater_args()
+		
 		self.validate_asset()
 
 		frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
 			self.company, self.base_grand_total)
-
-		# this sequence because outstanding may get -negative
-		self.make_gl_entries()
+			
 		if not self.is_return:
 			self.update_against_document_in_jv()
 			self.update_prevdoc_status()
 			self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
 			self.update_billing_status_in_pr()
 
+		# Updating stock ledger should always be called after updating prevdoc status, 
+		# because updating ordered qty in bin depends upon updated ordered qty in PO
+		if self.update_stock == 1:
+			self.update_stock_ledger()
+			from erpnext.stock.doctype.serial_no.serial_no import update_serial_nos_after_submit
+			update_serial_nos_after_submit(self, "items")
+			
+		# this sequence because outstanding may get -negative
+		self.make_gl_entries()
+
 		self.update_project()
 		
 	def validate_asset(self):
@@ -271,22 +339,51 @@
 						
 					if self.docstatus==1 and not asset.supplier:
 						frappe.db.set_value("Asset", asset.name, "supplier", self.supplier)
-					
-	def make_gl_entries(self):
-		auto_accounting_for_stock = \
+
+	def make_gl_entries(self, repost_future_gle=False):
+		self.auto_accounting_for_stock = \
 			cint(frappe.defaults.get_global_default("auto_accounting_for_stock"))
 
-		stock_received_but_not_billed = self.get_company_default("stock_received_but_not_billed")
-		expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
-
+		self.stock_received_but_not_billed = self.get_company_default("stock_received_but_not_billed")
+		self.expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
+		self.negative_expense_to_be_booked = 0.0
 		gl_entries = []
+		
+		
+		self.make_supplier_gl_entry(gl_entries)
+		self.make_item_gl_entries(gl_entries)
+		self.make_tax_gl_entries(gl_entries)
+		
+		gl_entries = merge_similar_entries(gl_entries)
+		
+		self.make_payment_gl_entries(gl_entries)
 
-		# parent's gl entry
+		self.make_write_off_gl_entry(gl_entries)
+		
+		if gl_entries:
+			update_outstanding = "No" if (cint(self.is_paid) or self.write_off_account) else "Yes"
+			
+			make_gl_entries(gl_entries,  cancel=(self.docstatus == 2),
+				update_outstanding=update_outstanding, merge_entries=False)
+			
+			if update_outstanding == "No":
+				update_outstanding_amt(self.credit_to, "Supplier", self.supplier,
+					self.doctype, self.return_against if cint(self.is_return) else self.name)
+
+			if repost_future_gle and cint(self.update_stock) and self.auto_accounting_for_stock:
+				from erpnext.controllers.stock_controller import update_gl_entries_after
+				items, warehouses = self.get_items_and_warehouses()
+				update_gl_entries_after(self.posting_date, self.posting_time, warehouses, items)
+					
+		elif self.docstatus == 2 and cint(self.update_stock) and self.auto_accounting_for_stock:
+			delete_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
+		
+
+	def make_supplier_gl_entry(self, gl_entries):
 		if self.grand_total:
 			# Didnot use base_grand_total to book rounding loss gle
 			grand_total_in_company_currency = flt(self.grand_total * self.conversion_rate,
 				self.precision("grand_total"))
-
 			gl_entries.append(
 				self.get_gl_dict({
 					"account": self.credit_to,
@@ -301,6 +398,88 @@
 				}, self.party_account_currency)
 			)
 
+	def make_item_gl_entries(self, gl_entries):
+		# item gl entries
+		stock_items = self.get_stock_items()
+		expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
+		warehouse_account = get_warehouse_account()
+		
+		for item in self.get("items"):
+			if flt(item.base_net_amount):
+				account_currency = get_account_currency(item.expense_account)
+				
+				if self.update_stock and self.auto_accounting_for_stock:
+					val_rate_db_precision = 6 if cint(item.precision("valuation_rate")) <= 6 else 9
+
+					# warehouse account
+					warehouse_debit_amount = flt(flt(item.valuation_rate, val_rate_db_precision) 
+						* flt(item.qty)	* flt(item.conversion_factor), item.precision("base_net_amount"))
+						
+					gl_entries.append(
+						self.get_gl_dict({
+							"account": item.expense_account,
+							"against": self.supplier,
+							"debit": warehouse_debit_amount,
+							"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
+							"cost_center": item.cost_center
+						}, account_currency)
+					)
+					
+					# Amount added through landed-cost-voucher
+					if flt(item.landed_cost_voucher_amount):
+						gl_entries.append(self.get_gl_dict({
+							"account": expenses_included_in_valuation,
+							"against": item.expense_account,
+							"cost_center": item.cost_center,
+							"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
+							"credit": flt(item.landed_cost_voucher_amount)
+						}))
+
+					# sub-contracting warehouse
+					if flt(item.rm_supp_cost):
+						supplier_warehouse_account = warehouse_account[self.supplier_warehouse]["name"]
+						gl_entries.append(self.get_gl_dict({
+							"account": supplier_warehouse_account,
+							"against": item.expense_account,
+							"cost_center": item.cost_center,
+							"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
+							"credit": flt(item.rm_supp_cost)
+						}, warehouse_account[self.supplier_warehouse]["account_currency"]))
+				else:
+					gl_entries.append(
+						self.get_gl_dict({
+							"account": item.expense_account,
+							"against": self.supplier,
+							"debit": flt(item.base_net_amount, item.precision("base_net_amount")),
+							"debit_in_account_currency": (flt(item.base_net_amount, 
+								item.precision("base_net_amount")) if account_currency==self.company_currency 
+								else flt(item.net_amount, item.precision("net_amount"))),
+							"cost_center": item.cost_center
+						}, account_currency)
+					)
+				
+			if self.auto_accounting_for_stock and self.is_opening == "No" and \
+				item.item_code in stock_items and item.item_tax_amount:
+					# Post reverse entry for Stock-Received-But-Not-Billed if it is booked in Purchase Receipt
+					if item.purchase_receipt:
+						negative_expense_booked_in_pr = frappe.db.sql("""select name from `tabGL Entry`
+							where voucher_type='Purchase Receipt' and voucher_no=%s and account=%s""",
+							(item.purchase_receipt, self.expenses_included_in_valuation))
+
+						if not negative_expense_booked_in_pr:
+							gl_entries.append(
+								self.get_gl_dict({
+									"account": self.stock_received_but_not_billed,
+									"against": self.supplier,
+									"debit": flt(item.item_tax_amount, item.precision("item_tax_amount")),
+									"remarks": self.remarks or "Accounting Entry for Stock"
+								})
+							)
+
+							self.negative_expense_to_be_booked += flt(item.item_tax_amount, \
+								item.precision("item_tax_amount"))
+
+	def make_tax_gl_entries(self, gl_entries):
 		# tax table gl entries
 		valuation_tax = {}
 		for tax in self.get("taxes"):
@@ -320,69 +499,31 @@
 						"cost_center": tax.cost_center
 					}, account_currency)
 				)
-
 			# accumulate valuation tax
 			if self.is_opening == "No" and tax.category in ("Valuation", "Valuation and Total") and flt(tax.base_tax_amount_after_discount_amount):
-				if auto_accounting_for_stock and not tax.cost_center:
+				if self.auto_accounting_for_stock and not tax.cost_center:
 					frappe.throw(_("Cost Center is required in row {0} in Taxes table for type {1}").format(tax.idx, _(tax.category)))
 				valuation_tax.setdefault(tax.cost_center, 0)
 				valuation_tax[tax.cost_center] += \
 					(tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.base_tax_amount_after_discount_amount)
-
-		# item gl entries
-		negative_expense_to_be_booked = 0.0
-		stock_items = self.get_stock_items()
-		for item in self.get("items"):
-			if flt(item.base_net_amount):
-				account_currency = get_account_currency(item.expense_account)
-				gl_entries.append(
-					self.get_gl_dict({
-						"account": item.expense_account,
-						"against": self.supplier,
-						"debit": item.base_net_amount,
-						"debit_in_account_currency": item.base_net_amount \
-							if account_currency==self.company_currency else item.net_amount,
-						"cost_center": item.cost_center
-					}, account_currency)
-				)
-
-			if auto_accounting_for_stock and self.is_opening == "No" and \
-				item.item_code in stock_items and item.item_tax_amount:
-					# Post reverse entry for Stock-Received-But-Not-Billed if it is booked in Purchase Receipt
-					if item.purchase_receipt:
-						negative_expense_booked_in_pr = frappe.db.sql("""select name from `tabGL Entry`
-							where voucher_type='Purchase Receipt' and voucher_no=%s and account=%s""",
-							(item.purchase_receipt, expenses_included_in_valuation))
-
-						if not negative_expense_booked_in_pr:
-							gl_entries.append(
-								self.get_gl_dict({
-									"account": stock_received_but_not_billed,
-									"against": self.supplier,
-									"debit": flt(item.item_tax_amount, self.precision("item_tax_amount", item)),
-									"remarks": self.remarks or "Accounting Entry for Stock"
-								})
-							)
-
-							negative_expense_to_be_booked += flt(item.item_tax_amount, self.precision("item_tax_amount", item))
-
-		if self.is_opening == "No" and negative_expense_to_be_booked and valuation_tax:
+		
+		if self.is_opening == "No" and self.negative_expense_to_be_booked and valuation_tax:
 			# credit valuation tax amount in "Expenses Included In Valuation"
 			# this will balance out valuation amount included in cost of goods sold
 
 			total_valuation_amount = sum(valuation_tax.values())
-			amount_including_divisional_loss = negative_expense_to_be_booked
+			amount_including_divisional_loss = self.negative_expense_to_be_booked
 			i = 1
 			for cost_center, amount in valuation_tax.items():
 				if i == len(valuation_tax):
 					applicable_amount = amount_including_divisional_loss
 				else:
-					applicable_amount = negative_expense_to_be_booked * (amount / total_valuation_amount)
+					applicable_amount = self.negative_expense_to_be_booked * (amount / total_valuation_amount)
 					amount_including_divisional_loss -= applicable_amount
 
 				gl_entries.append(
 					self.get_gl_dict({
-						"account": expenses_included_in_valuation,
+						"account": self.expenses_included_in_valuation,
 						"cost_center": cost_center,
 						"against": self.supplier,
 						"credit": applicable_amount,
@@ -392,6 +533,36 @@
 
 				i += 1
 
+	def make_payment_gl_entries(self, gl_entries):
+		# Make Cash GL Entries
+		if cint(self.is_paid) and self.cash_bank_account and self.paid_amount:
+			bank_account_currency = get_account_currency(self.cash_bank_account)
+			# CASH, make payment entries
+			gl_entries.append(
+				self.get_gl_dict({
+					"account": self.credit_to,
+					"party_type": "Supplier",
+					"party": self.supplier,
+					"against": self.cash_bank_account,
+					"debit": self.base_paid_amount,
+					"debit_in_account_currency": self.base_paid_amount \
+						if self.party_account_currency==self.company_currency else self.paid_amount,
+					"against_voucher": self.return_against if cint(self.is_return) else self.name,
+					"against_voucher_type": self.doctype,
+				}, self.party_account_currency)
+			)
+						
+			gl_entries.append(
+				self.get_gl_dict({
+					"account": self.cash_bank_account,
+					"against": self.supplier,
+					"credit": self.base_paid_amount,
+					"credit_in_account_currency": self.base_paid_amount \
+						if bank_account_currency==self.company_currency else self.paid_amount
+				}, bank_account_currency)
+			)
+
+	def make_write_off_gl_entry(self, gl_entries):
 		# writeoff account includes petty difference in the invoice amount
 		# and the amount that is paid
 		if self.write_off_account and flt(self.write_off_amount):
@@ -421,13 +592,11 @@
 				})
 			)
 
-		if gl_entries:
-			from erpnext.accounts.general_ledger import make_gl_entries
-			make_gl_entries(gl_entries, cancel=(self.docstatus == 2))
-
 	def on_cancel(self):
 		self.check_for_closed_status()
-
+		
+		self.update_status_updater_args()
+		
 		if not self.is_return:
 			from erpnext.accounts.utils import remove_against_link_from_jv
 			remove_against_link_from_jv(self.doctype, self.name)
@@ -436,6 +605,11 @@
 			self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
 			self.update_billing_status_in_pr()
 
+		# Updating stock ledger should always be called after updating prevdoc status, 
+		# because updating ordered qty in bin depends upon updated ordered qty in PO
+		if self.update_stock == 1:
+			self.update_stock_ledger()
+			
 		self.make_gl_entries_on_cancel()
 		self.update_project()
 		self.validate_asset()
diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
index b0ac627..91d3ae4 100644
--- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
@@ -6,11 +6,12 @@
 import unittest
 import frappe
 import frappe.model
-from frappe.utils import cint
+from frappe.utils import cint, flt
 import frappe.defaults
 from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory, \
 	test_records as pr_test_records
 from erpnext.exceptions import InvalidCurrency
+from erpnext.stock.doctype.stock_entry.test_stock_entry import get_qty_after_transaction
 
 test_dependencies = ["Item", "Cost Center"]
 test_ignore = ["Serial No"]
@@ -119,20 +120,20 @@
 		set_perpetual_inventory(0)
 
 	def test_purchase_invoice_calculation(self):
-		wrapper = frappe.copy_doc(test_records[0])
-		wrapper.insert()
-		wrapper.load_from_db()
+		pi = frappe.copy_doc(test_records[0])
+		pi.insert()
+		pi.load_from_db()
 
 		expected_values = [
 			["_Test Item Home Desktop 100", 90, 59],
 			["_Test Item Home Desktop 200", 135, 177]
 		]
-		for i, item in enumerate(wrapper.get("items")):
+		for i, item in enumerate(pi.get("items")):
 			self.assertEqual(item.item_code, expected_values[i][0])
 			self.assertEqual(item.item_tax_amount, expected_values[i][1])
 			self.assertEqual(item.valuation_rate, expected_values[i][2])
 
-		self.assertEqual(wrapper.base_net_total, 1250)
+		self.assertEqual(pi.base_net_total, 1250)
 
 		# tax amounts
 		expected_values = [
@@ -146,7 +147,7 @@
 			["_Test Account Discount - _TC", 168.03, 1512.30],
 		]
 
-		for i, tax in enumerate(wrapper.get("taxes")):
+		for i, tax in enumerate(pi.get("taxes")):
 			self.assertEqual(tax.account_head, expected_values[i][0])
 			self.assertEqual(tax.tax_amount, expected_values[i][1])
 			self.assertEqual(tax.total, expected_values[i][2])
@@ -314,6 +315,99 @@
 			where voucher_type='Sales Invoice' and voucher_no=%s""", pi.name)
 
 		self.assertFalse(gle)
+	
+	def test_purchase_invoice_update_stock_gl_entry_with_perpetual_inventory(self):
+		set_perpetual_inventory()
+		
+		pi = make_purchase_invoice(update_stock=1, posting_date=frappe.utils.nowdate(), 
+			posting_time=frappe.utils.nowtime())
+		
+		gl_entries = frappe.db.sql("""select account, account_currency, debit, credit,
+			debit_in_account_currency, credit_in_account_currency
+			from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s
+			order by account asc""", pi.name, as_dict=1)
+
+		self.assertTrue(gl_entries)
+		
+		expected_gl_entries = dict((d[0], d) for d in [
+			[pi.credit_to, 0.0, 250.0],
+			[pi.items[0].warehouse, 250.0, 0.0]
+		])
+		
+		for i, gle in enumerate(gl_entries):
+			self.assertEquals(expected_gl_entries[gle.account][0], gle.account)
+			self.assertEquals(expected_gl_entries[gle.account][1], gle.debit)
+			self.assertEquals(expected_gl_entries[gle.account][2], gle.credit)
+			
+	def test_purchase_invoice_for_is_paid_and_update_stock_gl_entry_with_perpetual_inventory(self):
+		set_perpetual_inventory()
+		pi = make_purchase_invoice(update_stock=1, posting_date=frappe.utils.nowdate(), 
+			posting_time=frappe.utils.nowtime(), cash_bank_account="Cash - _TC", is_paid=1)
+
+		gl_entries = frappe.db.sql("""select account, account_currency, sum(debit) as debit, 
+				sum(credit) as credit, debit_in_account_currency, credit_in_account_currency 
+			from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s 
+			group by account, voucher_no order by account asc;""", pi.name, as_dict=1)
+
+		self.assertTrue(gl_entries)
+		
+		expected_gl_entries = dict((d[0], d) for d in [
+			[pi.credit_to, 250.0, 250.0],
+			[pi.items[0].warehouse, 250.0, 0.0],
+			["Cash - _TC", 0.0, 250.0]
+		])
+				
+		for i, gle in enumerate(gl_entries):
+			self.assertEquals(expected_gl_entries[gle.account][0], gle.account)
+			self.assertEquals(expected_gl_entries[gle.account][1], gle.debit)
+			self.assertEquals(expected_gl_entries[gle.account][2], gle.credit)
+	
+	def test_update_stock_and_purchase_return(self):
+		actual_qty_0 = get_qty_after_transaction()
+		
+		pi = make_purchase_invoice(update_stock=1, posting_date=frappe.utils.nowdate(),
+			posting_time=frappe.utils.nowtime())
+		
+		actual_qty_1 = get_qty_after_transaction()
+		self.assertEquals(actual_qty_0 + 5, actual_qty_1)
+
+		# return entry
+		pi1 = make_purchase_invoice(is_return=1, return_against=pi.name, qty=-2, rate=50, update_stock=1)
+
+		actual_qty_2 = get_qty_after_transaction()
+		self.assertEquals(actual_qty_1 - 2, actual_qty_2)
+		
+		pi1.cancel()
+		self.assertEquals(actual_qty_1, get_qty_after_transaction())
+		
+		pi.cancel()
+		self.assertEquals(actual_qty_0, get_qty_after_transaction())
+		
+	def test_subcontracting_via_purchase_invoice(self):
+		from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
+		
+		make_stock_entry(item_code="_Test Item", target="_Test Warehouse 1 - _TC", qty=100, basic_rate=100)
+		make_stock_entry(item_code="_Test Item Home Desktop 100", target="_Test Warehouse 1 - _TC", 
+			qty=100, basic_rate=100)
+		
+		pi = make_purchase_invoice(item_code="_Test FG Item", qty=10, rate=500, 
+			update_stock=1, is_subcontracted="Yes")
+		
+		self.assertEquals(len(pi.get("supplied_items")), 2)
+		
+		rm_supp_cost = sum([d.amount for d in pi.get("supplied_items")])
+		self.assertEquals(pi.get("items")[0].rm_supp_cost, flt(rm_supp_cost, 2))
+		
+	def test_rejected_serial_no(self):
+		pi = make_purchase_invoice(item_code="_Test Serialized Item With Series", received_qty=2, qty=1,
+			rejected_qty=1, rate=500, update_stock=1,
+			rejected_warehouse = "_Test Rejected Warehouse - _TC")
+		
+		self.assertEquals(frappe.db.get_value("Serial No", pi.get("items")[0].serial_no, "warehouse"),
+			pi.get("items")[0].warehouse)
+			
+		self.assertEquals(frappe.db.get_value("Serial No", pi.get("items")[0].rejected_serial_no, 
+			"warehouse"), pi.get("items")[0].rejected_warehouse)
 
 def make_purchase_invoice(**args):
 	pi = frappe.new_doc("Purchase Invoice")
@@ -322,23 +416,37 @@
 		pi.posting_date = args.posting_date
 	if args.posting_time:
 		pi.posting_time = args.posting_time
+	if args.update_stock:
+		pi.update_stock = 1
+	if args.is_paid:
+		pi.is_paid = 1
+		
+	if args.cash_bank_account:
+		pi.cash_bank_account=args.cash_bank_account
+		
 	pi.company = args.company or "_Test Company"
 	pi.supplier = args.supplier or "_Test Supplier"
 	pi.currency = args.currency or "INR"
 	pi.conversion_rate = args.conversion_rate or 1
 	pi.is_return = args.is_return
 	pi.return_against = args.return_against
+	pi.is_subcontracted = args.is_subcontracted or "No"
+	pi.supplier_warehouse = "_Test Warehouse 1 - _TC"
 
 	pi.append("items", {
 		"item_code": args.item or args.item_code or "_Test Item",
 		"warehouse": args.warehouse or "_Test Warehouse - _TC",
 		"qty": args.qty or 5,
+		"received_qty": args.received_qty or 0,
+		"rejected_qty": args.rejected_qty or 0,
 		"rate": args.rate or 50,
 		"conversion_factor": 1.0,
 		"serial_no": args.serial_no,
 		"stock_uom": "_Test UOM",
 		"cost_center": "_Test Cost Center - _TC",
-		"project": args.project
+		"project": args.project,
+		"rejected_warehouse": args.rejected_warehouse or "",
+		"rejected_serial_no": args.rejected_serial_no or ""
 	})
 	if not args.do_not_save:
 		pi.insert()
diff --git a/erpnext/accounts/doctype/purchase_invoice/test_records.json b/erpnext/accounts/doctype/purchase_invoice/test_records.json
index 4218828..7feca23 100644
--- a/erpnext/accounts/doctype/purchase_invoice/test_records.json
+++ b/erpnext/accounts/doctype/purchase_invoice/test_records.json
@@ -22,7 +22,8 @@
     "parentfield": "items",
     "qty": 10,
     "rate": 50,
-    "uom": "_Test UOM"
+    "uom": "_Test UOM",
+	"warehouse": "_Test Warehouse - _TC"
    },
    {
     "amount": 750,
@@ -37,7 +38,8 @@
     "parentfield": "items",
     "qty": 5,
     "rate": 150,
-    "uom": "_Test UOM"
+    "uom": "_Test UOM",
+	"warehouse": "_Test Warehouse - _TC"
    }
   ],
   "grand_total": 0,
diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
index 784c747..8599645 100755
--- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
+++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
@@ -215,6 +215,31 @@
   }, 
   {
    "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "received_qty", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Received Qty", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "2", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
    "bold": 1, 
    "collapsible": 0, 
    "fieldname": "qty", 
@@ -243,6 +268,31 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "fieldname": "rejected_qty", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Rejected Qty", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "2", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
    "fieldname": "col_break2", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -767,6 +817,185 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "fieldname": "warehouse_section", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Warehouse", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "default": "", 
+   "fieldname": "warehouse", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Accepted Warehouse", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Warehouse", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "rejected_warehouse", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Rejected Warehouse", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Warehouse", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "batch_no", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Batch No", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Batch", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "col_br_wh", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "serial_no", 
+   "fieldtype": "Text", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Serial No", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "rejected_serial_no", 
+   "fieldtype": "Text", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Rejected Serial No", 
+   "length": 0, 
+   "no_copy": 1, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
    "fieldname": "accounting", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -1057,6 +1286,32 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "fieldname": "bom", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "BOM", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "BOM", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
    "fieldname": "col_break6", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -1206,7 +1461,7 @@
    "unique": 0
   }, 
   {
-   "allow_on_submit": 0, 
+   "allow_on_submit": 1, 
    "bold": 0, 
    "collapsible": 0, 
    "fieldname": "valuation_rate", 
@@ -1254,6 +1509,31 @@
    "search_index": 0, 
    "set_only_once": 0, 
    "unique": 0
+  }, 
+  {
+   "allow_on_submit": 1, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "landed_cost_voucher_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Landed Cost Voucher Amount", 
+   "length": 0, 
+   "no_copy": 1, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
   }
  ], 
  "hide_heading": 0, 
@@ -1265,14 +1545,16 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2016-03-28 05:05:27.752823", 
+ "modified": "2016-04-18 08:08:53.056818", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Purchase Invoice Item", 
  "owner": "Administrator", 
  "permissions": [], 
+ "quick_entry": 0, 
  "read_only": 0, 
  "read_only_onload": 0, 
  "sort_field": "modified", 
- "sort_order": "DESC"
+ "sort_order": "DESC", 
+ "track_seen": 0
 }
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index f6f746a..18049cc 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -278,20 +278,20 @@
 // Hide Fields
 // ------------
 cur_frm.cscript.hide_fields = function(doc) {
-	par_flds = ['project', 'due_date', 'is_opening', 'source', 'total_advance', 'get_advances_received',
+	parent_fields = ['project', 'due_date', 'is_opening', 'source', 'total_advance', 'get_advances_received',
 		'advances', 'sales_partner', 'commission_rate', 'total_commission', 'advances', 'from_date', 'to_date'];
 
 	if(cint(doc.is_pos) == 1) {
-		hide_field(par_flds);
+		hide_field(parent_fields);
 	} else {
-		for (i in par_flds) {
-			var docfield = frappe.meta.docfield_map[doc.doctype][par_flds[i]];
-			if(!docfield.hidden) unhide_field(par_flds[i]);
+		for (i in parent_fields) {
+			var docfield = frappe.meta.docfield_map[doc.doctype][parent_fields[i]];
+			if(!docfield.hidden) unhide_field(parent_fields[i]);
 		}
 	}
 
-	item_flds_stock = ['serial_no', 'batch_no', 'actual_qty', 'expense_account', 'warehouse', 'expense_account', 'warehouse']
-	cur_frm.fields_dict['items'].grid.set_column_disp(item_flds_stock,
+	item_fields_stock = ['serial_no', 'batch_no', 'actual_qty', 'expense_account', 'warehouse', 'expense_account', 'warehouse']
+	cur_frm.fields_dict['items'].grid.set_column_disp(item_fields_stock,
 		(cint(doc.update_stock)==1 ? true : false));
 
 	// India related fields
@@ -303,25 +303,6 @@
 	cur_frm.refresh_fields();
 }
 
-
-cur_frm.cscript.mode_of_payment = function(doc) {
-	if(doc.is_pos) {
-		return cur_frm.call({
-			method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.get_bank_cash_account",
-			args: {
-				"mode_of_payment": doc.mode_of_payment,
-				"company": doc.company
-			 },
-			 callback: function(r, rt) {
-				if(r.message) {
-					cur_frm.set_value("cash_bank_account", r.message["account"]);
-				}
-
-			 }
-		});
-	 }
-}
-
 cur_frm.cscript.update_stock = function(doc, dt, dn) {
 	cur_frm.cscript.hide_fields(doc, dt, dn);
 }
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index bc1d73d..53747bf 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -81,14 +81,10 @@
 		self.validate_multiple_billing("Delivery Note", "dn_detail", "amount", "items")
 		self.update_packing_list()
 
-	def on_submit(self):
-		if cint(self.update_stock) == 1:
-			self.update_stock_ledger()
-		else:
-			# Check for Approving Authority
-			if not self.recurring_id:
-				frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
-				 	self.company, self.base_grand_total, self)
+	def on_submit(self):			
+		if not self.recurring_id:
+			frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
+			 	self.company, self.base_grand_total, self)
 
 		self.check_prev_docstatus()
 
@@ -99,7 +95,12 @@
 		self.update_status_updater_args()
 		self.update_prevdoc_status()
 		self.update_billing_status_in_dn()
-
+		
+		# Updating stock ledger should always be called after updating prevdoc status, 
+		# because updating reserved qty in bin depends upon updated delivered qty in SO
+		if self.update_stock == 1:
+			self.update_stock_ledger()
+		
 		# this sequence because outstanding may get -ve
 		self.make_gl_entries()
 
@@ -117,9 +118,6 @@
 		self.update_time_log_batch(None)
 
 	def on_cancel(self):
-		if cint(self.update_stock) == 1:
-			self.update_stock_ledger()
-
 		self.check_close_sales_order("sales_order")
 
 		from erpnext.accounts.utils import remove_against_link_from_jv
@@ -137,6 +135,11 @@
 			self.update_billing_status_for_zero_amount_refdoc("Sales Order")
 
 		self.validate_c_form_on_cancel()
+		
+		# Updating stock ledger should always be called after updating prevdoc status, 
+		# because updating reserved qty in bin depends upon updated delivered qty in SO
+		if self.update_stock == 1:
+			self.update_stock_ledger()
 
 		self.make_gl_entries_on_cancel()
 
@@ -461,21 +464,6 @@
 				
 				d.income_account = disposal_account
 
-	def on_update(self):
-		if cint(self.is_pos) == 1:
-			if flt(self.paid_amount) == 0:
-				if self.cash_bank_account:
-					frappe.db.set(self, 'paid_amount',
-						flt(flt(self.grand_total) - flt(self.write_off_amount), self.precision("paid_amount")))
-				else:
-					# show message that the amount is not paid
-					frappe.db.set(self,'paid_amount',0)
-					frappe.msgprint(_("Note: Payment Entry will not be created since 'Cash or Bank Account' was not specified"))
-		else:
-			frappe.db.set(self,'paid_amount',0)
-
-		frappe.db.set(self, 'base_paid_amount',
-			flt(self.paid_amount*self.conversion_rate, self.precision("base_paid_amount")))
 
 	def check_prev_docstatus(self):
 		for d in self.get('items'):
diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py
index 2063edf..a8a090f 100644
--- a/erpnext/accounts/general_ledger.py
+++ b/erpnext/accounts/general_ledger.py
@@ -25,7 +25,6 @@
 def process_gl_map(gl_map, merge_entries=True):
 	if merge_entries:
 		gl_map = merge_similar_entries(gl_map)
-
 	for entry in gl_map:
 		# toggle debit, credit if negative entry
 		if flt(entry.debit) < 0:
diff --git a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
index fcbc469..98a972b 100644
--- a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
+++ b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
@@ -3,10 +3,13 @@
 
 frappe.require("assets/erpnext/js/financial_statements.js");
 
-frappe.query_reports["Profit and Loss Statement"] = erpnext.financial_statements;
+frappe.query_reports["Profit and Loss Statement"] = $.extend({}, erpnext.financial_statements);
 
 frappe.query_reports["Profit and Loss Statement"]["filters"].push({
 	"fieldname": "accumulated_values",
 	"label": __("Accumulated Values"),
 	"fieldtype": "Check"
-})
\ No newline at end of file
+});
+
+console.log(frappe.query_reports["Profit and Loss Statement"]);
+
diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.js b/erpnext/buying/doctype/purchase_common/purchase_common.js
index 2f1959b..79eaeeb 100644
--- a/erpnext/buying/doctype/purchase_common/purchase_common.js
+++ b/erpnext/buying/doctype/purchase_common/purchase_common.js
@@ -42,7 +42,7 @@
 
 		this.frm.set_query("item_code", "items", function() {
 			if(me.frm.doc.is_subcontracted == "Yes") {
-				 return{
+				return{
 					query: "erpnext.controllers.queries.item_query",
 					filters:{ 'is_sub_contracted_item': 1 }
 				}
@@ -114,8 +114,49 @@
 	},
 
 	qty: function(doc, cdt, cdn) {
+		if ((doc.doctype == "Purchase Receipt") || (doc.doctype == "Purchase Invoice" && doc.update_stock)) {
+			var item = frappe.get_doc(cdt, cdn);
+			frappe.model.round_floats_in(item, ["qty", "received_qty"]);
+			if(!(item.received_qty || item.rejected_qty) && item.qty) {
+				item.received_qty = item.qty;
+			}
+
+			if(item.qty > item.received_qty) {
+				msgprint(__("Error: {0} > {1}", [__(frappe.meta.get_label(item.doctype, "qty", item.name)),
+							__(frappe.meta.get_label(item.doctype, "received_qty", item.name))]))
+				item.qty = item.rejected_qty = 0.0;
+			} else {
+				item.rejected_qty = flt(item.received_qty - item.qty, precision("rejected_qty", item));
+			}
+		}
+		
 		this._super(doc, cdt, cdn);
 		this.conversion_factor(doc, cdt, cdn);
+		
+	},
+	
+	received_qty: function(doc, cdt, cdn) {
+		var item = frappe.get_doc(cdt, cdn);
+		frappe.model.round_floats_in(item, ["qty", "received_qty"]);
+
+		item.qty = (item.qty < item.received_qty) ? item.qty : item.received_qty;
+		this.qty(doc, cdt, cdn);
+	},
+	
+	rejected_qty: function(doc, cdt, cdn) {
+		var item = frappe.get_doc(cdt, cdn);
+		frappe.model.round_floats_in(item, ["received_qty", "rejected_qty"]);
+
+		if(item.rejected_qty > item.received_qty) {
+			msgprint(__("Error: {0} > {1}", [__(frappe.meta.get_label(item.doctype, "rejected_qty", item.name)),
+						__(frappe.meta.get_label(item.doctype, "received_qty", item.name))]));
+			item.qty = item.rejected_qty = 0.0;
+		} else {
+			
+			item.qty = flt(item.received_qty - item.rejected_qty, precision("qty", item));
+		}
+
+		this.qty(doc, cdt, cdn);
 	},
 
 	conversion_factor: function(doc, cdt, cdn) {
@@ -194,6 +235,10 @@
 
 		erpnext.utils.get_address_display(this.frm, "shipping_address",
 			"shipping_address_display", is_your_company_address=true)
+	},
+	
+	tc_name: function() {
+		this.get_terms();
 	}
 });
 
diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.py b/erpnext/buying/doctype/purchase_common/purchase_common.py
index 1c3fe1e..9516f24 100644
--- a/erpnext/buying/doctype/purchase_common/purchase_common.py
+++ b/erpnext/buying/doctype/purchase_common/purchase_common.py
@@ -51,7 +51,7 @@
 				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 == 'Purchase Receipt Item':
+			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):
@@ -72,15 +72,15 @@
 
 		if items and len(items) != len(set(items)) and \
 			not cint(frappe.db.get_single_value("Buying Settings", "allow_multiple_items") or 0):
-			frappe.msgprint(_("Warning: Same item has been entered multiple times."))
+			frappe.msgprint(_("Warning: Same item has been entered multiple times."), small=True)
 
 
 	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)
-		
+
 	def check_docstatus(self, check, doctype, docname, detail_doctype = ''):
 		if check == 'Next':
 			submitted = frappe.db.sql("""select t1.name from `tab%s` t1,`tab%s` t2
diff --git a/erpnext/buying/doctype/purchase_order/test_purchase_order.py b/erpnext/buying/doctype/purchase_order/test_purchase_order.py
index 94dd070..c24bcdc 100644
--- a/erpnext/buying/doctype/purchase_order/test_purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/test_purchase_order.py
@@ -45,6 +45,32 @@
 
 		po.load_from_db()
 		self.assertEquals(po.get("items")[0].received_qty, 4)
+		
+	def test_ordered_qty_against_pi_with_update_stock(self):
+		existing_ordered_qty = get_ordered_qty()
+
+		po = create_purchase_order()
+		
+		self.assertEqual(get_ordered_qty(), existing_ordered_qty + 10)
+
+		frappe.db.set_value('Item', '_Test Item', 'tolerance', 50)
+
+		pi = make_purchase_invoice(po.name)
+		pi.update_stock = 1
+		pi.items[0].qty = 12
+		pi.insert()
+		pi.submit()
+		
+		self.assertEqual(get_ordered_qty(), existing_ordered_qty)
+
+		po.load_from_db()
+		self.assertEquals(po.get("items")[0].received_qty, 12)
+
+		pi.cancel()
+		self.assertEqual(get_ordered_qty(), existing_ordered_qty + 10)
+
+		po.load_from_db()
+		self.assertEquals(po.get("items")[0].received_qty, 0)
 
 	def test_make_purchase_invoice(self):
 		po = create_purchase_order(do_not_submit=True)
diff --git a/erpnext/buying/doctype/supplier/supplier.js b/erpnext/buying/doctype/supplier/supplier.js
index 0b8b8ef..5088f2e 100644
--- a/erpnext/buying/doctype/supplier/supplier.js
+++ b/erpnext/buying/doctype/supplier/supplier.js
@@ -7,7 +7,7 @@
 		frappe.setup_language_field(frm);
 	},
 	refresh: function(frm) {
-		frm.dashboard.show_links();
+		frm.dashboard.show_dashboard();
 
 		if(frappe.defaults.get_default("supp_master_name")!="Naming Series") {
 			frm.toggle_display("naming_series", false);
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 50d4d8a..594a576 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -54,6 +54,26 @@
 			if not self.get("__islocal"):
 				validate_recurring_document(self)
 				convert_to_recurring(self, self.get("posting_date") or self.get("transaction_date"))
+		
+		self.validate_paid_amount()
+	
+	def validate_paid_amount(self):
+		if hasattr(self, "is_pos") or hasattr(self, "is_paid"):
+			is_paid = self.get("is_pos") or self.get("is_paid")
+			if cint(is_paid) == 1:
+				if flt(self.paid_amount) == 0:
+					if self.cash_bank_account:
+						self.paid_amount = flt(flt(self.grand_total) - flt(self.write_off_amount), 
+							self.precision("paid_amount"))
+					else:
+						# show message that the amount is not paid
+						self.paid_amount = 0
+						frappe.throw(_("Note: Payment Entry will not be created since 'Cash or Bank Account' was not specified"))
+			else:
+				frappe.db.set(self,'paid_amount',0)
+
+			frappe.db.set(self, 'base_paid_amount',
+				flt(self.paid_amount*self.conversion_rate, self.precision("base_paid_amount")))
 
 	def on_update_after_submit(self):
 		if self.meta.get_field("is_recurring"):
@@ -126,14 +146,6 @@
 		"""set missing item values"""
 		from erpnext.stock.get_item_details import get_item_details
 
-		if self.doctype == "Purchase Invoice":
-			auto_accounting_for_stock = cint(frappe.defaults.get_global_default("auto_accounting_for_stock"))
-
-			if auto_accounting_for_stock:
-				stock_not_billed_account = self.get_company_default("stock_received_but_not_billed")
-
-			stock_items = self.get_stock_items()
-
 		if hasattr(self, "items"):
 			parent_dict = {}
 			for fieldname in self.meta.get_valid_columns():
@@ -180,14 +192,8 @@
 							item.rate = flt(item.price_list_rate *
 								(1.0 - (flt(item.discount_percentage) / 100.0)), item.precision("rate"))
 
-					if self.doctype == "Purchase Invoice":
-						if auto_accounting_for_stock and item.item_code in stock_items \
-							and self.is_opening == 'No' \
-							and (not item.po_detail or not frappe.db.get_value("Purchase Order Item",
-								item.po_detail, "delivered_by_supplier")):
-
-								item.expense_account = stock_not_billed_account
-								item.cost_center = None
+			if self.doctype == "Purchase Invoice":
+				self.set_expense_account()
 
 	def set_taxes(self):
 		if not self.meta.get_field("taxes"):
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 6a1b205..74a3d69 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -4,7 +4,7 @@
 from __future__ import unicode_literals
 import frappe
 from frappe import _, msgprint
-from frappe.utils import flt
+from frappe.utils import flt,cint, cstr
 
 from erpnext.setup.utils import get_company_currency
 from erpnext.accounts.party import get_party_details
@@ -32,10 +32,29 @@
 		self.set_qty_as_per_stock_uom()
 		self.validate_stock_or_nonstock_items()
 		self.validate_warehouse()
+		
+		if self.doctype=="Purchase Invoice":
+			self.validate_purchase_receipt_if_update_stock()
+		
+		if self.doctype=="Purchase Receipt" or (self.doctype=="Purchase Invoice" and self.update_stock):
+			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)
+			
+			#sub-contracting
+			self.validate_for_subcontracting()
+			self.create_raw_materials_supplied("supplied_items")
+			self.set_landed_cost_voucher_amount()
+		
+		if self.doctype in ("Purchase Receipt", "Purchase Invoice"):
+			self.update_valuation_rate("items")
 
 	def set_missing_values(self, for_validate=False):
 		super(BuyingController, self).set_missing_values(for_validate)
-
+		
 		self.set_supplier_from_item_default()
 		self.set_price_list_currency("Buying")
 
@@ -60,6 +79,13 @@
 			if tax_for_valuation:
 				frappe.throw(_("Tax Category can not be 'Valuation' or 'Valuation and Total' as all items are non-stock items"))
 
+	def set_landed_cost_voucher_amount(self):
+		for d in self.get("items"):
+			lc_voucher_amount = frappe.db.sql("""select sum(applicable_charges)
+				from `tabLanded Cost Item`
+				where docstatus = 1 and purchase_receipt_item = %s""", d.name)
+			d.landed_cost_voucher_amount = lc_voucher_amount[0][0] if lc_voucher_amount else 0.0
+			
 	def set_total_in_words(self):
 		from frappe.utils import money_in_words
 		company_currency = get_company_currency(self.company)
@@ -94,7 +120,6 @@
 			if item.item_code and item.qty and item.item_code in stock_items:
 				item_proportion = flt(item.base_net_amount) / stock_items_amount if stock_items_amount \
 					else flt(item.qty) / stock_items_qty
-
 				if i == (last_stock_item_idx - 1):
 					item.item_tax_amount = flt(valuation_amount_adjustment,
 						self.precision("item_tax_amount", item))
@@ -108,10 +133,10 @@
 					item.conversion_factor = get_conversion_factor(item.item_code, item.uom).get("conversion_factor") or 1.0
 
 				qty_in_stock_uom = flt(item.qty * item.conversion_factor)
-				rm_supp_cost = flt(item.rm_supp_cost) if self.doctype=="Purchase Receipt" else 0.0
+				rm_supp_cost = flt(item.rm_supp_cost) if self.doctype in ["Purchase Receipt", "Purchase Invoice"] else 0.0
 
 				landed_cost_voucher_amount = flt(item.landed_cost_voucher_amount) \
-					if self.doctype == "Purchase Receipt" else 0.0
+					if self.doctype in ["Purchase Receipt", "Purchase Invoice"] else 0.0
 
 				item.valuation_rate = ((item.base_net_amount + item.item_tax_amount + rm_supp_cost
 					 + landed_cost_voucher_amount) / qty_in_stock_uom)
@@ -123,7 +148,7 @@
 			frappe.throw(_("Please enter 'Is Subcontracted' as Yes or No"))
 
 		if self.is_subcontracted == "Yes":
-			if self.doctype == "Purchase Receipt" and not self.supplier_warehouse:
+			if self.doctype in ["Purchase Receipt", "Purchase Invoice"] and not self.supplier_warehouse:
 				frappe.throw(_("Supplier Warehouse mandatory for sub-contracted Purchase Receipt"))
 
 			for item in self.get("items"):
@@ -139,7 +164,7 @@
 		if self.is_subcontracted=="Yes":
 			parent_items = []
 			for item in self.get("items"):
-				if self.doctype == "Purchase Receipt":
+				if self.doctype in ["Purchase Receipt", "Purchase Invoice"]:
 					item.rm_supp_cost = 0.0
 				if item.item_code in self.sub_contracted_items:
 					self.update_raw_materials_supplied(item, raw_material_table)
@@ -149,7 +174,7 @@
 
 			self.cleanup_raw_materials_supplied(parent_items, raw_material_table)
 
-		elif self.doctype == "Purchase Receipt":
+		elif self.doctype in ["Purchase Receipt", "Purchase Invoice"]:
 			for item in self.get("items"):
 				item.rm_supp_cost = 0.0
 
@@ -179,7 +204,7 @@
 
 			rm.conversion_factor = item.conversion_factor
 
-			if self.doctype == "Purchase Receipt":
+			if self.doctype in ["Purchase Receipt", "Purchase Invoice"]:
 				rm.consumed_qty = required_qty
 				rm.description = bom_item.description
 				if item.batch_no and not rm.batch_no:
@@ -205,7 +230,7 @@
 			rm.amount = required_qty * flt(rm.rate)
 			raw_materials_cost += flt(rm.amount)
 
-		if self.doctype == "Purchase Receipt":
+		if self.doctype in ("Purchase Receipt", "Purchase Invoice"):
 			item.rm_supp_cost = raw_materials_cost
 
 	def cleanup_raw_materials_supplied(self, parent_items, raw_material_table):
@@ -261,3 +286,106 @@
 				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)
+	
+	def validate_purchase_return(self):
+		for d in self.get("items"):
+			if self.is_return and flt(d.rejected_qty) != 0:
+				frappe.throw(_("Row #{0}: Rejected Qty can not be entered in Purchase Return").format(d.idx))
+
+			# validate rate with ref PR
+
+	def validate_rejected_warehouse(self):
+		for d in self.get("items"):
+			if flt(d.rejected_qty) and not d.rejected_warehouse:
+				if self.rejected_warehouse:
+					d.rejected_warehouse = self.rejected_warehouse
+				
+				if not d.rejected_warehouse:
+					frappe.throw(_("Row #{0}: Rejected Warehouse is mandatory against rejected Item {1}").format(d.idx, d.item_code))
+
+	# validate accepted and rejected qty
+	def validate_accepted_rejected_qty(self):
+		for d in self.get("items"):
+			if not flt(d.received_qty) and flt(d.qty):
+				d.received_qty = flt(d.qty) - flt(d.rejected_qty)
+
+			elif not flt(d.qty) and flt(d.rejected_qty):
+				d.qty = flt(d.received_qty) - flt(d.rejected_qty)
+
+			elif not flt(d.rejected_qty):
+				d.rejected_qty = flt(d.received_qty) -  flt(d.qty)
+
+			# Check Received Qty = Accepted Qty + Rejected Qty
+			if ((flt(d.qty) + flt(d.rejected_qty)) != flt(d.received_qty)):
+				frappe.throw(_("Accepted + Rejected Qty must be equal to Received quantity for Item {0}").format(d.item_code))
+	
+	def update_stock_ledger(self, allow_negative_stock=False, via_landed_cost_voucher=False):
+		self.update_ordered_qty()
+		
+		sl_entries = []
+		stock_items = self.get_stock_items()
+
+		for d in self.get('items'):
+			if d.item_code in stock_items and d.warehouse:
+				pr_qty = flt(d.qty) * flt(d.conversion_factor)
+
+				if pr_qty:
+					val_rate_db_precision = 6 if cint(self.precision("valuation_rate", d)) <= 6 else 9
+					rate = flt(d.valuation_rate, val_rate_db_precision)
+					sle = self.get_sl_entries(d, {
+						"actual_qty": flt(pr_qty),
+						"serial_no": cstr(d.serial_no).strip()
+					})
+					if self.is_return:
+						sle.update({
+							"outgoing_rate": rate
+						})
+					else:
+						sle.update({
+							"incoming_rate": rate
+						})
+					sl_entries.append(sle)
+
+				if flt(d.rejected_qty) > 0:
+					sl_entries.append(self.get_sl_entries(d, {
+						"warehouse": d.rejected_warehouse,
+						"actual_qty": flt(d.rejected_qty) * flt(d.conversion_factor),
+						"serial_no": cstr(d.rejected_serial_no).strip(),
+						"incoming_rate": 0.0
+					}))
+
+		self.make_sl_entries_for_supplier_warehouse(sl_entries)
+		self.make_sl_entries(sl_entries, allow_negative_stock=allow_negative_stock,
+			via_landed_cost_voucher=via_landed_cost_voucher)
+			
+	def update_ordered_qty(self):
+		po_map = {}
+		for d in self.get("items"):
+			if self.doctype=="Purchase Receipt" \
+				and d.prevdoc_doctype=="Purchase Order" and d.prevdoc_detail_docname:
+					po_map.setdefault(d.prevdoc_docname, []).append(d.prevdoc_detail_docname)
+			
+			elif self.doctype=="Purchase Invoice" and d.purchase_order and d.po_detail:
+				po_map.setdefault(d.purchase_order, []).append(d.po_detail)
+
+		for po, po_item_rows in po_map.items():
+			if po and po_item_rows:
+				po_obj = frappe.get_doc("Purchase Order", po)
+
+				if po_obj.status in ["Closed", "Cancelled"]:
+					frappe.throw(_("{0} {1} is cancelled or closed").format(_("Purchase Order"), po),
+						frappe.InvalidStatusError)
+
+				po_obj.update_ordered_qty(po_item_rows)
+	
+	def make_sl_entries_for_supplier_warehouse(self, sl_entries):
+		if hasattr(self, 'supplied_items'):
+			for d in self.get('supplied_items'):
+				# negative quantity is passed, as raw material qty has to be decreased
+				# when PR is submitted and it has to be increased when PR is cancelled
+				sl_entries.append(self.get_sl_entries(d, {
+					"item_code": d.rm_item_code,
+					"warehouse": self.supplier_warehouse,
+					"actual_qty": -1*flt(d.consumed_qty),
+				}))
+	
diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py
index ac8a5df..9187706 100644
--- a/erpnext/controllers/sales_and_purchase_return.py
+++ b/erpnext/controllers/sales_and_purchase_return.py
@@ -152,6 +152,7 @@
 			target_doc.prevdoc_docname = source_doc.prevdoc_docname
 			target_doc.prevdoc_detail_docname = source_doc.prevdoc_detail_docname
 		elif doctype == "Purchase Invoice":
+			target_doc.received_qty = -1* source_doc.qty
 			target_doc.purchase_order = source_doc.purchase_order
 			target_doc.purchase_receipt = source_doc.purchase_receipt
 			target_doc.po_detail = source_doc.po_detail
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index 3c9efa1..b9b94f5 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -7,6 +7,7 @@
 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.controllers.stock_controller import StockController
 
@@ -228,6 +229,79 @@
 				status = frappe.db.get_value("Sales Order", d.get(ref_fieldname), "status")
 				if status == "Closed":
 					frappe.throw(_("Sales Order {0} is {1}").format(d.get(ref_fieldname), status))
+					
+	def update_reserved_qty(self):
+		so_map = {}
+		for d in self.get("items"):
+			if d.so_detail:
+				if self.doctype == "Delivery Note" and d.against_sales_order:
+					so_map.setdefault(d.against_sales_order, []).append(d.so_detail)
+				elif self.doctype == "Sales Invoice" and d.sales_order and self.update_stock:
+					so_map.setdefault(d.sales_order, []).append(d.so_detail)
+
+		for so, so_item_rows in so_map.items():
+			if so and so_item_rows:
+				sales_order = frappe.get_doc("Sales Order", so)
+
+				if sales_order.status in ["Closed", "Cancelled"]:
+					frappe.throw(_("{0} {1} is cancelled or closed").format(_("Sales Order"), so),
+						frappe.InvalidStatusError)
+
+				sales_order.update_reserved_qty(so_item_rows)
+
+	def update_stock_ledger(self):
+		self.update_reserved_qty()
+
+		sl_entries = []
+		for d in self.get_item_list():
+			if frappe.db.get_value("Item", d.item_code, "is_stock_item") == 1 and flt(d.qty):
+				return_rate = 0
+				if cint(self.is_return) and self.return_against and self.docstatus==1:
+					return_rate = self.get_incoming_rate_for_sales_return(d.item_code, self.return_against)
+
+				# On cancellation or if return entry submission, make stock ledger entry for
+				# target warehouse first, to update serial no values properly
+
+				if d.warehouse and ((not cint(self.is_return) and self.docstatus==1)
+					or (cint(self.is_return) and self.docstatus==2)):
+						sl_entries.append(self.get_sl_entries(d, {
+							"actual_qty": -1*flt(d.qty),
+							"incoming_rate": return_rate
+						}))
+
+				if d.target_warehouse:
+					target_warehouse_sle = self.get_sl_entries(d, {
+						"actual_qty": flt(d.qty),
+						"warehouse": d.target_warehouse
+					})
+
+					if self.docstatus == 1:
+						if not cint(self.is_return):
+							args = frappe._dict({
+								"item_code": d.item_code,
+								"warehouse": d.warehouse,
+								"posting_date": self.posting_date,
+								"posting_time": self.posting_time,
+								"qty": -1*flt(d.qty),
+								"serial_no": d.serial_no
+							})
+							target_warehouse_sle.update({
+								"incoming_rate": get_incoming_rate(args)
+							})
+						else:
+							target_warehouse_sle.update({
+								"outgoing_rate": return_rate
+							})
+					sl_entries.append(target_warehouse_sle)
+
+				if d.warehouse and ((not cint(self.is_return) and self.docstatus==2)
+					or (cint(self.is_return) and self.docstatus==1)):
+						sl_entries.append(self.get_sl_entries(d, {
+							"actual_qty": -1*flt(d.qty),
+							"incoming_rate": return_rate
+						}))
+
+		self.make_sl_entries(sl_entries)
 
 def check_active_sales_items(obj):
 	for d in obj.get("items"):
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index a832ab7..845a4d0 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -8,8 +8,6 @@
 import frappe.defaults
 from erpnext.accounts.utils import get_fiscal_year
 from erpnext.accounts.general_ledger import make_gl_entries, delete_gl_entries, process_gl_map
-from erpnext.stock.utils import get_incoming_rate
-
 from erpnext.controllers.accounts_controller import AccountsController
 
 class StockController(AccountsController):
@@ -169,7 +167,7 @@
 		else:
 			is_expense_account = frappe.db.get_value("Account",
 				item.get("expense_account"), "report_type")=="Profit and Loss"
-			if self.doctype not in ("Purchase Receipt", "Stock Reconciliation", "Stock Entry") and not is_expense_account:
+			if self.doctype not in ("Purchase Receipt", "Purchase Invoice", "Stock Reconciliation", "Stock Entry") and not is_expense_account:
 				frappe.throw(_("Expense / Difference account ({0}) must be a 'Profit or Loss' account")
 					.format(item.get("expense_account")))
 			if is_expense_account and not item.get("cost_center"):
@@ -230,79 +228,6 @@
 			incoming_rate = incoming_rate[0][0] if incoming_rate else 0.0
 
 		return incoming_rate
-
-	def update_reserved_qty(self):
-		so_map = {}
-		for d in self.get("items"):
-			if d.so_detail:
-				if self.doctype == "Delivery Note" and d.against_sales_order:
-					so_map.setdefault(d.against_sales_order, []).append(d.so_detail)
-				elif self.doctype == "Sales Invoice" and d.sales_order and self.update_stock:
-					so_map.setdefault(d.sales_order, []).append(d.so_detail)
-
-		for so, so_item_rows in so_map.items():
-			if so and so_item_rows:
-				sales_order = frappe.get_doc("Sales Order", so)
-
-				if sales_order.status in ["Closed", "Cancelled"]:
-					frappe.throw(_("{0} {1} is cancelled or closed").format(_("Sales Order"), so),
-						frappe.InvalidStatusError)
-
-				sales_order.update_reserved_qty(so_item_rows)
-
-	def update_stock_ledger(self):
-		self.update_reserved_qty()
-
-		sl_entries = []
-		for d in self.get_item_list():
-			if frappe.db.get_value("Item", d.item_code, "is_stock_item") == 1 and flt(d.qty):
-				return_rate = 0
-				if cint(self.is_return) and self.return_against and self.docstatus==1:
-					return_rate = self.get_incoming_rate_for_sales_return(d.item_code, self.return_against)
-
-				# On cancellation or if return entry submission, make stock ledger entry for
-				# target warehouse first, to update serial no values properly
-
-				if d.warehouse and ((not cint(self.is_return) and self.docstatus==1)
-					or (cint(self.is_return) and self.docstatus==2)):
-						sl_entries.append(self.get_sl_entries(d, {
-							"actual_qty": -1*flt(d.qty),
-							"incoming_rate": return_rate
-						}))
-
-				if d.target_warehouse:
-					target_warehouse_sle = self.get_sl_entries(d, {
-						"actual_qty": flt(d.qty),
-						"warehouse": d.target_warehouse
-					})
-
-					if self.docstatus == 1:
-						if not cint(self.is_return):
-							args = frappe._dict({
-								"item_code": d.item_code,
-								"warehouse": d.warehouse,
-								"posting_date": self.posting_date,
-								"posting_time": self.posting_time,
-								"qty": -1*flt(d.qty),
-								"serial_no": d.serial_no
-							})
-							target_warehouse_sle.update({
-								"incoming_rate": get_incoming_rate(args)
-							})
-						else:
-							target_warehouse_sle.update({
-								"outgoing_rate": return_rate
-							})
-					sl_entries.append(target_warehouse_sle)
-
-				if d.warehouse and ((not cint(self.is_return) and self.docstatus==2)
-					or (cint(self.is_return) and self.docstatus==1)):
-						sl_entries.append(self.get_sl_entries(d, {
-							"actual_qty": -1*flt(d.qty),
-							"incoming_rate": return_rate
-						}))
-
-		self.make_sl_entries(sl_entries)
 		
 	def validate_warehouse(self):
 		from erpnext.stock.utils import validate_warehouse_company
diff --git a/erpnext/hr/doctype/employee/employee.js b/erpnext/hr/doctype/employee/employee.js
index 5c241fb..cb26154 100755
--- a/erpnext/hr/doctype/employee/employee.js
+++ b/erpnext/hr/doctype/employee/employee.js
@@ -25,7 +25,7 @@
 	refresh: function() {
 		var me = this;
 		erpnext.toggle_naming_series();
-		this.frm.dashboard.show_links();
+		this.frm.dashboard.show_dashboard();
 	},
 
 	date_of_birth: function() {
diff --git a/erpnext/manufacturing/doctype/production_order/.py b/erpnext/manufacturing/doctype/production_order/.py
new file mode 100644
index 0000000..4476b16
--- /dev/null
+++ b/erpnext/manufacturing/doctype/production_order/.py
@@ -0,0 +1,8 @@
+import frappe
+
+def set_required_items(production_order):
+	pass
+
+def reserve_for_production(production_order):
+	'''Reserve pending raw materials for production'''
+	pass
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.json b/erpnext/manufacturing/doctype/production_order/production_order.json
index 14e3674..3b71b76 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.json
+++ b/erpnext/manufacturing/doctype/production_order/production_order.json
@@ -78,7 +78,7 @@
    "no_copy": 1, 
    "oldfieldname": "status", 
    "oldfieldtype": "Select", 
-   "options": "\nDraft\nSubmitted\nStopped\nIn Process\nCompleted\nCancelled", 
+   "options": "\nDraft\nSubmitted\nNot Started\nStopped\nIn Process\nCompleted\nCancelled", 
    "permlevel": 0, 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
@@ -309,6 +309,33 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "description": "Warehouse for reserving items", 
+   "fieldname": "source_warehouse", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Source Warehouse", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Warehouse", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
    "fieldname": "wip_warehouse", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -1024,6 +1051,32 @@
    "search_index": 0, 
    "set_only_once": 0, 
    "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "required_items", 
+   "fieldtype": "Table", 
+   "hidden": 1, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Required Items", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Production Order Item", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
   }
  ], 
  "hide_heading": 0, 
@@ -1036,7 +1089,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-04-06 05:44:08.681263", 
+ "modified": "2016-04-18 08:42:47.582203", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "Production Order", 
@@ -1083,6 +1136,7 @@
    "write": 0
   }
  ], 
+ "quick_entry": 1, 
  "read_only": 0, 
  "read_only_onload": 0, 
  "sort_order": "ASC", 
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index 88ee997..6c8dfd5 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -15,6 +15,8 @@
 from erpnext.stock.doctype.stock_entry.stock_entry import get_additional_costs
 from erpnext.manufacturing.doctype.manufacturing_settings.manufacturing_settings import get_mins_between_operations
 from erpnext.stock.stock_balance import get_planned_qty, update_bin_qty
+from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict
+from erpnext.stock.utils import get_bin
 
 class OverProductionError(frappe.ValidationError): pass
 class StockOverProductionError(frappe.ValidationError): pass
@@ -27,13 +29,6 @@
 
 class ProductionOrder(Document):
 	def validate(self):
-		if self.docstatus == 0:
-			self.status = "Draft"
-
-		from erpnext.controllers.status_updater import validate_status
-		validate_status(self.status, ["Draft", "Submitted", "Stopped",
-			"In Process", "Completed", "Cancelled"])
-
 		self.validate_production_item()
 		if self.bom_no:
 			validate_bom_no(self.production_item, self.bom_no)
@@ -43,6 +38,7 @@
 		self.calculate_operating_cost()
 		self.validate_qty()
 		self.validate_operation_time()
+		self.status = self.get_status()
 
 		from erpnext.utilities.transaction_base import validate_uom_is_integer
 		validate_uom_is_integer(self, "stock_uom", ["qty", "produced_qty"])
@@ -65,7 +61,7 @@
 	def validate_warehouse(self):
 		from erpnext.stock.utils import validate_warehouse_company
 
-		for w in [self.fg_warehouse, self.wip_warehouse]:
+		for w in [self.source_warehouse, self.fg_warehouse, self.wip_warehouse]:
 			validate_warehouse_company(w, self.company)
 
 	def calculate_operating_cost(self):
@@ -113,23 +109,36 @@
 
 
 	def update_status(self, status=None):
+		'''Update status of production order'''
+		status = self.get_status()
+		if status != self.status:
+			self.db_set("status", status)
+
+		self.update_required_items()
+
+	def get_status(self, status=None):
+		'''Return the status based on stock entries against this production order'''
 		if not status:
 			status = self.status
 
-		if status != 'Stopped':
-			stock_entries = frappe._dict(frappe.db.sql("""select purpose, sum(fg_completed_qty)
-				from `tabStock Entry` where production_order=%s and docstatus=1
-				group by purpose""", self.name))
+		if self.docstatus==0:
+			status = 'Draft'
+		elif self.docstatus==1:
+			if status != 'Stopped':
+				stock_entries = frappe._dict(frappe.db.sql("""select purpose, sum(fg_completed_qty)
+					from `tabStock Entry` where production_order=%s and docstatus=1
+					group by purpose""", self.name))
 
-			status = "Submitted"
-			if stock_entries:
-				status = "In Process"
-				produced_qty = stock_entries.get("Manufacture")
-				if flt(produced_qty) == flt(self.qty):
-					status = "Completed"
+				status = "Not Started"
+				if stock_entries:
+					status = "In Process"
+					produced_qty = stock_entries.get("Manufacture")
+					if flt(produced_qty) == flt(self.qty):
+						status = "Completed"
+		else:
+			status = 'Cancelled'
 
-		if status != self.status:
-			self.db_set("status", status)
+		return status
 
 	def update_production_order_qty(self):
 		"""Update **Manufactured Qty** and **Material Transferred for Qty** in Production Order
@@ -147,13 +156,16 @@
 
 			self.db_set(fieldname, qty)
 
+	def before_submit(self):
+		self.set_required_items()
+
 	def on_submit(self):
 		if not self.wip_warehouse:
 			frappe.throw(_("Work-in-Progress Warehouse is required before Submit"))
 		if not self.fg_warehouse:
 			frappe.throw(_("For Warehouse is required before Submit"))
 
-		frappe.db.set(self,'status', 'Submitted')
+		self.update_reserved_qty_for_production()
 		self.make_time_logs()
 		self.update_completed_qty_in_material_request()
 		self.update_planned_qty()
@@ -162,6 +174,7 @@
 		self.validate_cancel()
 
 		frappe.db.set(self,'status', 'Cancelled')
+		self.clear_required_items()
 		self.delete_time_logs()
 		self.update_completed_qty_in_material_request()
 		self.update_planned_qty()
@@ -342,6 +355,74 @@
 			if not d.time_in_mins > 0:
 				frappe.throw(_("Operation Time must be greater than 0 for Operation {0}".format(d.operation)))
 
+	def update_required_items(self):
+		'''
+		update bin reserved_qty_for_production
+		called from Stock Entry for production, after submit, cancel
+		'''
+		if self.docstatus==1 and self.source_warehouse:
+			if self.material_transferred_for_manufacturing == self.produced_qty:
+				# clear required items table and save document
+				self.clear_required_items()
+			else:
+				# calculate transferred qty based on submitted
+				# stock entries
+				self.update_transaferred_qty_for_required_items()
+
+				# update in bin
+				self.update_reserved_qty_for_production()
+
+	def clear_required_items(self):
+		'''Remove the required_items table and update the bins'''
+		items = [d.item_code for d in self.required_items]
+		self.required_items = []
+
+		self.update_child_table('required_items')
+
+		# completed, update reserved qty in bin
+		self.update_reserved_qty_for_production(items)
+
+	def update_reserved_qty_for_production(self, items=None):
+		'''update reserved_qty_for_production in bins'''
+		if not self.source_warehouse:
+			return
+
+		if not items:
+			items = [d.item_code for d in self.required_items]
+
+		for item in items:
+			stock_bin = get_bin(item, self.source_warehouse)
+			stock_bin.update_reserved_qty_for_production()
+
+	def set_required_items(self):
+		'''set required_items for production to keep track of reserved qty'''
+		if self.source_warehouse:
+			item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=self.qty,
+				fetch_exploded = self.use_multi_level_bom)
+
+			for item in item_dict.values():
+				self.append('required_items', {'item_code': item.item_code,
+					'required_qty': item.qty})
+
+			#print frappe.as_json(self.required_items)
+
+	def update_transaferred_qty_for_required_items(self):
+		'''update transferred qty from submitted stock entries for that item against
+			the production order'''
+
+		for d in self.required_items:
+			transferred_qty = frappe.db.sql('''select count(qty)
+				from `tabStock Entry` entry, `tabStock Entry Detail` detail
+				where
+					entry.production_order = %s
+					entry.purpose = "Material Transfer for Manufacture"
+					and entry.docstatus = 1
+					and detail.parent = entry.name
+					and detail.item_code = %s''', (self.name, d.item_code))[0][0]
+
+			d.db_set('transferred_qty', transferred_qty, update_modified = False)
+
+
 @frappe.whitelist()
 def get_item_details(item):
 	res = frappe.db.sql("""select stock_uom, description
@@ -372,6 +453,8 @@
 	stock_entry.fg_completed_qty = qty or (flt(production_order.qty) - flt(production_order.produced_qty))
 
 	if purpose=="Material Transfer for Manufacture":
+		if production_order.source_warehouse:
+			stock_entry.from_warehouse = production_order.source_warehouse
 		stock_entry.to_warehouse = production_order.wip_warehouse
 	else:
 		stock_entry.from_warehouse = production_order.wip_warehouse
diff --git a/erpnext/manufacturing/doctype/production_order/test_production_order.py b/erpnext/manufacturing/doctype/production_order/test_production_order.py
index 3b558a9..1879e78 100644
--- a/erpnext/manufacturing/doctype/production_order/test_production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/test_production_order.py
@@ -5,14 +5,19 @@
 from __future__ import unicode_literals
 import unittest
 import frappe
-from frappe.utils import flt, time_diff_in_hours, now, add_days
+from frappe.utils import flt, time_diff_in_hours, now, add_days, cint
 from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
 from erpnext.manufacturing.doctype.production_order.production_order \
 	import make_stock_entry, ItemHasVariantError
 from erpnext.stock.doctype.stock_entry import test_stock_entry
 from erpnext.projects.doctype.time_log.time_log import OverProductionLoggedError
+from erpnext.stock.utils import get_bin
 
 class TestProductionOrder(unittest.TestCase):
+	def setUp(self):
+		self.warehouse = '_Test Warehouse 2 - _TC'
+		self.item = '_Test Item'
+
 	def check_planned_qty(self):
 		set_perpetual_inventory(0)
 
@@ -140,6 +145,73 @@
 		prod_order = make_prod_order_test_record(item="_Test Variant Item", qty=1, do_not_save=True)
 		self.assertRaises(ItemHasVariantError, prod_order.save)
 
+	def test_reserved_qty_for_production_submit(self):
+		self.bin1_at_start = get_bin(self.item, self.warehouse)
+
+		# reset to correct value
+		self.bin1_at_start.update_reserved_qty_for_production()
+
+		self.pro_order = make_prod_order_test_record(item="_Test FG Item", qty=2,
+			source_warehouse=self.warehouse)
+
+		self.bin1_on_submit = get_bin(self.item, self.warehouse)
+
+		# reserved qty for production is updated
+		self.assertEqual(cint(self.bin1_at_start.reserved_qty_for_production) + 2,
+			cint(self.bin1_on_submit.reserved_qty_for_production))
+		self.assertEqual(cint(self.bin1_at_start.projected_qty),
+			cint(self.bin1_on_submit.projected_qty) + 2)
+
+	def test_reserved_qty_for_production_cancel(self):
+		self.test_reserved_qty_for_production_submit()
+
+		self.pro_order.cancel()
+
+		bin1_on_cancel = get_bin(self.item, self.warehouse)
+
+		# reserved_qty_for_producion updated
+		self.assertEqual(cint(self.bin1_at_start.reserved_qty_for_production),
+			cint(bin1_on_cancel.reserved_qty_for_production))
+		self.assertEqual(self.bin1_at_start.projected_qty,
+			cint(bin1_on_cancel.projected_qty))
+
+	def test_reserved_qty_for_production_on_stock_entry(self):
+		test_stock_entry.make_stock_entry(item_code="_Test Item",
+			target= self.warehouse, qty=100, basic_rate=100)
+		test_stock_entry.make_stock_entry(item_code="_Test Item Home Desktop 100",
+			target= self.warehouse, qty=100, basic_rate=100)
+
+		self.test_reserved_qty_for_production_submit()
+
+		s = frappe.get_doc(make_stock_entry(self.pro_order.name,
+			"Material Transfer for Manufacture", 2))
+
+		s.submit()
+
+		bin1_on_start_production = get_bin(self.item, self.warehouse)
+
+		# reserved_qty_for_producion updated
+		self.assertEqual(cint(self.bin1_at_start.reserved_qty_for_production),
+			cint(bin1_on_start_production.reserved_qty_for_production))
+
+		# projected qty will now be 2 less (becuase of item movement)
+		self.assertEqual(cint(self.bin1_at_start.projected_qty),
+			cint(bin1_on_start_production.projected_qty) + 2)
+
+		s = frappe.get_doc(make_stock_entry(self.pro_order.name, "Manufacture", 2))
+
+		bin1_on_end_production = get_bin(self.item, self.warehouse)
+
+		# no change in reserved / projected
+		self.assertEqual(cint(bin1_on_end_production.reserved_qty_for_production),
+			cint(bin1_on_start_production.reserved_qty_for_production))
+		self.assertEqual(cint(bin1_on_end_production.projected_qty),
+			cint(bin1_on_end_production.projected_qty))
+
+		# required_items removed
+		self.pro_order.reload()
+		self.assertEqual(len(self.pro_order.required_items), 0)
+
 def make_prod_order_test_record(**args):
 	args = frappe._dict(args)
 
@@ -152,6 +224,10 @@
 	pro_order.fg_warehouse = args.fg_warehouse or "_Test Warehouse 1 - _TC"
 	pro_order.company = args.company or "_Test Company"
 	pro_order.stock_uom = "_Test UOM"
+
+	if args.source_warehouse:
+		pro_order.source_warehouse = args.source_warehouse
+
 	if args.planned_start_date:
 		pro_order.planned_start_date = args.planned_start_date
 
diff --git a/erpnext/manufacturing/doctype/production_order_item/__init__.py b/erpnext/manufacturing/doctype/production_order_item/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/manufacturing/doctype/production_order_item/__init__.py
diff --git a/erpnext/manufacturing/doctype/production_order_item/production_order_item.json b/erpnext/manufacturing/doctype/production_order_item/production_order_item.json
new file mode 100644
index 0000000..2b93549
--- /dev/null
+++ b/erpnext/manufacturing/doctype/production_order_item/production_order_item.json
@@ -0,0 +1,110 @@
+{
+ "allow_copy": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "creation": "2016-04-18 07:38:26.314642", 
+ "custom": 0, 
+ "docstatus": 0, 
+ "doctype": "DocType", 
+ "document_type": "", 
+ "fields": [
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "item_code", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Item Code", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Item", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "required_qty", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Required Qty", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "transferred_qty", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Transferred Qty", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }
+ ], 
+ "hide_heading": 0, 
+ "hide_toolbar": 0, 
+ "idx": 0, 
+ "in_create": 0, 
+ "in_dialog": 0, 
+ "is_submittable": 0, 
+ "issingle": 0, 
+ "istable": 1, 
+ "max_attachments": 0, 
+ "modified": "2016-04-18 07:38:26.314642", 
+ "modified_by": "Administrator", 
+ "module": "Manufacturing", 
+ "name": "Production Order Item", 
+ "name_case": "", 
+ "owner": "Administrator", 
+ "permissions": [], 
+ "quick_entry": 1, 
+ "read_only": 0, 
+ "read_only_onload": 0, 
+ "sort_field": "modified", 
+ "sort_order": "DESC", 
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/production_order_item/production_order_item.py b/erpnext/manufacturing/doctype/production_order_item/production_order_item.py
new file mode 100644
index 0000000..c18338c
--- /dev/null
+++ b/erpnext/manufacturing/doctype/production_order_item/production_order_item.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class ProductionOrderItem(Document):
+	pass
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 469e327..ccc4629 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -196,7 +196,7 @@
 erpnext.patches.v5_7.item_template_attributes
 execute:frappe.delete_doc_if_exists("DocType", "Manage Variants")
 execute:frappe.delete_doc_if_exists("DocType", "Manage Variants Item")
-erpnext.patches.v4_2.repost_reserved_qty #2015-08-20
+erpnext.patches.v4_2.repost_reserved_qty #2016-04-15
 erpnext.patches.v5_4.update_purchase_cost_against_project
 erpnext.patches.v5_8.update_order_reference_in_return_entries
 erpnext.patches.v5_8.add_credit_note_print_heading
diff --git a/erpnext/patches/v7_0/update_party_status.py b/erpnext/patches/v7_0/update_party_status.py
index 1307377..208b476 100644
--- a/erpnext/patches/v7_0/update_party_status.py
+++ b/erpnext/patches/v7_0/update_party_status.py
@@ -1,9 +1,21 @@
 import frappe
-from erpnext.accounts.party_status import update_status
+from erpnext.accounts.party_status import status_depends_on, default_status
+from frappe.desk.notifications import get_filters_for
 
 def execute():
-	for doctype in ('Customer', 'Supplier'):
-		frappe.reload_doctype(doctype)
-		for doc in frappe.get_all(doctype):
-			doc = frappe.get_doc(doctype, doc.name)
-			update_status(doc)
\ No newline at end of file
+	for party_type in ('Customer', 'Supplier'):
+		frappe.reload_doctype(party_type)
+
+		# set all as default status
+		frappe.db.sql('update `tab{0}` set status=%s'.format(party_type), default_status[party_type])
+
+		for doctype in status_depends_on[party_type]:
+			filters = get_filters_for(doctype)
+			parties = frappe.get_all(doctype, fields="{0} as party".format(party_type.lower()),
+				filters=filters, limit_page_length=1)
+
+			parties = filter(None, [p.party for p in parties])
+
+			if parties:
+				frappe.db.sql('update `tab{0}` set status="Open" where name in ({1})'.format(party_type,
+					', '.join(len(parties) * ['%s'])), parties)
\ No newline at end of file
diff --git a/erpnext/projects/doctype/time_log/time_log.json b/erpnext/projects/doctype/time_log/time_log.json
index 21e68cc..050fc54 100644
--- a/erpnext/projects/doctype/time_log/time_log.json
+++ b/erpnext/projects/doctype/time_log/time_log.json
@@ -11,6 +11,32 @@
  "document_type": "Setup", 
  "fields": [
   {
+   "allow_on_submit": 1, 
+   "bold": 1, 
+   "collapsible": 0, 
+   "depends_on": "__islocal", 
+   "fieldname": "title", 
+   "fieldtype": "Data", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Title", 
+   "length": 0, 
+   "no_copy": 1, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
    "allow_on_submit": 0, 
    "bold": 1, 
    "collapsible": 0, 
@@ -896,31 +922,6 @@
    "search_index": 0, 
    "set_only_once": 0, 
    "unique": 0
-  }, 
-  {
-   "allow_on_submit": 1, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "fieldname": "title", 
-   "fieldtype": "Data", 
-   "hidden": 1, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "label": "Title", 
-   "length": 0, 
-   "no_copy": 1, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
   }
  ], 
  "hide_heading": 0, 
@@ -933,7 +934,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-03-29 15:55:12.780956", 
+ "modified": "2016-04-15 07:51:03.097280", 
  "modified_by": "Administrator", 
  "module": "Projects", 
  "name": "Time Log", 
@@ -953,8 +954,6 @@
    "print": 1, 
    "read": 1, 
    "report": 1, 
-   "restrict": 0, 
-   "restricted": 1, 
    "role": "Projects User", 
    "set_user_permissions": 0, 
    "share": 1, 
@@ -975,8 +974,6 @@
    "print": 1, 
    "read": 1, 
    "report": 1, 
-   "restrict": 0, 
-   "restricted": 0, 
    "role": "Projects Manager", 
    "set_user_permissions": 0, 
    "share": 1, 
@@ -984,6 +981,7 @@
    "write": 1
   }
  ], 
+ "quick_entry": 1, 
  "read_only": 0, 
  "read_only_onload": 0, 
  "sort_order": "ASC", 
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index a2ee1b7..b4e712a 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -516,10 +516,10 @@
 			);
 		}
 		
-		if(this.frm.doc.doctype == "Sales Invoice") {
+		if(this.frm.doc.doctype == "Sales Invoice" || this.frm.doc.doctype == "Purchase Invoice") {
 			frappe.model.round_floats_in(this.frm.doc, ["paid_amount"]);
 			
-			if(this.frm.doc.is_pos) {
+			if(this.frm.doc.is_pos || this.frm.doc.is_paid) {
 				if(!this.frm.doc.paid_amount || update_paid_amount===undefined || update_paid_amount) {
 					this.frm.doc.paid_amount = flt(total_amount_to_pay);
 				}
diff --git a/erpnext/public/js/financial_statements.js b/erpnext/public/js/financial_statements.js
index 557a392..3c87dab 100644
--- a/erpnext/public/js/financial_statements.js
+++ b/erpnext/public/js/financial_statements.js
@@ -68,5 +68,20 @@
 	"tree": true,
 	"name_field": "account",
 	"parent_field": "parent_account",
-	"initial_depth": 3
+	"initial_depth": 3,
+	onload: function(report) {
+		// dropdown for links to other financial statements
+		report.page.add_inner_button(__("Balance Sheet"), function() {
+			var filters = report.get_values();
+			frappe.set_route('query-report', 'Balance Sheet', {company: filters.company});
+		}, 'Financial Statements');
+		report.page.add_inner_button(__("Profit and Loss"), function() {
+			var filters = report.get_values();
+			frappe.set_route('query-report', 'Profit and Loss Statement', {company: filters.company});
+		}, 'Financial Statements');
+		report.page.add_inner_button(__("Cash Flow Statement"), function() {
+			var filters = report.get_values();
+			frappe.set_route('query-report', 'Cash Flow', {company: filters.company});
+		}, 'Financial Statements');
+	},
 };
diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js
index 95bed47..d30924e 100644
--- a/erpnext/selling/doctype/customer/customer.js
+++ b/erpnext/selling/doctype/customer/customer.js
@@ -7,7 +7,7 @@
 		frappe.setup_language_field(frm);
 	},
 	refresh: function(frm) {
-		frm.dashboard.show_links();
+		frm.dashboard.show_dashboard();
 
 		if(frappe.defaults.get_default("cust_master_name")!="Naming Series") {
 			frm.toggle_display("naming_series", false);
diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py
index 7ac8941..5fa2d7e 100644
--- a/erpnext/selling/doctype/sales_order/test_sales_order.py
+++ b/erpnext/selling/doctype/sales_order/test_sales_order.py
@@ -126,6 +126,34 @@
 
 		dn.cancel()
 		self.assertEqual(get_reserved_qty(), existing_reserved_qty + 10)
+		
+	def test_reserved_qty_for_over_delivery_via_sales_invoice(self):
+		# set over-delivery tolerance
+		frappe.db.set_value('Item', "_Test Item", 'tolerance', 50)
+
+		existing_reserved_qty = get_reserved_qty()
+
+		so = make_sales_order()
+		self.assertEqual(get_reserved_qty(), existing_reserved_qty + 10)
+
+		si = make_sales_invoice(so.name)
+		si.update_stock = 1
+		si.get("items")[0].qty = 12
+		si.insert()
+		si.submit()
+		
+		self.assertEqual(get_reserved_qty(), existing_reserved_qty)
+		
+		so.load_from_db()
+		self.assertEqual(so.get("items")[0].delivered_qty, 12)
+		self.assertEqual(so.per_delivered, 100)
+
+		si.cancel()
+		self.assertEqual(get_reserved_qty(), existing_reserved_qty + 10)
+		
+		so.load_from_db()
+		self.assertEqual(so.get("items")[0].delivered_qty, 0)
+		self.assertEqual(so.per_delivered, 0)
 
 	def test_reserved_qty_for_partial_delivery_with_packing_list(self):
 		existing_reserved_qty_item1 = get_reserved_qty("_Test Item")
diff --git a/erpnext/stock/doctype/bin/bin.js b/erpnext/stock/doctype/bin/bin.js
new file mode 100644
index 0000000..40411b6
--- /dev/null
+++ b/erpnext/stock/doctype/bin/bin.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Bin', {
+	refresh: function(frm) {
+
+	}
+});
diff --git a/erpnext/stock/doctype/bin/bin.json b/erpnext/stock/doctype/bin/bin.json
index 9eb3995..bb0de3f 100644
--- a/erpnext/stock/doctype/bin/bin.json
+++ b/erpnext/stock/doctype/bin/bin.json
@@ -16,6 +16,7 @@
    "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 1, 
    "in_list_view": 1, 
    "label": "Warehouse", 
@@ -42,6 +43,7 @@
    "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 1, 
    "in_list_view": 1, 
    "label": "Item Code", 
@@ -69,6 +71,7 @@
    "fieldtype": "Float", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Reserved Quantity", 
@@ -95,6 +98,7 @@
    "fieldtype": "Float", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 1, 
    "in_list_view": 1, 
    "label": "Actual Quantity", 
@@ -121,6 +125,7 @@
    "fieldtype": "Float", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Ordered Quantity", 
@@ -147,6 +152,7 @@
    "fieldtype": "Float", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "label": "Requested Quantity", 
@@ -172,6 +178,7 @@
    "fieldtype": "Float", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "label": "Planned Qty", 
@@ -197,6 +204,7 @@
    "fieldtype": "Float", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "label": "Projected Qty", 
@@ -218,10 +226,36 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "fieldname": "reserved_qty_for_production", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Reserved Qty for Production", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
    "fieldname": "ma_rate", 
    "fieldtype": "Float", 
    "hidden": 1, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "label": "Moving Average Rate", 
@@ -247,6 +281,7 @@
    "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 1, 
    "in_list_view": 0, 
    "label": "UOM", 
@@ -273,6 +308,7 @@
    "fieldtype": "Float", 
    "hidden": 1, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "label": "FCFS Rate", 
@@ -298,6 +334,7 @@
    "fieldtype": "Float", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "label": "Valuation Rate", 
@@ -323,6 +360,7 @@
    "fieldtype": "Float", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "label": "Stock Value", 
@@ -350,7 +388,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-02-10 02:39:45.738623", 
+ "modified": "2016-04-18 08:12:57.341517", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Bin", 
@@ -417,8 +455,10 @@
    "write": 0
   }
  ], 
+ "quick_entry": 1, 
  "read_only": 0, 
  "read_only_onload": 0, 
  "search_fields": "item_code,warehouse", 
- "sort_order": "ASC"
+ "sort_order": "ASC", 
+ "track_seen": 0
 }
\ No newline at end of file
diff --git a/erpnext/stock/doctype/bin/bin.py b/erpnext/stock/doctype/bin/bin.py
index ae7c6e7..a1580d5 100644
--- a/erpnext/stock/doctype/bin/bin.py
+++ b/erpnext/stock/doctype/bin/bin.py
@@ -65,12 +65,15 @@
 		self.indented_qty = flt(self.indented_qty) + flt(args.get("indented_qty"))
 		self.planned_qty = flt(self.planned_qty) + flt(args.get("planned_qty"))
 
-		self.projected_qty = flt(self.actual_qty) + flt(self.ordered_qty) + \
-		 	flt(self.indented_qty) + flt(self.planned_qty) - flt(self.reserved_qty)
-
+		self.set_projected_qty()
 		self.save()
 		update_item_projected_qty(self.item_code)
 
+	def set_projected_qty(self):
+		self.projected_qty = (flt(self.actual_qty) + flt(self.ordered_qty)
+			+ flt(self.indented_qty) + flt(self.planned_qty) - flt(self.reserved_qty)
+			- flt(self.reserved_qty_for_production))
+
 	def get_first_sle(self):
 		sle = frappe.db.sql("""
 			select * from `tabStock Ledger Entry`
@@ -81,8 +84,25 @@
 		""", (self.item_code, self.warehouse), as_dict=1)
 		return sle and sle[0] or None
 
+	def update_reserved_qty_for_production(self):
+		'''Update qty reserved for production from Production Item tables
+			in open production orders'''
+		self.reserved_qty_for_production = frappe.db.sql('''select sum(required_qty - transferred_qty)
+			from `tabProduction Order` pro, `tabProduction Order Item` item
+			where
+				item.item_code = %s
+				and item.parent = pro.name
+				and pro.docstatus = 1
+				and pro.source_warehouse = %s''', (self.item_code, self.warehouse))[0][0]
+
+		self.set_projected_qty()
+
+		self.db_set('reserved_qty_for_production', self.reserved_qty_for_production)
+		self.db_set('projected_qty', self.projected_qty)
+
+
 def update_item_projected_qty(item_code):
-	'''Set Item project qty'''
+	'''Set total_projected_qty in Item as sum of projected qty in all warehouses'''
 	frappe.db.sql('''update tabItem set
 		total_projected_qty = ifnull((select sum(projected_qty) from tabBin where item_code=%s), 0)
 		where name=%s''', (item_code, item_code))
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 63abaa5..6712ee8 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -191,6 +191,8 @@
 		if not self.is_return:
 			self.check_credit_limit()
 
+		# Updating stock ledger should always be called after updating prevdoc status, 
+		# because updating reserved qty in bin depends upon updated delivered qty in SO
 		self.update_stock_ledger()
 		self.make_gl_entries()
 
@@ -201,6 +203,8 @@
 		self.update_prevdoc_status()
 		self.update_billing_status()
 
+		# Updating stock ledger should always be called after updating prevdoc status, 
+		# because updating reserved qty in bin depends upon updated delivered qty in SO
 		self.update_stock_ledger()
 
 		self.cancel_packing_slips()
diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js
index 900c40c..4a4de4c 100644
--- a/erpnext/stock/doctype/item/item.js
+++ b/erpnext/stock/doctype/item/item.js
@@ -16,12 +16,6 @@
 
 	},
 
-	dashboard_update: function(frm) {
-		if(frm.dashboard_data.stock_data && frm.dashboard_data.stock_data.length) {
-			frm.dashboard.add_stats(frappe.render_template('item_dashboard', {data: frm.dashboard_data.stock_data}))
-		}
-	},
-
 	refresh: function(frm) {
 
 		if(frm.doc.is_stock_item) {
@@ -82,7 +76,25 @@
 
 		erpnext.item.toggle_attributes(frm);
 
-		frm.dashboard.show_links();
+		frm.dashboard.show_dashboard();
+	},
+
+	dashboard_update: function(frm) {
+		if(frm.dashboard_data.stock_data && frm.dashboard_data.stock_data.length) {
+			var max_count = 0;
+			frm.dashboard_data.stock_data.forEach(function(d) {
+				d.actual_or_pending = d.projected_qty - d.reserved_qty;
+				d.pending_qty = 0;
+				if(d.actual_or_pending > d.actual_qty) {
+					d.pending_qty = d.actual_or_pending - d.actual_qty;
+				}
+
+				max_count = Math.max(d.actual_or_pending, d.actual_qty,
+					d.reserved_qty, max_count);
+			})
+			frm.dashboard.add_stats(frappe.render_template('item_dashboard',
+				{data: frm.dashboard_data.stock_data, max_count: max_count}));
+		}
 	},
 
 	validate: function(frm){
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index f0e5f29..649f97b 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -633,8 +633,8 @@
 			group by posting_date''', name))
 
 def get_stock_data(name):
-	return frappe.get_all('Bin', fields=['warehouse', 'actual_qty', 'projected_qty'],
-		filters={'item_code': name})
+	return frappe.get_all('Bin', fields=['warehouse', 'actual_qty', 'projected_qty', 'reserved_qty'],
+		filters={'item_code': name}, order_by = 'warehouse asc')
 
 def validate_end_of_life(item_code, end_of_life=None, disabled=None, verbose=1):
 	if (not end_of_life) or (disabled is None):
diff --git a/erpnext/stock/doctype/item/item_dashboard.html b/erpnext/stock/doctype/item/item_dashboard.html
index a002a50..cef209a 100644
--- a/erpnext/stock/doctype/item/item_dashboard.html
+++ b/erpnext/stock/doctype/item/item_dashboard.html
@@ -1,12 +1,39 @@
-<div style="padding-left: 15px;">
+<div style="padding-left: 15px; padding-right: 15px;">
 	<h5>Stock Levels</h5>
-	<div class="row">
-		<div class="col-md-6 col-xs-12">
-			<ul class="list-unstyled">
-			{% data.every(function(d) { %}
-				<li class="small">{{ d.warehouse }}: {{ d.actual_qty }} ({{ d.projected_qty }})</li>
-			{% }) %}
-			</ul>
-		</div>
-	</div>
+	<ul class="list-group">
+	{% for(var i=0; i < data.length; i++) { var d = data[i]; %}
+		<li class="list-group-item" style="background-color: inherit;">
+			<div class="row">
+				<div class="col-sm-8 small" style="margin-top: 8px;">{{ d.warehouse }}</div>
+				<div class="col-sm-4 small">
+					<span class="inline-graph">
+						<span class="inline-graph-half" title="{{ __("Reserved Qty") }}">
+							<span class="inline-graph-count">{{ d.reserved_qty }}</span>
+							<span class="inline-graph-bar">
+								<span class="inline-graph-bar-inner"
+									style="width: {{ cint(Math.abs(d.reserved_qty)/max_count * 100) || 5 }}%">
+								</span>
+							</span>
+						</span>
+						<span class="inline-graph-half" title="{{ __("Acutal Qty {0} / Waiting Qty {1}", [d.actual_qty, d.pending_qty]) }}">
+							<span class="inline-graph-count">
+								{{ d.actual_qty }} {{ (d.pending_qty > 0) ? ("(" + d.pending_qty+ ")") : "" }}
+							</span>
+							<span class="inline-graph-bar">
+								<span class="inline-graph-bar-inner dark"
+									style="width: {{ cint(d.actual_qty/max_count * 100) }}%">
+								</span>
+								{% if(d.pending_qty > 0) { %}
+								<span class="inline-graph-bar-inner" title="{{ __("Projected Qty") }}"
+									style="width: {{ cint(d.pending_qty/max_count * 100) }}%">
+								</span>
+								{% } %}
+							</span>
+						</span>
+					</span>
+				</div>
+			</div>
+		</li>
+	{% } %}
+	</ul>
 </div>
\ No newline at end of file
diff --git a/erpnext/stock/doctype/landed_cost_item/landed_cost_item.json b/erpnext/stock/doctype/landed_cost_item/landed_cost_item.json
index 9c1a74f..fafcc84 100644
--- a/erpnext/stock/doctype/landed_cost_item/landed_cost_item.json
+++ b/erpnext/stock/doctype/landed_cost_item/landed_cost_item.json
@@ -6,6 +6,7 @@
  "custom": 0, 
  "docstatus": 0, 
  "doctype": "DocType", 
+ "document_type": "Document", 
  "fields": [
   {
    "allow_on_submit": 0, 
@@ -15,6 +16,7 @@
    "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Item Code", 
@@ -23,6 +25,7 @@
    "options": "Item", 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 1, 
    "report_hide": 0, 
    "reqd": 1, 
@@ -39,6 +42,7 @@
    "fieldtype": "Text Editor", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Description", 
@@ -48,6 +52,7 @@
    "oldfieldtype": "Data", 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "print_width": "300px", 
    "read_only": 1, 
    "report_hide": 0, 
@@ -61,18 +66,47 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "purchase_receipt", 
-   "fieldtype": "Link", 
+   "fieldname": "receipt_document_type", 
+   "fieldtype": "Select", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "Purchase Receipt", 
+   "label": "Receipt Document Type", 
    "length": 0, 
    "no_copy": 1, 
-   "options": "Purchase Receipt", 
+   "options": "Purchase Invoice\nPurchase Receipt", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "receipt_document", 
+   "fieldtype": "Dynamic Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Receipt Document", 
+   "length": 0, 
+   "no_copy": 1, 
+   "options": "receipt_document_type", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
    "read_only": 1, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -88,12 +122,14 @@
    "fieldtype": "Column Break", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -109,6 +145,7 @@
    "fieldtype": "Float", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Qty", 
@@ -116,6 +153,7 @@
    "no_copy": 0, 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 1, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -131,6 +169,7 @@
    "fieldtype": "Currency", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "label": "Rate", 
@@ -139,6 +178,7 @@
    "options": "Company:company:default_currency", 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 1, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -154,6 +194,7 @@
    "fieldtype": "Currency", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Amount", 
@@ -164,6 +205,7 @@
    "options": "Company:company:default_currency", 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 1, 
    "report_hide": 0, 
    "reqd": 1, 
@@ -179,6 +221,7 @@
    "fieldtype": "Currency", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Applicable Charges", 
@@ -187,6 +230,7 @@
    "options": "Company:company:default_currency", 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 1, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -202,6 +246,7 @@
    "fieldtype": "Data", 
    "hidden": 1, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "label": "Purchase Receipt Item", 
@@ -209,6 +254,7 @@
    "no_copy": 1, 
    "permlevel": 0, 
    "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
    "read_only": 1, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -226,12 +272,13 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2015-11-16 06:29:49.057949", 
+ "modified": "2016-04-07 16:18:00.859492", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Landed Cost Item", 
  "owner": "wasim@webnotestech.com", 
  "permissions": [], 
  "read_only": 0, 
- "read_only_onload": 0
+ "read_only_onload": 0, 
+ "track_seen": 0
 }
\ No newline at end of file
diff --git a/erpnext/stock/doctype/landed_cost_purchase_receipt/landed_cost_purchase_receipt.json b/erpnext/stock/doctype/landed_cost_purchase_receipt/landed_cost_purchase_receipt.json
index 165982f..db3b89e 100644
--- a/erpnext/stock/doctype/landed_cost_purchase_receipt/landed_cost_purchase_receipt.json
+++ b/erpnext/stock/doctype/landed_cost_purchase_receipt/landed_cost_purchase_receipt.json
@@ -6,25 +6,54 @@
  "custom": 0, 
  "docstatus": 0, 
  "doctype": "DocType", 
+ "document_type": "Document", 
  "fields": [
   {
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "purchase_receipt", 
-   "fieldtype": "Link", 
+   "fieldname": "receipt_document_type", 
+   "fieldtype": "Select", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Receipt Document Type", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "\nPurchase Invoice\nPurchase Receipt", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "receipt_document", 
+   "fieldtype": "Dynamic Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
-   "label": "Purchase Receipt", 
+   "label": "Receipt Document", 
    "length": 0, 
    "no_copy": 0, 
    "oldfieldname": "purchase_receipt_no", 
    "oldfieldtype": "Link", 
-   "options": "Purchase Receipt", 
+   "options": "receipt_document_type", 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "print_width": "220px", 
    "read_only": 0, 
    "report_hide": 0, 
@@ -42,6 +71,7 @@
    "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Supplier", 
@@ -50,6 +80,7 @@
    "options": "Supplier", 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 1, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -65,12 +96,14 @@
    "fieldtype": "Column Break", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -87,6 +120,7 @@
    "fieldtype": "Date", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Posting Date", 
@@ -94,6 +128,7 @@
    "no_copy": 0, 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 1, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -109,6 +144,7 @@
    "fieldtype": "Currency", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Grand Total", 
@@ -116,6 +152,7 @@
    "no_copy": 0, 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 1, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -133,12 +170,13 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2015-11-16 06:29:49.106523", 
+ "modified": "2016-04-07 15:14:56.955036", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Landed Cost Purchase Receipt", 
  "owner": "wasim@webnotestech.com", 
  "permissions": [], 
  "read_only": 0, 
- "read_only_onload": 0
+ "read_only_onload": 0, 
+ "track_seen": 0
 }
\ No newline at end of file
diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js
index 0bb8f90..5a86c89 100644
--- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js
+++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js
@@ -8,20 +8,28 @@
 erpnext.stock.LandedCostVoucher = erpnext.stock.StockController.extend({
 	setup: function() {
 		var me = this;
-		this.frm.fields_dict.purchase_receipts.grid.get_field('purchase_receipt').get_query =
-			function() {
+		this.frm.fields_dict.purchase_receipts.grid.get_field('receipt_document').get_query =
+			function(doc, cdt ,cdn) {
+				var d = locals[cdt][cdn]
+				
+				var filters = [
+					[d.receipt_document_type, 'docstatus', '=', '1'],
+					[d.receipt_document_type, 'company', '=', me.frm.doc.company],
+				]
+				
+				if(d.receipt_document_type == "Purchase Invoice") {
+					filters.push(["Purchase Invoice", "update_stock", "=", "1"])
+				}
+								
 				if(!me.frm.doc.company) msgprint(__("Please enter company first"));
 				return {
-					filters:[
-						['Purchase Receipt', 'docstatus', '=', '1'],
-						['Purchase Receipt', 'company', '=', me.frm.doc.company],
-					]
+					filters:filters
 				}
 		};
 
-		this.frm.add_fetch("purchase_receipt", "supplier", "supplier");
-		this.frm.add_fetch("purchase_receipt", "posting_date", "posting_date");
-		this.frm.add_fetch("purchase_receipt", "base_grand_total", "grand_total");
+		this.frm.add_fetch("receipt_document", "supplier", "supplier");
+		this.frm.add_fetch("receipt_document", "posting_date", "posting_date");
+		this.frm.add_fetch("receipt_document", "base_grand_total", "grand_total");
 
 	},
 
diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
index 3418c9e..ac59e06 100644
--- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
+++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
@@ -14,9 +14,9 @@
 		for pr in self.get("purchase_receipts"):
 			pr_items = frappe.db.sql("""select pr_item.item_code, pr_item.description,
 				pr_item.qty, pr_item.base_rate, pr_item.base_amount, pr_item.name
-				from `tabPurchase Receipt Item` pr_item where parent = %s
-				and exists(select name from tabItem where name = pr_item.item_code and is_stock_item = 1)""",
-				pr.purchase_receipt, as_dict=True)
+				from `tab{doctype} Item` pr_item where parent = %s
+				and exists(select name from tabItem where name = pr_item.item_code and is_stock_item = 1)
+				""".format(doctype=pr.receipt_document_type), pr.receipt_document, as_dict=True)
 
 			for d in pr_items:
 				item = self.append("items")
@@ -25,13 +25,13 @@
 				item.qty = d.qty
 				item.rate = d.base_rate
 				item.amount = d.base_amount
-				item.purchase_receipt = pr.purchase_receipt
+				item.receipt_document_type = pr.receipt_document_type
+				item.receipt_document = pr.receipt_document
 				item.purchase_receipt_item = d.name
 
 		if self.get("taxes"):
 			self.set_applicable_charges_for_item()
 
-
 	def validate(self):
 		self.check_mandatory()
 		self.validate_purchase_receipts()
@@ -43,25 +43,26 @@
 
 	def check_mandatory(self):
 		if not self.get("purchase_receipts"):
-			frappe.throw(_("Please enter Purchase Receipts"))
+			frappe.throw(_("Please enter Receipt Document"))
 
 		if not self.get("taxes"):
 			frappe.throw(_("Please enter Taxes and Charges"))
 
 	def validate_purchase_receipts(self):
-		purchase_receipts = []
+		receipt_documents = []
+		
 		for d in self.get("purchase_receipts"):
-			if frappe.db.get_value("Purchase Receipt", d.purchase_receipt, "docstatus") != 1:
-				frappe.throw(_("Purchase Receipt must be submitted"))
+			if frappe.db.get_value(d.receipt_document_type, d.receipt_document, "docstatus") != 1:
+				frappe.throw(_("Receipt document must be submitted"))
 			else:
-				purchase_receipts.append(d.purchase_receipt)
+				receipt_documents.append(d.receipt_document)
 
 		for item in self.get("items"):
-			if not item.purchase_receipt:
+			if not item.receipt_document:
 				frappe.throw(_("Item must be added using 'Get Items from Purchase Receipts' button"))
-			elif item.purchase_receipt not in purchase_receipts:
-				frappe.throw(_("Item Row {0}: Purchase Receipt {1} does not exist in above 'Purchase Receipts' table")
-					.format(item.idx, item.purchase_receipt))
+			elif item.receipt_document not in receipt_documents:
+				frappe.throw(_("Item Row {idx}: {doctype} {docname} does not exist in above '{doctype}' table")
+					.format(idx=item.idx, doctype=item.receipt_document_type, docname=item.receipt_document))
 
 	def set_total_taxes_and_charges(self):
 		self.total_taxes_and_charges = sum([flt(d.amount) for d in self.get("taxes")])
@@ -83,36 +84,35 @@
 		self.update_landed_cost()
 
 	def update_landed_cost(self):
-		purchase_receipts = list(set([d.purchase_receipt for d in self.get("items")]))
-		for purchase_receipt in purchase_receipts:
-			pr = frappe.get_doc("Purchase Receipt", purchase_receipt)
+		for d in self.get("items"):
+			doc = frappe.get_doc(d.receipt_document_type, d.receipt_document)
 
 			# set landed cost voucher amount in pr item
-			pr.set_landed_cost_voucher_amount()
+			doc.set_landed_cost_voucher_amount()
 
 			# set valuation amount in pr item
-			pr.update_valuation_rate("items")
+			doc.update_valuation_rate("items")
 
 			# save will update landed_cost_voucher_amount and voucher_amount in PR,
 			# as those fields are allowed to edit after submit
-			pr.save()
+			doc.save()
 
 			# update latest valuation rate in serial no
-			self.update_rate_in_serial_no(pr)
+			self.update_rate_in_serial_no(doc)
 
 			# update stock & gl entries for cancelled state of PR
-			pr.docstatus = 2
-			pr.update_stock_ledger(allow_negative_stock=True, via_landed_cost_voucher=True)
-			pr.make_gl_entries_on_cancel()
+			doc.docstatus = 2
+			doc.update_stock_ledger(allow_negative_stock=True, via_landed_cost_voucher=True)
+			doc.make_gl_entries_on_cancel()
 
 
 			# update stock & gl entries for submit state of PR
-			pr.docstatus = 1
-			pr.update_stock_ledger(via_landed_cost_voucher=True)
-			pr.make_gl_entries()
+			doc.docstatus = 1
+			doc.update_stock_ledger(via_landed_cost_voucher=True)
+			doc.make_gl_entries()
 
-	def update_rate_in_serial_no(self, purchase_receipt):
-		for item in purchase_receipt.get("items"):
+	def update_rate_in_serial_no(self, receipt_document):
+		for item in receipt_document.get("items"):
 			if item.serial_no:
 				serial_nos = get_serial_nos(item.serial_no)
 				if serial_nos:
diff --git a/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py
index 7f190d2..c58607f 100644
--- a/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py
+++ b/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py
@@ -7,7 +7,7 @@
 import frappe
 from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt \
 	import set_perpetual_inventory, get_gl_entries, test_records as pr_test_records
-
+from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
 
 class TestLandedCostVoucher(unittest.TestCase):
 	def test_landed_cost_voucher(self):
@@ -21,10 +21,9 @@
 				"item_code": "_Test Item",
 				"warehouse": "_Test Warehouse - _TC"
 			},
-			fieldname=["qty_after_transaction", "stock_value"],
-			as_dict=1)
+			fieldname=["qty_after_transaction", "stock_value"], as_dict=1)
 
-		self.submit_landed_cost_voucher(pr)
+		self.submit_landed_cost_voucher("Purchase Receipt", pr.name)
 
 		pr_lc_value = frappe.db.get_value("Purchase Receipt Item", {"parent": pr.name}, "landed_cost_voucher_amount")
 		self.assertEquals(pr_lc_value, 25.0)
@@ -35,8 +34,7 @@
 				"item_code": "_Test Item",
 				"warehouse": "_Test Warehouse - _TC"
 			},
-			fieldname=["qty_after_transaction", "stock_value"],
-			as_dict=1)
+			fieldname=["qty_after_transaction", "stock_value"], as_dict=1)
 
 		self.assertEqual(last_sle.qty_after_transaction, last_sle_after_landed_cost.qty_after_transaction)
 
@@ -62,7 +60,56 @@
 			self.assertEquals(expected_values[gle.account][1], gle.credit)
 
 		set_perpetual_inventory(0)
+		
+	def test_landed_cost_voucher_against_purchase_invoice(self):
+		set_perpetual_inventory(1)
+		
+		pi = make_purchase_invoice(update_stock=1, posting_date=frappe.utils.nowdate(),
+			posting_time=frappe.utils.nowtime())
 
+		last_sle = frappe.db.get_value("Stock Ledger Entry", {
+				"voucher_type": pi.doctype,
+				"voucher_no": pi.name,
+				"item_code": "_Test Item",
+				"warehouse": "_Test Warehouse - _TC"
+			},
+			fieldname=["qty_after_transaction", "stock_value"], as_dict=1)
+
+		self.submit_landed_cost_voucher("Purchase Invoice", pi.name)
+		
+		pi_lc_value = frappe.db.get_value("Purchase Invoice Item", {"parent": pi.name}, 
+			"landed_cost_voucher_amount")
+			
+		self.assertEquals(pi_lc_value, 50.0)
+
+		last_sle_after_landed_cost = frappe.db.get_value("Stock Ledger Entry", {
+				"voucher_type": pi.doctype,
+				"voucher_no": pi.name,
+				"item_code": "_Test Item",
+				"warehouse": "_Test Warehouse - _TC"
+			},
+			fieldname=["qty_after_transaction", "stock_value"], as_dict=1)
+
+		self.assertEqual(last_sle.qty_after_transaction, last_sle_after_landed_cost.qty_after_transaction)
+
+		self.assertEqual(last_sle_after_landed_cost.stock_value - last_sle.stock_value, 50.0)
+
+		gl_entries = get_gl_entries("Purchase Invoice", pi.name)
+
+		self.assertTrue(gl_entries)
+
+		expected_values = {
+			pi.get("items")[0].warehouse: [300.0, 0.0],
+			"Creditors - _TC": [0.0, 250.0],
+			"Expenses Included In Valuation - _TC": [0.0, 50.0]
+		}
+
+		for gle in gl_entries:
+			self.assertEquals(expected_values[gle.account][0], gle.debit)
+			self.assertEquals(expected_values[gle.account][1], gle.credit)
+
+		set_perpetual_inventory(0)
+		
 	def test_landed_cost_voucher_for_serialized_item(self):
 		set_perpetual_inventory(1)
 		frappe.db.sql("delete from `tabSerial No` where name in ('SN001', 'SN002', 'SN003', 'SN004', 'SN005')")
@@ -74,7 +121,7 @@
 
 		serial_no_rate = frappe.db.get_value("Serial No", "SN001", "purchase_rate")
 
-		self.submit_landed_cost_voucher(pr)
+		self.submit_landed_cost_voucher("Purchase Receipt", pr.name)
 
 		serial_no = frappe.db.get_value("Serial No", "SN001",
 			["warehouse", "purchase_rate"], as_dict=1)
@@ -84,19 +131,23 @@
 
 		set_perpetual_inventory(0)
 
-	def submit_landed_cost_voucher(self, pr):
+	def submit_landed_cost_voucher(self, receipt_document_type, receipt_document):
+		ref_doc = frappe.get_doc(receipt_document_type, receipt_document)
+		
 		lcv = frappe.new_doc("Landed Cost Voucher")
 		lcv.company = "_Test Company"
 		lcv.set("purchase_receipts", [{
-			"purchase_receipt": pr.name,
-			"supplier": pr.supplier,
-			"posting_date": pr.posting_date,
-			"grand_total": pr.base_grand_total
+			"receipt_document_type": receipt_document_type,
+			"receipt_document": receipt_document,
+			"supplier": ref_doc.supplier,
+			"posting_date": ref_doc.posting_date,
+			"grand_total": ref_doc.base_grand_total
 		}])
+		
 		lcv.set("taxes", [{
 			"description": "Insurance Charges",
 			"account": "_Test Account Insurance Charges - _TC",
-			"amount": 50.0
+			"amount": 50
 		}])
 
 		lcv.insert()
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
index 2a7629e..9b9581b 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
@@ -21,10 +21,23 @@
 				"batch_no": doc.batch_no
 			}
 		}
+
+		$.each(["warehouse", "rejected_warehouse"], function(i, field) {
+			frm.set_query(field, "items", function() {
+				return {
+					filters: [["Warehouse", "company", "in", ["", cstr(frm.doc.company)]]]
+				}
+			})
+		})
+		
+		frm.set_query("supplier_warehouse", function() {
+			return {
+				filters: [["Warehouse", "company", "in", ["", cstr(frm.doc.company)]]]
+			}
+		})
 	}
 });
 
-
 erpnext.stock.PurchaseReceiptController = erpnext.buying.BuyingController.extend({
 	refresh: function() {
 		this._super();
@@ -76,48 +89,6 @@
 		this.frm.toggle_reqd("supplier_warehouse", this.frm.doc.is_subcontracted==="Yes");
 	},
 
-	received_qty: function(doc, cdt, cdn) {
-		var item = frappe.get_doc(cdt, cdn);
-		frappe.model.round_floats_in(item, ["qty", "received_qty"]);
-
-		item.qty = (item.qty < item.received_qty) ? item.qty : item.received_qty;
-		this.qty(doc, cdt, cdn);
-	},
-
-	qty: function(doc, cdt, cdn) {
-		var item = frappe.get_doc(cdt, cdn);
-		frappe.model.round_floats_in(item, ["qty", "received_qty"]);
-
-		if(!(item.received_qty || item.rejected_qty) && item.qty) {
-			item.received_qty = item.qty;
-		}
-
-		if(item.qty > item.received_qty) {
-			msgprint(__("Error: {0} > {1}", [__(frappe.meta.get_label(item.doctype, "qty", item.name)),
-						__(frappe.meta.get_label(item.doctype, "received_qty", item.name))]))
-			item.qty = item.rejected_qty = 0.0;
-		} else {
-			item.rejected_qty = flt(item.received_qty - item.qty, precision("rejected_qty", item));
-		}
-
-		this._super(doc, cdt, cdn);
-	},
-
-	rejected_qty: function(doc, cdt, cdn) {
-		var item = frappe.get_doc(cdt, cdn);
-		frappe.model.round_floats_in(item, ["received_qty", "rejected_qty"]);
-
-		if(item.rejected_qty > item.received_qty) {
-			msgprint(__("Error: {0} > {1}", [__(frappe.meta.get_label(item.doctype, "rejected_qty", item.name)),
-						__(frappe.meta.get_label(item.doctype, "received_qty", item.name))]));
-			item.qty = item.rejected_qty = 0.0;
-		} else {
-			item.qty = flt(item.received_qty - item.rejected_qty, precision("qty", item));
-		}
-
-		this.qty(doc, cdt, cdn);
-	},
-
 	make_purchase_invoice: function() {
 		frappe.model.open_mapped_doc({
 			method: "erpnext.stock.doctype.purchase_receipt.purchase_receipt.make_purchase_invoice",
@@ -132,10 +103,6 @@
 		})
 	},
 
-	tc_name: function() {
-		this.get_terms();
-	},
-
 	close_purchase_receipt: function() {
 		cur_frm.cscript.update_status("Closed");
 	},
@@ -242,8 +209,6 @@
 		cur_frm.email_doc(frappe.boot.notification_settings.purchase_receipt_message);
 }
 
-
-
 frappe.provide("erpnext.buying");
 
 frappe.ui.form.on("Purchase Receipt", "is_subcontracted", function(frm) {
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 8ee6de9..1babf2e 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -4,7 +4,7 @@
 from __future__ import unicode_literals
 import frappe
 
-from frappe.utils import cstr, flt, cint
+from frappe.utils import flt, cint
 
 from frappe import _
 import frappe.defaults
@@ -52,62 +52,13 @@
 		self.set_status()
 		self.po_required()
 		self.validate_with_previous_doc()
-		self.validate_purchase_return()
-		self.validate_rejected_warehouse()
-		self.validate_accepted_rejected_qty()
 		self.validate_inspection()
 		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')
-		pc_obj.validate_for_items(self)
 		self.check_for_closed_status(pc_obj)
 
-		# sub-contracting
-		self.validate_for_subcontracting()
-		self.create_raw_materials_supplied("supplied_items")
-		self.set_landed_cost_voucher_amount()
-		self.update_valuation_rate("items")
-
-
-	def set_landed_cost_voucher_amount(self):
-		for d in self.get("items"):
-			lc_voucher_amount = frappe.db.sql("""select sum(applicable_charges)
-				from `tabLanded Cost Item`
-				where docstatus = 1 and purchase_receipt_item = %s""", d.name)
-			d.landed_cost_voucher_amount = lc_voucher_amount[0][0] if lc_voucher_amount else 0.0
-
-	def validate_purchase_return(self):
-		for d in self.get("items"):
-			if self.is_return and flt(d.rejected_qty) != 0:
-				frappe.throw(_("Row #{0}: Rejected Qty can not be entered in Purchase Return").format(d.idx))
-
-			# validate rate with ref PR
-
-	def validate_rejected_warehouse(self):
-		for d in self.get("items"):
-			if flt(d.rejected_qty) and not d.rejected_warehouse:
-				d.rejected_warehouse = self.rejected_warehouse
-				if not d.rejected_warehouse:
-					frappe.throw(_("Row #{0}: Rejected Warehouse is mandatory against rejected Item {1}").format(d.idx, d.item_code))
-
-	# validate accepted and rejected qty
-	def validate_accepted_rejected_qty(self):
-		for d in self.get("items"):
-			if not flt(d.received_qty) and flt(d.qty):
-				d.received_qty = flt(d.qty) - flt(d.rejected_qty)
-
-			elif not flt(d.qty) and flt(d.rejected_qty):
-				d.qty = flt(d.received_qty) - flt(d.rejected_qty)
-
-			elif not flt(d.rejected_qty):
-				d.rejected_qty = flt(d.received_qty) -  flt(d.qty)
-
-			# Check Received Qty = Accepted Qty + Rejected Qty
-			if ((flt(d.qty) + flt(d.rejected_qty)) != flt(d.received_qty)):
-				frappe.throw(_("Accepted + Rejected Qty must be equal to Received quantity for Item {0}").format(d.item_code))
-
-
 	def validate_with_previous_doc(self):
 		super(PurchaseReceipt, self).validate_with_previous_doc({
 			"Purchase Order": {
@@ -130,59 +81,6 @@
 				 if not d.prevdoc_docname:
 					 frappe.throw(_("Purchase Order number required for Item {0}").format(d.item_code))
 
-	def update_stock_ledger(self, allow_negative_stock=False, via_landed_cost_voucher=False):
-		sl_entries = []
-		stock_items = self.get_stock_items()
-
-		for d in self.get('items'):
-			if d.item_code in stock_items and d.warehouse:
-				pr_qty = flt(d.qty) * flt(d.conversion_factor)
-
-				if pr_qty:
-					val_rate_db_precision = 6 if cint(self.precision("valuation_rate", d)) <= 6 else 9
-					rate = flt(d.valuation_rate, val_rate_db_precision)
-					sle = self.get_sl_entries(d, {
-						"actual_qty": flt(pr_qty),
-						"serial_no": cstr(d.serial_no).strip()
-					})
-					if self.is_return:
-						sle.update({
-							"outgoing_rate": rate
-						})
-					else:
-						sle.update({
-							"incoming_rate": rate
-						})
-					sl_entries.append(sle)
-
-				if flt(d.rejected_qty) > 0:
-					sl_entries.append(self.get_sl_entries(d, {
-						"warehouse": d.rejected_warehouse,
-						"actual_qty": flt(d.rejected_qty) * flt(d.conversion_factor),
-						"serial_no": cstr(d.rejected_serial_no).strip(),
-						"incoming_rate": 0.0
-					}))
-
-		self.bk_flush_supp_wh(sl_entries)
-		self.make_sl_entries(sl_entries, allow_negative_stock=allow_negative_stock,
-			via_landed_cost_voucher=via_landed_cost_voucher)
-
-	def update_ordered_qty(self):
-		po_map = {}
-		for d in self.get("items"):
-			if d.prevdoc_doctype and d.prevdoc_doctype == "Purchase Order" and d.prevdoc_detail_docname:
-				po_map.setdefault(d.prevdoc_docname, []).append(d.prevdoc_detail_docname)
-
-		for po, po_item_rows in po_map.items():
-			if po and po_item_rows:
-				po_obj = frappe.get_doc("Purchase Order", po)
-
-				if po_obj.status in ["Closed", "Cancelled"]:
-					frappe.throw(_("{0} {1} is cancelled or closed").format(_("Purchase Order"), po),
-						frappe.InvalidStatusError)
-
-				po_obj.update_ordered_qty(po_item_rows)
-
 	def get_already_received_qty(self, po, po_detail):
 		qty = frappe.db.sql("""select sum(qty) from `tabPurchase Receipt Item`
 			where prevdoc_detail_docname = %s and docstatus = 1
@@ -195,16 +93,6 @@
 			["qty", "warehouse"])
 		return po_qty, po_warehouse
 
-	def bk_flush_supp_wh(self, sl_entries):
-		for d in self.get('supplied_items'):
-			# negative quantity is passed as raw material qty has to be decreased
-			# when PR is submitted and it has to be increased when PR is cancelled
-			sl_entries.append(self.get_sl_entries(d, {
-				"item_code": d.rm_item_code,
-				"warehouse": self.supplier_warehouse,
-				"actual_qty": -1*flt(d.consumed_qty),
-			}))
-
 	def validate_inspection(self):
 		for d in self.get('items'):		 #Enter inspection date for all items that require inspection
 			if frappe.db.get_value("Item", d.item_code, "inspection_required") and not d.qa_no:
@@ -225,19 +113,20 @@
 		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)
+		frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype, 
+			self.company, self.base_grand_total)
 
 		# Set status as Submitted
 		frappe.db.set(self, 'status', 'Submitted')
 
 		self.update_prevdoc_status()
-		self.update_ordered_qty()
-
 		self.update_billing_status()
 
 		if not self.is_return:
 			purchase_controller.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
 		self.update_stock_ledger()
 
 		from erpnext.stock.doctype.serial_no.serial_no import update_serial_nos_after_submit
@@ -267,17 +156,15 @@
 
 		frappe.db.set(self,'status','Cancelled')
 
-		self.update_stock_ledger()
-
-		self.update_prevdoc_status()
-		# Must be called after updating received qty in PO
-		self.update_ordered_qty()
-
+		self.update_prevdoc_status()		
 		self.update_billing_status()
 
 		if not self.is_return:
 			pc_obj.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
+		self.update_stock_ledger()
 		self.make_gl_entries_on_cancel()
 
 	def get_current_stock(self):
@@ -352,13 +239,11 @@
 						}, warehouse_account[self.supplier_warehouse]["account_currency"]))
 
 					# divisional loss adjustment
-					sle_valuation_amount = flt(flt(d.valuation_rate, val_rate_db_precision) * flt(d.qty) * flt(d.conversion_factor),
-							self.precision("base_net_amount", d))
-
-					distributed_amount = flt(flt(d.base_net_amount, self.precision("base_net_amount", d))) + \
+					distributed_amount = flt(flt(d.base_net_amount, d.precision("base_net_amount"))) + \
 						flt(d.landed_cost_voucher_amount) + flt(d.rm_supp_cost) + flt(d.item_tax_amount)
 
-					divisional_loss = flt(distributed_amount - sle_valuation_amount, self.precision("base_net_amount", d))
+					divisional_loss = flt(distributed_amount - stock_value_diff, 
+						d.precision("base_net_amount"))
 					if divisional_loss:
 						gl_entries.append(self.get_gl_dict({
 							"account": stock_rbnb,
diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py
index 42e8d1b..71ce0f8 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.py
+++ b/erpnext/stock/doctype/serial_no/serial_no.py
@@ -303,7 +303,8 @@
 	if not stock_ledger_entries: return
 
 	for d in controller.get(parentfield):
-		update_rejected_serial_nos = True if (controller.doctype=="Purchase Receipt" and d.rejected_qty) else False
+		update_rejected_serial_nos = True if (controller.doctype in ("Purchase Receipt", "Purchase Invoice") 
+			and d.rejected_qty) else False
 		accepted_serial_nos_updated = False
 		warehouse = d.t_warehouse if controller.doctype == "Stock Entry" else d.warehouse
 
diff --git a/erpnext/stock/doctype/warehouse/test_records.json b/erpnext/stock/doctype/warehouse/test_records.json
index d5df175..e2162d2 100644
--- a/erpnext/stock/doctype/warehouse/test_records.json
+++ b/erpnext/stock/doctype/warehouse/test_records.json
@@ -13,6 +13,12 @@
  },
  {
   "company": "_Test Company",
+  "create_account_under": "Fixed Assets - _TC",
+  "doctype": "Warehouse",
+  "warehouse_name": "_Test Warehouse 2"
+ },
+ {
+  "company": "_Test Company",
   "create_account_under": "Stock Assets - _TC",
   "doctype": "Warehouse",
   "warehouse_name": "_Test Rejected Warehouse"
diff --git a/erpnext/stock/doctype/warehouse/warehouse.json b/erpnext/stock/doctype/warehouse/warehouse.json
index 00fe999..4e9dd07 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.json
+++ b/erpnext/stock/doctype/warehouse/warehouse.json
@@ -91,6 +91,54 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "fieldname": "disabled", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Disabled", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "column_break_4", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
    "depends_on": "eval:sys_defaults.auto_accounting_for_stock", 
    "description": "Account for the warehouse (Perpetual Inventory) will be created under this Account.", 
    "fieldname": "create_account_under", 
@@ -117,32 +165,8 @@
   {
    "allow_on_submit": 0, 
    "bold": 0, 
-   "collapsible": 0, 
-   "fieldname": "disabled", 
-   "fieldtype": "Check", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "label": "Disabled", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "description": "For Reference Only.", 
+   "collapsible": 1, 
+   "description": "", 
    "fieldname": "warehouse_contact_info", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -408,7 +432,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-03-30 03:31:43.954827", 
+ "modified": "2016-04-18 05:44:24.837579", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Warehouse", 
@@ -535,6 +559,7 @@
    "write": 0
   }
  ], 
+ "quick_entry": 1, 
  "read_only": 0, 
  "read_only_onload": 0, 
  "sort_order": "DESC", 
diff --git a/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py b/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py
index b21b402..89963ab 100644
--- a/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py
+++ b/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py
@@ -14,7 +14,8 @@
 	return [_("Item Code") + ":Link/Item:140", _("Item Name") + "::100", _("Description") + "::200",
 		_("Item Group") + ":Link/Item Group:100", _("Brand") + ":Link/Brand:100", _("Warehouse") + ":Link/Warehouse:120",
 		_("UOM") + ":Link/UOM:100", _("Actual Qty") + ":Float:100", _("Planned Qty") + ":Float:100",
-		_("Requested Qty") + ":Float:110", _("Ordered Qty") + ":Float:100", _("Reserved Qty") + ":Float:100",
+		_("Requested Qty") + ":Float:110", _("Ordered Qty") + ":Float:100",
+		_("Reserved Qty") + ":Float:100", _("Reserved Qty for Production") + ":Float:100",
 		_("Projected Qty") + ":Float:100", _("Reorder Level") + ":Float:100", _("Reorder Qty") + ":Float:100",
 		_("Shortage Qty") + ":Float:100"]
 
@@ -51,7 +52,7 @@
 
 		data.append([item.name, item.item_name, item.description, item.item_group, item.brand, bin.warehouse,
 			item.stock_uom, bin.actual_qty, bin.planned_qty, bin.indented_qty, bin.ordered_qty,
-			bin.reserved_qty, bin.projected_qty, re_order_level, re_order_qty, shortage_qty])
+			bin.reserved_qty, bin.reserved_qty_for_production, bin.projected_qty, re_order_level, re_order_qty, shortage_qty])
 
 	return data
 
@@ -63,7 +64,8 @@
 		bin_filters.warehouse = filters.warehouse
 
 	bin_list = frappe.get_all("Bin", fields=["item_code", "warehouse",
-		"actual_qty", "planned_qty", "indented_qty", "ordered_qty", "reserved_qty", "projected_qty"],
+		"actual_qty", "planned_qty", "indented_qty", "ordered_qty", "reserved_qty",
+		"reserved_qty_for_production", "projected_qty"],
 		filters=bin_filters, order_by="item_code, warehouse")
 
 	return bin_list
diff --git a/erpnext/stock/stock_balance.py b/erpnext/stock/stock_balance.py
index 7247d9e..7d92813 100644
--- a/erpnext/stock/stock_balance.py
+++ b/erpnext/stock/stock_balance.py
@@ -148,8 +148,9 @@
 			mismatch = True
 
 	if mismatch:
-		bin.projected_qty = flt(bin.actual_qty) + flt(bin.ordered_qty) + \
+		bin.projected_qty = (flt(bin.actual_qty) + flt(bin.ordered_qty) +
 			flt(bin.indented_qty) + flt(bin.planned_qty) - flt(bin.reserved_qty)
+			- flt(bin.reserved_qty_for_production))
 
 		bin.save()