From 613cb3a0cb2a4186dbb457a8dbde5d7c051b2ec9 Mon Sep 17 00:00:00 2001 From: aungthetkhaing Date: Mon, 26 May 2025 18:07:55 +0630 Subject: [PATCH] fix : - make second display to be responsive --- .../channels/second_display_view.js | 19 +- app/controllers/foodcourt/qrpay_controller.rb | 41 ++- app/services/kbz_merchant.rb | 62 ++++- app/views/foodcourt/qrpay/init.html.erb | 22 +- .../second_display/_second_display.html.erb | 255 +++++++++++++++--- .../foodcourt/second_display/index.html.erb | 4 +- 6 files changed, 320 insertions(+), 83 deletions(-) diff --git a/app/assets/javascripts/channels/second_display_view.js b/app/assets/javascripts/channels/second_display_view.js index 1a0c6adb..4f67961a 100644 --- a/app/assets/javascripts/channels/second_display_view.js +++ b/app/assets/javascripts/channels/second_display_view.js @@ -265,12 +265,29 @@ App.checkin = App.cable.subscriptions.create("SecondDisplayViewChannel", {

Amount: ${new Intl.NumberFormat( "en-IN", ).format(Number(data.grand_total))} MMK

-

Invoice #: ${data.invoice_no}

+

Receipt NO: ${data.invoice_no}

`; document.querySelector("#qrpay_svg").innerHTML = data.qr_svg; document.querySelector(".payment-details").innerHTML = html; $("#mmqr_payment").removeClass("hidden"); $("#second_display_order_items").addClass("hidden"); } + + if (status == "pay_success") { + $("#mmqr_payment").addClass("hidden"); + $("#payment_success").removeClass("hidden"); + console.log(data); + const html = ` +

Amount Paid: ${new Intl.NumberFormat( + "en-IN", + ).format(Number(data.data.paid_amount))} MMK

+

Receipt No: ${data.data.receipt_no}

+ `; + document.querySelector(".payment-summary").innerHTML = html; + + setTimeout(() => { + jQuery("#s_reload").click(); + }, 3000); + } }, }); diff --git a/app/controllers/foodcourt/qrpay_controller.rb b/app/controllers/foodcourt/qrpay_controller.rb index cc2845c3..e1227d22 100644 --- a/app/controllers/foodcourt/qrpay_controller.rb +++ b/app/controllers/foodcourt/qrpay_controller.rb @@ -191,32 +191,25 @@ class Foodcourt::QrpayController < BaseFoodcourtController @merchant = KbzMerchant.new(@paymethod) @response = @merchant.create_order(amount: @sale_data.grand_total, merch_order_id: @sale_data.receipt_no) - @qr_string = @response['qrCode'] + case @response[:status] + when 'success' + @qr_string = @response[:data]["qrCode"] + qrcode = RQRCode::QRCode.new(@qr_string) - qrcode = RQRCode::QRCode.new(@qr_string) + @qr_svg = qrcode.as_svg( + color: "000", + shape_rendering: "crispEdges", + module_size: 2, + standalone: true, + use_path: true + ) + ActionCable.server.broadcast('second_display_view_channel', { data: @qr_string, qr_svg: @qr_svg, grand_total: @sale_data.grand_total, invoice_no: @sale_data.receipt_no }) - @qr_svg = qrcode.as_svg( - color: "000", - shape_rendering: "crispEdges", - module_size: 2, - standalone: true, - use_path: true - ) - - # png_data = qrcode.as_png( - # bit_depth: 1, - # border_modules: 4, - # color_mode: ChunkyPNG::COLOR_GRAYSCALE, - # color: 'black', - # file: nil, - # fill: 'white', - # module_px_size: 8, # Pixel size of each module - # resize_exactly_to: false, - # resize_gte_to: false, - # size: 240 # Approximate size of the image in pixels (e.g., 240x240) - # ).to_s - - ActionCable.server.broadcast('second_display_view_channel', { data: @qr_string, qr_svg: @qr_svg, grand_total: @sale_data.grand_total, invoice_no: @sale_data.receipt_no }) + when 'error' + @error = @response[:message] + when 'failed' + @error = @response[:message] + end end end diff --git a/app/services/kbz_merchant.rb b/app/services/kbz_merchant.rb index fc4b7dfb..4c04511c 100644 --- a/app/services/kbz_merchant.rb +++ b/app/services/kbz_merchant.rb @@ -132,22 +132,68 @@ class KbzMerchant ) puts "Response: #{response}" - response.body - # puts "Response: #{response}" + JSON.parse(response.body) rescue HTTParty::Error => e - raise PaymentError, "HTTP error: #{e.message}" + { + error: true, + code: 'http_error', + message: "HTTP error: #{e.message}", + alert: "Payment service unavailable. Please try again later." + } rescue SocketError => e - raise PaymentError, "Network error: #{e.message}" + { + error: true, + code: 'network_error', + message: "Network error: #{e.message}", + alert: "Network connection failed. Please check your internet." + } + rescue JSON::ParserError => e + { + error: true, + code: 'invalid_response', + message: "Invalid response format: #{e.message}", + alert: "Received invalid payment response. Please contact support." + } + rescue StandardError => e + { + error: true, + code: 'unexpected_error', + message: "Unexpected error: #{e.message}", + alert: "An unexpected error occurred. Please try again." + } end end def handle_response(response) - json_response = JSON.parse(response) - if json_response.dig('Response', 'result') == 'SUCCESS' - json_response['Response'] + if response['error'] + { + status: 'error', + code: response['code'], + message: response['message'] + } + elsif response.dig('Response', 'result') == 'SUCCESS' + { + status: 'success', + data: response['Response'] + } else - raise PaymentError, "Payment failed: #{json_response['Response']['msg']}" + error_code = response.dig('Response', 'code') + error_message = response.dig('Response', 'msg') + case error_code + when 'OrderCenter.FAILED_CREATE_ORDER_FOR_DUPLICATED_MERCHANT_ORDER_ID' + { + status: 'failed', + code: error_code, + message: 'Duplicate order ID detected. Please use a unique reference ID.' + } + else + { + status: 'failed', + code: error_code || 'unknown_error', + message: error_message || 'Payment processing failed' + } + end end end end diff --git a/app/views/foodcourt/qrpay/init.html.erb b/app/views/foodcourt/qrpay/init.html.erb index c44a6473..9b55723e 100644 --- a/app/views/foodcourt/qrpay/init.html.erb +++ b/app/views/foodcourt/qrpay/init.html.erb @@ -48,6 +48,10 @@ <% end %>
+ <% if @error %> + + <% end %> +
@@ -248,8 +252,12 @@ document.addEventListener('DOMContentLoaded', function() { const paymentWaiting = document.querySelector('.payment-waiting'); let amountToReceive = <%= number_with_precision(@sale_data.grand_total, precision: precision.to_i) %>; + let receipt_no = document.querySelector('#receipt_no').textContent; + console.log(receipt_no); const ws = new WebSocket("wss://juicecorner-0mo.sx-fc.app/cable"); + + ws.onopen = () => { console.log("Nagato channel connected"); @@ -277,16 +285,6 @@

Amount Received: ${amountToReceive}

`; - ws.close(); - - // fetch('/foodcourt/qrpay/process_payment', { - // method: 'POST', - // headers: { - // 'Content-Type': 'application/json', - // 'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content, - // }, - // body: JSON.stringify({ sale_id: "SAL-0qg000000671" }) - // }) fetch('/foodcourt/qrpay/process_payment', { method: 'POST', @@ -298,7 +296,7 @@ }).then((res) => res.json()) .then((data) => { if(data.status) { - customer_display_view(null, "reload"); + customer_display_view({msg: "Payment Successful", paid_amount: amountToReceive,receipt_no:receipt_no}, "pay_success"); setTimeout(() => { window.location.href = "/"; }, 3000) @@ -317,6 +315,8 @@ function customer_display_view(data, status) { let url = '/foodcourt/customer_view'; + console.log(data); + $.ajax({ type: "POST", url: url, diff --git a/app/views/foodcourt/second_display/_second_display.html.erb b/app/views/foodcourt/second_display/_second_display.html.erb index 33e5f5dd..e78c2703 100644 --- a/app/views/foodcourt/second_display/_second_display.html.erb +++ b/app/views/foodcourt/second_display/_second_display.html.erb @@ -1,81 +1,83 @@
-
+ +

Invoice Details

-
+
-
- - - - - - - - - - - - -
#ItemsQTYPrice
+
+
+ + + + + + + + + + + + +
#ItemsQTYPrice
+
-