diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 56af066c54..60caf0fec1 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -431,7 +431,4 @@ erpnext.patches.v8_5.set_default_mode_of_payment
erpnext.patches.v8_5.update_customer_group_in_POS_profile
erpnext.patches.v8_6.update_timesheet_company_from_PO
erpnext.patches.v8_6.set_write_permission_for_quotation_for_sales_manager
-<<<<<<< HEAD
-erpnext.patches.v8_5.remove_project_type_property_setter
-=======
->>>>>>> Set write permission to sales manger for permlevel 1 in Quotation doctype
+erpnext.patches.v8_5.remove_project_type_property_setter
\ No newline at end of file
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 84ee8f5f17..00f886512a 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.js
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.js
@@ -39,6 +39,7 @@ class PointOfSale {
this.make_cart();
this.make_items();
this.bind_events();
+ this.disable_text_box_and_button();
}
]);
}
@@ -72,6 +73,7 @@ class PointOfSale {
make_cart() {
this.cart = new POSCart({
+ frm: this.frm,
wrapper: this.wrapper.find('.cart-container'),
events: {
customer_change: (customer) => this.frm.set_value('customer', customer),
@@ -93,6 +95,10 @@ class PointOfSale {
});
}
+ disable_text_box_and_button() {
+ $(this.wrapper).find('input, button').prop("disabled", !(this.frm.doc.docstatus===0));
+ }
+
make_items() {
this.items = new POSItems({
wrapper: this.wrapper.find('.item-container'),
@@ -108,21 +114,28 @@ class PointOfSale {
});
}
- add_item_to_cart(item_code, qty = 1) {
+ add_item_to_cart(item_code, qty = 1, barcode) {
if(this.cart.exists(item_code)) {
// increase qty by 1
this.frm.doc.items.forEach((item) => {
if (item.item_code === item_code) {
- const final_qty = item.qty + qty;
- frappe.model.set_value(item.doctype, item.name, 'qty', final_qty)
- .then(() => {
- if (final_qty === 0) {
- frappe.model.clear_doc(item.doctype, item.name);
- }
- // update cart
- this.cart.add_item(item);
- });
+ if (barcode) {
+ value = barcode['serial_no'] ?
+ item.serial_no + '\n' + barcode['serial_no'] : barcode['batch_no'];
+ frappe.model.set_value(item.doctype, item.name,
+ Object.keys(barcode)[0], final_qty);
+ } else {
+ const final_qty = item.qty + qty;
+ frappe.model.set_value(item.doctype, item.name, 'qty', final_qty)
+ .then(() => {
+ if (final_qty === 0) {
+ frappe.model.clear_doc(item.doctype, item.name);
+ }
+ // update cart
+ this.cart.add_item(item);
+ });
+ }
}
});
return;
@@ -200,7 +213,8 @@ class PointOfSale {
}
class POSCart {
- constructor({wrapper, events}) {
+ constructor({frm, wrapper, events}) {
+ this.frm = frm;
this.wrapper = wrapper;
this.events = events;
this.make();
@@ -301,25 +315,9 @@ class POSCart {
$item.remove();
}
}
-
- exists(item_code) {
- let $item = this.$cart_items.find(`[data-item-code="${item_code}"]`);
- return $item.length > 0;
- }
-
- highlight_item(item_code) {
- const $item = this.$cart_items.find(`[data-item-code="${item_code}"]`);
- $item.addClass('highlight');
- setTimeout(() => $item.removeClass('highlight'), 1000);
- }
-
- scroll_to_item(item_code) {
- const $item = this.$cart_items.find(`[data-item-code="${item_code}"]`);
- // const scrollTop = $item.offset().top - this.$cart_items.offset().top + this.$cart_items.scrollTop();
- // this.$cart_items.animate({ scrollTop });
- }
-
+
get_item_html(item) {
+ const rate = format_currency(item.rate, this.frm.doc.currency);
return `
@@ -332,7 +330,7 @@ class POSCart {
${item.discount_percentage}%
- ${item.rate}
+ ${rate}
`;
@@ -354,6 +352,23 @@ class POSCart {
}
}
+ exists(item_code) {
+ let $item = this.$cart_items.find(`[data-item-code="${item_code}"]`);
+ return $item.length > 0;
+ }
+
+ highlight_item(item_code) {
+ const $item = this.$cart_items.find(`[data-item-code="${item_code}"]`);
+ $item.addClass('highlight');
+ setTimeout(() => $item.removeClass('highlight'), 1000);
+ }
+
+ scroll_to_item(item_code) {
+ const $item = this.$cart_items.find(`[data-item-code="${item_code}"]`);
+ // const scrollTop = $item.offset().top - this.$cart_items.offset().top + this.$cart_items.scrollTop();
+ // this.$cart_items.animate({ scrollTop });
+ }
+
bind_events() {
const events = this.events;
this.$cart_items.on('click',
@@ -381,6 +396,8 @@ class POSItems {
this.wrapper = wrapper;
this.pos_profile = pos_profile;
this.items = {};
+ this.currency = this.pos_profile.currency ||
+ frappe.defaults.get_default('currency');
this.make_dom();
this.make_fields();
@@ -516,7 +533,8 @@ class POSItems {
}
get_item_html(item) {
- const { item_code, item_name, image: item_image, item_stock=0, item_price=0} = item;
+ const price_list_rate = format_currency(item.price_list_rate, this.currency)
+ const { item_code, item_name, item_image, item_stock=0} = item;
const item_title = item_name || item_code;
const template = `
@@ -542,7 +560,7 @@ class POSItems {
${item_image ? `` : '' }
- ${item_price}
+ ${price_list_rate}
@@ -552,38 +570,17 @@ class POSItems {
return template;
}
- get_items(start = 0, page_length = 20) {
+ get_items(start = 10, page_length = 20) {
+ var me = this;
return new Promise(res => {
frappe.call({
- method: "frappe.desk.reportview.get",
- type: "GET",
+ method: "erpnext.selling.page.point_of_sale.point_of_sale.get_items",
args: {
- doctype: "Item",
- fields: [
- "`tabItem`.`name`",
- "`tabItem`.`owner`",
- "`tabItem`.`docstatus`",
- "`tabItem`.`modified`",
- "`tabItem`.`modified_by`",
- "`tabItem`.`item_name`",
- "`tabItem`.`item_code`",
- "`tabItem`.`disabled`",
- "`tabItem`.`item_group`",
- "`tabItem`.`stock_uom`",
- "`tabItem`.`image`",
- "`tabItem`.`variant_of`",
- "`tabItem`.`has_variants`",
- "`tabItem`.`end_of_life`",
- "`tabItem`.`total_projected_qty`"
- ],
- filters: [['disabled', '=', '0']],
- order_by: "`tabItem`.`modified` desc",
- page_length: page_length,
- start: start
+ 'price_list': this.pos_profile.selling_price_list,
+ 'item': me.search_field.$input.value || ""
}
}).then(r => {
- const data = r.message;
- const items = frappe.utils.dict(data.keys, data.values);
+ const items = r.message;
// convert to key, value
let items_dict = {};
@@ -687,8 +684,11 @@ class Payment {
}
set_primary_action() {
+ var me = this;
+
this.dialog.set_primary_action(__("Submit"), function() {
- // save form
+ this.frm.doc.savesubmit()
+ this.dialog.hide()
});
}
diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.py b/erpnext/selling/page/point_of_sale/point_of_sale.py
new file mode 100644
index 0000000000..045ef07a73
--- /dev/null
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.py
@@ -0,0 +1,46 @@
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe, json
+from frappe import _
+from frappe.utils import nowdate
+from erpnext.setup.utils import get_exchange_rate
+from frappe.core.doctype.communication.email import make
+from erpnext.stock.get_item_details import get_pos_profile
+from erpnext.accounts.party import get_party_account_currency
+from erpnext.controllers.accounts_controller import get_taxes_and_charges
+
+@frappe.whitelist()
+def get_items(price_list, item=None):
+ condition = ""
+ order_by = ""
+ args = {"price_list": price_list}
+
+ if item:
+ # search serial no
+ item_code = frappe.db.sql("""select name as serial_no, item_code
+ from `tabSerial No` where name=%s""", (item), as_dict=1)
+ if item_code:
+ item_code[0]["name"] = item_code[0]["item_code"]
+ return item_code
+
+ # search barcode
+ item_code = frappe.db.sql("""select name, item_code from `tabItem`
+ where barcode=%s""",
+ (item), as_dict=1)
+ if item_code:
+ item_code[0]["barcode"] = item
+ return item_code
+
+ # locate function is used to sort by closest match from the beginning of the value
+ return frappe.db.sql("""select i.name as item_code, i.item_name, i.image as item_image,
+ item_det.price_list_rate, item_det.currency
+ from `tabItem` i LEFT JOIN
+ (select item_code, price_list_rate, currency from
+ `tabItem Price` where price_list=%(price_list)s) item_det
+ ON
+ (item_det.item_code=i.name or item_det.item_code=i.variant_of)
+ where
+ i.has_variants = 0 and (i.item_code like %(item_code)s or i.item_name like %(item_code)s)
+ limit 24""", {'item_code': '%%%s%%'%(frappe.db.escape(item)), 'price_list': price_list} , as_dict=1)