kaui 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +5 -29
  3. data/app/assets/javascripts/kaui/kaui.js +1 -1
  4. data/app/assets/stylesheets/kaui/account.less +9 -1
  5. data/app/assets/stylesheets/kaui/common.less +46 -3
  6. data/app/controllers/kaui/accounts_controller.rb +11 -15
  7. data/app/controllers/kaui/admin_tenants_controller.rb +77 -106
  8. data/app/controllers/kaui/audit_logs_controller.rb +3 -3
  9. data/app/controllers/kaui/bundles_controller.rb +4 -0
  10. data/app/controllers/kaui/engine_controller_util.rb +25 -17
  11. data/app/controllers/kaui/invoice_tags_controller.rb +28 -0
  12. data/app/controllers/kaui/invoices_controller.rb +65 -14
  13. data/app/controllers/kaui/payment_methods_controller.rb +14 -3
  14. data/app/controllers/kaui/sessions_controller.rb +6 -0
  15. data/app/controllers/kaui/subscriptions_controller.rb +13 -4
  16. data/app/helpers/kaui/account_helper.rb +10 -2
  17. data/app/helpers/kaui/payment_method_helper.rb +5 -3
  18. data/app/helpers/kaui/plugin_helper.rb +10 -49
  19. data/app/helpers/kaui/subscription_helper.rb +26 -9
  20. data/app/helpers/kaui/uuid_helper.rb +1 -0
  21. data/app/models/kaui/admin_tenant.rb +8 -84
  22. data/app/models/kaui/catalog.rb +28 -2
  23. data/app/models/kaui/tag.rb +1 -1
  24. data/app/views/kaui/account_emails/_form.html.erb +1 -1
  25. data/app/views/kaui/accounts/_billing_info.html.erb +4 -0
  26. data/app/views/kaui/accounts/_form.html.erb +1 -1
  27. data/app/views/kaui/accounts/_payment_methods.html.erb +3 -0
  28. data/app/views/kaui/accounts/index.html.erb +7 -4
  29. data/app/views/kaui/admin_tenants/_form_plugin_config.erb +59 -241
  30. data/app/views/kaui/admin_tenants/_show_catalog_simple.erb +2 -2
  31. data/app/views/kaui/admin_tenants/new_catalog.html.erb +16 -15
  32. data/app/views/kaui/bundles/_bundle_details.html.erb +12 -0
  33. data/app/views/kaui/bundles/index.html.erb +3 -14
  34. data/app/views/kaui/chargebacks/_form.html.erb +1 -1
  35. data/app/views/kaui/charges/_form.html.erb +1 -1
  36. data/app/views/kaui/invoice_tags/_form.html.erb +33 -0
  37. data/app/views/kaui/invoice_tags/_form_bar.html.erb +21 -0
  38. data/app/views/kaui/invoice_tags/edit.html.erb +10 -0
  39. data/app/views/kaui/invoices/_invoice_table.html.erb +30 -9
  40. data/app/views/kaui/invoices/index.html.erb +6 -4
  41. data/app/views/kaui/invoices/show.html.erb +11 -2
  42. data/app/views/kaui/layouts/kaui_flash.html.erb +8 -1
  43. data/app/views/kaui/payments/_form.html.erb +1 -1
  44. data/app/views/kaui/payments/_payment_table.html.erb +2 -2
  45. data/app/views/kaui/payments/index.html.erb +3 -1
  46. data/app/views/kaui/subscriptions/_edit_form.html.erb +1 -1
  47. data/app/views/kaui/subscriptions/_form.html.erb +1 -1
  48. data/app/views/kaui/subscriptions/_subscriptions_table.html.erb +3 -3
  49. data/config/routes.rb +6 -1
  50. data/lib/kaui.rb +55 -0
  51. data/lib/kaui/version.rb +1 -1
  52. data/test/dummy/config/database.yml +2 -2
  53. data/test/dummy/config/initializers/cookies_serializer.rb +1 -1
  54. data/test/dummy/config/initializers/money.rb +2 -0
  55. data/test/functional/kaui/account_emails_controller_test.rb +2 -2
  56. data/test/functional/kaui/account_tags_controller_test.rb +1 -1
  57. data/test/functional/kaui/accounts_controller_test.rb +4 -4
  58. data/test/functional/kaui/admin_tenants_controller_test.rb +3 -23
  59. data/test/functional/kaui/bundle_tags_controller_test.rb +1 -1
  60. data/test/functional/kaui/bundles_controller_test.rb +3 -3
  61. data/test/functional/kaui/chargebacks_controller_test.rb +2 -2
  62. data/test/functional/kaui/charges_controller_test.rb +2 -2
  63. data/test/functional/kaui/credits_controller_test.rb +5 -5
  64. data/test/functional/kaui/home_controller_test.rb +5 -5
  65. data/test/functional/kaui/invoice_items_controller_test.rb +3 -3
  66. data/test/functional/kaui/invoices_controller_test.rb +2 -2
  67. data/test/functional/kaui/refunds_controller_test.rb +2 -2
  68. data/test/functional/kaui/subscriptions_controller_test.rb +6 -6
  69. data/test/killbill_test_helper.rb +8 -6
  70. data/test/unit/helpers/kaui/payment_method_helper_test.rb +17 -0
  71. data/test/unit/kaui/account_test.rb +2 -2
  72. data/test/unit/kaui/admin_tenant_test.rb +10 -47
  73. data/test/unit/kaui/invoice_item_test.rb +1 -1
  74. data/test/unit/kaui/invoice_payment_test.rb +7 -7
  75. data/test/unit/kaui/invoice_test.rb +4 -4
  76. data/test/unit/kaui/payment_test.rb +7 -7
  77. metadata +110 -86
