From 1046ea07e427eed2225a4efbc747d2795a85690e Mon Sep 17 00:00:00 2001
From: panhachom <panhachom@gmail.com>
Date: Wed, 25 Dec 2024 16:55:02 +0700
Subject: [PATCH] close #234 validate public key when enable pre auth

---
 .../payment_methods_controller_decorator.rb   | 53 +++++++++++++++++++
 app/models/spree/gateway/payway_v2.rb         |  6 +++
 .../index/list.html.erb.deface                | 45 ++++++++++++++++
 3 files changed, 104 insertions(+)
 create mode 100644 app/overrides/spree/admin/payment_methods/index/list.html.erb.deface

diff --git a/app/controllers/spree/admin/payment_methods_controller_decorator.rb b/app/controllers/spree/admin/payment_methods_controller_decorator.rb
index 27b89b59..599c5a41 100644
--- a/app/controllers/spree/admin/payment_methods_controller_decorator.rb
+++ b/app/controllers/spree/admin/payment_methods_controller_decorator.rb
@@ -1,11 +1,64 @@
 module Spree
   module Admin
     module PaymentMethodsControllerDecorator
+
       def scope
         scope = current_store.payment_methods_including_vendor.accessible_by(current_ability, :index)
         scope = scope.where.not(vendor_id: nil) if params[:tab] == 'vendors'
         scope
       end
+
+      # overrdie
+      # handling error response
+      def create
+        @payment_method = params[:payment_method].delete(:type).constantize.new(payment_method_params)
+        @object = @payment_method
+        set_current_store
+        invoke_callbacks(:create, :before)
+        if @payment_method.save
+          invoke_callbacks(:create, :after)
+          flash[:success] = Spree.t(:successfully_created, resource: Spree.t(:payment_method))
+          redirect_to location_after_create
+        else
+          invoke_callbacks(:create, :fails)
+          respond_with(@object) do |format|
+            format.html { render action: :new, status: :unprocessable_entity }
+            format.js { render layout: false, status: :unprocessable_entity }
+          end
+        end
+      end
+
+      # overrdie
+      # handling error response
+      def update
+        invoke_callbacks(:update, :before)
+        payment_method_type = params[:payment_method].delete(:type)
+        if @payment_method['type'].to_s != payment_method_type
+          @payment_method.update_columns(
+            type: payment_method_type,
+            updated_at: Time.current
+          )
+          @payment_method = scope.find(params[:id])
+        end
+
+        attributes = payment_method_params.merge(preferences_params)
+        attributes.each do |k, _v|
+          attributes.delete(k) if k.include?('password') && attributes[k].blank?
+        end
+
+        if @payment_method.update(attributes)
+          set_current_store
+          invoke_callbacks(:update, :after)
+          flash[:success] = Spree.t(:successfully_updated, resource: Spree.t(:payment_method))
+          redirect_to spree.edit_admin_payment_method_path(@payment_method)
+        else
+          invoke_callbacks(:update, :fails)
+          respond_with(@payment_method) do |format|
+            format.html { render :edit, status: :unprocessable_entity }
+            format.json { render json: @payment_method.errors.full_messages.to_sentence, status: :unprocessable_entity }
+          end
+        end
+      end
     end
   end
 end
diff --git a/app/models/spree/gateway/payway_v2.rb b/app/models/spree/gateway/payway_v2.rb
index 60c0a2d6..018a6730 100644
--- a/app/models/spree/gateway/payway_v2.rb
+++ b/app/models/spree/gateway/payway_v2.rb
@@ -17,6 +17,12 @@ class Gateway::PaywayV2 < PaymentMethod
     #   Gem.loaded_specs.key?('spree_auth_devise')
     # end
 
+    validates :preferred_public_key, presence: true, if: :require_public_key?
+
+    def require_public_key?
+      enable_pre_auth == true
+    end
+
     def payment_source_class
       Spree::VpagoPaymentSource
     end
diff --git a/app/overrides/spree/admin/payment_methods/index/list.html.erb.deface b/app/overrides/spree/admin/payment_methods/index/list.html.erb.deface
new file mode 100644
index 00000000..6c1d6c00
--- /dev/null
+++ b/app/overrides/spree/admin/payment_methods/index/list.html.erb.deface
@@ -0,0 +1,45 @@
+<!-- replace ".table-responsive" -->
+
+<div class="table-responsive border rounded bg-white">
+  <table class="table sortable" id='listing_payment_methods' data-hook data-sortable-link="<%= update_positions_admin_payment_methods_url %>">
+    <thead class="text-muted">
+      <tr data-hook="admin_payment_methods_index_headers">
+        <th></th>
+        <th><%= Spree.t(:name) %></th>
+        <th><%= Spree.t(:provider) %></th>
+        <th class="text-center"><%= Spree.t(:transaction_type) %></th>
+        <th class="text-center"><%= Spree.t(:display) %></th>
+        <th class="text-center"><%= Spree.t(:active) %></th>
+        <th data-hook="admin_payment_methods_index_header_actions" class="actions"></th>
+      </tr>
+    </thead>
+    <tbody id="sortVert">
+      <% @payment_methods.each do |method| %>
+        <tr id="<%= spree_dom_id method %>" data-hook="admin_payment_methods_index_rows">
+          <td class="move-handle text-center">
+            <% if can?(:edit, method) %>
+              <%= svg_icon name: "grip-vertical.svg", width: '18', height: '18' %>
+            <% end %>
+          </td>
+          <td><%= method.name %></td>
+          <td><%= method.type.split('::', 3).last %></td>
+          <td class="text-center">
+            <% if method.enable_pre_auth? %>
+              <span class="badge badge-pill badge-info">Pre-Auth</span>
+            <% else %>
+              <span class="badge badge-pill badge-success">Purchase</span>
+            <% end %>
+          </td>
+          <td class="text-center"><%= Spree.t("admin.display_on.#{method.display_on}") %></td>
+          <td class="text-center"><%= active_badge(method.active) %></td>
+          <td data-hook="admin_payment_methods_index_row_actions" class="actions">
+            <span class="d-flex justify-content-end">
+              <%= link_to_edit(method, no_text: true) if can? :edit, method %>
+              <%= link_to_delete(method, no_text: true) if can? :delete, method %>
+            </span>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
\ No newline at end of file