Merge branch 'staging-fixes' of https://github.com/frappe/erpnext into pos_issue
diff --git a/erpnext/accounts/doctype/sales_invoice/pos.py b/erpnext/accounts/doctype/sales_invoice/pos.py
index 1ef7b54..40ca736 100755
--- a/erpnext/accounts/doctype/sales_invoice/pos.py
+++ b/erpnext/accounts/doctype/sales_invoice/pos.py
@@ -55,6 +55,7 @@
 		'barcode_data': get_barcode_data(items_list),
 		'tax_data': get_item_tax_data(),
 		'price_list_data': get_price_list_data(doc.selling_price_list),
+		'customer_wise_price_list': get_customer_wise_price_list(),
 		'bin_data': get_bin_data(pos_profile),
 		'pricing_rules': get_pricing_rule_data(doc),
 		'print_template': print_template,
@@ -328,6 +329,21 @@
 
 	return itemwise_price_list
 
+def get_customer_wise_price_list():
+	customer_wise_price = {}
+	customer_price_list_mapping = frappe._dict(frappe.get_all('Customer',fields = ['default_price_list', 'name'], as_list=1))
+
+	price_lists = frappe.db.sql(""" Select ifnull(price_list_rate, 0) as price_list_rate,
+		item_code, price_list from `tabItem Price` """, as_dict=1)
+
+	for item in price_lists:
+		if item.price_list and customer_price_list_mapping.get(item.price_list):
+
+			customer_wise_price.setdefault(customer_price_list_mapping.get(item.price_list),{}).setdefault(
+				item.item_code, item.price_list_rate
+			)
+
+	return customer_wise_price
 
 def get_bin_data(pos_profile):
 	itemwise_bin_data = {}
diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js
index c89035c..17d6d0d 100755
--- a/erpnext/accounts/page/pos/pos.js
+++ b/erpnext/accounts/page/pos/pos.js
@@ -125,7 +125,7 @@
 
 		this.page.add_menu_item(__("Cashier Closing"), function () {
 			frappe.set_route('List', 'Cashier Closing');
-		});		
+		});
 
 		this.page.add_menu_item(__("POS Profile"), function () {
 			frappe.set_route('List', 'POS Profile');
@@ -313,6 +313,7 @@
 		this.contacts = r.message.contacts;
 		this.address = r.message.address || {};
 		this.price_list_data = r.message.price_list_data;
+		this.customer_wise_price_list = r.message.customer_wise_price_list
 		this.bin_data = r.message.bin_data;
 		this.pricing_rules = r.message.pricing_rules;
 		this.print_template = r.message.print_template;
@@ -798,6 +799,7 @@
 				if (item.action) {
 					$(this).val("");
 				}
+				me.make_item_list(item.customer_name);
 			});
 	},
 
@@ -1037,7 +1039,7 @@
 		this.numeric_keypad.show();
 	},
 