@@ -65,7 +65,7 @@ class Kaui::AuditLogsController < Kaui::EngineController
65
65
  elsif object_type == 'CUSTOM_FIELD'
66
66
  audit_logs_with_history = Kaui::CustomField.new({:custom_field_id => object_id}).audit_logs_with_history(cached_options_for_klient)
67
67
  elsif object_type == 'INVOICE'
68
- invoice = Kaui::Invoice::find_by_id(object_id, false, "NONE", cached_options_for_klient)
68
+ invoice = Kaui::Invoice::find_by_id(object_id, "NONE", cached_options_for_klient)
69
69
  audit_logs_with_history = invoice.audit_logs_with_history(cached_options_for_klient)
70
70
  elsif object_type == 'INVOICE_ITEM'
71
71
  invoice_item = Kaui::InvoiceItem.new
@@ -74,8 +74,8 @@ class Kaui::AuditLogsController < Kaui::EngineController
74
74
  =begin See https://github.com/killbill/killbill/issues/1104
75
75
  elsif object_type == 'INVOICE_PAYMENT'
76
76
  invoice_payment = Kaui::InvoicePayment::find_by_id(object_id, false, false, cached_options_for_klient)
77
- =end
78
77
  audit_logs_with_history = invoice_payment.audit_logs_with_history(cached_options_for_klient)
78
+ =end
79
79
  elsif object_type == 'PAYMENT_ATTEMPT'
80
80
  audit_logs_with_history = Kaui::Payment::attempt_audit_logs_with_history(object_id, cached_options_for_klient)
81
81
  elsif object_type == 'PAYMENT'
@@ -113,4 +113,4 @@ class Kaui::AuditLogsController < Kaui::EngineController
113
113
  OBJECT_WITH_HISTORY.include?(object_type)
114
114
  end
115
115
 
116
- end
116
+ end
@@ -31,6 +31,10 @@ class Kaui::BundlesController < Kaui::EngineController
31
31
  @available_tags = wait(fetch_available_tags)
32
32
  @available_subscription_tags = wait(fetch_available_subscription_tags)
33
33
 
34
+ # TODO This doesn't take into account catalog versions
35
+ catalogs = Kaui::Catalog.get_account_catalog_json(@account.account_id, nil, cached_options_for_klient) || []
36
+ @catalog = catalogs[-1]
37
+
34
38
  @subscription = {}
35
39
  @bundles.each do |bundle|
36
40
  bundle.subscriptions.each do |sub|
@@ -41,7 +41,7 @@ module Kaui::EngineControllerUtil
41
41
  b = data_extractor.call(b, ordering_column)
42
42
  sort = a <=> b
43
43
  sort.nil? ? -1 : sort
