kaui 4.0.11 → 4.0.13
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.
- checksums.yaml +4 -4
- data/app/assets/javascripts/kaui/kaui_override.js +21 -0
- data/app/assets/stylesheets/kaui/subscription.css +75 -0
- data/app/assets/stylesheets/kaui/tags.css +6 -3
- data/app/controllers/kaui/account_timelines_controller.rb +3 -3
- data/app/controllers/kaui/accounts_controller.rb +52 -52
- data/app/controllers/kaui/admin_allowed_users_controller.rb +29 -29
- data/app/controllers/kaui/admin_controller.rb +2 -2
- data/app/controllers/kaui/admin_tenants_controller.rb +89 -81
- data/app/controllers/kaui/audit_logs_controller.rb +1 -1
- data/app/controllers/kaui/bundles_controller.rb +53 -5
- data/app/controllers/kaui/chargebacks_controller.rb +1 -1
- data/app/controllers/kaui/charges_controller.rb +5 -2
- data/app/controllers/kaui/credits_controller.rb +1 -1
- data/app/controllers/kaui/custom_fields_controller.rb +11 -11
- data/app/controllers/kaui/engine_controller_util.rb +5 -5
- data/app/controllers/kaui/home_controller.rb +6 -2
- data/app/controllers/kaui/invoices_controller.rb +6 -4
- data/app/controllers/kaui/payment_methods_controller.rb +5 -5
- data/app/controllers/kaui/payments_controller.rb +19 -19
- data/app/controllers/kaui/queues_controller.rb +6 -6
- data/app/controllers/kaui/registrations_controller.rb +1 -1
- data/app/controllers/kaui/role_definitions_controller.rb +2 -2
- data/app/controllers/kaui/sessions_controller.rb +1 -1
- data/app/controllers/kaui/subscriptions_controller.rb +15 -14
- data/app/controllers/kaui/tag_definitions_controller.rb +1 -1
- data/app/controllers/kaui/tenants_controller.rb +2 -2
- data/app/controllers/kaui/transactions_controller.rb +6 -6
- data/app/helpers/kaui/account_helper.rb +9 -7
- data/app/helpers/kaui/exception_helper.rb +7 -5
- data/app/helpers/kaui/payment_helper.rb +2 -9
- data/app/helpers/kaui/plugin_helper.rb +3 -5
- data/app/helpers/kaui/subscription_helper.rb +46 -30
- data/app/helpers/kaui/uuid_helper.rb +1 -1
- data/app/models/kaui/account.rb +4 -3
- data/app/models/kaui/admin_tenant.rb +2 -2
- data/app/models/kaui/allowed_user.rb +3 -1
- data/app/models/kaui/allowed_user_tenant.rb +2 -2
- data/app/models/kaui/audit_log.rb +1 -1
- data/app/models/kaui/bundle.rb +11 -5
- data/app/models/kaui/invoice.rb +1 -1
- data/app/models/kaui/invoice_payment.rb +2 -2
- data/app/models/kaui/killbill_authenticatable.rb +2 -39
- data/app/models/kaui/killbill_registerable.rb +3 -11
- data/app/models/kaui/overdue.rb +5 -2
- data/app/models/kaui/payment.rb +1 -1
- data/app/models/kaui/payment_state.rb +3 -1
- data/app/models/kaui/rails_methods.rb +2 -2
- data/app/models/kaui/tag_definition.rb +2 -2
- data/app/models/kaui/tenant.rb +2 -1
- data/app/models/kaui/transaction.rb +1 -1
- data/app/services/dependencies/kenui.rb +1 -1
- data/app/views/kaui/accounts/_account_details.html.erb +1 -1
- data/app/views/kaui/admin_tenants/new_overdue_config.html.erb +25 -1
- data/app/views/kaui/bundles/_bundle_filterbar.html.erb +119 -0
- data/app/views/kaui/bundles/index.html.erb +28 -3
- data/app/views/kaui/components/search_input/_search_input.html.erb +39 -1
- data/app/views/kaui/invoices/index.html.erb +15 -11
- data/app/views/kaui/refunds/_form.html.erb +3 -11
- data/app/views/kaui/subscriptions/_form.html.erb +7 -1
- data/app/views/kaui/subscriptions/_subscriptions_table.html.erb +12 -1
- data/config/routes.rb +79 -79
- data/lib/devise/models/killbill_authenticatable.rb +38 -0
- data/lib/devise/models/killbill_registerable.rb +9 -0
- data/lib/generators/kaui/install/install_generator.rb +1 -4
- data/lib/kaui/version.rb +1 -1
- data/lib/kaui.rb +7 -7
- metadata +5 -2
|
@@ -10,68 +10,6 @@ module Kaui
|
|
|
10
10
|
@tenants = Kaui::Tenant.all.select { |tenant| tenants_for_current_user.include?(tenant.kb_tenant_id) }
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
def new
|
|
14
|
-
@tenant = Kaui::Tenant.new
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def create
|
|
18
|
-
param_tenant = params[:tenant]
|
|
19
|
-
|
|
20
|
-
old_tenant = Kaui::Tenant.find_by_name(param_tenant[:name]) || Kaui::Tenant.find_by_api_key(param_tenant[:api_key])
|
|
21
|
-
if old_tenant
|
|
22
|
-
old_tenant.kaui_allowed_users << Kaui::AllowedUser.where(kb_username: current_user.kb_username).first_or_create
|
|
23
|
-
redirect_to admin_tenant_path(old_tenant[:id]), notice: 'Tenant was successfully configured' and return
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
begin
|
|
27
|
-
options = tenant_options_for_client
|
|
28
|
-
new_tenant = nil
|
|
29
|
-
|
|
30
|
-
begin
|
|
31
|
-
options[:api_key] = param_tenant[:api_key]
|
|
32
|
-
options[:api_secret] = param_tenant[:api_secret]
|
|
33
|
-
new_tenant = Kaui::AdminTenant.find_by_api_key(param_tenant[:api_key], options)
|
|
34
|
-
rescue KillBillClient::API::Unauthorized, KillBillClient::API::NotFound, KillBillClient::API::InternalServerError => e
|
|
35
|
-
# Create the tenant in Kill Bill
|
|
36
|
-
if e.instance_of?(KillBillClient::API::InternalServerError) && !e.message&.include?('TenantCacheLoader cannot find value')
|
|
37
|
-
flash[:error] = "Internal server error while retrieving tenant: #{as_string(e)}"
|
|
38
|
-
redirect_to admin_tenants_path and return
|
|
39
|
-
end
|
|
40
|
-
new_tenant = Kaui::AdminTenant.new
|
|
41
|
-
new_tenant.external_key = param_tenant[:name]
|
|
42
|
-
new_tenant.api_key = param_tenant[:api_key]
|
|
43
|
-
new_tenant.api_secret = param_tenant[:api_secret]
|
|
44
|
-
new_tenant = new_tenant.create(false, options[:username], nil, comment, options)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# Transform object to Kaui model
|
|
48
|
-
tenant_model = Kaui::Tenant.new
|
|
49
|
-
tenant_model.name = param_tenant[:name]
|
|
50
|
-
tenant_model.api_key = param_tenant[:api_key]
|
|
51
|
-
tenant_model.api_secret = param_tenant[:api_secret]
|
|
52
|
-
tenant_model.kb_tenant_id = new_tenant.tenant_id
|
|
53
|
-
|
|
54
|
-
# Save in KAUI tables
|
|
55
|
-
tenant_model.save!
|
|
56
|
-
# Make sure at least the current user can access the tenant
|
|
57
|
-
tenant_model.kaui_allowed_users << Kaui::AllowedUser.where(kb_username: current_user.kb_username).first_or_create
|
|
58
|
-
rescue KillBillClient::API::Conflict => _e
|
|
59
|
-
# tenant api_key was found but has a wrong api_secret
|
|
60
|
-
flash[:error] = "Submitted credentials for #{param_tenant[:api_key]} did not match the expected credentials."
|
|
61
|
-
redirect_to admin_tenants_path and return
|
|
62
|
-
rescue StandardError => e
|
|
63
|
-
flash[:error] = "Failed to create the tenant: #{as_string(e)}"
|
|
64
|
-
redirect_to admin_tenants_path and return
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# Select the tenant, see TenantsController
|
|
68
|
-
session[:kb_tenant_id] = tenant_model.kb_tenant_id
|
|
69
|
-
session[:kb_tenant_name] = tenant_model.name
|
|
70
|
-
session[:tenant_id] = tenant_model.id
|
|
71
|
-
|
|
72
|
-
redirect_to admin_tenant_path(tenant_model[:id]), notice: 'Tenant was successfully configured'
|
|
73
|
-
end
|
|
74
|
-
|
|
75
13
|
def show
|
|
76
14
|
@tenant = safely_find_tenant_by_id(params[:id])
|
|
77
15
|
@allowed_users = @tenant.kaui_allowed_users & retrieve_allowed_users_for_current_user
|
|
@@ -140,6 +78,68 @@ module Kaui
|
|
|
140
78
|
end
|
|
141
79
|
end
|
|
142
80
|
|
|
81
|
+
def new
|
|
82
|
+
@tenant = Kaui::Tenant.new
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def create
|
|
86
|
+
param_tenant = params[:tenant]
|
|
87
|
+
|
|
88
|
+
old_tenant = Kaui::Tenant.find_by(name: param_tenant[:name]) || Kaui::Tenant.find_by(api_key: param_tenant[:api_key])
|
|
89
|
+
if old_tenant
|
|
90
|
+
old_tenant.kaui_allowed_users << Kaui::AllowedUser.where(kb_username: current_user.kb_username).first_or_create
|
|
91
|
+
redirect_to admin_tenant_path(old_tenant[:id]), notice: 'Tenant was successfully configured' and return
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
begin
|
|
95
|
+
options = tenant_options_for_client
|
|
96
|
+
new_tenant = nil
|
|
97
|
+
|
|
98
|
+
begin
|
|
99
|
+
options[:api_key] = param_tenant[:api_key]
|
|
100
|
+
options[:api_secret] = param_tenant[:api_secret]
|
|
101
|
+
new_tenant = Kaui::AdminTenant.find_by_api_key(param_tenant[:api_key], options)
|
|
102
|
+
rescue KillBillClient::API::Unauthorized, KillBillClient::API::NotFound, KillBillClient::API::InternalServerError => e
|
|
103
|
+
# Create the tenant in Kill Bill
|
|
104
|
+
if e.instance_of?(KillBillClient::API::InternalServerError) && !e.message&.include?('TenantCacheLoader cannot find value')
|
|
105
|
+
flash[:error] = "Internal server error while retrieving tenant: #{as_string(e)}"
|
|
106
|
+
redirect_to admin_tenants_path and return
|
|
107
|
+
end
|
|
108
|
+
new_tenant = Kaui::AdminTenant.new
|
|
109
|
+
new_tenant.external_key = param_tenant[:name]
|
|
110
|
+
new_tenant.api_key = param_tenant[:api_key]
|
|
111
|
+
new_tenant.api_secret = param_tenant[:api_secret]
|
|
112
|
+
new_tenant = new_tenant.create(false, options[:username], nil, comment, options)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Transform object to Kaui model
|
|
116
|
+
tenant_model = Kaui::Tenant.new
|
|
117
|
+
tenant_model.name = param_tenant[:name]
|
|
118
|
+
tenant_model.api_key = param_tenant[:api_key]
|
|
119
|
+
tenant_model.api_secret = param_tenant[:api_secret]
|
|
120
|
+
tenant_model.kb_tenant_id = new_tenant.tenant_id
|
|
121
|
+
|
|
122
|
+
# Save in KAUI tables
|
|
123
|
+
tenant_model.save!
|
|
124
|
+
# Make sure at least the current user can access the tenant
|
|
125
|
+
tenant_model.kaui_allowed_users << Kaui::AllowedUser.where(kb_username: current_user.kb_username).first_or_create
|
|
126
|
+
rescue KillBillClient::API::Conflict => _e
|
|
127
|
+
# tenant api_key was found but has a wrong api_secret
|
|
128
|
+
flash[:error] = "Submitted credentials for #{param_tenant[:api_key]} did not match the expected credentials."
|
|
129
|
+
redirect_to admin_tenants_path and return
|
|
130
|
+
rescue StandardError => e
|
|
131
|
+
flash[:error] = "Failed to create the tenant: #{as_string(e)}"
|
|
132
|
+
redirect_to admin_tenants_path and return
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Select the tenant, see TenantsController
|
|
136
|
+
session[:kb_tenant_id] = tenant_model.kb_tenant_id
|
|
137
|
+
session[:kb_tenant_name] = tenant_model.name
|
|
138
|
+
session[:tenant_id] = tenant_model.id
|
|
139
|
+
|
|
140
|
+
redirect_to admin_tenant_path(tenant_model[:id]), notice: 'Tenant was successfully configured'
|
|
141
|
+
end
|
|
142
|
+
|
|
143
143
|
def upload_catalog
|
|
144
144
|
current_tenant = safely_find_tenant_by_id(params[:id])
|
|
145
145
|
|
|
@@ -158,7 +158,7 @@ module Kaui
|
|
|
158
158
|
end
|
|
159
159
|
if catalog_validation_errors.blank?
|
|
160
160
|
Kaui::AdminTenant.upload_catalog(catalog_xml, options[:username], nil, comment, options)
|
|
161
|
-
redirect_to admin_tenant_path(current_tenant.id), notice: I18n.
|
|
161
|
+
redirect_to admin_tenant_path(current_tenant.id), notice: I18n.t('flashes.notices.catalog_uploaded_successfully')
|
|
162
162
|
else
|
|
163
163
|
errors = ''
|
|
164
164
|
catalog_validation_errors.each do |validation_error|
|
|
@@ -234,7 +234,7 @@ module Kaui
|
|
|
234
234
|
options = tenant_options_for_client
|
|
235
235
|
fetch_state_for_new_catalog_screen(options)
|
|
236
236
|
|
|
237
|
-
simple_plan = params.require(:simple_plan).
|
|
237
|
+
simple_plan = params.require(:simple_plan).permit!.to_h.compact_blank
|
|
238
238
|
# Fix issue in Rails where first entry in the multi-select array is an empty string
|
|
239
239
|
simple_plan['available_base_products']&.reject!(&:blank?)
|
|
240
240
|
|
|
@@ -288,7 +288,15 @@ module Kaui
|
|
|
288
288
|
options = tenant_options_for_client
|
|
289
289
|
options[:api_key] = @tenant.api_key
|
|
290
290
|
options[:api_secret] = @tenant.api_secret
|
|
291
|
-
|
|
291
|
+
begin
|
|
292
|
+
@overdue = Kaui::Overdue.get_overdue_json(options)
|
|
293
|
+
@overdue_corrupted = false
|
|
294
|
+
rescue StandardError => e
|
|
295
|
+
Rails.logger.warn("Failed to load overdue configuration for tenant #{@tenant.id}: #{e.class}: #{e.message}")
|
|
296
|
+
@overdue = KillBillClient::Model::Overdue.new.tap { |o| o.overdue_states = [] }
|
|
297
|
+
@overdue_corrupted = true
|
|
298
|
+
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.'
|
|
299
|
+
end
|
|
292
300
|
end
|
|
293
301
|
|
|
294
302
|
def modify_overdue_config
|
|
@@ -298,12 +306,12 @@ module Kaui
|
|
|
298
306
|
options[:api_key] = current_tenant.api_key
|
|
299
307
|
options[:api_secret] = current_tenant.api_secret
|
|
300
308
|
|
|
301
|
-
view_form_model = params.require(:kill_bill_client_model_overdue).
|
|
302
|
-
view_form_model['states'] = view_form_model['states'].values
|
|
309
|
+
view_form_model = params.require(:kill_bill_client_model_overdue).permit!.to_h.compact_blank
|
|
310
|
+
view_form_model['states'] = view_form_model['states'].values if view_form_model['states'].present?
|
|
303
311
|
|
|
304
312
|
overdue = Kaui::Overdue.from_overdue_form_model(view_form_model)
|
|
305
313
|
Kaui::Overdue.upload_tenant_overdue_config_json(overdue.to_json, options[:username], nil, comment, options)
|
|
306
|
-
redirect_to admin_tenant_path(current_tenant.id, active_tab: 'OverdueShow'), notice: I18n.
|
|
314
|
+
redirect_to admin_tenant_path(current_tenant.id, active_tab: 'OverdueShow'), notice: I18n.t('flashes.notices.overdue_added_successfully')
|
|
307
315
|
end
|
|
308
316
|
|
|
309
317
|
def upload_overdue_config
|
|
@@ -319,13 +327,13 @@ module Kaui
|
|
|
319
327
|
begin
|
|
320
328
|
Nokogiri::XML(overdue_config_xml, &:strict)
|
|
321
329
|
rescue Nokogiri::XML::SyntaxError => e
|
|
322
|
-
flash[:error] = I18n.
|
|
330
|
+
flash[:error] = I18n.t('errors.messages.invalid_xml', error: e)
|
|
323
331
|
redirect_to admin_tenant_path(current_tenant.id) and return
|
|
324
332
|
end
|
|
325
333
|
|
|
326
334
|
Kaui::AdminTenant.upload_overdue_config(overdue_config_xml, options[:username], nil, comment, options)
|
|
327
335
|
|
|
328
|
-
redirect_to admin_tenant_path(current_tenant.id, active_tab: 'OverdueShow'), notice: I18n.
|
|
336
|
+
redirect_to admin_tenant_path(current_tenant.id, active_tab: 'OverdueShow'), notice: I18n.t('flashes.notices.overdue_uploaded_successfully')
|
|
329
337
|
end
|
|
330
338
|
|
|
331
339
|
def upload_invoice_template
|
|
@@ -341,7 +349,7 @@ module Kaui
|
|
|
341
349
|
|
|
342
350
|
Kaui::AdminTenant.upload_invoice_template(invoice_template, is_manual_pay, true, options[:username], nil, comment, options)
|
|
343
351
|
|
|
344
|
-
redirect_to admin_tenant_path(current_tenant.id), notice: I18n.
|
|
352
|
+
redirect_to admin_tenant_path(current_tenant.id), notice: I18n.t('flashes.notices.invoice_template_uploaded_successfully')
|
|
345
353
|
end
|
|
346
354
|
|
|
347
355
|
def upload_invoice_translation
|
|
@@ -357,7 +365,7 @@ module Kaui
|
|
|
357
365
|
|
|
358
366
|
Kaui::AdminTenant.upload_invoice_translation(invoice_translation, locale, true, options[:username], nil, comment, options)
|
|
359
367
|
|
|
360
|
-
redirect_to admin_tenant_path(current_tenant.id), notice: I18n.
|
|
368
|
+
redirect_to admin_tenant_path(current_tenant.id), notice: I18n.t('flashes.notices.invoice_translation_uploaded_successfully')
|
|
361
369
|
end
|
|
362
370
|
|
|
363
371
|
def upload_catalog_translation
|
|
@@ -373,7 +381,7 @@ module Kaui
|
|
|
373
381
|
|
|
374
382
|
Kaui::AdminTenant.upload_catalog_translation(catalog_translation, locale, true, options[:username], nil, comment, options)
|
|
375
383
|
|
|
376
|
-
redirect_to admin_tenant_path(current_tenant.id), notice: I18n.
|
|
384
|
+
redirect_to admin_tenant_path(current_tenant.id), notice: I18n.t('flashes.notices.catalog_translation_uploaded_successfully')
|
|
377
385
|
end
|
|
378
386
|
|
|
379
387
|
def upload_plugin_config
|
|
@@ -407,18 +415,18 @@ module Kaui
|
|
|
407
415
|
au = Kaui::AllowedUser.find(params.require(:allowed_user).require(:id))
|
|
408
416
|
|
|
409
417
|
unless current_user.root?
|
|
410
|
-
render json: { alert: 'Only the root user can remove users from tenants' }.to_json, status:
|
|
418
|
+
render json: { alert: 'Only the root user can remove users from tenants' }.to_json, status: :unauthorized
|
|
411
419
|
return
|
|
412
420
|
end
|
|
413
421
|
|
|
414
422
|
# remove the association
|
|
415
423
|
au.kaui_tenants.delete current_tenant
|
|
416
|
-
render json: '{}', status:
|
|
424
|
+
render json: '{}', status: :ok
|
|
417
425
|
end
|
|
418
426
|
|
|
419
427
|
def add_allowed_user
|
|
420
428
|
current_tenant = safely_find_tenant_by_id(params[:tenant_id])
|
|
421
|
-
allowed_user = Kaui::AllowedUser.
|
|
429
|
+
allowed_user = Kaui::AllowedUser.find_by(kb_username: params.require(:allowed_user).require(:kb_username))
|
|
422
430
|
|
|
423
431
|
unless current_user.root?
|
|
424
432
|
flash[:error] = 'Only the root user can add users from tenants'
|
|
@@ -498,10 +506,10 @@ module Kaui
|
|
|
498
506
|
|
|
499
507
|
if params[:commit] == 'Submit'
|
|
500
508
|
date = Date.parse(params[:new_date]).strftime('%Y-%m-%d')
|
|
501
|
-
msg = I18n.
|
|
509
|
+
msg = I18n.t('flashes.notices.clock_updated_successfully', new_date: date)
|
|
502
510
|
else
|
|
503
511
|
date = nil
|
|
504
|
-
msg = I18n.
|
|
512
|
+
msg = I18n.t('flashes.notices.clock_reset_successfully')
|
|
505
513
|
end
|
|
506
514
|
|
|
507
515
|
begin
|
|
@@ -515,7 +523,7 @@ module Kaui
|
|
|
515
523
|
end
|
|
516
524
|
|
|
517
525
|
def switch_tenant
|
|
518
|
-
tenant = Kaui::Tenant.
|
|
526
|
+
tenant = Kaui::Tenant.find_by(kb_tenant_id: params.require(:kb_tenant_id))
|
|
519
527
|
|
|
520
528
|
# Select the tenant, see TenantsController
|
|
521
529
|
session[:kb_tenant_id] = tenant.kb_tenant_id
|
|
@@ -560,7 +568,7 @@ module Kaui
|
|
|
560
568
|
end
|
|
561
569
|
|
|
562
570
|
def safely_find_tenant_by_id(tenant_id)
|
|
563
|
-
tenant = Kaui::Tenant.
|
|
571
|
+
tenant = Kaui::Tenant.find_by(id: tenant_id)
|
|
564
572
|
raise ActiveRecord::RecordNotFound, "Could not find tenant #{tenant_id}" unless retrieve_tenants_for_current_user.include?(tenant.kb_tenant_id)
|
|
565
573
|
|
|
566
574
|
tenant
|
|
@@ -606,7 +614,7 @@ module Kaui
|
|
|
606
614
|
end
|
|
607
615
|
|
|
608
616
|
catalog_xml = {}
|
|
609
|
-
catalog_xml = response[0][:xml]
|
|
617
|
+
catalog_xml = response[0][:xml] if response.present?
|
|
610
618
|
|
|
611
619
|
catalog_xml
|
|
612
620
|
end
|
|
@@ -5,10 +5,11 @@ module Kaui
|
|
|
5
5
|
# rubocop:disable Lint/HashCompareByIdentity
|
|
6
6
|
def index
|
|
7
7
|
cached_options_for_klient = options_for_klient
|
|
8
|
+
@search_query = params[:q].presence
|
|
9
|
+
@search_by = params[:search_by] || 'bundle_id'
|
|
8
10
|
@per_page = (params[:per_page] || 10).to_i
|
|
9
11
|
@page = (params[:page] || 1).to_i
|
|
10
12
|
|
|
11
|
-
fetch_bundles = promise { Kaui::Account.paginated_bundles(@account.account_id, (@page - 1) * @per_page, @per_page, 'NONE', cached_options_for_klient) }
|
|
12
13
|
fetch_bundle_tags = promise do
|
|
13
14
|
all_bundle_tags = @account.all_tags(:BUNDLE, false, 'NONE', cached_options_for_klient)
|
|
14
15
|
all_bundle_tags.each_with_object({}) do |entry, hsh|
|
|
@@ -36,8 +37,15 @@ module Kaui
|
|
|
36
37
|
fetch_available_tags = promise { Kaui::TagDefinition.all_for_bundle(cached_options_for_klient) }
|
|
37
38
|
fetch_available_subscription_tags = promise { Kaui::TagDefinition.all_for_subscription(cached_options_for_klient) }
|
|
38
39
|
|
|
39
|
-
@
|
|
40
|
-
|
|
40
|
+
if @search_query.present?
|
|
41
|
+
@bundles = search_bundles(@search_query, @search_by, cached_options_for_klient)
|
|
42
|
+
@total_pages = 1
|
|
43
|
+
@page = 1
|
|
44
|
+
else
|
|
45
|
+
fetched = Kaui::Account.paginated_bundles(@account.account_id, (@page - 1) * @per_page, @per_page, 'NONE', cached_options_for_klient)
|
|
46
|
+
@bundles = fetched
|
|
47
|
+
@total_pages = (fetched.pagination_max_nb_records.to_f / @per_page).ceil
|
|
48
|
+
end
|
|
41
49
|
|
|
42
50
|
@tags_per_bundle = wait(fetch_bundle_tags)
|
|
43
51
|
@tags_per_subscription = wait(fetch_subscription_tags)
|
|
@@ -46,8 +54,15 @@ module Kaui
|
|
|
46
54
|
@available_tags = wait(fetch_available_tags)
|
|
47
55
|
@available_subscription_tags = wait(fetch_available_subscription_tags)
|
|
48
56
|
|
|
49
|
-
#
|
|
50
|
-
|
|
57
|
+
# Collect the distinct start dates from subscriptions on this page, then fetch
|
|
58
|
+
# only the catalog versions needed — one per unique date — to avoid loading all
|
|
59
|
+
# historical versions into memory.
|
|
60
|
+
start_dates = @bundles.flat_map(&:subscriptions).filter_map(&:start_date).uniq
|
|
61
|
+
@catalogs = start_dates.filter_map do |date|
|
|
62
|
+
Kaui::Catalog.get_account_catalog_json(@account.account_id, date, cached_options_for_klient)&.last
|
|
63
|
+
rescue StandardError
|
|
64
|
+
nil
|
|
65
|
+
end.uniq(&:effective_date)
|
|
51
66
|
|
|
52
67
|
@subscription = {}
|
|
53
68
|
@bundles.each do |bundle|
|
|
@@ -112,5 +127,38 @@ module Kaui
|
|
|
112
127
|
end
|
|
113
128
|
redirect_to kaui_engine.account_bundles_path(@account.account_id), notice: msg
|
|
114
129
|
end
|
|
130
|
+
|
|
131
|
+
private
|
|
132
|
+
|
|
133
|
+
def search_bundles(query, search_by, options)
|
|
134
|
+
case search_by
|
|
135
|
+
when 'bundle_id'
|
|
136
|
+
bundle = Kaui::Bundle.find_by_id(query, options)
|
|
137
|
+
bundle ? [bundle] : []
|
|
138
|
+
when 'bundle_external_key'
|
|
139
|
+
bundle = Kaui::Bundle.find_by_external_key(query, false, options)
|
|
140
|
+
bundle ? [bundle] : []
|
|
141
|
+
when 'subscription_id'
|
|
142
|
+
subscription = KillBillClient::Model::Subscription.find_by_id(query, 'NONE', options)
|
|
143
|
+
if subscription
|
|
144
|
+
bundle = Kaui::Bundle.find_by_id(subscription.bundle_id, options)
|
|
145
|
+
bundle ? [bundle] : []
|
|
146
|
+
else
|
|
147
|
+
[]
|
|
148
|
+
end
|
|
149
|
+
when 'subscription_external_key'
|
|
150
|
+
subscription = KillBillClient::Model::Subscription.find_by_external_key(query, 'NONE', options)
|
|
151
|
+
if subscription
|
|
152
|
+
bundle = Kaui::Bundle.find_by_id(subscription.bundle_id, options)
|
|
153
|
+
bundle ? [bundle] : []
|
|
154
|
+
else
|
|
155
|
+
[]
|
|
156
|
+
end
|
|
157
|
+
else
|
|
158
|
+
[]
|
|
159
|
+
end
|
|
160
|
+
rescue KillBillClient::API::NotFound
|
|
161
|
+
[]
|
|
162
|
+
end
|
|
115
163
|
end
|
|
116
164
|
end
|
|
@@ -29,7 +29,7 @@ module Kaui
|
|
|
29
29
|
account.bundles(cached_options_for_klient).each do |bundle|
|
|
30
30
|
bundle.subscriptions.each do |subscription|
|
|
31
31
|
# Already cancelled?
|
|
32
|
-
next
|
|
32
|
+
next if subscription.billing_end_date.present?
|
|
33
33
|
|
|
34
34
|
# Cancel the entitlement immediately but use the default billing policy
|
|
35
35
|
entitlement = Kaui::Subscription.new(subscription_id: subscription.subscription_id)
|
|
@@ -19,13 +19,16 @@ module Kaui
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def create
|
|
22
|
-
charge = Kaui::InvoiceItem.new(params.require(:invoice_item).
|
|
22
|
+
charge = Kaui::InvoiceItem.new(params.require(:invoice_item).permit!.to_h.compact_blank)
|
|
23
23
|
charge.account_id ||= params.require(:account_id)
|
|
24
24
|
|
|
25
|
+
# Preserve the original invoice_id since the API may not return it
|
|
26
|
+
original_invoice_id = charge.invoice_id
|
|
27
|
+
|
|
25
28
|
auto_commit = params[:auto_commit] == '1'
|
|
26
29
|
|
|
27
30
|
charge = charge.create(auto_commit, current_user.kb_username, params[:reason], params[:comment], options_for_klient)
|
|
28
|
-
redirect_to kaui_engine.account_invoice_path(charge.account_id, charge.invoice_id), notice: 'Charge was successfully created'
|
|
31
|
+
redirect_to kaui_engine.account_invoice_path(charge.account_id, charge.invoice_id || original_invoice_id), notice: 'Charge was successfully created'
|
|
29
32
|
end
|
|
30
33
|
end
|
|
31
34
|
end
|
|
@@ -19,7 +19,7 @@ module Kaui
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def create
|
|
22
|
-
credit = Kaui::Credit.new(params[:credit].
|
|
22
|
+
credit = Kaui::Credit.new(params[:credit].permit!.to_h.compact_blank)
|
|
23
23
|
credit.account_id ||= params.require(:account_id)
|
|
24
24
|
|
|
25
25
|
# No need to show the newly created invoice for account level credits
|
|
@@ -101,7 +101,7 @@ module Kaui
|
|
|
101
101
|
end
|
|
102
102
|
|
|
103
103
|
if test_uuid.blank?
|
|
104
|
-
flash[:error] = I18n.
|
|
104
|
+
flash[:error] = I18n.t('object_invalid_dont_exist')
|
|
105
105
|
redirect_to custom_fields_path
|
|
106
106
|
return
|
|
107
107
|
end
|
|
@@ -120,12 +120,12 @@ module Kaui
|
|
|
120
120
|
when :INVOICE_ITEM
|
|
121
121
|
Kaui::InvoiceItem.new(invoice_item_id: @custom_field.object_id)
|
|
122
122
|
else
|
|
123
|
-
flash.now[:error] = I18n.
|
|
123
|
+
flash.now[:error] = I18n.t('invalid_object_type', error: @custom_field.object_type)
|
|
124
124
|
render :new and return
|
|
125
125
|
end
|
|
126
126
|
model.add_custom_field(@custom_field, current_user.kb_username, params[:reason], params[:comment], options_for_klient)
|
|
127
127
|
|
|
128
|
-
redirect_to custom_fields_path, notice: I18n.
|
|
128
|
+
redirect_to custom_fields_path, notice: I18n.t('custom_field_created_success')
|
|
129
129
|
end
|
|
130
130
|
|
|
131
131
|
private
|
|
@@ -143,7 +143,7 @@ module Kaui
|
|
|
143
143
|
rescue StandardError
|
|
144
144
|
# Ignore
|
|
145
145
|
ensure
|
|
146
|
-
msg = { status: '200', message: I18n.
|
|
146
|
+
msg = { status: '200', message: I18n.t('custom_field_uuid_exist_in_invoice_item_db') } if test_uuid.present?
|
|
147
147
|
end
|
|
148
148
|
when 'ACCOUNT'
|
|
149
149
|
begin
|
|
@@ -151,7 +151,7 @@ module Kaui
|
|
|
151
151
|
rescue StandardError
|
|
152
152
|
# Ignore
|
|
153
153
|
ensure
|
|
154
|
-
msg = { status: '200', message: I18n.
|
|
154
|
+
msg = { status: '200', message: I18n.t('custom_field_uuid_exist_in_account_db') } if test_uuid.present? && (test_uuid.account_id == param_uuid)
|
|
155
155
|
end
|
|
156
156
|
when 'BUNDLE'
|
|
157
157
|
begin
|
|
@@ -159,7 +159,7 @@ module Kaui
|
|
|
159
159
|
rescue StandardError
|
|
160
160
|
# Ignore
|
|
161
161
|
ensure
|
|
162
|
-
msg = { status: '200', message: I18n.
|
|
162
|
+
msg = { status: '200', message: I18n.t('custom_field_uuid_exist_in_bundle_db') } if test_uuid.present? && (test_uuid.bundle_id == param_uuid)
|
|
163
163
|
end
|
|
164
164
|
when 'SUBSCRIPTION'
|
|
165
165
|
begin
|
|
@@ -167,7 +167,7 @@ module Kaui
|
|
|
167
167
|
rescue StandardError
|
|
168
168
|
# Ignore
|
|
169
169
|
ensure
|
|
170
|
-
msg = { status: '200', message: I18n.
|
|
170
|
+
msg = { status: '200', message: I18n.t('custom_field_uuid_exist_in_subscription_db') } if test_uuid.present? && (test_uuid.subscription_id == param_uuid)
|
|
171
171
|
end
|
|
172
172
|
when 'INVOICE'
|
|
173
173
|
begin
|
|
@@ -176,7 +176,7 @@ module Kaui
|
|
|
176
176
|
rescue StandardError
|
|
177
177
|
# Ignore
|
|
178
178
|
ensure
|
|
179
|
-
msg = { status: '200', message: I18n.
|
|
179
|
+
msg = { status: '200', message: I18n.t('custom_field_uuid_exist_in_invoice_db') } if test_uuid.present? && (test_uuid.invoice_id == param_uuid)
|
|
180
180
|
end
|
|
181
181
|
when 'PAYMENT'
|
|
182
182
|
begin
|
|
@@ -184,18 +184,18 @@ module Kaui
|
|
|
184
184
|
rescue StandardError
|
|
185
185
|
# Ignore
|
|
186
186
|
ensure
|
|
187
|
-
msg = { status: '200', message: I18n.
|
|
187
|
+
msg = { status: '200', message: I18n.t('custom_field_uuid_exist_in_invoice_payment_db') } if test_uuid.present? && (test_uuid.payment_id == param_uuid)
|
|
188
188
|
end
|
|
189
189
|
begin
|
|
190
190
|
test_uuid = Kaui::Payment.find_by_external_key(param_uuid, false, true, options_for_klient)
|
|
191
191
|
rescue StandardError
|
|
192
192
|
# Ignore
|
|
193
193
|
ensure
|
|
194
|
-
msg = { status: '200', message: I18n.
|
|
194
|
+
msg = { status: '200', message: I18n.t('custom_field_uuid_exist_in_payment_db') } if test_uuid.present? && (test_uuid.payment_id == param_uuid)
|
|
195
195
|
end
|
|
196
196
|
end
|
|
197
197
|
|
|
198
|
-
msg ||= { status: '431', message: I18n.
|
|
198
|
+
msg ||= { status: '431', message: I18n.t('custom_field_uuid_do_not_exist_in_db') }
|
|
199
199
|
render json: msg
|
|
200
200
|
end
|
|
201
201
|
end
|
|
@@ -111,9 +111,9 @@ module Kaui
|
|
|
111
111
|
def promise_as_string(promise)
|
|
112
112
|
return 'nil' if promise.nil?
|
|
113
113
|
|
|
114
|
-
executor = promise.instance_variable_get(
|
|
114
|
+
executor = promise.instance_variable_get(:@executor)
|
|
115
115
|
executor_as_string = "queue_length=#{executor.queue_length}, pool_size=#{executor.length}"
|
|
116
|
-
"#{promise.instance_variable_get(
|
|
116
|
+
"#{promise.instance_variable_get(:@promise_body)}[state=#{promise.state}, parent=#{promise_as_string(promise.instance_variable_get(:@parent))}, executor=[#{executor_as_string}]]"
|
|
117
117
|
end
|
|
118
118
|
|
|
119
119
|
# Used to format flash error messages
|
|
@@ -127,7 +127,7 @@ module Kaui
|
|
|
127
127
|
as_string(exception.cause)
|
|
128
128
|
else
|
|
129
129
|
log_rescue_error(exception)
|
|
130
|
-
exception.message
|
|
130
|
+
exception.message.to_s[0..200]
|
|
131
131
|
end
|
|
132
132
|
end
|
|
133
133
|
|
|
@@ -147,10 +147,10 @@ module Kaui
|
|
|
147
147
|
if error_message.respond_to?(:[]) && error_message['message'].present?
|
|
148
148
|
# Likely BillingExceptionJson
|
|
149
149
|
error_message = error_message['message']
|
|
150
|
-
error_message += " (code=#{error_message['code']})"
|
|
150
|
+
error_message += " (code=#{error_message['code']})" if error_message['code'].present?
|
|
151
151
|
end
|
|
152
152
|
# Limit the error size to avoid ActionDispatch::Cookies::CookieOverflow
|
|
153
|
-
error_message[0..
|
|
153
|
+
error_message.to_s[0..200]
|
|
154
154
|
end
|
|
155
155
|
|
|
156
156
|
def nested_hash_value(obj, key)
|
|
@@ -20,6 +20,10 @@ module Kaui
|
|
|
20
20
|
|
|
21
21
|
def search
|
|
22
22
|
object_type, search_query = splitting_new_search(params[:q])
|
|
23
|
+
if search_query.nil?
|
|
24
|
+
search_error('Please specify a search type (e.g., "Account: search_term")')
|
|
25
|
+
return
|
|
26
|
+
end
|
|
23
27
|
object_type = object_type.tr(' ', '_').downcase
|
|
24
28
|
cached_options_for_klient = options_for_klient
|
|
25
29
|
send("#{object_type}_search", search_query, nil, 0, cached_options_for_klient)
|
|
@@ -254,7 +258,7 @@ module Kaui
|
|
|
254
258
|
end
|
|
255
259
|
|
|
256
260
|
def unsupported_search_field(object_type, object_field)
|
|
257
|
-
field_name = object_field.
|
|
261
|
+
field_name = object_field.tr('_', ' ')
|
|
258
262
|
search_error("\"#{object_type}\": Search by \"#{field_name}\" is not supported.")
|
|
259
263
|
end
|
|
260
264
|
|
|
@@ -283,7 +287,7 @@ module Kaui
|
|
|
283
287
|
'0'
|
|
284
288
|
end
|
|
285
289
|
|
|
286
|
-
search_error("\"#{search_by}\" is not a valid search by value") if
|
|
290
|
+
search_error("\"#{search_by}\" is not a valid search by value") if search_by.present? && !search_by.in?(Kaui::ObjectHelper::ADVANCED_SEARCH_OBJECT_FIELDS)
|
|
287
291
|
|
|
288
292
|
[object_type, search_for, search_by, fast]
|
|
289
293
|
end
|
|
@@ -6,7 +6,7 @@ module Kaui
|
|
|
6
6
|
def index
|
|
7
7
|
@search_query = params[:account_id]
|
|
8
8
|
@advance_search_query = params[:q] || request.query_string
|
|
9
|
-
@ordering = params[:ordering] ||
|
|
9
|
+
@ordering = params[:ordering] || 'desc'
|
|
10
10
|
@offset = params[:offset] || 0
|
|
11
11
|
@limit = params[:limit] || 50
|
|
12
12
|
@search_fields = Kaui::Invoice::ADVANCED_SEARCH_COLUMNS.map { |attr| [attr, attr.split('_').join(' ').capitalize] }
|
|
@@ -21,7 +21,7 @@ module Kaui
|
|
|
21
21
|
all_fields_checked = params[:allFieldsChecked] == 'true'
|
|
22
22
|
query_string = handle_balance_search(params[:search])
|
|
23
23
|
columns = if all_fields_checked
|
|
24
|
-
KillBillClient::Model::InvoiceAttributes.instance_variable_get(
|
|
24
|
+
KillBillClient::Model::InvoiceAttributes.instance_variable_get(:@json_attributes) - Kaui::Invoice::TABLE_IGNORE_COLUMNS
|
|
25
25
|
else
|
|
26
26
|
params.require(:columnsString).split(',').map { |attr| attr.split.join('_').downcase }
|
|
27
27
|
end
|
|
@@ -52,7 +52,7 @@ module Kaui
|
|
|
52
52
|
csv << columns.map { |attr| invoice&.send(attr.downcase) }
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
|
-
send_data csv_string, filename: "invoices-#{
|
|
55
|
+
send_data csv_string, filename: "invoices-#{Time.zone.today}.csv", type: 'text/csv'
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
def pagination
|
|
@@ -134,7 +134,7 @@ module Kaui
|
|
|
134
134
|
end
|
|
135
135
|
end
|
|
136
136
|
|
|
137
|
-
fetch_invoice_tags = promise { @invoice.tags(false, 'NONE', cached_options_for_klient).sort
|
|
137
|
+
fetch_invoice_tags = promise { @invoice.tags(false, 'NONE', cached_options_for_klient).sort }
|
|
138
138
|
fetch_available_invoice_tags = promise { Kaui::TagDefinition.all_for_invoice(cached_options_for_klient) }
|
|
139
139
|
|
|
140
140
|
@payments = wait(fetch_payments)
|
|
@@ -173,7 +173,9 @@ module Kaui
|
|
|
173
173
|
end
|
|
174
174
|
|
|
175
175
|
def show_html
|
|
176
|
+
# rubocop:disable Rails/OutputSafety -- Invoice HTML from Kill Bill backend is trusted
|
|
176
177
|
render html: Kaui::Invoice.as_html(params.require(:id), options_for_klient).html_safe
|
|
178
|
+
# rubocop:enable Rails/OutputSafety
|
|
177
179
|
end
|
|
178
180
|
|
|
179
181
|
def commit_invoice
|
|
@@ -2,13 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
module Kaui
|
|
4
4
|
class PaymentMethodsController < Kaui::EngineController
|
|
5
|
+
def show
|
|
6
|
+
restful_show
|
|
7
|
+
end
|
|
8
|
+
|
|
5
9
|
def new
|
|
6
10
|
@payment_method = Kaui::PaymentMethod.new(account_id: params[:account_id],
|
|
7
11
|
plugin_name: params[:plugin_name] || Kaui.creditcard_plugin_name.call)
|
|
8
12
|
end
|
|
9
13
|
|
|
10
14
|
def create
|
|
11
|
-
@payment_method = Kaui::PaymentMethod.new(params[:payment_method].
|
|
15
|
+
@payment_method = Kaui::PaymentMethod.new(params[:payment_method].permit!.to_h.compact_blank)
|
|
12
16
|
# Transform "1" into boolean
|
|
13
17
|
@payment_method.is_default = @payment_method.is_default == '1'
|
|
14
18
|
# Sensible default
|
|
@@ -84,10 +88,6 @@ module Kaui
|
|
|
84
88
|
end
|
|
85
89
|
end
|
|
86
90
|
|
|
87
|
-
def show
|
|
88
|
-
restful_show
|
|
89
|
-
end
|
|
90
|
-
|
|
91
91
|
def restful_show
|
|
92
92
|
payment_method = Kaui::PaymentMethod.find_by_id(params.require(:id), false, false, [], 'NONE', options_for_klient)
|
|
93
93
|
redirect_to kaui_engine.account_path(payment_method.account_id)
|