Update cart ui from cur_frm, Add number pad
This commit is contained in:
parent
854d335ab1
commit
21fc26c2a2
@ -23,6 +23,9 @@
|
|||||||
width: 40%;
|
width: 40%;
|
||||||
margin-left: 15px;
|
margin-left: 15px;
|
||||||
}
|
}
|
||||||
|
.cart-wrapper {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
.cart-wrapper .list-item__content:not(:first-child) {
|
.cart-wrapper .list-item__content:not(:first-child) {
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
@ -30,6 +33,10 @@
|
|||||||
height: 200px;
|
height: 200px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
.cart-items input {
|
||||||
|
height: 22px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
.fields {
|
.fields {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
@ -63,3 +70,38 @@
|
|||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
}
|
}
|
||||||
|
@keyframes yellow-fade {
|
||||||
|
0% {
|
||||||
|
background-color: #fffce7;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.highlight {
|
||||||
|
animation: yellow-fade 1s ease-in 1;
|
||||||
|
}
|
||||||
|
input[type=number]::-webkit-inner-spin-button,
|
||||||
|
input[type=number]::-webkit-outer-spin-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.number-pad {
|
||||||
|
border-collapse: collapse;
|
||||||
|
cursor: pointer;
|
||||||
|
display: table;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
.num-row {
|
||||||
|
display: table-row;
|
||||||
|
}
|
||||||
|
.num-col {
|
||||||
|
display: table-cell;
|
||||||
|
border: 1px solid #d1d8dd;
|
||||||
|
}
|
||||||
|
.num-col > div {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 50px;
|
||||||
|
}
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.cart-wrapper {
|
.cart-wrapper {
|
||||||
|
margin-bottom: 10px;
|
||||||
.list-item__content:not(:first-child) {
|
.list-item__content:not(:first-child) {
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
@ -43,6 +44,11 @@
|
|||||||
.cart-items {
|
.cart-items {
|
||||||
height: 200px;
|
height: 200px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
|
input {
|
||||||
|
height: 22px;
|
||||||
|
font-size: @text-medium;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.fields {
|
.fields {
|
||||||
@ -84,4 +90,42 @@
|
|||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes yellow-fade {
|
||||||
|
0% {background-color: @light-yellow;}
|
||||||
|
100% {background-color: transparent;}
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlight {
|
||||||
|
animation: yellow-fade 1s ease-in 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=number]::-webkit-inner-spin-button,
|
||||||
|
input[type=number]::-webkit-outer-spin-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// number pad
|
||||||
|
|
||||||
|
.number-pad {
|
||||||
|
border-collapse: collapse;
|
||||||
|
cursor: pointer;
|
||||||
|
display: table;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
.num-row {
|
||||||
|
display: table-row;
|
||||||
|
}
|
||||||
|
.num-col {
|
||||||
|
display: table-cell;
|
||||||
|
border: 1px solid @border-color;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 50px;
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
/* global Clusterize */
|
||||||
|
|
||||||
frappe.pages['point-of-sale'].on_page_load = function(wrapper) {
|
frappe.pages['point-of-sale'].on_page_load = function(wrapper) {
|
||||||
var page = frappe.ui.make_app_page({
|
var page = frappe.ui.make_app_page({
|
||||||
parent: wrapper,
|
parent: wrapper,
|
||||||
@ -5,11 +7,11 @@ frappe.pages['point-of-sale'].on_page_load = function(wrapper) {
|
|||||||
single_column: true
|
single_column: true
|
||||||
});
|
});
|
||||||
|
|
||||||
wrapper.pos = new erpnext.PointOfSale(wrapper);
|
wrapper.pos = new PointOfSale(wrapper);
|
||||||
cur_pos = wrapper.pos;
|
window.cur_pos = wrapper.pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
erpnext.PointOfSale = class PointOfSale {
|
class PointOfSale {
|
||||||
constructor(wrapper) {
|
constructor(wrapper) {
|
||||||
this.wrapper = $(wrapper).find('.layout-main-section');
|
this.wrapper = $(wrapper).find('.layout-main-section');
|
||||||
this.page = wrapper.page;
|
this.page = wrapper.page;
|
||||||
@ -20,24 +22,25 @@ erpnext.PointOfSale = class PointOfSale {
|
|||||||
];
|
];
|
||||||
|
|
||||||
frappe.require(assets, () => {
|
frappe.require(assets, () => {
|
||||||
this.prepare().then(() => {
|
this.make();
|
||||||
this.make();
|
|
||||||
this.bind_events();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
prepare() {
|
|
||||||
this.set_online_status();
|
|
||||||
this.prepare_menu();
|
|
||||||
this.make_sales_invoice_frm()
|
|
||||||
return this.get_pos_profile();
|
|
||||||
}
|
|
||||||
|
|
||||||
make() {
|
make() {
|
||||||
this.make_dom();
|
return frappe.run_serially([
|
||||||
this.make_cart();
|
() => {
|
||||||
this.make_items();
|
this.prepare_dom();
|
||||||
|
this.prepare_menu();
|
||||||
|
this.set_online_status();
|
||||||
|
},
|
||||||
|
() => this.make_sales_invoice_frm(),
|
||||||
|
() => this.setup_pos_profile(),
|
||||||
|
() => {
|
||||||
|
this.make_cart();
|
||||||
|
this.make_items();
|
||||||
|
this.bind_events();
|
||||||
|
}
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_online_status() {
|
set_online_status() {
|
||||||
@ -54,7 +57,7 @@ erpnext.PointOfSale = class PointOfSale {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
make_dom() {
|
prepare_dom() {
|
||||||
this.wrapper.append(`
|
this.wrapper.append(`
|
||||||
<div class="pos">
|
<div class="pos">
|
||||||
<section class="cart-container">
|
<section class="cart-container">
|
||||||
@ -68,29 +71,64 @@ erpnext.PointOfSale = class PointOfSale {
|
|||||||
}
|
}
|
||||||
|
|
||||||
make_cart() {
|
make_cart() {
|
||||||
this.cart = new erpnext.POSCart(this.wrapper.find('.cart-container'));
|
this.cart = new POSCart({
|
||||||
}
|
wrapper: this.wrapper.find('.cart-container'),
|
||||||
|
|
||||||
make_items() {
|
|
||||||
this.items = new erpnext.POSItems({
|
|
||||||
wrapper: this.wrapper.find('.item-container'),
|
|
||||||
pos_profile: this.pos_profile,
|
|
||||||
events: {
|
events: {
|
||||||
item_click: (item_code) => this.add_item_to_cart(item_code)
|
customer_change: (customer) => this.cur_frm.set_value('customer', customer),
|
||||||
|
increase_qty: (item_code) => {
|
||||||
|
this.add_item_to_cart(item_code);
|
||||||
|
},
|
||||||
|
decrease_qty: (item_code) => {
|
||||||
|
this.add_item_to_cart(item_code, -1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
add_item_to_cart(item_code) {
|
make_items() {
|
||||||
const item = this.items.get(item_code);
|
this.items = new POSItems({
|
||||||
this.cart.add_item(item);
|
wrapper: this.wrapper.find('.item-container'),
|
||||||
|
pos_profile: this.pos_profile,
|
||||||
|
events: {
|
||||||
|
item_click: (item_code) => {
|
||||||
|
if(!this.cur_frm.doc.customer) {
|
||||||
|
frappe.throw(__('Please select a customer'));
|
||||||
|
}
|
||||||
|
this.add_item_to_cart(item_code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
add_item_to_cart(item_code, qty = 1) {
|
||||||
|
|
||||||
|
if(this.cart.exists(item_code)) {
|
||||||
|
// increase qty by 1
|
||||||
|
this.cur_frm.doc.items.forEach((item) => {
|
||||||
|
if (item.item_code === item_code) {
|
||||||
|
frappe.model.set_value(item.doctype, item.name, 'qty', item.qty + qty);
|
||||||
|
// update cart
|
||||||
|
this.cart.add_item(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add to cur_frm
|
||||||
|
const item = this.cur_frm.add_child('items', { item_code: item_code });
|
||||||
|
this.cur_frm.script_manager
|
||||||
|
.trigger('item_code', item.doctype, item.name)
|
||||||
|
.then(() => {
|
||||||
|
// update cart
|
||||||
|
this.cart.add_item(item);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bind_events() {
|
bind_events() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get_pos_profile() {
|
setup_pos_profile() {
|
||||||
return frappe.call({
|
return frappe.call({
|
||||||
method: 'erpnext.stock.get_item_details.get_pos_profile',
|
method: 'erpnext.stock.get_item_details.get_pos_profile',
|
||||||
args: {
|
args: {
|
||||||
@ -104,13 +142,14 @@ erpnext.PointOfSale = class PointOfSale {
|
|||||||
make_sales_invoice_frm() {
|
make_sales_invoice_frm() {
|
||||||
const dt = 'Sales Invoice';
|
const dt = 'Sales Invoice';
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
frappe.model.with_doctype(dt, function() {
|
frappe.model.with_doctype(dt, () => {
|
||||||
const page = $('<div>');
|
const page = $('<div>');
|
||||||
const frm = new _f.Frm(dt, page, false);
|
const frm = new _f.Frm(dt, page, false);
|
||||||
const name = frappe.model.make_new_doc_and_get_name(dt, true);
|
const name = frappe.model.make_new_doc_and_get_name(dt, true);
|
||||||
frm.refresh(name);
|
frm.refresh(name);
|
||||||
frm.doc.items = [];
|
frm.doc.items = [];
|
||||||
resolve(frm);
|
this.cur_frm = frm;
|
||||||
|
resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -141,16 +180,18 @@ erpnext.PointOfSale = class PointOfSale {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
erpnext.POSCart = class POSCart {
|
class POSCart {
|
||||||
constructor(wrapper) {
|
constructor({wrapper, events}) {
|
||||||
this.wrapper = wrapper;
|
this.wrapper = wrapper;
|
||||||
this.items = {};
|
this.events = events;
|
||||||
this.make();
|
this.make();
|
||||||
|
this.bind_events();
|
||||||
}
|
}
|
||||||
|
|
||||||
make() {
|
make() {
|
||||||
this.make_dom();
|
this.make_dom();
|
||||||
this.make_customer_field();
|
this.make_customer_field();
|
||||||
|
this.make_numpad();
|
||||||
}
|
}
|
||||||
|
|
||||||
make_dom() {
|
make_dom() {
|
||||||
@ -172,7 +213,10 @@ erpnext.POSCart = class POSCart {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="number-pad-container">
|
||||||
|
</div>
|
||||||
`);
|
`);
|
||||||
|
this.$cart_items = this.wrapper.find('.cart-items');
|
||||||
}
|
}
|
||||||
|
|
||||||
make_customer_field() {
|
make_customer_field() {
|
||||||
@ -181,8 +225,9 @@ erpnext.POSCart = class POSCart {
|
|||||||
fieldtype: 'Link',
|
fieldtype: 'Link',
|
||||||
label: 'Customer',
|
label: 'Customer',
|
||||||
options: 'Customer',
|
options: 'Customer',
|
||||||
|
reqd: 1,
|
||||||
onchange: (e) => {
|
onchange: (e) => {
|
||||||
cur_frm.set_value('customer', this.customer_field.value);
|
this.events.customer_change.apply(null, [this.customer_field.get_value()]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
parent: this.wrapper.find('.customer-field'),
|
parent: this.wrapper.find('.customer-field'),
|
||||||
@ -190,96 +235,113 @@ erpnext.POSCart = class POSCart {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
add_item(item) {
|
make_numpad() {
|
||||||
const { item_code } = item;
|
this.numpad = new NumberPad({
|
||||||
const _item = this.items[item_code];
|
wrapper: this.wrapper.find('.number-pad-container'),
|
||||||
|
onclick: (btn_value) => {
|
||||||
if (_item) {
|
// on click
|
||||||
// exists, increase quantity
|
console.log(btn_value);
|
||||||
_item.quantity += 1;
|
|
||||||
this.update_quantity(_item);
|
|
||||||
} else {
|
|
||||||
// add it to this.items
|
|
||||||
item['qty'] = 1;
|
|
||||||
this.child = cur_frm.add_child('items', item)
|
|
||||||
cur_frm.script_manager.trigger("item_code", this.child.doctype, this.child.name);
|
|
||||||
|
|
||||||
const _item = {
|
|
||||||
doc: item,
|
|
||||||
quantity: 1,
|
|
||||||
discount: 2,
|
|
||||||
rate: 2
|
|
||||||
}
|
}
|
||||||
Object.assign(this.items, {
|
});
|
||||||
[item_code]: _item
|
|
||||||
});
|
|
||||||
this.add_item_to_cart(_item);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
add_item_to_cart(item) {
|
add_item(item) {
|
||||||
this.wrapper.find('.cart-items .empty-state').hide();
|
this.wrapper.find('.cart-items .empty-state').hide();
|
||||||
const $item = $(this.get_item_html(item))
|
|
||||||
$item.appendTo(this.wrapper.find('.cart-items'));
|
|
||||||
// $item.addClass('added');
|
|
||||||
// this.wrapper.find('.cart-items').append(this.get_item_html(item))
|
|
||||||
}
|
|
||||||
|
|
||||||
update_quantity(item) {
|
if (this.exists(item.item_code)) {
|
||||||
this.wrapper.find(`.list-item[data-item-name="${item.doc.item_code}"] .quantity`)
|
// update quantity
|
||||||
.text(item.quantity);
|
this.update_item(item);
|
||||||
|
} else {
|
||||||
$.each(cur_frm.doc["items"] || [], function(i, d) {
|
// add to cart
|
||||||
if (d.item_code == item.doc.item_code) {
|
const $item = $(this.get_item_html(item));
|
||||||
frappe.model.set_value(d.doctype, d.name, "qty", d.qty + 1);
|
$item.appendTo(this.$cart_items);
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
remove_item(item_code) {
|
|
||||||
delete this.items[item_code];
|
|
||||||
|
|
||||||
// this.refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
refresh() {
|
|
||||||
const item_codes = Object.keys(this.items);
|
|
||||||
const html = item_codes
|
|
||||||
.map(item_code => this.get_item_html(item_code))
|
|
||||||
.join("");
|
|
||||||
this.wrapper.find('.cart-items').html(html);
|
|
||||||
}
|
|
||||||
|
|
||||||
get_item_html(_item) {
|
|
||||||
|
|
||||||
let item;
|
|
||||||
if (typeof _item === "object") {
|
|
||||||
item = _item;
|
|
||||||
}
|
|
||||||
else if (typeof _item === "string") {
|
|
||||||
item = this.items[_item];
|
|
||||||
}
|
}
|
||||||
|
this.highlight_item(item.item_code);
|
||||||
|
this.scroll_to_item(item.item_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
update_item(item) {
|
||||||
|
const $item = this.$cart_items.find(`[data-item-code="${item.item_code}"]`);
|
||||||
|
if(item.qty > 0) {
|
||||||
|
$item.find('.quantity input').val(item.qty);
|
||||||
|
$item.find('.discount').text(item.discount_percentage);
|
||||||
|
$item.find('.rate').text(item.rate);
|
||||||
|
} else {
|
||||||
|
$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) {
|
||||||
return `
|
return `
|
||||||
<div class="list-item" data-item-name="${item.doc.item_code}">
|
<div class="list-item" data-item-code="${item.item_code}">
|
||||||
<div class="item-name list-item__content list-item__content--flex-2 ellipsis">
|
<div class="item-name list-item__content list-item__content--flex-2 ellipsis">
|
||||||
${item.doc.item_name}
|
${item.item_name}
|
||||||
</div>
|
</div>
|
||||||
<div class="quantity list-item__content text-right">
|
<div class="quantity list-item__content text-right">
|
||||||
${item.quantity}
|
${get_quantity_html(item.qty)}
|
||||||
</div>
|
</div>
|
||||||
<div class="discount list-item__content text-right">
|
<div class="discount list-item__content text-right">
|
||||||
${item.discount}
|
${item.discount_percentage}%
|
||||||
</div>
|
</div>
|
||||||
<div class="rate list-item__content text-right">
|
<div class="rate list-item__content text-right">
|
||||||
${item.rate}
|
${item.rate}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
function get_quantity_html(value) {
|
||||||
|
return `
|
||||||
|
<div class="input-group input-group-xs">
|
||||||
|
<span class="input-group-btn">
|
||||||
|
<button class="btn btn-default btn-xs" data-action="increment">+</button>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<input class="form-control" type="number" value="${value}">
|
||||||
|
|
||||||
|
<span class="input-group-btn">
|
||||||
|
<button class="btn btn-default btn-xs" data-action="decrement">-</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bind_events() {
|
||||||
|
const events = this.events;
|
||||||
|
this.$cart_items.on('click',
|
||||||
|
'[data-action="increment"], [data-action="decrement"]', function() {
|
||||||
|
const $btn = $(this);
|
||||||
|
const $item = $btn.closest('.list-item[data-item-code]');
|
||||||
|
const item_code = $item.attr('data-item-code');
|
||||||
|
const action = $btn.attr('data-action');
|
||||||
|
|
||||||
|
if(action === 'increment') {
|
||||||
|
events.increase_qty(item_code);
|
||||||
|
} else if(action === 'decrement') {
|
||||||
|
events.decrease_qty(item_code);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
erpnext.POSItems = class POSItems {
|
class POSItems {
|
||||||
constructor({wrapper, pos_profile, events}) {
|
constructor({wrapper, pos_profile, events}) {
|
||||||
this.wrapper = wrapper;
|
this.wrapper = wrapper;
|
||||||
this.pos_profile = pos_profile;
|
this.pos_profile = pos_profile;
|
||||||
@ -439,16 +501,10 @@ erpnext.POSItems = class POSItems {
|
|||||||
<div class="image-field"
|
<div class="image-field"
|
||||||
style="${!item_image ? 'background-color: #fafbfc;' : ''} border: 0px;"
|
style="${!item_image ? 'background-color: #fafbfc;' : ''} border: 0px;"
|
||||||
>
|
>
|
||||||
${!item_image ?
|
${!item_image ? `<span class="placeholder-text">
|
||||||
`<span class="placeholder-text">
|
|
||||||
${frappe.get_abbr(item_title)}
|
${frappe.get_abbr(item_title)}
|
||||||
</span>` :
|
</span>` : '' }
|
||||||
''
|
${item_image ? `<img src="${item_image}" alt="${item_title}">` : '' }
|
||||||
}
|
|
||||||
${item_image ?
|
|
||||||
`<img src="${item_image}" alt="${item_title}">` :
|
|
||||||
''
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
<span class="price-info">
|
<span class="price-info">
|
||||||
${item_price}
|
${item_price}
|
||||||
@ -509,12 +565,12 @@ erpnext.POSItems = class POSItems {
|
|||||||
"`tabItem`.`end_of_life`",
|
"`tabItem`.`end_of_life`",
|
||||||
"`tabItem`.`total_projected_qty`"
|
"`tabItem`.`total_projected_qty`"
|
||||||
],
|
],
|
||||||
|
filters: [['disabled', '=', '0']],
|
||||||
order_by: "`tabItem`.`modified` desc",
|
order_by: "`tabItem`.`modified` desc",
|
||||||
page_length: page_length,
|
page_length: page_length,
|
||||||
start: start
|
start: start
|
||||||
}
|
}
|
||||||
})
|
}).then(r => {
|
||||||
.then(r => {
|
|
||||||
const data = r.message;
|
const data = r.message;
|
||||||
const items = frappe.utils.dict(data.keys, data.values);
|
const items = frappe.utils.dict(data.keys, data.values);
|
||||||
|
|
||||||
@ -528,4 +584,52 @@ erpnext.POSItems = class POSItems {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NumberPad {
|
||||||
|
constructor({wrapper, onclick}) {
|
||||||
|
this.wrapper = wrapper;
|
||||||
|
this.onclick = onclick;
|
||||||
|
this.make_dom();
|
||||||
|
this.bind_events();
|
||||||
|
}
|
||||||
|
|
||||||
|
make_dom() {
|
||||||
|
const button_array = [
|
||||||
|
[1, 2, 3, 'Qty'],
|
||||||
|
[4, 5, 6, 'Disc'],
|
||||||
|
[7, 8, 9, 'Price'],
|
||||||
|
['Del', 0, '.', 'Pay']
|
||||||
|
];
|
||||||
|
|
||||||
|
this.wrapper.html(`
|
||||||
|
<div class="number-pad">
|
||||||
|
${button_array.map(get_row).join("")}
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
|
||||||
|
function get_row(row) {
|
||||||
|
return '<div class="num-row">' + row.map(get_col).join("") + '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_col(col) {
|
||||||
|
return `<div class="num-col" data-value="${col}"><div>${col}</div></div>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bind_events() {
|
||||||
|
// bind click event
|
||||||
|
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')]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
highlight_button($btn) {
|
||||||
|
// const $btn = this.wrapper.find(`[data-value="${value}"]`);
|
||||||
|
$btn.addClass('highlight');
|
||||||
|
setTimeout(() => $btn.removeClass('highlight'), 1000);
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user