44
- end unless search_key.nil? # Keep DB ordering when listing all entries
44
+ end unless search_key.nil? # Keep DB ordering when listing all entries (note! make sure to set "ordering": false in DataTables config as the client-side sort behavior can be confusing)
45
45
  pages.reverse! if ordering_dir == 'desc' && limit >= 0 || ordering_dir == 'asc' && limit < 0
46
46
 
47
47
  pages.each { |page| json[:data] << formatter.call(page) }
@@ -51,24 +51,29 @@ module Kaui::EngineControllerUtil
51
51
  end
52
52
  end
53
53
 
54
- def promise(execute = true, &block)
55
- promise = Concurrent::Promise.new({:executor => Kaui.thread_pool}, &block)
56
- promise.execute if execute
57
- promise
54
+ def promise
55
+ # Evaluation starts immediately
56
+ ::Concurrent::Promises.future do
57
+ # https://github.com/rails/rails/issues/26847
58
+ Rails.application.executor.wrap do
59
+ yield
60
+ end
61
+ end
58
62
  end
59
63
 
60
64
  def wait(promise)
61
- # If already executed, no-op
62
- promise.execute
63
-
64
- # Make sure to set a timeout to avoid infinite wait
65
- value = promise.value!(60)
66
- raise promise.reason unless promise.reason.nil?
67
- if value.nil? && promise.state != :fulfilled
68
- Rails.logger.warn("Unable to run promise #{promise_as_string(promise)}")
69
- raise Timeout::Error
65
+ # https://github.com/rails/rails/issues/26847
66
+ ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
67
+ # Make sure to set a timeout to avoid infinite wait
68
+ value = promise.value!(60)
69
+ raise promise.reason unless promise.reason.nil?
70
+ if value.nil? && promise.state != :fulfilled
71
+ # Could be https://github.com/ruby-concurrency/concurrent-ruby/issues/585
72
+ Rails.logger.warn("Unable to run promise #{promise_as_string(promise)}")
73
+ raise Timeout::Error
74
+ end
75
+ value
70
76
  end
71
- value
72
77
  end
73
78
 
74
79
  def promise_as_string(promise)
@@ -81,7 +86,9 @@ module Kaui::EngineControllerUtil
81
86
  # Used to format flash error messages
82
87
  def as_string(e)
83
88
  if e.is_a?(KillBillClient::API::ResponseError)
84
- "Error #{e.response.code}: #{as_string_from_response(e.response.body)}"
89
+ as_string_from_response(e.response.body)
90
+ elsif e.respond_to?(:cause) && !e.cause.nil?
91
+ as_string(e.cause)
85
92
  else
86
93
  log_rescue_error(e)
87
94
  e.message
@@ -103,6 +110,7 @@ module Kaui::EngineControllerUtil
103
110
  if error_message.respond_to? :[] and error_message['message'].present?
104
111
  # Likely BillingExceptionJson
105
112
  error_message = error_message['message']
113
+ error_message += " (code=#{error_message['code']})" unless error_message['code'].blank?
106
114
  end
107
115
  # Limit the error size to avoid ActionDispatch::Cookies::CookieOverflow
108
116
  error_message[0..1000]
@@ -125,7 +133,7 @@ module Kaui::EngineControllerUtil
125
133
  response = yield
126
134
  response_status = 200
127
135
  rescue KillBillClient::API::ResponseError => e
128
- response = e.response.message
136
+ response = as_string_from_response(e.response.body)
129
137
  response_status = e.code
130
138
  rescue Exception => e
131
139
  response = e.message
@@ -0,0 +1,28 @@
1
+ class Kaui::InvoiceTagsController < Kaui::EngineController
2
+
3
+ def edit
4
+ @invoice_id = params.require(:invoice_id)
5
+
6
+ cached_options_for_klient = options_for_klient
7
+ fetch_tag_names = promise { (Kaui::Tag.all_for_invoice(@invoice_id, false, 'NONE', cached_options_for_klient).map { |tag| tag.tag_definition_name }).sort }
8
+ fetch_available_tags = promise { Kaui::TagDefinition.all_for_invoice(cached_options_for_klient) }
9
+
10
+ @tag_names = wait(fetch_tag_names)
11
+ @available_tags = wait(fetch_available_tags)
12
+ end
13
+
14
+ def update
15
+ account_id = params.require(:account_id)
16
+ invoice_id = params.require(:invoice_id)
17
+
18
+ tags = []
19
+ params.each do |tag, tag_name|
20
+ tag_info = tag.split('_')
21
+ next if tag_info.size != 2 or tag_info[0] != 'tag'
22
+ tags << tag_info[1]
23
+ end
24
+
25
+ Kaui::Tag.set_for_invoice(invoice_id, tags, current_user.kb_username, params[:reason], params[:comment], options_for_klient)
26
+ redirect_to kaui_engine.invoice_path(invoice_id, :account_id => account_id), :notice => 'Invoice tags successfully set'
27
+ end
28
+ end
@@ -18,26 +18,39 @@ class Kaui::InvoicesController < Kaui::EngineController
18
18
  if account.nil?