-	make_item_list: function () {
+	make_item_list: function (customer=null) {
 		var me = this;
 		if (!this.price_list) {
 			frappe.msgprint(__("Price List not found or disabled"));
@@ -1051,10 +1053,17 @@
 
 		if (this.items.length > 0) {
 			$.each(this.items, function(index, obj) {
+				let customer_price_list = me.customer_wise_price_list[customer];
+				let item_price
+				if (customer && customer_price_list && customer_price_list[obj.name]) {
+					item_price = format_currency(customer_price_list[obj.name], me.frm.doc.currency);
+				} else {
+					item_price = format_currency(me.price_list_data[obj.name], me.frm.doc.currency);
+				}
 				if(index < me.page_len) {
 					$(frappe.render_template("pos_item", {
 						item_code: obj.name,
-						item_price: format_currency(me.price_list_data[obj.name], me.frm.doc.currency),
+						item_price: item_price,
 						item_name: obj.name === obj.item_name ? "" : obj.item_name,
 						item_image: obj.image,
 						item_stock: __('Stock Qty') + ": " + me.get_actual_qty(obj),
@@ -1417,8 +1426,20 @@
 		this.child.income_account = this.pos_profile_data['income_account'] || this.items[0].income_account;
 		this.child.warehouse = (this.item_serial_no[this.child.item_code]
 			? this.item_serial_no[this.child.item_code][1] : (this.pos_profile_data['warehouse'] || this.items[0].default_warehouse));
-		this.child.price_list_rate = flt(this.price_list_data[this.child.item_code] * this.child.conversion_factor, 9) / flt(this.frm.doc.conversion_rate, 9);
-		this.child.rate = flt(this.price_list_data[this.child.item_code] * this.child.conversion_factor, 9) / flt(this.frm.doc.conversion_rate, 9);
+
+		customer = this.frm.doc.customer;
+		let rate
+
+		customer_price_list = this.customer_wise_price_list[customer]
+		if (customer_price_list && customer_price_list[this.child.item_code]){
+			rate = flt(this.customer_wise_price_list[customer][this.child.item_code] * this.child.conversion_factor, 9) / flt(this.frm.doc.conversion_rate, 9);
+		}
+		else{
+			rate = flt(this.price_list_data[this.child.item_code] * this.child.conversion_factor, 9) / flt(this.frm.doc.conversion_rate, 9);
+		}
+
+		this.child.price_list_rate = rate;
+		this.child.rate = rate;
 		this.child.actual_qty = me.get_actual_qty(this.items[0]);
 		this.child.amount = flt(this.child.qty) * flt(this.child.rate);
 		this.child.batch_no = this.item_batch_no[this.child.item_code];
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 4ef8b2e..20e1098 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -477,7 +477,7 @@
 		var me = this;
 		var item = frappe.get_doc(cdt, cdn);
 
-		if (item.serial_no) {
+		if (item && item.serial_no) {
 			if (!item.item_code) {
 				this.frm.trigger("item_code", cdt, cdn);
 			}
diff --git a/erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.js b/erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.js
index 67ff8cb..13bd878 100644
--- a/erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.js
+++ b/erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.js
@@ -20,6 +20,16 @@
 			};
 		});
 	},
+
+	total_amount: function(frm) {
+		get_difference_amount(frm);
+	},
+	custody_amount: function(frm){
+		get_difference_amount(frm);
+	},
+	expense_amount: function(frm){
+		get_difference_amount(frm);
+	},
 	refresh: function(frm) {
 		get_closing_voucher_details(frm);
 	},
@@ -47,6 +57,10 @@
 	}
 });
 
+var get_difference_amount = function(frm){
+	frm.doc.difference = frm.doc.total_amount - frm.doc.custody_amount - frm.doc.expense_amount;
+	refresh_field("difference");
+};
 
 var get_closing_voucher_details = function(frm) {
 	if (frm.doc.period_end_date && frm.doc.period_start_date && frm.doc.company && frm.doc.pos_profile && frm.doc.user) {
diff --git a/erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.json b/erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.json
index e242395..0ebea83 100644
--- a/erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.json
+++ b/erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.json
@@ -1,5 +1,6 @@
 {
  "allow_copy": 0, 
+ "allow_events_in_timeline": 0, 
  "allow_guest_to_view": 0, 
  "allow_import": 0, 
  "allow_rename": 0, 
@@ -314,6 +315,197 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "expense_details_section", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Expense Details", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "expense_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Expense Amount", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "custody_amount", 
+   "fieldtype": "Data", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Amount in Custody", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "column_break_13", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "total_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Total Collected Amount", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "difference", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Difference", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "section_break_9", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -766,7 +958,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-08-21 16:15:54.363636", 
+ "modified": "2019-01-26 13:23:49.192650", 
  "modified_by": "Administrator", 
  "module": "Selling", 
  "name": "POS Closing Voucher", 
diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.js b/erpnext/selling/page/point_of_sale/point_of_sale.js
index 1ee5971..8b4d684 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.js
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.js
@@ -164,6 +164,12 @@
 				}
 			}
 		});
+
+		frappe.ui.form.on('Sales Invoice', 'selling_price_list', (frm) => {
+			if(this.items) {
+				this.items.reset_items();
+			}
+		})
 	}
 
 	toggle_editing(flag) {
@@ -1384,6 +1390,7 @@
 	}
 
 	get_items({start = 0, page_length = 40, search_value='', item_group=this.parent_item_group}={}) {
+		const price_list = this.frm.doc.selling_price_list;
 		return new Promise(res => {
 			frappe.call({
 				method: "erpnext.selling.page.point_of_sale.point_of_sale.get_items",
@@ -1391,10 +1398,10 @@
 				args: {
 					start,
 					page_length,
-					'price_list': this.frm.doc.selling_price_list,
+					price_list,
 					item_group,
 					search_value,
-					'pos_profile': this.frm.doc.pos_profile
+					pos_profile: this.frm.doc.pos_profile
 				}
 			}).then(r => {
 				// const { items, serial_no, batch_no } = r.message;