From 5289a204609d871c018229409ee832bd1e1ed812 Mon Sep 17 00:00:00 2001 From: Kyle Date: Sat, 2 May 2026 11:52:20 +0700 Subject: [PATCH 1/4] Fix bug display invoices for a different account --- app/views/kaui/invoices/index.html.erb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/kaui/invoices/index.html.erb b/app/views/kaui/invoices/index.html.erb index af72e531..5d8e7961 100644 --- a/app/views/kaui/invoices/index.html.erb +++ b/app/views/kaui/invoices/index.html.erb @@ -50,7 +50,7 @@ $(document).ready(function() { } }); - var stateKey = 'DataTables_invoices-table_' + window.location.pathname.replace(/\//g, '_'); + var stateKey = 'DataTables_invoices-table'; var state = JSON.parse(localStorage.getItem(stateKey)); if (state) { state.start = <%= @offset %>; @@ -64,10 +64,10 @@ $(document).ready(function() { }, "stateSave": true, "stateSaveCallback": function(settings, data) { - localStorage.setItem('DataTables_invoices-table', JSON.stringify(data)); + localStorage.setItem(stateKey, JSON.stringify(data)); }, "stateLoadCallback": function(settings) { - return JSON.parse(localStorage.getItem('DataTables_invoices-table')); + return JSON.parse(localStorage.getItem(stateKey)); }, "scrollX": true, "dom": "<'row'r>t<'row'<'col-md-6'i><'col-md-6'p>>", From 4af2854dc7b44535200331500cf3a0d6a6703c92 Mon Sep 17 00:00:00 2001 From: Kyle Date: Sun, 3 May 2026 21:29:10 +0700 Subject: [PATCH 2/4] Fix bug failed to search in Account Invoices and Account Payments --- app/controllers/kaui/engine_controller.rb | 3 +- .../kaui/engine_controller_util.rb | 28 +++++++++++++++++-- app/controllers/kaui/invoices_controller.rb | 6 ++-- app/controllers/kaui/payments_controller.rb | 6 ++-- lib/kaui/error_handler.rb | 3 +- 5 files changed, 36 insertions(+), 10 deletions(-) diff --git a/app/controllers/kaui/engine_controller.rb b/app/controllers/kaui/engine_controller.rb index 618ca4dd..01e2fcce 100644 --- a/app/controllers/kaui/engine_controller.rb +++ b/app/controllers/kaui/engine_controller.rb @@ -38,7 +38,8 @@ def check_for_redirect_to_tenant_screen end def populate_account_details - @account ||= params[:account_id].present? ? Kaui::Account.find_by_id(params[:account_id], false, false, options_for_klient) : Kaui::Account.new + account_id = scalar_account_id_param + @account ||= account_id.present? ? Kaui::Account.find_by_id(account_id, false, false, options_for_klient) : Kaui::Account.new end def retrieve_tenants_for_current_user diff --git a/app/controllers/kaui/engine_controller_util.rb b/app/controllers/kaui/engine_controller_util.rb index 478b76f7..c88419b9 100644 --- a/app/controllers/kaui/engine_controller_util.rb +++ b/app/controllers/kaui/engine_controller_util.rb @@ -37,8 +37,8 @@ def remapping_addvanced_search_fields(search_string, advanced_search_name_change end def paginate(searcher, data_extractor, formatter, table_default_columns = []) - search_key = (params[:search] || {})[:value].presence - advance_search_query = params[:advance_search_query].presence + search_key = normalize_search_key((params[:search] || {})[:value]).presence + advance_search_query = normalize_search_key(params[:advance_search_query]).presence search_key = advance_search_query if advance_search_query search_key = handle_balance_search(search_key) if search_key.present? @@ -84,6 +84,30 @@ def paginate(searcher, data_extractor, formatter, table_default_columns = []) end end + def advanced_search_query?(search_key) + search_key.to_s.include?('_q') + end + + def scalar_account_id_param + path_account_id = request.path_parameters[:account_id].presence + return path_account_id if path_account_id.present? + + account_id = params[:account_id] + account_id if account_id.is_a?(String) || account_id.is_a?(Numeric) + end + + def normalize_search_key(search_key) + return if search_key.blank? + + if search_key.respond_to?(:to_unsafe_h) + search_key.to_unsafe_h.to_query + elsif search_key.is_a?(Hash) + search_key.to_query + else + search_key + end + end + def promise(&) # Evaluation starts immediately ::Concurrent::Promises.future do diff --git a/app/controllers/kaui/invoices_controller.rb b/app/controllers/kaui/invoices_controller.rb index 31495708..d9d004d3 100644 --- a/app/controllers/kaui/invoices_controller.rb +++ b/app/controllers/kaui/invoices_controller.rb @@ -4,7 +4,7 @@ module Kaui class InvoicesController < Kaui::EngineController def index - @search_query = params[:account_id] + @search_query = scalar_account_id_param @advance_search_query = params[:q] || request.query_string @ordering = params[:ordering] || 'desc' @offset = params[:offset] || 0 @@ -15,7 +15,7 @@ def index end def download - account_id = params[:account_id] + account_id = scalar_account_id_param start_date = params[:startDate] end_date = params[:endDate] all_fields_checked = params[:allFieldsChecked] == 'true' @@ -60,7 +60,7 @@ def pagination searcher = lambda do |search_key, offset, limit| account = begin - Kaui::Account.find_by_id_or_key(search_key, false, false, cached_options_for_klient) + Kaui::Account.find_by_id_or_key(search_key, false, false, cached_options_for_klient) unless advanced_search_query?(search_key) rescue StandardError nil end diff --git a/app/controllers/kaui/payments_controller.rb b/app/controllers/kaui/payments_controller.rb index ba96abd3..f3922765 100644 --- a/app/controllers/kaui/payments_controller.rb +++ b/app/controllers/kaui/payments_controller.rb @@ -5,7 +5,7 @@ module Kaui class PaymentsController < Kaui::EngineController def index - @search_query = params[:q] || params[:account_id] + @search_query = params[:q] || scalar_account_id_param @advance_search_query = params[:q] || request.query_string @ordering = params[:ordering] || (@search_query.blank? ? 'desc' : 'asc') @offset = params[:offset] || 0 @@ -16,7 +16,7 @@ def index end def download - account_id = params[:account_id] + account_id = scalar_account_id_param start_date = params[:startDate] end_date = params[:endDate] all_fields_checked = params[:allFieldsChecked] == 'true' @@ -104,7 +104,7 @@ def pagination payments = Kaui::Payment.list_or_search(payment_state, offset, limit, options_for_klient) else account = begin - Kaui::Account.find_by_id_or_key(search_key, false, false, options_for_klient) + Kaui::Account.find_by_id_or_key(search_key, false, false, options_for_klient) unless advanced_search_query?(search_key) rescue StandardError nil end diff --git a/lib/kaui/error_handler.rb b/lib/kaui/error_handler.rb index 07ff0819..a76b9df3 100644 --- a/lib/kaui/error_handler.rb +++ b/lib/kaui/error_handler.rb @@ -26,7 +26,8 @@ module ErrorHandler end def perform_redirect_after_error(error:, error_message:, redirect: true) - account_id = nested_hash_value(params.permit!.to_h, :account_id) + account_id = request.path_parameters[:account_id].presence || nested_hash_value(params.permit!.to_h, :account_id) + account_id = nil unless account_id.is_a?(String) || account_id.is_a?(Numeric) home_path = kaui_engine.home_path redirect_path = if redirect && account_id.present? kaui_engine.account_path(account_id) From 0f4ec6f03c689c78f641abc9196029b6042889b5 Mon Sep 17 00:00:00 2001 From: Kyle Date: Mon, 4 May 2026 10:07:34 +0700 Subject: [PATCH 3/4] New button delete overdue config --- .../kaui/admin_tenants_controller.rb | 24 +++++++++++ .../admin_tenants/new_overdue_config.html.erb | 13 ++++++ config/locales/en.yml | 2 + config/routes.rb | 1 + .../kaui/admin_tenants_controller_test.rb | 43 +++++++++++++++++++ 5 files changed, 83 insertions(+) diff --git a/app/controllers/kaui/admin_tenants_controller.rb b/app/controllers/kaui/admin_tenants_controller.rb index 3cba9d54..757637dd 100644 --- a/app/controllers/kaui/admin_tenants_controller.rb +++ b/app/controllers/kaui/admin_tenants_controller.rb @@ -288,13 +288,19 @@ def new_overdue_config options = tenant_options_for_client options[:api_key] = @tenant.api_key options[:api_secret] = @tenant.api_secret + @overdue_config_exists = false begin @overdue = Kaui::Overdue.get_overdue_json(options) @overdue_corrupted = false + @overdue_config_exists = @overdue.overdue_states.present? && !@overdue.has_states + rescue KillBillClient::API::NotFound + @overdue = KillBillClient::Model::Overdue.new.tap { |o| o.overdue_states = [] } + @overdue_corrupted = false rescue StandardError => e Rails.logger.warn("Failed to load overdue configuration for tenant #{@tenant.id}: #{e.class}: #{e.message}") @overdue = KillBillClient::Model::Overdue.new.tap { |o| o.overdue_states = [] } @overdue_corrupted = true + @overdue_config_exists = true flash.now[:warning] = 'The existing overdue configuration is corrupted and cannot be loaded. Use the XML upload below to replace it with a valid configuration.' end end @@ -342,6 +348,24 @@ def upload_overdue_config redirect_to admin_tenant_path(current_tenant.id, active_tab: 'OverdueShow'), notice: I18n.t('flashes.notices.overdue_uploaded_successfully') end + def delete_overdue_config + current_tenant = safely_find_tenant_by_id(params[:id]) + + options = tenant_options_for_client + options[:api_key] = current_tenant.api_key + options[:api_secret] = current_tenant.api_secret + + begin + Kaui::AdminTenant.delete_tenant_user_key_value('OVERDUE_CONFIG', options[:username], nil, comment, options) + rescue StandardError => e + flash[:error] = "Failed to delete overdue config: #{as_string(e)}" + redirect_to admin_tenant_new_overdue_config_path(id: current_tenant.id) and return + end + + flash[:overdue_deleted] = true + redirect_to admin_tenant_path(current_tenant.id, active_tab: 'OverdueShow'), notice: I18n.t('flashes.notices.overdue_deleted_successfully') + end + def upload_invoice_template current_tenant = safely_find_tenant_by_id(params[:id]) diff --git a/app/views/kaui/admin_tenants/new_overdue_config.html.erb b/app/views/kaui/admin_tenants/new_overdue_config.html.erb index 124d084d..389b1d2f 100644 --- a/app/views/kaui/admin_tenants/new_overdue_config.html.erb +++ b/app/views/kaui/admin_tenants/new_overdue_config.html.erb @@ -10,6 +10,19 @@ Overdue Configuration + <% if @overdue_config_exists && can?(:config_upload, Kaui::AdminTenant) %> + <% overdue_delete_confirmation = t('admin_tenants.delete_overdue_config_confirmation') %> +
+ <%= form_tag(kaui_engine.admin_tenant_delete_overdue_config_path(id: @tenant.id), method: :delete, class: 'd-inline', onsubmit: "return confirm('#{j(overdue_delete_confirmation)}');") do %> + <%= render "kaui/components/button/button", { + label: 'Delete', + variant: "d-inline-flex align-items-center gap-1", + type: "submit", + html_class: "kaui-button delete-button custom-hover" + } %> + <% end %> +
+ <% end %>
diff --git a/config/locales/en.yml b/config/locales/en.yml index 6255bc0a..5c5a2af1 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -51,6 +51,7 @@ en: overdue_uploaded_successfully: 'Overdue config was successfully uploaded' overdue_added_successfully: 'Overdue config was successfully added' overdue_updated_successfully: 'Overdue config was successfully updated' + overdue_deleted_successfully: 'Overdue config was successfully deleted' invoice_template_uploaded_successfully: 'Invoice template was successfully uploaded' invoice_translation_uploaded_successfully: 'Invoice translation was successfully uploaded' catalog_translation_uploaded_successfully: 'Catalog translation was successfully uploaded' @@ -85,3 +86,4 @@ en: admin_tenants: clock_warning: "This action will affect all tenants across the system. Proceed with caution." + delete_overdue_config_confirmation: "This action is irreversible and will permanently delete the overdue configuration for this tenant. Are you sure you want to continue?" diff --git a/config/routes.rb b/config/routes.rb index 26696661..54ecdf21 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -189,6 +189,7 @@ def nested_param delete '/:id/delete_catalog' => 'admin_tenants#delete_catalog', :as => 'admin_tenant_delete_catalog' get '/:id/new_plan_currency' => 'admin_tenants#new_plan_currency', :as => 'admin_tenant_new_plan_currency' get '/:id/new_overdue_config' => 'admin_tenants#new_overdue_config', :as => 'admin_tenant_new_overdue_config' + delete '/:id' => 'admin_tenants#delete_overdue_config', :as => 'admin_tenant_delete_overdue_config' post '/upload_catalog' => 'admin_tenants#upload_catalog', :as => 'admin_tenant_upload_catalog' post '/display_catalog_xml' => 'admin_tenants#display_catalog_xml', :as => 'admin_tenant_display_catalog_xml' post '/display_overdue_xml' => 'admin_tenants#display_overdue_xml', :as => 'admin_tenant_display_overdue_xml' diff --git a/test/functional/kaui/admin_tenants_controller_test.rb b/test/functional/kaui/admin_tenants_controller_test.rb index e3d68a7a..0ec7b720 100644 --- a/test/functional/kaui/admin_tenants_controller_test.rb +++ b/test/functional/kaui/admin_tenants_controller_test.rb @@ -210,6 +210,49 @@ class AdminTenantsControllerTest < Kaui::FunctionalTestHelper assert_response :success end + test 'should upload and delete overdue config' do + tenant = create_kaui_tenant + + post :upload_overdue_config, params: { id: tenant.id, overdue: fixture_file_upload("#{FIXTURES_PATH}/overdue-v1.xml") } + assert_redirected_to admin_tenant_path(tenant.id, active_tab: 'OverdueShow') + assert_equal I18n.t('flashes.notices.overdue_uploaded_successfully'), flash[:notice] + + delete :delete_overdue_config, params: { id: tenant.id } + assert_redirected_to admin_tenant_path(tenant.id, active_tab: 'OverdueShow') + assert_equal I18n.t('flashes.notices.overdue_deleted_successfully'), flash[:notice] + end + + test 'should delete overdue config created via modify' do + tenant = create_kaui_tenant + + parameters = { + id: tenant.id, + kill_bill_client_model_overdue: { + states: { '0' => { + name: 'Overdue_test', + external_message: 'Overdue_Test_Ya', + is_block_changes: true, + subscription_cancellation_policy: 'NONE', + condition: { + time_since_earliest_unpaid_invoice_equals_or_exceeds: 1, + control_tag_inclusion: 'NONE', + control_tag_exclusion: 'NONE', + number_of_unpaid_invoices_equals_or_exceeds: 0, + total_unpaid_invoice_balance_equals_or_exceeds: 0 + } + } } + } + } + + post :modify_overdue_config, params: parameters + assert_redirected_to admin_tenant_path(tenant.id, active_tab: 'OverdueShow') + assert_equal I18n.t('flashes.notices.overdue_added_successfully'), flash[:notice].to_s.strip + + delete :delete_overdue_config, params: { id: tenant.id } + assert_redirected_to admin_tenant_path(tenant.id, active_tab: 'OverdueShow') + assert_equal I18n.t('flashes.notices.overdue_deleted_successfully'), flash[:notice] + end + test 'should modify overdue config' do tenant = create_kaui_tenant From 999e9f375465670a2210cb650153e11e5f31feb5 Mon Sep 17 00:00:00 2001 From: Kyle Date: Mon, 4 May 2026 10:16:06 +0700 Subject: [PATCH 4/4] Save search button is now triggering the search --- app/assets/javascripts/kaui/multi_functions_bar_utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/kaui/multi_functions_bar_utils.js b/app/assets/javascripts/kaui/multi_functions_bar_utils.js index 8e59d494..409ca80f 100644 --- a/app/assets/javascripts/kaui/multi_functions_bar_utils.js +++ b/app/assets/javascripts/kaui/multi_functions_bar_utils.js @@ -374,7 +374,7 @@ $(document).ready(function() { container.hide(); populateSavedSearchesDropdown(); - $('#advanceSearchModal').modal('hide'); + $('#applyAdvanceSearch').trigger('click'); }); $(document).on('hidden.bs.modal', '#advanceSearchModal', function () {