19
19
  Kaui::Invoice.list_or_search(search_key, offset, limit, cached_options_for_klient)
20
20
  else
21
- account.invoices(cached_options_for_klient).map! { |invoice| Kaui::Invoice.build_from_raw_invoice(invoice) }
21
+ account.invoices(cached_options_for_klient.merge({ :params => { :includeVoidedInvoices => true } })).map! { |invoice| Kaui::Invoice.build_from_raw_invoice(invoice) }
22
22
  end
23
23
  end
24
24
 
25
- data_extractor = lambda do |invoice, column|
26
- [
25
+ account_id = (params[:search] || {})[:value]
26
+ if account_id.blank?
27
+ # Don't show amount and balance, and they will not be populated
28
+ data_extractor = lambda do |invoice, column|
29
+ [
30
+ invoice.invoice_number.to_i,
31
+ invoice.invoice_date
32
+ ][column]
33
+ end
34
+ formatter = lambda do |invoice|
35
+ row = [view_context.link_to(invoice.invoice_number, view_context.url_for(:controller => :invoices, :action => :show, :account_id => invoice.account_id, :id => invoice.invoice_id))]
36
+ row += Kaui.invoice_search_columns.call(invoice, view_context)[1]
37
+ row
38
+ end
39
+ else
40
+ data_extractor = lambda do |invoice, column|
41
+ [
27
42
  invoice.invoice_number.to_i,
28
43
  invoice.invoice_date,
29
44
  invoice.amount,
30
- invoice.balance
31
- ][column]
32
- end
33
-
34
- formatter = lambda do |invoice|
35
- [
36
- view_context.link_to(invoice.invoice_number, view_context.url_for(:controller => :invoices, :action => :show, :account_id => invoice.account_id, :id => invoice.invoice_id)),
37
- invoice.invoice_date,
38
- view_context.humanized_money_with_symbol(invoice.amount_to_money),
39
- view_context.humanized_money_with_symbol(invoice.balance_to_money)
40
- ]
45
+ invoice.balance,
46
+ invoice.status
47
+ ][column]
48
+ end
49
+ formatter = lambda do |invoice|
50
+ row = [view_context.link_to(invoice.invoice_number, view_context.url_for(:controller => :invoices, :action => :show, :account_id => invoice.account_id, :id => invoice.invoice_id))]
51
+ row += Kaui.account_invoices_columns.call(invoice, view_context)[1]
52
+ row
53
+ end
41
54
  end
42
55
 
43
56
  paginate searcher, data_extractor, formatter
@@ -48,6 +61,26 @@ class Kaui::InvoicesController < Kaui::EngineController
48
61
  cached_options_for_klient = options_for_klient
49
62
 
50
63
  @invoice = Kaui::Invoice.find_by_id(params.require(:id), 'FULL', cached_options_for_klient)
64
+ # This will put the TAX items at the bottom
65
+ precedence = {
66
+ 'EXTERNAL_CHARGE' => 0,
67
+ 'FIXED' => 1,
68
+ 'RECURRING' => 2,
69
+ 'REPAIR_ADJ' => 3,
70
+ 'USAGE' => 4,
71
+ 'PARENT_SUMMARY' => 5,
72
+ 'ITEM_ADJ' => 6,
73
+ 'CBA_ADJ' => 7,
74
+ 'CREDIT_ADJ' => 8,
75
+ 'TAX' => 9
76
+ }
77
+ # TODO The pretty description has to be shared with the view
78
+ @invoice.items.sort_by! do |ii|
79
+ # Make sure not to compare nil (ArgumentError comparison of Array with Array failed)
80
+ a = precedence[ii.item_type] || 100
81
+ b = (ii.pretty_plan_name.blank? || !ii.item_type.in?(%w{USAGE RECURRING}) ? ii.description : ii.pretty_plan_name) || ''
82
+ [a, b]
83
+ end
51
84
 
