From 9c0eccf25964e9e684a61971727a70f77dac20ed Mon Sep 17 00:00:00 2001 From: Homayoon Hedayatifard Date: Sun, 30 Jul 2023 01:54:49 +0330 Subject: [PATCH 1/7] Add invoices#restful_show_by_number --- app/controllers/kaui/invoices_controller.rb | 5 +++++ config/routes.rb | 1 + test/functional/kaui/invoices_controller_test.rb | 5 +++++ 3 files changed, 11 insertions(+) diff --git a/app/controllers/kaui/invoices_controller.rb b/app/controllers/kaui/invoices_controller.rb index f55a8b6c..fa67c496 100644 --- a/app/controllers/kaui/invoices_controller.rb +++ b/app/controllers/kaui/invoices_controller.rb @@ -147,6 +147,11 @@ def restful_show redirect_to account_invoice_path(invoice.account_id, invoice.invoice_id) end + def restful_show_by_number + invoice = Kaui::Invoice.find_by_number(params.require(:number), 'NONE', options_for_klient) + redirect_to account_invoice_path(invoice.account_id, invoice.invoice_id) + end + def show_html render html: Kaui::Invoice.as_html(params.require(:id), options_for_klient).html_safe end diff --git a/config/routes.rb b/config/routes.rb index 7aeca6c6..a9305843 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -98,6 +98,7 @@ def nested_param scope '/invoices' do match '/pagination' => 'invoices#pagination', :via => :get, :as => 'invoices_pagination' match '/:id/show_html' => 'invoices#show_html', :via => :get, :as => 'show_html_invoice' + match '/:number' => 'invoices#restful_show_by_number', :via => :get, :constraints => { number: /\d+/ } match '/:id' => 'invoices#restful_show', :via => :get, :as => 'invoice' match '/commit' => 'invoices#commit_invoice', :via => :post, :as => 'commit_invoice' match '/void' => 'invoices#void_invoice', :via => :delete, :as => 'void_invoice' diff --git a/test/functional/kaui/invoices_controller_test.rb b/test/functional/kaui/invoices_controller_test.rb index a48d56d9..cd629615 100644 --- a/test/functional/kaui/invoices_controller_test.rb +++ b/test/functional/kaui/invoices_controller_test.rb @@ -75,6 +75,11 @@ class InvoicesControllerTest < Kaui::FunctionalTestHelper assert_redirected_to account_invoice_path(@invoice_item.account_id, @invoice_item.invoice_id) end + test 'should expose restful show by number endpoint' do + get :restful_show_by_number, params: { number: @bundle_invoice.invoice_number } + assert_redirected_to account_invoice_path(@bundle_invoice.account_id, @bundle_invoice.invoice_id) + end + test 'should render HTML invoice' do get :show_html, params: { id: @invoice_item.invoice_id } assert_response 200 From e675563bc320513c1e10b9ff22bafbc56ced9511 Mon Sep 17 00:00:00 2001 From: Homayoon Hedayatifard Date: Sun, 30 Jul 2023 01:55:24 +0330 Subject: [PATCH 2/7] Allow searching invoices by number --- app/controllers/kaui/home_controller.rb | 9 ++++++++- app/helpers/kaui/object_helper.rb | 6 ++++++ app/views/kaui/home/_advanced_search_modal.html.erb | 2 +- test/functional/kaui/home_controller_test.rb | 9 +++++++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/app/controllers/kaui/home_controller.rb b/app/controllers/kaui/home_controller.rb index 13499a01..1ed10846 100644 --- a/app/controllers/kaui/home_controller.rb +++ b/app/controllers/kaui/home_controller.rb @@ -61,6 +61,13 @@ def invoice_search(search_query, search_by = nil, fast = 0, options = {}) end elsif search_by == 'EXTERNAL_KEY' unsupported_external_key_search('INVOICE') + elsif search_by == 'NUMBER' + begin + invoice = Kaui::Invoice.find_by_number(search_query, 'NONE', options) + redirect_to account_invoice_path(invoice.account_id, invoice.invoice_id) and return + rescue KillBillClient::API::NotFound, KillBillClient::API::BadRequest => _e + search_error("No invoice matches \"#{search_query}\"") + end else invoice = Kaui::Invoice.list_or_search(search_query, 0, 1, options).first if invoice.blank? @@ -267,7 +274,7 @@ def parse_query(query) '0' end - search_error("\"#{search_by}\" is not a valid search by value") if !search_by.blank? && !%w[ID EXTERNAL_KEY].include?(search_by) + search_error("\"#{search_by}\" is not a valid search by value") if !search_by.blank? && !search_by.in?(Kaui::ObjectHelper::ADVANCED_SEARCH_OBJECT_FIELDS) [object_type, search_for, search_by, fast] end diff --git a/app/helpers/kaui/object_helper.rb b/app/helpers/kaui/object_helper.rb index 21251d5f..0ba68314 100644 --- a/app/helpers/kaui/object_helper.rb +++ b/app/helpers/kaui/object_helper.rb @@ -2,6 +2,8 @@ module Kaui module ObjectHelper + ADVANCED_SEARCH_OBJECT_FIELDS = %w[ID EXTERNAL_KEY NUMBER].freeze + # Because we don't have access to the account_id, we use the restful_show routes def url_for_object(object_id, object_type) case object_type @@ -29,5 +31,9 @@ def object_types def object_types_for_advanced_search %i[ACCOUNT BUNDLE INVOICE CREDIT CUSTOM_FIELD INVOICE_PAYMENT INVOICE PAYMENT SUBSCRIPTION TRANSACTION TAG TAG_DEFINITION] end + + def object_fields_for_advanced_search + [' '] + ADVANCED_SEARCH_OBJECT_FIELDS + end end end diff --git a/app/views/kaui/home/_advanced_search_modal.html.erb b/app/views/kaui/home/_advanced_search_modal.html.erb index eeac60e1..1e96430a 100644 --- a/app/views/kaui/home/_advanced_search_modal.html.erb +++ b/app/views/kaui/home/_advanced_search_modal.html.erb @@ -23,7 +23,7 @@
<%= label_tag :search_by, 'Search by', :class => 'col-sm-4 control-label' %>
- <%= select_tag :search_by, options_for_select(['', 'ID', 'EXTERNAL_KEY'],''), :class => 'form-control' %> + <%= select_tag :search_by, options_for_select(object_fields_for_advanced_search,''), :class => 'form-control' %>
diff --git a/test/functional/kaui/home_controller_test.rb b/test/functional/kaui/home_controller_test.rb index 786278fc..fb8dd585 100644 --- a/test/functional/kaui/home_controller_test.rb +++ b/test/functional/kaui/home_controller_test.rb @@ -66,6 +66,15 @@ class HomeControllerTest < Kaui::FunctionalTestHelper assert_redirected_to home_path assert_equal '"INVOICE": Search by "EXTERNAL KEY" is not supported.', flash[:error] + # search by number + get :search, params: { q: query_builder('INVOICE', @bundle_invoice.invoice_number, 'NUMBER') } + assert_redirected_to account_invoice_path(@bundle_invoice.account_id, @bundle_invoice.invoice_id) + + # search by number and fails + get :search, params: { q: query_builder('INVOICE', '112', 'NUMBER') } + assert_redirected_to home_path + assert_equal 'No invoice matches "112"', flash[:error] + # search by BLANK only first get :search, params: { q: query_builder('INVOICE', @bundle_invoice.invoice_number, nil, '1') } assert_redirected_to account_invoice_path(@bundle_invoice.account_id, @bundle_invoice.invoice_id) From 18ae5e11d5a0dd2a52a24d2cd92f42e3a5581ada Mon Sep 17 00:00:00 2001 From: Homayoon Hedayatifard Date: Sun, 30 Jul 2023 14:13:19 +0330 Subject: [PATCH 3/7] Make #unsupported_external_key_search's message dynamic based on the selected field --- app/controllers/kaui/home_controller.rb | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/controllers/kaui/home_controller.rb b/app/controllers/kaui/home_controller.rb index 1ed10846..82775e87 100644 --- a/app/controllers/kaui/home_controller.rb +++ b/app/controllers/kaui/home_controller.rb @@ -60,7 +60,7 @@ def invoice_search(search_query, search_by = nil, fast = 0, options = {}) search_error("No invoice matches \"#{search_query}\"") end elsif search_by == 'EXTERNAL_KEY' - unsupported_external_key_search('INVOICE') + unsupported_search_field('INVOICE', search_by) elsif search_by == 'NUMBER' begin invoice = Kaui::Invoice.find_by_number(search_query, 'NONE', options) @@ -164,7 +164,7 @@ def credit_search(search_query, search_by = nil, _fast = 0, options = {}) search_error("No credit matches \"#{search_query}\"") end else - unsupported_external_key_search('CREDIT') + unsupported_search_field('CREDIT', search_by) end end @@ -177,7 +177,7 @@ def custom_field_search(search_query, search_by = nil, fast = 0, options = {}) redirect_to custom_fields_path(q: search_query, fast:) end else - unsupported_external_key_search('CUSTOM FIELD') + unsupported_search_field('CUSTOM FIELD', search_by) end end @@ -190,7 +190,7 @@ def invoice_payment_search(search_query, search_by = nil, _fast = 0, options = { search_error("No invoice payment matches \"#{search_query}\"") end else - unsupported_external_key_search('INVOICE PAYMENT') + unsupported_search_field('INVOICE PAYMENT', search_by) end end @@ -203,7 +203,7 @@ def subscription_search(search_query, search_by = nil, _fast = 0, options = {}) search_error("No subscription matches \"#{search_query}\"") end else - unsupported_external_key_search('SUBSCRIPTION') + unsupported_search_field('SUBSCRIPTION', search_by) end end @@ -216,7 +216,7 @@ def tag_search(search_query, search_by = nil, fast = 0, options = {}) redirect_to tags_path(q: search_query, fast:) end else - unsupported_external_key_search('TAG') + unsupported_search_field('TAG', search_by) end end @@ -229,7 +229,7 @@ def tag_definition_search(search_query, search_by = nil, fast = 0, options = {}) search_error("No tag definition matches \"#{search_query}\"") end elsif search_by == 'EXTERNAL_KEY' - unsupported_external_key_search('TAG DEFINITION') + unsupported_search_field('TAG DEFINITION', search_by) else tag_definition = Kaui::TagDefinition.find_by_name(search_query, 'NONE', options) if tag_definition.blank? @@ -245,8 +245,8 @@ def tag_definition_search(search_query, search_by = nil, fast = 0, options = {}) end end - def unsupported_external_key_search(object_type) - search_error("\"#{object_type}\": Search by \"EXTERNAL KEY\" is not supported.") + def unsupported_search_field(object_type, object_field) + search_error("\"#{object_type}\": Search by \"#{object_field}\" is not supported.") end def search_error(message) From 2c1c19dbb00845d225a08384275acd26be77a98c Mon Sep 17 00:00:00 2001 From: Homayoon Hedayatifard Date: Sun, 30 Jul 2023 14:15:56 +0330 Subject: [PATCH 4/7] Make Advanced Search modal's Search By options dynamic based on the object type --- app/helpers/kaui/object_helper.rb | 9 ++++++++ .../kaui/home/_advanced_search_modal.html.erb | 21 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/app/helpers/kaui/object_helper.rb b/app/helpers/kaui/object_helper.rb index 0ba68314..bf70c222 100644 --- a/app/helpers/kaui/object_helper.rb +++ b/app/helpers/kaui/object_helper.rb @@ -3,6 +3,11 @@ module Kaui module ObjectHelper ADVANCED_SEARCH_OBJECT_FIELDS = %w[ID EXTERNAL_KEY NUMBER].freeze + ADVANCED_SEARCH_OBJECT_FIELDS_MAP = { + # ID is supported by all object types, hence not listed. + EXTERNAL_KEY: %w[ACCOUNT PAYMENT TRANSACTION BUNDLE], + NUMBER: %w[INVOICE] + }.freeze # Because we don't have access to the account_id, we use the restful_show routes def url_for_object(object_id, object_type) @@ -35,5 +40,9 @@ def object_types_for_advanced_search def object_fields_for_advanced_search [' '] + ADVANCED_SEARCH_OBJECT_FIELDS end + + def advanced_search_object_fields_map + ADVANCED_SEARCH_OBJECT_FIELDS_MAP + end end end diff --git a/app/views/kaui/home/_advanced_search_modal.html.erb b/app/views/kaui/home/_advanced_search_modal.html.erb index 1e96430a..bd6df877 100644 --- a/app/views/kaui/home/_advanced_search_modal.html.erb +++ b/app/views/kaui/home/_advanced_search_modal.html.erb @@ -68,13 +68,34 @@ $('#advancedQuery').val(query); } + const searchByFieldsMap = <%= advanced_search_object_fields_map.to_json.html_safe %>; + function refresh_search_by() { + var objectType = $('#object_type').val(); + + // Clears the selected field if it's not supported by the selected object type + var searchBy = $('#search_by').val(); + if (searchByFieldsMap[searchBy] && !searchByFieldsMap[searchBy].includes(objectType)) { + $('#search_by').val(' '); + refresh_query(); + } + + // Updates search options to only show fields supported by the selected object type + for (field in searchByFieldsMap) { + var isSupported = searchByFieldsMap[field].includes(objectType); + var fieldOption = $(`#search_by > option[value=${field}]`); + isSupported ? fieldOption.show() : fieldOption.hide(); + } + } + $('#search_for').keyup(function(){ refresh_query(); }); $('#search_for').change(function(){ refresh_query(); }); $('#object_type').change(function(){ refresh_query(); }); + $('#object_type').change(function(){ refresh_search_by(); }); $('#search_by').change(function(){ refresh_query(); }); $('#fast').change(function(){ refresh_query(); }); refresh_query(); + refresh_search_by(); }); <% end %> \ No newline at end of file From b51e278ae86c6ca97a96d4aaf25e553c12314385 Mon Sep 17 00:00:00 2001 From: Homayoon Hedayatifard Date: Sun, 30 Jul 2023 15:57:37 +0330 Subject: [PATCH 5/7] Remove an extra INVOICE item in Advanced Search object types --- app/helpers/kaui/object_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/kaui/object_helper.rb b/app/helpers/kaui/object_helper.rb index bf70c222..8e89e4cb 100644 --- a/app/helpers/kaui/object_helper.rb +++ b/app/helpers/kaui/object_helper.rb @@ -34,7 +34,7 @@ def object_types end def object_types_for_advanced_search - %i[ACCOUNT BUNDLE INVOICE CREDIT CUSTOM_FIELD INVOICE_PAYMENT INVOICE PAYMENT SUBSCRIPTION TRANSACTION TAG TAG_DEFINITION] + %i[ACCOUNT BUNDLE INVOICE CREDIT CUSTOM_FIELD INVOICE_PAYMENT PAYMENT SUBSCRIPTION TRANSACTION TAG TAG_DEFINITION] end def object_fields_for_advanced_search From 57d0af9b4106ca4eda16a2580981c42b5137f96a Mon Sep 17 00:00:00 2001 From: Homayoon Hedayatifard Date: Mon, 31 Jul 2023 12:22:58 +0330 Subject: [PATCH 6/7] Fix failing tests --- app/controllers/kaui/home_controller.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/kaui/home_controller.rb b/app/controllers/kaui/home_controller.rb index 82775e87..4ee7f478 100644 --- a/app/controllers/kaui/home_controller.rb +++ b/app/controllers/kaui/home_controller.rb @@ -246,7 +246,8 @@ def tag_definition_search(search_query, search_by = nil, fast = 0, options = {}) end def unsupported_search_field(object_type, object_field) - search_error("\"#{object_type}\": Search by \"#{object_field}\" is not supported.") + field_name = object_field.gsub('_', ' ') + search_error("\"#{object_type}\": Search by \"#{field_name}\" is not supported.") end def search_error(message) From 1ca7f75d863949b24604c6ff2c8b11199379cae3 Mon Sep 17 00:00:00 2001 From: Homayoon Hedayatifard Date: Mon, 31 Jul 2023 12:23:27 +0330 Subject: [PATCH 7/7] Fix Rubocop violations --- app/controllers/kaui/home_controller.rb | 7 ++++--- lib/kaui.rb | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/controllers/kaui/home_controller.rb b/app/controllers/kaui/home_controller.rb index 4ee7f478..483709f2 100644 --- a/app/controllers/kaui/home_controller.rb +++ b/app/controllers/kaui/home_controller.rb @@ -52,16 +52,17 @@ def account_search(search_query, search_by = nil, fast = 0, options = {}) end def invoice_search(search_query, search_by = nil, fast = 0, options = {}) - if search_by == 'ID' + case search_by + when 'ID' begin invoice = Kaui::Invoice.find_by_id(search_query, 'NONE', options) redirect_to account_invoice_path(invoice.account_id, invoice.invoice_id) and return rescue KillBillClient::API::NotFound => _e search_error("No invoice matches \"#{search_query}\"") end - elsif search_by == 'EXTERNAL_KEY' + when 'EXTERNAL_KEY' unsupported_search_field('INVOICE', search_by) - elsif search_by == 'NUMBER' + when 'NUMBER' begin invoice = Kaui::Invoice.find_by_number(search_query, 'NONE', options) redirect_to account_invoice_path(invoice.account_id, invoice.invoice_id) and return diff --git a/lib/kaui.rb b/lib/kaui.rb index a76c771a..0f5e2f27 100644 --- a/lib/kaui.rb +++ b/lib/kaui.rb @@ -206,9 +206,11 @@ def self.config # ruby-1.8 compatibility module Kernel + # rubocop:disable Style/ArgumentsForwarding def define_singleton_method(*args, &) class << self self end.send(:define_method, *args, &) end + # rubocop:enable Style/ArgumentsForwarding end