Connect Numpad events with POSCart
diff --git a/erpnext/public/css/pos.css b/erpnext/public/css/pos.css
index de1e097..c6ec637 100644
--- a/erpnext/public/css/pos.css
+++ b/erpnext/public/css/pos.css
@@ -33,6 +33,19 @@
height: 200px;
overflow: auto;
}
+.cart-items .list-item.current-item {
+ background-color: #fffce7;
+}
+.cart-items .list-item.current-item.qty input {
+ border: 1px solid #5E64FF;
+ font-weight: bold;
+}
+.cart-items .list-item.current-item.disc .discount {
+ font-weight: bold;
+}
+.cart-items .list-item.current-item.rate .rate {
+ font-weight: bold;
+}
.cart-items input {
height: 22px;
font-size: 12px;
@@ -105,3 +118,10 @@
text-align: center;
line-height: 50px;
}
+.num-col.active {
+ background-color: #fffce7;
+}
+.num-col.brand-primary {
+ background-color: #5E64FF;
+ color: #ffffff;
+}
diff --git a/erpnext/public/less/pos.less b/erpnext/public/less/pos.less
index de16514..6f49c66 100644
--- a/erpnext/public/less/pos.less
+++ b/erpnext/public/less/pos.less
@@ -45,6 +45,23 @@
height: 200px;
overflow: auto;
+ .list-item.current-item {
+ background-color: @light-yellow;
+ }
+
+ .list-item.current-item.qty input {
+ border: 1px solid @brand-primary;
+ font-weight: bold;
+ }
+
+ .list-item.current-item.disc .discount {
+ font-weight: bold;
+ }
+
+ .list-item.current-item.rate .rate {
+ font-weight: bold;
+ }
+
input {
height: 22px;
font-size: @text-medium;
@@ -128,4 +145,13 @@
text-align: center;
line-height: 50px;
}
+
+ &.active {
+ background-color: @light-yellow;
+ }
+
+ &.brand-primary {
+ background-color: @brand-primary;
+ color: #ffffff;
+ }
}
\ 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 00f8865..8ed0878 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.js
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.js
@@ -90,6 +90,9 @@
}
this.payment.open_modal();
}
+ },
+ on_select_change: () => {
+ this.cart.numpad.set_inactive();
}
}
});
@@ -109,6 +112,7 @@
frappe.throw(__('Please select a customer'));
}
this.add_item_to_cart(item_code);
+ this.cart && this.cart.unselect_all();
}
}
});
@@ -121,10 +125,10 @@
this.frm.doc.items.forEach((item) => {
if (item.item_code === item_code) {
if (barcode) {
- value = barcode['serial_no'] ?
+ const 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);
+ frappe.model.set_value(item.doctype, item.name,
+ Object.keys(barcode)[0], value);
} else {
const final_qty = item.qty + qty;
frappe.model.set_value(item.doctype, item.name, 'qty', final_qty)
@@ -270,23 +274,45 @@
make_numpad() {
this.numpad = new NumberPad({
+ button_array: [
+ [1, 2, 3, 'Qty'],
+ [4, 5, 6, 'Disc'],
+ [7, 8, 9, 'Rate'],
+ ['Del', 0, '.', 'Pay']
+ ],
+ add_class: {
+ 'Pay': 'brand-primary'
+ },
+ disable_highlight: ['Qty', 'Disc', 'Rate'],
wrapper: this.wrapper.find('.number-pad-container'),
onclick: (btn_value) => {
// on click
- if (['Qty', 'Disc', 'Price'].includes(btn_value)) {
+ if (['Qty', 'Disc', 'Rate'].includes(btn_value)) {
+ if (!this.selected_item) {
+ frappe.show_alert({
+ indicator: 'red',
+ message: __('Please select an item in the cart first')
+ });
+ return;
+ }
+ this.numpad.set_active(btn_value);
this.set_input_active(btn_value);
}
- this.events.on_numpad.apply(null, [btn_value]);
+ this.events.on_numpad(btn_value);
}
});
}
set_input_active(btn_value) {
- if (!this.selected_item) return;
+ this.selected_item.removeClass('qty disc rate');
if (btn_value === 'Qty') {
- this.selected_item.find('.quantity input').css('border', '1px solid blue');
+ this.selected_item.addClass('qty');
+ } else if (btn_value == 'Disc') {
+ this.selected_item.addClass('disc');
+ } else if (btn_value == 'Rate') {
+ this.selected_item.addClass('rate');
}
}
@@ -315,7 +341,7 @@
$item.remove();
}
}
-
+
get_item_html(item) {
const rate = format_currency(item.rate, this.frm.doc.currency);
return `
@@ -365,12 +391,15 @@
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 });
+ const scrollTop = $item.offset().top - this.$cart_items.offset().top + this.$cart_items.scrollTop();
+ this.$cart_items.animate({ scrollTop });
}
bind_events() {
+ const me = this;
const events = this.events;
+
+ // quantity change
this.$cart_items.on('click',
'[data-action="increment"], [data-action="decrement"]', function() {
const $btn = $(this);
@@ -384,10 +413,30 @@
events.decrease_qty(item_code);
}
});
- const me = this;
+
+ // current item
this.$cart_items.on('click', '.list-item', function() {
me.selected_item = $(this);
+ me.$cart_items.find('.list-item').removeClass('current-item qty disc rate');
+ me.selected_item.addClass('current-item');
+ me.events.on_select_change();
});
+
+ // disable current item
+ // $('body').on('click', function(e) {
+ // console.log(e);
+ // if($(e.target).is('.list-item')) {
+ // return;
+ // }
+ // me.$cart_items.find('.list-item').removeClass('current-item qty disc rate');
+ // me.selected_item = null;
+ // });
+ }
+
+ unselect_all() {
+ this.$cart_items.find('.list-item').removeClass('current-item qty disc rate');
+ this.selected_item = null;
+ this.events.on_select_change();
}
}
@@ -396,7 +445,7 @@
this.wrapper = wrapper;
this.pos_profile = pos_profile;
this.items = {};
- this.currency = this.pos_profile.currency ||
+ this.currency = this.pos_profile.currency ||
frappe.defaults.get_default('currency');
this.make_dom();
@@ -595,10 +644,12 @@
}
class NumberPad {
- constructor({wrapper, onclick, button_array}) {
+ constructor({wrapper, onclick, button_array, add_class, disable_highlight}) {
this.wrapper = wrapper;
this.onclick = onclick;
this.button_array = button_array;
+ this.add_class = add_class;
+ this.disable_highlight = disable_highlight;
this.make_dom();
this.bind_events();
}
@@ -606,10 +657,10 @@
make_dom() {
if (!this.button_array) {
this.button_array = [
- [1, 2, 3, 'Qty'],
- [4, 5, 6, 'Disc'],
- [7, 8, 9, 'Price'],
- ['Del', 0, '.', 'Pay']
+ [1, 2, 3],
+ [4, 5, 6],
+ [7, 8, 9],
+ ['', 0, '']
];
}
@@ -626,6 +677,15 @@
function get_col(col) {
return `<div class="num-col" data-value="${col}"><div>${col}</div></div>`;
}
+
+ this.set_class();
+ }
+
+ set_class() {
+ for (const btn in this.add_class) {
+ const class_name = this.add_class[btn];
+ this.get_btn(btn).addClass(class_name);
+ }
}
bind_events() {
@@ -633,16 +693,32 @@
const me = this;
this.wrapper.on('click', '.num-col', function() {
const $btn = $(this);
- me.highlight_button($btn);
- me.onclick.apply(null, [$btn.attr('data-value')]);
+ const btn_value = $btn.attr('data-value');
+ if (!me.disable_highlight.includes(btn_value)) {
+ me.highlight_button($btn);
+ }
+ me.onclick(btn_value);
});
}
+ get_btn(btn_value) {
+ return this.wrapper.find(`.num-col[data-value="${btn_value}"]`);
+ }
+
highlight_button($btn) {
- // const $btn = this.wrapper.find(`[data-value="${value}"]`);
$btn.addClass('highlight');
setTimeout(() => $btn.removeClass('highlight'), 1000);
}
+
+ set_active(btn_value) {
+ const $btn = this.get_btn(btn_value);
+ this.wrapper.find('.num-col').removeClass('active');
+ $btn.addClass('active');
+ }
+
+ set_inactive() {
+ this.wrapper.find('.num-col').removeClass('active');
+ }
}
class Payment {
diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.py b/erpnext/selling/page/point_of_sale/point_of_sale.py
index 045ef07..9f3c289 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.py
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.py
@@ -15,7 +15,6 @@
def get_items(price_list, item=None):
condition = ""
order_by = ""
- args = {"price_list": price_list}
if item:
# search serial no
@@ -42,5 +41,7 @@
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)
+ i.disabled = 0 and 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)