52
85
  fetch_payments = promise { @invoice.payments(true, true, 'FULL', cached_options_for_klient).map { |payment| Kaui::InvoicePayment.build_from_raw_payment(payment) } }
53
86
  fetch_pms = fetch_payments.then { |payments| Kaui::PaymentMethod.payment_methods_for_payments(payments, cached_options_for_klient) }
@@ -68,6 +101,9 @@ class Kaui::InvoicesController < Kaui::EngineController
68
101
  custom_fields_per_invoice_item.inject({}) { |hsh, entry| (hsh[entry.object_id] ||= []) << entry; hsh }
69
102
  }
70
103
 
104
+ fetch_invoice_tags = promise { @invoice.tags(false, 'NONE', cached_options_for_klient).sort { |tag_a, tag_b| tag_a <=> tag_b } }
105
+ fetch_available_invoice_tags = promise { Kaui::TagDefinition.all_for_invoice(cached_options_for_klient) }
106
+
71
107
  @payments = wait(fetch_payments)
72
108
  @payment_methods = wait(fetch_pms)
73
109
  @custom_fields = wait(fetch_invoice_fields)
@@ -75,6 +111,21 @@ class Kaui::InvoicesController < Kaui::EngineController
75
111
  @custom_fields_per_invoice_item = wait(fetch_custom_fields_per_invoice_item)
76
112
  @tags_per_invoice_item = wait(fetch_tags_per_invoice_item)
77
113
  @available_invoice_item_tags = wait(fetch_available_invoice_item_tags)
114
+ @invoice_tags = wait(fetch_invoice_tags)
115
+ @available_invoice_tags = wait(fetch_available_invoice_tags)
116
+ @available_invoice_tags.reject! { |td| td.name == 'WRITTEN_OFF' } if @invoice.status == 'VOID'
117
+ end
118
+
119
+ def void_invoice
120
+ cached_options_for_klient = options_for_klient
121
+ invoice = KillBillClient::Model::Invoice.find_by_id(params.require(:id), 'NONE', cached_options_for_klient)
122
+ begin
123
+ invoice.void(current_user.kb_username, params[:reason], params[:comment], cached_options_for_klient)
124
+ redirect_to account_invoice_path(invoice.account_id, invoice.invoice_id), :notice => 'Invoice successfully voided'
125
+ rescue => e
126
+ flash[:error] = "Unable to void invoice: #{as_string(e)}"
127
+ redirect_to account_invoice_path(invoice.account_id, invoice.invoice_id)
128
+ end
78
129
  end
79
130
 
80
131
  def restful_show
@@ -45,9 +45,15 @@ class Kaui::PaymentMethodsController < Kaui::EngineController
45
45
  }
46
46
 
47
47
  @plugin_properties = params[:plugin_properties].values.select{ |item| !(item['value'].blank? || item['key'].blank?) } rescue @plugin_properties = nil
48
- @plugin_properties.map! do |property|
49
- KillBillClient::Model::PluginPropertyAttributes.new(property)
50
- end unless @plugin_properties.blank?
48
+ if @plugin_properties.blank?
49
+ # In case of error, we want the view to receive nil, not [], so that at least the first row is populated (required to make the JS work)
50
+ # See https://github.com/killbill/killbill-admin-ui/issues/258
51
+ @plugin_properties = nil
52
+ else
53
+ @plugin_properties.map! do |property|
54
+ KillBillClient::Model::PluginPropertyAttributes.new(property)
55
+ end
56
+ end
51
57
 
52
58
  begin
