From 86b37782fe3618b6e6dd4f04e129d357bda2c6bb Mon Sep 17 00:00:00 2001 From: Diptanil Saha Date: Thu, 3 Jul 2025 15:16:07 +0530 Subject: [PATCH] fix: pos payment section (#48366) --- erpnext/hooks.py | 1 + erpnext/public/scss/point-of-sale.scss | 21 ---- erpnext/public/sounds/numpad-touch.mp3 | Bin 0 -> 1688 bytes .../selling/page/point_of_sale/pos_payment.js | 105 +++++++----------- 4 files changed, 44 insertions(+), 83 deletions(-) create mode 100644 erpnext/public/sounds/numpad-touch.mp3 diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 90395e22b6b..806955d6e7c 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -280,6 +280,7 @@ standard_portal_menu_items = [ sounds = [ {"name": "incoming-call", "src": "/assets/erpnext/sounds/incoming-call.mp3", "volume": 0.2}, {"name": "call-disconnect", "src": "/assets/erpnext/sounds/call-disconnect.mp3", "volume": 0.2}, + {"name": "numpad-touch", "src": "/assets/erpnext/sounds/numpad-touch.mp3", "volume": 0.8}, ] has_upload_permission = {"Employee": "erpnext.setup.doctype.employee.employee.has_upload_permission"} diff --git a/erpnext/public/scss/point-of-sale.scss b/erpnext/public/scss/point-of-sale.scss index d4cc7094e55..f007bec5e8b 100644 --- a/erpnext/public/scss/point-of-sale.scss +++ b/erpnext/public/scss/point-of-sale.scss @@ -882,27 +882,6 @@ overflow: hidden; text-overflow: ellipsis; } - - > .cash-shortcuts { - display: none; - grid-template-columns: repeat(3, minmax(0, 1fr)); - gap: var(--margin-sm); - font-size: var(--text-sm); - text-align: center; - - > .shortcut { - @extend .pointer-no-select; - border-radius: var(--border-radius-sm); - background-color: var(--control-bg); - font-weight: 500; - padding: var(--padding-xs) var(--padding-sm); - transition: all 0.15s ease-in-out; - - &:hover { - background-color: var(--control-bg); - } - } - } } > .loyalty-card { diff --git a/erpnext/public/sounds/numpad-touch.mp3 b/erpnext/public/sounds/numpad-touch.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..97fbb32ffa963ae35df3b01153217cd4e2c54e00 GIT binary patch literal 1688 zcmeZtF=k-^0p*b3U{@f`&%nU!lUSB!W}s(ire|ni0G5Ri|9?9iK;lA}5t(`EKo(FR z12Y2yTQ)-j$wL+#eFG8)pAoIX_(WqyeJ? z19t<TQ!+yOx6d!j`bhouNU2fw|1S(OIxh zv~q^1_C=vN=N^Cdn&2p*JcrroR&pNm8O|fd2`)S`rPd5LHCQEh6gS^uxShw`!J~Rf zuHnu$#u+@^7bHFy7&`h3=|tIVmTb{r~^Da$=5_TH~U#z$8)T^Vd!O|4-*h&z8sn zxzCIwJ%+yqHpy5Cx&oPHT2R~=uXBl&2 zgEV*3{-kCj}V^1{Ov( zj)tY5>uz0PdUtqh?6l3npH_RfUdcCLVdP;r+`zuJd0HX^k5Fjcw9J2PTeaF&J>0Xs zXxlpr*E#wQ7TncO|Nq`_$*S1dky8i#) z$7}!J-gthcXY!6j|M}1T^NxL9a+o(U>GrE{|AS_ncKzs@?c?a{Y78nIR#5{`*EDLl kXw(c`A@KjVz>#ar2N)Qa$S^P{Fff=j0LwgFiYX8W0DWL { $btn.removeClass("shadow-base-inner bg-selected"); }, 100); @@ -162,22 +182,17 @@ erpnext.PointOfSale.Payment = class { // if clicked element doesn't have .mode-of-payment class then return if (!$(e.target).is(mode_clicked)) return; - const scrollLeft = - mode_clicked.offset().left - me.$payment_modes.offset().left + me.$payment_modes.scrollLeft(); - me.$payment_modes.animate({ scrollLeft }); - const mode = mode_clicked.attr("data-mode"); // hide all control fields and shortcuts $(`.mode-of-payment-control`).css("display", "none"); - $(`.cash-shortcuts`).css("display", "none"); me.$payment_modes.find(`.pay-amount`).css("display", "inline"); me.$payment_modes.find(`.loyalty-amount-name`).css("display", "none"); // remove highlight from all mode-of-payments $(".mode-of-payment").removeClass("border-primary"); - if (mode_clicked.hasClass("border-primary")) { + if (me.selected_mode?._label === me[`${mode}_control`]?._label) { // clicked one is selected then unselect it mode_clicked.removeClass("border-primary"); me.selected_mode = ""; @@ -185,12 +200,10 @@ erpnext.PointOfSale.Payment = class { // clicked one is not selected then select it mode_clicked.addClass("border-primary"); mode_clicked.find(".mode-of-payment-control").css("display", "flex"); - mode_clicked.find(".cash-shortcuts").css("display", "grid"); me.$payment_modes.find(`.${mode}-amount`).css("display", "none"); me.$payment_modes.find(`.${mode}-name`).css("display", "inline"); me.selected_mode = me[`${mode}_control`]; - me.selected_mode && me.selected_mode.$input.get(0).focus(); me.auto_set_remaining_amount(); } }); @@ -296,11 +309,6 @@ erpnext.PointOfSale.Payment = class { bind_paid_amount_event(frm) { this.update_totals_section(frm.doc); - - // need to re calculate cash shortcuts after discount is applied - const is_cash_shortcuts_invisible = !this.$payment_modes.find(".cash-shortcuts").is(":visible"); - this.attach_cash_shortcuts(frm.doc); - !is_cash_shortcuts_invisible && this.$payment_modes.find(".cash-shortcuts").css("display", "grid"); this.render_payment_mode_dom(); } @@ -457,8 +465,7 @@ erpnext.PointOfSale.Payment = class { .map((p, i) => { const mode = this.sanitize_mode_of_payment(p.mode_of_payment); const payment_type = p.type; - const margin = i % 2 === 0 ? "pr-2" : "pl-2"; - const amount = p.amount > 0 ? format_currency(p.amount, currency) : ""; + const amount = p.amount !== 0 ? format_currency(p.amount, currency) : ""; return `
@@ -498,11 +505,11 @@ erpnext.PointOfSale.Payment = class { }); this[`${mode}_control`].toggle_label(false); this[`${mode}_control`].set_value(p.amount); + + this.selected_mode_input_display(); }); this.render_loyalty_points_payment_mode(); - - this.attach_cash_shortcuts(doc); } focus_on_default_mop() { @@ -518,45 +525,6 @@ erpnext.PointOfSale.Payment = class { }); } - attach_cash_shortcuts(doc) { - const grand_total = cint(frappe.sys_defaults.disable_rounded_total) - ? doc.grand_total - : doc.rounded_total; - const currency = doc.currency; - - const shortcuts = this.get_cash_shortcuts(flt(grand_total)); - - this.$payment_modes.find(".cash-shortcuts").remove(); - let shortcuts_html = shortcuts - .map((s) => { - return `
${format_currency(s, currency)}
`; - }) - .join(""); - - this.$payment_modes - .find('[data-payment-type="Cash"]') - .find(".mode-of-payment-control") - .after(`
${shortcuts_html}
`); - } - - get_cash_shortcuts(grand_total) { - let steps = [1, 5, 10]; - const digits = String(Math.round(grand_total)).length; - - steps = steps.map((x) => x * 10 ** (digits - 2)); - - const get_nearest = (amount, x) => { - let nearest_x = Math.ceil(amount / x) * x; - return nearest_x === amount ? nearest_x + x : nearest_x; - }; - - return steps.reduce((finalArr, x) => { - let nearest_x = get_nearest(grand_total, x); - nearest_x = finalArr.indexOf(nearest_x) != -1 ? nearest_x + x : nearest_x; - return [...finalArr, nearest_x]; - }, []); - } - render_loyalty_points_payment_mode() { const me = this; const doc = this.events.get_frm().doc; @@ -671,7 +639,10 @@ erpnext.PointOfSale.Payment = class {
${label}
-
${format_currency(change || remaining, currency)}
+
${format_currency( + change || remaining, + currency + )}
` ); } @@ -708,4 +679,14 @@ erpnext.PointOfSale.Payment = class { } return true; } + + selected_mode_input_display() { + if (this.selected_mode) { + const mode = this.sanitize_mode_of_payment(this.selected_mode.df.label); + this.$payment_modes.find(`.mode-of-payment[data-mode="${mode}"]`).addClass("border-primary"); + this.$payment_modes.find(`.${mode}.mode-of-payment-control`).css("display", "flex"); + this.$payment_modes.find(`.${mode}-amount`).css("display", "none"); + this.$payment_modes.find(`.${mode}-name`).css("display", "inline"); + } + } };