From fc3315a6d7938212009955802cbd7181083e0025 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Wed, 11 Nov 2020 22:59:10 +0530 Subject: [PATCH] feat: pos item details with new ui --- erpnext/public/scss/point-of-sale.scss | 114 +++++++++++++++++- .../page/point_of_sale/pos_item_cart.js | 11 +- .../page/point_of_sale/pos_item_details.js | 83 ++++++------- .../page/point_of_sale/pos_item_selector.js | 16 +-- 4 files changed, 160 insertions(+), 64 deletions(-) diff --git a/erpnext/public/scss/point-of-sale.scss b/erpnext/public/scss/point-of-sale.scss index 37ca8fd13d..573b9dc2b7 100644 --- a/erpnext/public/scss/point-of-sale.scss +++ b/erpnext/public/scss/point-of-sale.scss @@ -119,7 +119,6 @@ display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--margin-lg); - flex: 1 1 0%; padding: var(--padding-lg); padding-top: var(--padding-xs); @@ -471,6 +470,13 @@ background-color: var(--blue-200); color: white; } + + > .edit-cart-btn { + @extend .primary-action; + display: none; + background-color: var(--gray-100); + font-weight: 500; + } } > .numpad-section { @@ -542,7 +548,7 @@ > .invoice-name-date { display: flex; flex-direction: column; - justify-content: end; + justify-content: flex-end; > .invoice-name { @extend .nowrap; @@ -580,4 +586,108 @@ } } } + + > .item-details-container { + @extend .pos-card; + grid-column: span 4 / span 4; + display: none; + flex-direction: column; + padding: var(--padding-lg); + padding-top: var(--padding-md); + + > .item-details-header { + display: flex; + justify-content: space-between; + margin-bottom: var(--margin-md); + + > .close-btn { + @extend .pointer-no-select; + } + } + + > .item-display { + display: flex; + + > .item-name-desc-price { + flex: 1 1 0%; + display: flex; + flex-direction: column; + justify-content: flex-end; + margin-right: var(--margin-md); + + > .item-name { + font-size: var(--text-3xl); + font-weight: 600; + } + + > .item-desc { + font-size: var(--text-md); + font-weight: 500; + } + + > .item-price { + font-size: var(--text-3xl); + font-weight: 700; + } + } + + > .item-image { + display: flex; + align-items: center; + justify-content: center; + width: 11rem; + height: 11rem; + border-radius: var(--border-radius-md); + margin-left: var(--margin-md); + color: var(--gray-500); + + > img { + @extend .image; + } + + > .item-abbr { + @extend .abbr; + display: flex; + align-items: center; + justify-content: center; + border-radius: var(--border-radius-md); + font-size: var(--text-3xl); + width: 100%; + height: 100%; + } + } + } + + > .discount-section { + display: flex; + align-items: center; + margin-bottom: var(--margin-sm); + + > .item-rate { + font-weight: 500; + margin-right: var(--margin-sm); + text-decoration: line-through; + } + + > .item-discount { + padding: 3px var(--padding-sm); + border-radius: var(--border-radius-sm); + background-color: var(--green-100); + color: var(--green-700); + font-size: var(--text-sm); + font-weight: 700; + } + } + + > .form-container { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + column-gap: var(--padding-xs); + + > .auto-fetch-btn { + @extend .pointer-no-select; + margin: auto var(--margin-xs); + } + } + } } \ No newline at end of file diff --git a/erpnext/selling/page/point_of_sale/pos_item_cart.js b/erpnext/selling/page/point_of_sale/pos_item_cart.js index e0a2ee7767..b560ba4a87 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_cart.js +++ b/erpnext/selling/page/point_of_sale/pos_item_cart.js @@ -95,9 +95,7 @@ erpnext.PointOfSale.ItemCart = class {
0.00
Checkout
-
- Edit Cart -
` +
Edit Cart
` ) this.$add_discount_elem = this.$component.find(".add-discount"); @@ -176,7 +174,7 @@ erpnext.PointOfSale.ItemCart = class { }); this.$component.on('click', '.checkout-btn', function() { - if (!$(this).hasClass('bg-primary')) return; + if ($(this).attr('style').indexOf('--blue-500') == -1) return; me.events.checkout(); me.toggle_checkout_btn(false); @@ -265,8 +263,9 @@ erpnext.PointOfSale.ItemCart = class { toggle_item_highlight(item) { const $cart_item = $(item); + const item_is_highlighted = $cart_item.attr("style") == "background-color:var(--gray-50);"; - if (!item) { + if (!item || item_is_highlighted) { this.item_is_selected = false; this.$cart_container.find('.cart-item-wrapper').css("background-color", ""); } else { @@ -522,7 +521,7 @@ erpnext.PointOfSale.ItemCart = class { const $item = this.get_cart_item(item); if (remove_item) { - $item && $item.remove(); + $item && $item.next().remove() && $item.remove(); } else { const { item_code, batch_no, uom } = item; const search_field = batch_no ? 'batch_no' : 'item_code'; diff --git a/erpnext/selling/page/point_of_sale/pos_item_details.js b/erpnext/selling/page/point_of_sale/pos_item_details.js index a4de9f165d..546154345b 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_details.js +++ b/erpnext/selling/page/point_of_sale/pos_item_details.js @@ -16,35 +16,36 @@ erpnext.PointOfSale.ItemDetails = class { prepare_dom() { this.wrapper.append( - `
` + `
` ) - this.$component = this.wrapper.find('.item-details'); + this.$component = this.wrapper.find('.item-details-container'); } init_child_components() { this.$component.html( - `
-
-
ITEM DETAILS
-
Close
+ `
+
Item Details
+
+ + +
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
STOCK DETAILS
-
-
` +
+
+
+
` ) this.$item_name = this.$component.find('.item-name'); - this.$item_description = this.$component.find('.item-description'); + this.$item_description = this.$component.find('.item-desc'); this.$item_price = this.$component.find('.item-price'); this.$item_image = this.$component.find('.item-image'); this.$form_container = this.$component.find('.form-container'); @@ -52,7 +53,7 @@ erpnext.PointOfSale.ItemDetails = class { } toggle_item_details_section(item) { - const { item_code, batch_no, uom } = this.current_item; + const { item_code, batch_no, uom } = this.current_item; const item_code_is_same = item && item_code === item.item_code; const batch_is_same = item && batch_no == item.batch_no; const uom_is_same = item && uom === item.uom; @@ -104,11 +105,11 @@ erpnext.PointOfSale.ItemDetails = class { } render_dom(item) { - let { item_code ,item_name, description, image, price_list_rate } = item; + let { item_name, description, image, price_list_rate } = item; function get_description_html() { if (description) { - description = description.indexOf('...') === -1 && description.length > 75 ? description.substr(0, 73) + '...' : description; + description = description.indexOf('...') === -1 && description.length > 140 ? description.substr(0, 139) + '...' : description; return description; } return ``; @@ -118,11 +119,9 @@ erpnext.PointOfSale.ItemDetails = class { this.$item_description.html(get_description_html()); this.$item_price.html(format_currency(price_list_rate, this.currency)); if (image) { - this.$item_image.html( - `${image}` - ); + this.$item_image.html(`${image}`); } else { - this.$item_image.html(frappe.get_abbr(item_code)); + this.$item_image.html(`
${frappe.get_abbr(item_name)}
`); } } @@ -130,12 +129,8 @@ erpnext.PointOfSale.ItemDetails = class { render_discount_dom(item) { if (item.discount_percentage) { this.$dicount_section.html( - `
- ${format_currency(item.price_list_rate, this.currency)} -
-
- ${item.discount_percentage}% off -
` + `
${format_currency(item.price_list_rate, this.currency)}
+
${item.discount_percentage}% off
` ) this.$item_price.html(format_currency(item.rate, this.currency)); } else { @@ -149,9 +144,7 @@ erpnext.PointOfSale.ItemDetails = class { fields_to_display.forEach((fieldname, idx) => { this.$form_container.append( - `
-
-
` + `
` ) const field_meta = this.item_meta.fields.find(df => df.fieldname === fieldname); @@ -185,22 +178,15 @@ erpnext.PointOfSale.ItemDetails = class { make_auto_serial_selection_btn(item) { if (item.has_serial_no) { - this.$form_container.append( - `
` - ) if (!item.has_batch_no) { this.$form_container.append( `
` ) } this.$form_container.append( - `
- Auto Fetch Serial Numbers -
` + `
Auto Fetch Serial Numbers
` ) - this.$form_container.find('.serial_no-control').find('textarea').css('height', '9rem'); - this.$form_container.find('.serial_no-control').parent().addClass('row-span-2'); + this.$form_container.find('.serial_no-control').find('textarea').css('height', '6rem'); } } @@ -294,8 +280,13 @@ erpnext.PointOfSale.ItemDetails = class { } frappe.model.on("POS Invoice Item", "*", (fieldname, value, item_row) => { - const field_control = me[`${fieldname}_control`]; - if (field_control) { + const field_control = this[`${fieldname}_control`]; + const { item_code, batch_no, uom } = this.current_item; + const item_code_is_same = item_code === item_row.item_code; + const batch_is_same = batch_no == item_row.batch_no; + const uom_is_same = uom === item_row.uom; + + if (field_control && item_code_is_same && batch_is_same && uom_is_same) { field_control.set_value(value); cur_pos.update_cart_html(item_row); } @@ -409,6 +400,6 @@ erpnext.PointOfSale.ItemDetails = class { } toggle_component(show) { - show ? this.$component.removeClass('d-none') : this.$component.addClass('d-none'); + show ? this.$component.css('display', 'flex') : this.$component.css('display', 'none'); } } \ No newline at end of file diff --git a/erpnext/selling/page/point_of_sale/pos_item_selector.js b/erpnext/selling/page/point_of_sale/pos_item_selector.js index 4195d93d4e..0bac84481d 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_selector.js +++ b/erpnext/selling/page/point_of_sale/pos_item_selector.js @@ -248,20 +248,16 @@ erpnext.PointOfSale.ItemSelector = class { resize_selector(minimize) { minimize ? - this.$component.find('.search-field').removeClass('mr-8') : - this.$component.find('.search-field').addClass('mr-8'); - - minimize ? - this.$component.find('.filter-section').addClass('flex-col') : - this.$component.find('.filter-section').removeClass('flex-col'); + this.$component.find('.filter-section').css('grid-template-columns', 'repeat(1, minmax(0, 1fr))') : + this.$component.find('.filter-section').css('grid-template-columns', 'repeat(12, minmax(0, 1fr))'); minimize ? - this.$component.removeClass('col-span-6').addClass('col-span-2') : - this.$component.removeClass('col-span-2').addClass('col-span-6') + this.$component.css('grid-column', 'span 2 / span 2') : + this.$component.css('grid-column', 'span 6 / span 6') minimize ? - this.$items_container.removeClass('grid-cols-4').addClass('grid-cols-1') : - this.$items_container.removeClass('grid-cols-1').addClass('grid-cols-4') + this.$items_container.css('grid-template-columns', 'repeat(1, minmax(0, 1fr))') : + this.$items_container.css('grid-template-columns', 'repeat(4, minmax(0, 1fr))') } toggle_component(show) {