53
59
  @payment_method = @payment_method.create(@payment_method.is_default, current_user.kb_username, params[:reason], params[:comment],
@@ -95,6 +101,11 @@ class Kaui::PaymentMethodsController < Kaui::EngineController
95
101
  end
96
102
  end
97
103
 
104
+ def refresh
105
+ Kaui::PaymentMethod.refresh(params.require(:account_id), current_user.kb_username, params[:reason], params[:comment], options_for_klient)
106
+ redirect_to kaui_engine.account_path(params.require(:account_id)), :notice => 'Payment methods successfully refreshed'
107
+ end
108
+
98
109
  private
99
110
 
100
111
  def find_value_from_properties(properties, key)
@@ -18,5 +18,11 @@ module Kaui
18
18
  def after_sign_out_path_for(resource)
19
19
  kaui_path
20
20
  end
21
+
22
+ def require_no_authentication
23
+ super
24
+ # Remove the somewhat confusing message "You are already signed in."
25
+ flash.discard(:alert) if flash[:alert] == I18n.t("devise.failure.already_authenticated")
26
+ end
21
27
  end
22
28
  end
@@ -11,9 +11,9 @@ class Kaui::SubscriptionsController < Kaui::EngineController
11
11
 
12
12
  if @plans.empty?
13
13
  if @subscription.product_category == 'BASE'
14
- flash[:error] = 'No available plan'
14
+ flash[:error] = 'No plan available in the catalog'
15
15
  else
16
- flash[:error] = "No available add-on for product #{@base_product_name}"
16
+ flash[:error] = "No add-on available in the catalog for product #{@base_product_name}"
17
17
  end
18
18
  redirect_to kaui_engine.account_bundles_path(@subscription.account_id), :error => 'No available plan'
19
19
  end
@@ -46,6 +46,16 @@ class Kaui::SubscriptionsController < Kaui::EngineController
46
46
  redirect_to kaui_engine.account_bundles_path(@subscription.account_id), :notice => 'Subscription was successfully created'
47
47
  rescue => e
48
48
  @plans = plans_details.nil? ? [] : plans_details.map { |p| p.plan }
49
+
50
+ if e.is_a?(::KillBillClient::API::BadRequest) && !e.response.nil? && !e.response.body.nil?
51
+ error_message = JSON.parse(e.response.body) rescue nil
52
+ if !error_message.nil? & !error_message['code'].nil? && error_message['code'] == 2010 # CAT_NO_PRICE_FOR_CURRENCY
53
+ # Hack for lack of proper Kill Bill messaging (https://github.com/killbill/killbill-admin-ui/issues/266)
54
+ flash.now[:error] = "Unable to create the subscription: a price for this currency hasn't been specified in the catalog"
55
+ render :new and return
56
+ end
57
+ end
58
+
49
59
  flash.now[:error] = "Error while creating the subscription: #{as_string(e)}"
50
60
  render :new
51
61
  end
@@ -212,8 +222,7 @@ class Kaui::SubscriptionsController < Kaui::EngineController
212
222
  else
213
223
  options = options_for_klient
214
224
 
215
- catalog = Kaui::Catalog.get_tenant_catalog_json( DateTime.now.to_s, options)
216
-
225
+ catalog = Kaui::Catalog.get_tenant_catalog_json(DateTime.now.to_s, options)
217
226
  return [] if catalog.blank?
218
227
 
219
228
  plans = []
@@ -3,7 +3,7 @@ module Kaui
3
3
 
4
4
  def pretty_account_identifier
5
5
  return nil if @account.nil?
6
- @account.name.presence || @account.email.presence || truncate_uuid(@account.external_key)
6
+ Kaui.pretty_account_identifier.call(@account)
7
7
  end
8
8
 
9
9
  def email_notifications_plugin_available?
@@ -12,9 +12,17 @@ module Kaui
12
12
  return false
13
13
  end
14
14
 
15
+ def deposit_plugin_available?
16
+ Killbill::Deposit::DepositClient.deposit_plugin_available?(Kaui.current_tenant_user_options(current_user, session)).first
17
+ rescue
18
+ return false
19
+ end
20
+
15
21
  def account_closed?
16
22
  return false if @account.nil?
17
- blocking_states = @account.blocking_states('ACCOUNT','account-service','NONE', Kaui.current_tenant_user_options(current_user, session))
23
+ # Note: we ignore errors here, so that the call doesn't prevent the screen to load. While the error isn't surfaced, if there is an error with the catalog for instance,
24
+ # the AJAX call to compute the next invoice date should hopefully trigger a flash error.
25
+ blocking_states = @account.blocking_states('ACCOUNT', 'account-service', 'NONE', Kaui.current_tenant_user_options(current_user, session)) rescue []
18
26
 
19
27
  is_account_closed = false
20
28
  blocking_states.each do |blocking_state|
@@ -1,9 +1,11 @@
1
1
  module Kaui
2
2
  module PaymentMethodHelper
3
3
 
4
- def is_json?(string)
5
- !string.blank? && !!JSON.parse(string) rescue false
4
+ def is_json?(value)
5
+ result = JSON.parse(value)
6
+ result.is_a?(Hash) || result.is_a?(Array)
7
+ rescue JSON::ParserError, TypeError
8
+ false
6
9
  end
7
-
8
10
  end
9
11
  end
@@ -1,59 +1,30 @@
1
1
  module Kaui
2
2
  module PluginHelper
3
- # including plugin that are installed
4
- def plugin_repository
5
- plugins = []
6
- plugin_repository = Kaui::AdminTenant.get_plugin_repository
7
- plugin_repository.each_pair do |key, info|
8
- plugins << {
9
- plugin_key: plugin_key(key.to_s, info),
10
- plugin_name: plugin_name(key.to_s, info),
11
- plugin_type: info[:type],
12
- installed: false
13
- }
14
- end
15
-
16
- installed_plugins = installed_plugins(plugins)
17
-
18
- plugins.sort! { |a, b| a[:plugin_key] <=> b[:plugin_key] }
19
- plugins.each { |plugin| installed_plugins << plugin }
20
3
 
4
+ def plugin_repository
21
5
  installed_plugins
22
6
  end
23
7
 
24
8
  private
25
9
 
26
- def plugin_name(key, info)
27
- if info[:artifact_id].nil?
28
- "killbill-#{key}"
29
- else
30
- "killbill-#{info[:artifact_id].gsub('killbill-','').gsub('-plugin','')}"
31
- end
32
- end
33
-
34
- def plugin_key(key, info)
35
- # hack:: replace paypal key with paypal_express, to set configuration and allow the ui to find the right configuration inputs
36
- if key.eql?('paypal')
37
- 'paypal_express'
38
- else
39
- "#{key}"
40
- end
41
- end
42
-
43
- def installed_plugins(plugins)
10
+ def installed_plugins
44
11
  installed_plugins = []
45
12
  nodes_info = KillBillClient::Model::NodesInfo.nodes_info(Kaui.current_tenant_user_options(current_user, session)) || []
46
- plugins_info = nodes_info.first.plugins_info || []
13
+ plugins_info = nodes_info.empty? ? [] : (nodes_info.first.plugins_info || [])
47
14
 
48
15
  plugins_info.each do |plugin|
49
16
  next if plugin.version.nil?
50
17
  # do not allow duplicate
51
18
  next if installed_plugins.any? { |p| p[:plugin_name].eql?(plugin.plugin_name) }
52
- plugin_key = Kaui::AdminTenant.rewrite_plugin_key(plugin.plugin_key) unless plugin.plugin_key.nil?
19
+ plugin_key = plugin.plugin_key
53
20
  installed_plugins << {
21
+ # Unique identifier chosen by the user and used for kpm operations
54
22
  plugin_key: plugin_key,
55
- plugin_name: plugin.plugin_name,
56
- plugin_type: find_plugin_type(plugins, plugin_key),
23
+ # Notes:
24
+ # * plugin.plugin_name comes from kpm and is arbitrary (see Utils.get_plugin_name_from_file_path in the kpm codebase for instance)
25
+ # * plugin_name here is the plugin name as seen by Kill Bill and is typically defined in the Activator.java (this value is the one that matters for plugin configuration)
26
+ # * The mapping here is a convention we've used over the years and is no way enforced anywhere - it likely won't work for proprietary plugins (the user would need to specify it by toggling the input on the UI)
27
+ plugin_name: "killbill-#{plugin_key}",
57
28
  installed: true
58
29
  }
59
30
  end
@@ -61,15 +32,5 @@ module Kaui
61
32
  # to_s to handle nil
62
33
  installed_plugins.sort! { |a,b| a[:plugin_key].to_s <=> b[:plugin_key].to_s }
63
34
  end
64
-
65
- def find_plugin_type(plugins, plugin_key_to_search)
66
- plugins.each do |plugin|
67
- if plugin[:plugin_key] == plugin_key_to_search
68
- return plugin[:plugin_type]
69
- end
70
- end
71
-
72
- return nil
73
- end
74
35
  end
75
36
  end