kaui 4.0.25 → 4.0.26
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/README.md +1 -1
- data/app/assets/images/kaui/blocking-states/shield-white.svg +3 -0
- data/app/assets/images/kaui/timeline/block.svg +4 -0
- data/app/assets/stylesheets/kaui/subscription.css +38 -0
- data/app/controllers/kaui/account_timelines_controller.rb +24 -6
- data/app/controllers/kaui/accounts_controller.rb +15 -0
- data/app/controllers/kaui/bundles_controller.rb +14 -0
- data/app/controllers/kaui/subscriptions_controller.rb +14 -0
- data/app/helpers/kaui/exception_helper.rb +1 -1
- data/app/views/kaui/account_timelines/show.html.erb +234 -120
- data/app/views/kaui/accounts/_billing_details.html.erb +13 -1
- data/app/views/kaui/accounts/_billing_info.html.erb +5 -1
- data/app/views/kaui/accounts/block.html.erb +16 -0
- data/app/views/kaui/admin_allowed_users/_form.html.erb +5 -1
- data/app/views/kaui/bundles/block.html.erb +16 -0
- data/app/views/kaui/components/blocking_state_form/_about_panel.html.erb +9 -0
- data/app/views/kaui/components/blocking_state_form/_fields.html.erb +79 -0
- data/app/views/kaui/subscriptions/_subscriptions_table.html.erb +16 -0
- data/app/views/kaui/subscriptions/block.html.erb +16 -0
- data/config/locales/en.yml +4 -0
- data/config/routes.rb +6 -0
- data/lib/kaui/version.rb +1 -1
- metadata +26 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 939bd1335abb8e3253fba3edb39871baab6a2bca5f7e10f26747b8bf22c3bfa9
|
|
4
|
+
data.tar.gz: eb850fd782524ffae4f8a7a652eece483244ddeb798d5221485b083e8f1d0039
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e07257d417598b8ef1514b22bf2551673b07c64aa66164f0e791751f2e93e362853a2d60c5d376bf3254b78498b208fb76c39abb7e342866288896b91acdeebe
|
|
7
|
+
data.tar.gz: a61104d90eddee06456c260d26c1adca1a6ad0fb0790587063592178ba40722be8b7efcbdaaf6de6575712f660d396b48613004dafadd43a12b7477c43495b79
|
data/README.md
CHANGED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M10 1.66675L17.0833 4.16675V9.44119C17.0833 13.2489 14.5321 16.5934 10.8563 17.5793L10 17.8085L9.14367 17.5793C5.46791 16.5934 2.91667 13.2489 2.91667 9.44119V4.16675L10 1.66675Z" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M10 18.3337C14.6024 18.3337 18.3334 14.6027 18.3334 10.0003C18.3334 5.39795 14.6024 1.66699 10 1.66699C5.39765 1.66699 1.66669 5.39795 1.66669 10.0003C1.66669 14.6027 5.39765 18.3337 10 18.3337Z" stroke="#414651" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
3
|
+
<path d="M4.39587 4.39795L15.6042 15.6062" stroke="#414651" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
4
|
+
</svg>
|
|
@@ -437,6 +437,44 @@ table tr.expired td {
|
|
|
437
437
|
right: 0.5rem;
|
|
438
438
|
}
|
|
439
439
|
|
|
440
|
+
/* app/views/kaui/components/blocking_state_form/_about_panel.html.erb */
|
|
441
|
+
|
|
442
|
+
.blocking-state-about-panel {
|
|
443
|
+
flex: 0 0 20rem;
|
|
444
|
+
max-width: 20rem;
|
|
445
|
+
height: fit-content;
|
|
446
|
+
padding: 1.25rem;
|
|
447
|
+
background-color: #EFF6FF;
|
|
448
|
+
border: 0.0625rem solid #DBEAFE;
|
|
449
|
+
border-radius: 0.5rem;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
.blocking-state-about-panel .icon-container {
|
|
453
|
+
display: inline-flex;
|
|
454
|
+
justify-content: center;
|
|
455
|
+
align-items: center;
|
|
456
|
+
width: 2.5rem;
|
|
457
|
+
height: 2.5rem;
|
|
458
|
+
border-radius: 50%;
|
|
459
|
+
background-color: #2563EB;
|
|
460
|
+
flex-shrink: 0;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
.blocking-state-about-panel h6 {
|
|
464
|
+
font-weight: 600;
|
|
465
|
+
font-size: 1rem;
|
|
466
|
+
line-height: 1.5rem;
|
|
467
|
+
color: #1B1C1E;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
.blocking-state-about-panel p {
|
|
471
|
+
font-size: 0.875rem;
|
|
472
|
+
font-weight: 400;
|
|
473
|
+
line-height: 1.25rem;
|
|
474
|
+
color: #414651;
|
|
475
|
+
margin-bottom: 0;
|
|
476
|
+
}
|
|
477
|
+
|
|
440
478
|
.kaui-subscription-new .form-group.d-flex.pb-3 .form-control {
|
|
441
479
|
height: 2.5rem;
|
|
442
480
|
border-radius: 0.375rem;
|
|
@@ -11,6 +11,7 @@ module Kaui
|
|
|
11
11
|
@invoices = timeline.invoices
|
|
12
12
|
@payments = timeline.payments
|
|
13
13
|
extract_invoices_by_id(@invoices)
|
|
14
|
+
@account_blocking_states = fetch_account_blocking_states(@account)
|
|
14
15
|
|
|
15
16
|
# Lookup all bundle names
|
|
16
17
|
@bundle_names = {}
|
|
@@ -51,6 +52,7 @@ module Kaui
|
|
|
51
52
|
@invoices = timeline.invoices
|
|
52
53
|
@payments = timeline.payments
|
|
53
54
|
extract_invoices_by_id(@invoices)
|
|
55
|
+
@account_blocking_states = fetch_account_blocking_states(@account)
|
|
54
56
|
|
|
55
57
|
# Lookup all bundle names
|
|
56
58
|
@bundle_names = {}
|
|
@@ -117,20 +119,30 @@ module Kaui
|
|
|
117
119
|
@bundles.each do |bundle|
|
|
118
120
|
bundle.subscriptions.each do |sub|
|
|
119
121
|
sub.events.each do |event|
|
|
120
|
-
# Skip SERVICE_STATE_CHANGE events
|
|
121
|
-
next if event.event_type == 'SERVICE_STATE_CHANGE'
|
|
122
|
-
|
|
123
122
|
effective_date = event.effective_date.present? ? Date.parse(event.effective_date).to_s : '[unknown]'
|
|
124
123
|
bundle_keys = @bundle_names[bundle.external_key]
|
|
125
|
-
event_type = event.event_type
|
|
126
|
-
phase = event.phase
|
|
127
124
|
audit_logs = event.audit_logs.present? ? event.audit_logs.map { |entry| Kaui::AuditLog.description(entry) }.join(', ') : ''
|
|
125
|
+
details = if event.event_type == 'SERVICE_STATE_CHANGE' || event.is_blocked_billing || event.is_blocked_entitlement
|
|
126
|
+
"#{event.service_name}/#{event.service_state_name} (billing=#{event.is_blocked_billing}, entitlement=#{event.is_blocked_entitlement})"
|
|
127
|
+
else
|
|
128
|
+
event.phase
|
|
129
|
+
end
|
|
128
130
|
|
|
129
|
-
csv << [effective_date, bundle_keys, event_type,
|
|
131
|
+
csv << [effective_date, bundle_keys, event.event_type, details, audit_logs] if filter_date?(effective_date, start_date, end_date)
|
|
130
132
|
end
|
|
131
133
|
end
|
|
132
134
|
end
|
|
133
135
|
end
|
|
136
|
+
|
|
137
|
+
if %w[ENTITLEMENT ALL].include?(event_type)
|
|
138
|
+
@account_blocking_states.each do |blocking_state|
|
|
139
|
+
effective_date = blocking_state.effective_date.present? ? Date.parse(blocking_state.effective_date).to_s : '[unknown]'
|
|
140
|
+
audit_logs = blocking_state.audit_logs.present? ? blocking_state.audit_logs.map { |entry| Kaui::AuditLog.description(entry) }.join(', ') : ''
|
|
141
|
+
details = "#{blocking_state.service}/#{blocking_state.state_name} (billing=#{blocking_state.is_block_billing}, entitlement=#{blocking_state.is_block_entitlement}, change=#{blocking_state.is_block_change})"
|
|
142
|
+
|
|
143
|
+
csv << [effective_date, '', 'SERVICE_STATE_CHANGE', details, audit_logs] if filter_date?(effective_date, start_date, end_date)
|
|
144
|
+
end
|
|
145
|
+
end
|
|
134
146
|
end
|
|
135
147
|
|
|
136
148
|
send_data csv_string, filename: "account-timelines-#{Time.zone.today}.csv", type: 'text/csv'
|
|
@@ -161,5 +173,11 @@ module Kaui
|
|
|
161
173
|
[invoice.invoice_id, Kaui::Invoice.build_from_raw_invoice(invoice)]
|
|
162
174
|
end
|
|
163
175
|
end
|
|
176
|
+
|
|
177
|
+
def fetch_account_blocking_states(account)
|
|
178
|
+
account.blocking_states(nil, nil, 'NONE', options_for_klient)
|
|
179
|
+
rescue StandardError
|
|
180
|
+
[]
|
|
181
|
+
end
|
|
164
182
|
end
|
|
165
183
|
end
|
|
@@ -391,5 +391,20 @@ module Kaui
|
|
|
391
391
|
data = KillBillClient::Model::Export.find_by_account_id(params[:account_id], current_user.kb_username, options_for_klient)
|
|
392
392
|
send_data data, filename: "account#{params[:account_id]}.txt", type: :txt
|
|
393
393
|
end
|
|
394
|
+
|
|
395
|
+
def block
|
|
396
|
+
@account = Kaui::Account.find_by_id(params.require(:account_id), false, false, options_for_klient)
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
def do_block
|
|
400
|
+
account_id = params.require(:account_id)
|
|
401
|
+
account = Kaui::Account.new(account_id:)
|
|
402
|
+
account.set_blocking_state(params.require(:state_name), params.require(:service),
|
|
403
|
+
params[:is_block_change] == '1', params[:is_block_entitlement] == '1',
|
|
404
|
+
params[:is_block_billing] == '1', params[:requested_date].presence,
|
|
405
|
+
current_user.kb_username, params[:reason], params[:comment], options_for_klient)
|
|
406
|
+
|
|
407
|
+
redirect_to account_path(account_id), notice: 'Blocking state was successfully created'
|
|
408
|
+
end
|
|
394
409
|
end
|
|
395
410
|
end
|
|
@@ -128,6 +128,20 @@ module Kaui
|
|
|
128
128
|
redirect_to kaui_engine.account_bundles_path(@account.account_id), notice: msg
|
|
129
129
|
end
|
|
130
130
|
|
|
131
|
+
def block
|
|
132
|
+
@bundle = Kaui::Bundle.find_by_id_or_key(params.require(:id), options_for_klient)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def do_block
|
|
136
|
+
bundle = Kaui::Bundle.new(bundle_id: params.require(:id))
|
|
137
|
+
bundle.set_blocking_state(params.require(:state_name), params.require(:service),
|
|
138
|
+
params[:is_block_change] == '1', params[:is_block_entitlement] == '1',
|
|
139
|
+
params[:is_block_billing] == '1', params[:requested_date].presence,
|
|
140
|
+
current_user.kb_username, params[:reason], params[:comment], options_for_klient)
|
|
141
|
+
|
|
142
|
+
redirect_to kaui_engine.account_bundles_path(params.require(:account_id)), notice: 'Blocking state was successfully created'
|
|
143
|
+
end
|
|
144
|
+
|
|
131
145
|
private
|
|
132
146
|
|
|
133
147
|
def search_bundles(query, search_by, options)
|
|
@@ -150,6 +150,20 @@ module Kaui
|
|
|
150
150
|
redirect_to kaui_engine.account_bundles_path(input_subscription['account_id']), notice: 'Subscription BCD was successfully changed'
|
|
151
151
|
end
|
|
152
152
|
|
|
153
|
+
def block
|
|
154
|
+
@subscription = Kaui::Subscription.find_by_id(params.require(:id), 'NONE', options_for_klient)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def do_block
|
|
158
|
+
subscription = Kaui::Subscription.new(subscription_id: params.require(:id))
|
|
159
|
+
subscription.set_blocking_state(params.require(:state_name), params.require(:service),
|
|
160
|
+
params[:is_block_change] == '1', params[:is_block_entitlement] == '1',
|
|
161
|
+
params[:is_block_billing] == '1', params[:requested_date].presence,
|
|
162
|
+
current_user.kb_username, params[:reason], params[:comment], options_for_klient)
|
|
163
|
+
|
|
164
|
+
redirect_to kaui_engine.account_bundles_path(params.require(:account_id)), notice: 'Blocking state was successfully created'
|
|
165
|
+
end
|
|
166
|
+
|
|
153
167
|
def edit_quantity
|
|
154
168
|
@subscription = Kaui::Subscription.find_by_id(params.require(:id), 'NONE', options_for_klient)
|
|
155
169
|
end
|
|
@@ -21,7 +21,7 @@ module Kaui
|
|
|
21
21
|
I18n.t('errors.messages.error_communicating_killbill')
|
|
22
22
|
else
|
|
23
23
|
# Show detailed error in development/test, or when KAUI_SHOW_ERROR_DETAILS is set (for Docker)
|
|
24
|
-
show_details = Rails.env.
|
|
24
|
+
show_details = Rails.env.local? || ENV['KAUI_SHOW_ERROR_DETAILS'].present?
|
|
25
25
|
show_details ? exception.message : nil
|
|
26
26
|
end
|
|
27
27
|
end
|
|
@@ -29,19 +29,25 @@
|
|
|
29
29
|
<div class="form-group p-0 w-100 max-width-148">
|
|
30
30
|
<label for="payment_filter" class="control-label">Payment</label>
|
|
31
31
|
<div class="d-flex">
|
|
32
|
-
<%= select_tag 'payment_filter', options_for_select('<option value="all">ALL</option><option value="authorize">AUTHORIZE</option><option value="purchase">PURCHASE</option><option value="capture">CAPTURE</option><option value="credit">CREDIT</option><option value="refund">REFUND</option><option value="void">VOID</option><option value="chargeback">CHARGEBACK</option>'.html_safe), :class => 'form-control' %>
|
|
32
|
+
<%= select_tag 'payment_filter', options_for_select('<option value="all">ALL</option><option value="none">NONE</option><option value="authorize">AUTHORIZE</option><option value="purchase">PURCHASE</option><option value="capture">CAPTURE</option><option value="credit">CREDIT</option><option value="refund">REFUND</option><option value="void">VOID</option><option value="chargeback">CHARGEBACK</option>'.html_safe), :class => 'form-control' %>
|
|
33
33
|
</div>
|
|
34
34
|
</div>
|
|
35
35
|
<div class="form-group p-0 w-100 max-width-148">
|
|
36
36
|
<label for="subscription_filter" class="control-label">Subscription</label>
|
|
37
37
|
<div class="d-flex">
|
|
38
|
-
<%= select_tag 'subscription_filter', options_for_select('<option value="all">ALL</option><option value="start_entitlement">START_ENTITLEMENT</option><option value="pause_entitlement">PAUSE_ENTITLEMENT</option><option value="resume_entitlement">RESUME_ENTITLEMENT</option><option value="stop_entitlement">STOP_ENTITLEMENT</option><option value="phase">PHASE</option><option value="change">CHANGE</option>'.html_safe), :class => 'form-control' %>
|
|
38
|
+
<%= select_tag 'subscription_filter', options_for_select('<option value="all">ALL</option><option value="none">NONE</option><option value="start_entitlement">START_ENTITLEMENT</option><option value="pause_entitlement">PAUSE_ENTITLEMENT</option><option value="resume_entitlement">RESUME_ENTITLEMENT</option><option value="stop_entitlement">STOP_ENTITLEMENT</option><option value="phase">PHASE</option><option value="change">CHANGE</option>'.html_safe), :class => 'form-control' %>
|
|
39
39
|
</div>
|
|
40
40
|
</div>
|
|
41
41
|
<div class="form-group p-0 w-100 max-width-148">
|
|
42
42
|
<label for="billing_filter" class="control-label">Billing</label>
|
|
43
43
|
<div class="d-flex">
|
|
44
|
-
<%= select_tag 'billing_filter', options_for_select('<option value="all">ALL</option><option value="invoice">INVOICE</option><option value="start_billing">START_BILLING</option><option value="pause_billing">PAUSE_BILLING</option><option value="resume_billing">RESUME_BILLING</option><option value="stop_billing">STOP_BILLING</option>'.html_safe), :class => 'form-control' %>
|
|
44
|
+
<%= select_tag 'billing_filter', options_for_select('<option value="all">ALL</option><option value="none">NONE</option><option value="invoice">INVOICE</option><option value="start_billing">START_BILLING</option><option value="pause_billing">PAUSE_BILLING</option><option value="resume_billing">RESUME_BILLING</option><option value="stop_billing">STOP_BILLING</option>'.html_safe), :class => 'form-control' %>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
<div class="form-group p-0 w-100 max-width-148">
|
|
48
|
+
<label for="blocking_state_filter" class="control-label">Blocking State</label>
|
|
49
|
+
<div class="d-flex">
|
|
50
|
+
<%= select_tag 'blocking_state_filter', options_for_select('<option value="all">ALL</option><option value="start_entitlement">START_ENTITLEMENT</option><option value="start_billing">START_BILLING</option><option value="service_state_change">SERVICE_STATE_CHANGE</option><option value="none">NONE</option>'.html_safe), :class => 'form-control' %>
|
|
45
51
|
</div>
|
|
46
52
|
</div>
|
|
47
53
|
<div class="form-group p-0 d-flex align-self-end justify-content-end w-100">
|
|
@@ -49,13 +55,6 @@
|
|
|
49
55
|
</div>
|
|
50
56
|
</form>
|
|
51
57
|
|
|
52
|
-
<div class="form-horizontal d-flex gap-2 mb-4 mx-0">
|
|
53
|
-
<div class="form-group p-0 d-flex align-items-center gap-2">
|
|
54
|
-
<label for="group-by" class="control-label mb-0 text-nowrap">Group by</label>
|
|
55
|
-
<%= select_tag 'group-by', options_for_select([['Object Type', 'type'], ['Date', 'date']], 'type'), :class => 'form-control' %>
|
|
56
|
-
</div>
|
|
57
|
-
</div>
|
|
58
|
-
|
|
59
58
|
<div id="timeline-entries">
|
|
60
59
|
<% if @account.present? %>
|
|
61
60
|
<% @invoices.each do |invoice_stub| %>
|
|
@@ -67,7 +66,7 @@
|
|
|
67
66
|
<% else %>
|
|
68
67
|
<% invoice = invoice_stub %>
|
|
69
68
|
<% end %>
|
|
70
|
-
<div title="<%= bundles %>" data-event-type="INVOICE" data-timestamp="<%= timeline_sort_timestamp(invoice.target_date) %>">
|
|
69
|
+
<div title="<%= bundles %>" data-event-type="INVOICE" data-event-category="invoice" data-timestamp="<%= timeline_sort_timestamp(invoice.target_date) %>">
|
|
71
70
|
<div class="datetime-container">
|
|
72
71
|
<% if invoice.target_date.present? %>
|
|
73
72
|
<%= invoice.target_date %>
|
|
@@ -155,7 +154,7 @@
|
|
|
155
154
|
<% invoice = nil %>
|
|
156
155
|
<% end %>
|
|
157
156
|
<% payment.transactions.each do |transaction| %>
|
|
158
|
-
<div title="<%= bundles %>" data-event-type="<%= transaction.transaction_type %>" data-timestamp="<%= timeline_sort_timestamp(transaction.effective_date) %>">
|
|
157
|
+
<div title="<%= bundles %>" data-event-type="<%= transaction.transaction_type %>" data-event-category="payment" data-timestamp="<%= timeline_sort_timestamp(transaction.effective_date) %>">
|
|
159
158
|
<div class="datetime-container">
|
|
160
159
|
<% if transaction.effective_date.present? %>
|
|
161
160
|
<%= format_date(transaction.effective_date, @account.time_zone).html_safe %>
|
|
@@ -235,61 +234,179 @@
|
|
|
235
234
|
<% @bundles.each do |bundle| %>
|
|
236
235
|
<% bundle.subscriptions.each do |sub| %>
|
|
237
236
|
<% sub.events.each do |event| %>
|
|
238
|
-
<%
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
237
|
+
<% if event.event_type == 'SERVICE_STATE_CHANGE' %>
|
|
238
|
+
<div title="<%= @bundle_names[bundle.external_key] %>" data-event-type="SERVICE_STATE_CHANGE" data-event-category="blocking_state" data-timestamp="<%= timeline_sort_timestamp(event.effective_date) %>">
|
|
239
|
+
<div class="datetime-container">
|
|
240
|
+
<% if event.effective_date.present? %>
|
|
241
|
+
<%= format_date(event.effective_date, @account.time_zone).html_safe %>
|
|
242
|
+
<% else %>
|
|
243
|
+
[unknown]
|
|
244
|
+
<% end %>
|
|
245
|
+
</div>
|
|
246
|
+
<div class="account-timeline-card d-flex gap-3">
|
|
247
|
+
<span class="icon-container">
|
|
248
|
+
<%= image_tag("kaui/timeline/block.svg", width: 20, height: 20) %>
|
|
249
|
+
</span>
|
|
250
|
+
|
|
251
|
+
<div class="d-flex justify-content-start flex-column gap-3 w-100 row">
|
|
252
|
+
<h3>BLOCKING STATE</h3>
|
|
253
|
+
<div class="w-100">
|
|
254
|
+
<div class="row account-timeline-card-detail">
|
|
255
|
+
<div class="col-sm-4">
|
|
256
|
+
<div>
|
|
257
|
+
<b>Service / State</b>
|
|
258
|
+
<p>
|
|
259
|
+
<%= event.service_name %> / <%= event.service_state_name %>
|
|
260
|
+
</p>
|
|
261
|
+
</div>
|
|
262
262
|
</div>
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
</
|
|
263
|
+
<div class="col-sm-4">
|
|
264
|
+
<div>
|
|
265
|
+
<b>Blocked</b>
|
|
266
|
+
<p>
|
|
267
|
+
<%= 'Billing' if event.is_blocked_billing %>
|
|
268
|
+
<%= 'Entitlement' if event.is_blocked_entitlement %>
|
|
269
|
+
</p>
|
|
270
|
+
</div>
|
|
271
|
+
<div>
|
|
272
|
+
<b>Bundle</b>
|
|
273
|
+
<p>
|
|
274
|
+
<%= truncate_uuid(@bundle_names[bundle.external_key]) %>
|
|
275
|
+
</p>
|
|
276
|
+
</div>
|
|
277
|
+
</div>
|
|
278
|
+
<div class="col-sm-4">
|
|
279
|
+
<div>
|
|
280
|
+
<b>Reason Code / Comments</b>
|
|
281
|
+
<p>
|
|
282
|
+
<% if event.audit_logs.present? %>
|
|
283
|
+
<% event.audit_logs.each do |entry| %>
|
|
284
|
+
<%= Kaui::AuditLog.description(entry) %>
|
|
285
|
+
<% end %>
|
|
286
|
+
<% end %>
|
|
287
|
+
</p>
|
|
288
|
+
</div>
|
|
271
289
|
</div>
|
|
272
290
|
</div>
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
291
|
+
</div>
|
|
292
|
+
</div>
|
|
293
|
+
</div>
|
|
294
|
+
</div>
|
|
295
|
+
<% else %>
|
|
296
|
+
<% event_category = %w[START_BILLING PAUSE_BILLING RESUME_BILLING STOP_BILLING].include?(event.event_type) ? 'billing' : 'subscription' %>
|
|
297
|
+
<div title="<%= @bundle_names[bundle.external_key] %>" data-event-type="<%= event.event_type %>" data-event-category="<%= event_category %>" data-timestamp="<%= timeline_sort_timestamp(event.effective_date) %>">
|
|
298
|
+
<div class="datetime-container">
|
|
299
|
+
<% if event.effective_date.present? %>
|
|
300
|
+
<%= format_date(event.effective_date, @account.time_zone).html_safe %>
|
|
301
|
+
<% else %>
|
|
302
|
+
[unknown]
|
|
303
|
+
<% end %>
|
|
304
|
+
</div>
|
|
305
|
+
<div class="account-timeline-card d-flex gap-3">
|
|
306
|
+
<span class="icon-container">
|
|
307
|
+
<%= image_tag("kaui/timeline/invoice.svg", width: 20, height: 20) %>
|
|
308
|
+
</span>
|
|
309
|
+
|
|
310
|
+
<div class="d-flex justify-content-start flex-column gap-3 w-100 row">
|
|
311
|
+
<h3><%= event.event_type %></h3>
|
|
312
|
+
<div class="w-100">
|
|
313
|
+
<div class="row account-timeline-card-detail">
|
|
314
|
+
<div class="col-sm-4">
|
|
315
|
+
<div>
|
|
316
|
+
<b>Details</b>
|
|
317
|
+
<p>
|
|
318
|
+
<% if event.is_blocked_billing || event.is_blocked_entitlement %>
|
|
319
|
+
<%= event.service_name %> / <%= event.service_state_name %><br/>
|
|
280
320
|
<% end %>
|
|
281
|
-
|
|
282
|
-
|
|
321
|
+
<%= event.phase %><span class="hide" title="<%= sub.product_category %>"></span>
|
|
322
|
+
</p>
|
|
323
|
+
</div>
|
|
324
|
+
|
|
325
|
+
</div>
|
|
326
|
+
<div class="col-sm-4">
|
|
327
|
+
<div>
|
|
328
|
+
<b>Bundle</b>
|
|
329
|
+
<p>
|
|
330
|
+
<%= truncate_uuid(@bundle_names[bundle.external_key]) %>
|
|
331
|
+
</p>
|
|
332
|
+
</div>
|
|
333
|
+
</div>
|
|
334
|
+
<div class="col-sm-4">
|
|
335
|
+
<div>
|
|
336
|
+
<b>Reason Code / Comments</b>
|
|
337
|
+
<p>
|
|
338
|
+
<% if event.audit_logs.present? %>
|
|
339
|
+
<% event.audit_logs.each do |entry| %>
|
|
340
|
+
<%= Kaui::AuditLog.description(entry) %>
|
|
341
|
+
<% end %>
|
|
342
|
+
<% end %>
|
|
343
|
+
</p>
|
|
344
|
+
</div>
|
|
283
345
|
</div>
|
|
284
346
|
</div>
|
|
285
347
|
</div>
|
|
286
348
|
</div>
|
|
287
349
|
</div>
|
|
288
350
|
</div>
|
|
289
|
-
|
|
351
|
+
<% end %>
|
|
290
352
|
<% end %>
|
|
291
353
|
<% end %>
|
|
292
354
|
<% end %>
|
|
355
|
+
|
|
356
|
+
<% (@account_blocking_states || []).each do |blocking_state| %>
|
|
357
|
+
<div data-event-type="SERVICE_STATE_CHANGE" data-event-category="blocking_state" data-timestamp="<%= timeline_sort_timestamp(blocking_state.effective_date) %>">
|
|
358
|
+
<div class="datetime-container">
|
|
359
|
+
<% if blocking_state.effective_date.present? %>
|
|
360
|
+
<%= format_date(blocking_state.effective_date, @account.time_zone).html_safe %>
|
|
361
|
+
<% else %>
|
|
362
|
+
[unknown]
|
|
363
|
+
<% end %>
|
|
364
|
+
</div>
|
|
365
|
+
<div class="account-timeline-card d-flex gap-3">
|
|
366
|
+
<span class="icon-container">
|
|
367
|
+
<%= image_tag("kaui/timeline/block.svg", width: 20, height: 20) %>
|
|
368
|
+
</span>
|
|
369
|
+
|
|
370
|
+
<div class="d-flex justify-content-start flex-column gap-3 w-100 row">
|
|
371
|
+
<h3>BLOCKING STATE</h3>
|
|
372
|
+
<div class="w-100">
|
|
373
|
+
<div class="row account-timeline-card-detail">
|
|
374
|
+
<div class="col-sm-4">
|
|
375
|
+
<div>
|
|
376
|
+
<b>Service / State</b>
|
|
377
|
+
<p>
|
|
378
|
+
<%= blocking_state.service %> / <%= blocking_state.state_name %>
|
|
379
|
+
</p>
|
|
380
|
+
</div>
|
|
381
|
+
</div>
|
|
382
|
+
<div class="col-sm-4">
|
|
383
|
+
<div>
|
|
384
|
+
<b>Blocked</b>
|
|
385
|
+
<p>
|
|
386
|
+
<%= 'Change' if blocking_state.is_block_change %>
|
|
387
|
+
<%= 'Billing' if blocking_state.is_block_billing %>
|
|
388
|
+
<%= 'Entitlement' if blocking_state.is_block_entitlement %>
|
|
389
|
+
</p>
|
|
390
|
+
</div>
|
|
391
|
+
</div>
|
|
392
|
+
<div class="col-sm-4">
|
|
393
|
+
<div>
|
|
394
|
+
<b>Reason Code / Comments</b>
|
|
395
|
+
<p>
|
|
396
|
+
<% if blocking_state.audit_logs.present? %>
|
|
397
|
+
<% blocking_state.audit_logs.each do |entry| %>
|
|
398
|
+
<%= Kaui::AuditLog.description(entry) %>
|
|
399
|
+
<% end %>
|
|
400
|
+
<% end %>
|
|
401
|
+
</p>
|
|
402
|
+
</div>
|
|
403
|
+
</div>
|
|
404
|
+
</div>
|
|
405
|
+
</div>
|
|
406
|
+
</div>
|
|
407
|
+
</div>
|
|
408
|
+
</div>
|
|
409
|
+
<% end %>
|
|
293
410
|
<% end %>
|
|
294
411
|
</div>
|
|
295
412
|
</div>
|
|
@@ -305,7 +422,7 @@
|
|
|
305
422
|
}
|
|
306
423
|
|
|
307
424
|
var eventsOrder = ["START_ENTITLEMENT", "START_BILLING", "PAUSE_ENTITLEMENT", "PAUSE_BILLING", "RESUME_ENTITLEMENT",
|
|
308
|
-
"RESUME_BILLING", "PHASE", "CHANGE", "STOP_ENTITLEMENT", "STOP_BILLING", "INVOICE", "AUTHORIZE", "PURCHASE", "CAPTURE",
|
|
425
|
+
"RESUME_BILLING", "PHASE", "CHANGE", "STOP_ENTITLEMENT", "STOP_BILLING", "SERVICE_STATE_CHANGE", "INVOICE", "AUTHORIZE", "PURCHASE", "CAPTURE",
|
|
309
426
|
"CREDIT", "REFUND", "VOID", "CHARGEBACK"];
|
|
310
427
|
|
|
311
428
|
jQuery.fn.dataTableExt.oSort['timeline-event-asc'] = function(e1,e2) {
|
|
@@ -359,92 +476,95 @@
|
|
|
359
476
|
});
|
|
360
477
|
}
|
|
361
478
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
function sortTimelineEntries(sortByDate) {
|
|
479
|
+
function sortTimelineEntries() {
|
|
365
480
|
var $container = $('#timeline-entries');
|
|
366
481
|
var $entries = $container.children('[data-event-type]');
|
|
367
482
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
if (sortByDate) {
|
|
375
|
-
orderedEntries = $entries.get().sort(function (a, b) {
|
|
376
|
-
var x = parseInt($(a).attr('data-timestamp'), 10);
|
|
377
|
-
var y = parseInt($(b).attr('data-timestamp'), 10);
|
|
378
|
-
x = isNaN(x) ? -Infinity : x;
|
|
379
|
-
y = isNaN(y) ? -Infinity : y;
|
|
380
|
-
// Most recent first; entries without a usable timestamp sort last
|
|
483
|
+
var orderedEntries = $entries.get().sort(function (a, b) {
|
|
484
|
+
var x = parseInt($(a).attr('data-timestamp'), 10);
|
|
485
|
+
var y = parseInt($(b).attr('data-timestamp'), 10);
|
|
486
|
+
x = isNaN(x) ? -Infinity : x;
|
|
487
|
+
y = isNaN(y) ? -Infinity : y;
|
|
488
|
+
if (y !== x) {
|
|
381
489
|
return y - x;
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
490
|
+
}
|
|
491
|
+
var typeX = eventsOrder.indexOf($(a).attr('data-event-type'));
|
|
492
|
+
var typeY = eventsOrder.indexOf($(b).attr('data-event-type'));
|
|
493
|
+
typeX = typeX === -1 ? Infinity : typeX;
|
|
494
|
+
typeY = typeY === -1 ? Infinity : typeY;
|
|
495
|
+
return typeX - typeY;
|
|
496
|
+
});
|
|
386
497
|
|
|
387
498
|
$.each(orderedEntries, function (_, entry) {
|
|
388
499
|
$container.append(entry);
|
|
389
500
|
});
|
|
390
501
|
|
|
391
|
-
// Re-apply any active filters, since the DOM order just changed
|
|
392
502
|
filterTimeline();
|
|
393
503
|
}
|
|
394
504
|
|
|
395
505
|
function filterTimeline() {
|
|
396
506
|
var selectedBundle = $("#bundles").val();
|
|
397
|
-
var selectedPayment = $('#payment_filter').val().toUpperCase();
|
|
398
|
-
var selectedSubscription = $('#subscription_filter').val().toUpperCase();
|
|
399
|
-
var selectedBilling = $('#billing_filter').val().toUpperCase();
|
|
400
507
|
var searchQuery = $('#search').val().toLowerCase();
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
508
|
+
var blockingStateFilter = $('#blocking_state_filter').val().toUpperCase();
|
|
509
|
+
|
|
510
|
+
var categoryFilters = {
|
|
511
|
+
payment: { value: $('#payment_filter').val().toUpperCase(), categories: ['payment'] },
|
|
512
|
+
subscription: { value: $('#subscription_filter').val().toUpperCase(), categories: ['subscription'] },
|
|
513
|
+
billing: { value: $('#billing_filter').val().toUpperCase(), categories: ['billing', 'invoice'] }
|
|
514
|
+
};
|
|
515
|
+
|
|
406
516
|
$('.account-timeline-card').parent().each(function() {
|
|
407
517
|
var $card = $(this);
|
|
408
|
-
var eventType = $card.
|
|
518
|
+
var eventType = ($card.attr('data-event-type') || '').toUpperCase();
|
|
519
|
+
var eventCategory = $card.attr('data-event-category') || '';
|
|
409
520
|
var bundleTitle = $card.attr('title');
|
|
410
521
|
var cardText = $card.text().toLowerCase();
|
|
411
|
-
|
|
522
|
+
|
|
412
523
|
var shouldShow = true;
|
|
413
|
-
|
|
524
|
+
|
|
414
525
|
if (selectedBundle && selectedBundle !== '' && selectedBundle !== 'All') {
|
|
415
526
|
if (!bundleTitle || bundleTitle.indexOf(selectedBundle) === -1) {
|
|
416
527
|
shouldShow = false;
|
|
417
528
|
}
|
|
418
529
|
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
530
|
+
|
|
531
|
+
if (shouldShow) {
|
|
532
|
+
if (blockingStateFilter === 'NONE') {
|
|
533
|
+
if (eventCategory === 'blocking_state') {
|
|
534
|
+
shouldShow = false;
|
|
535
|
+
}
|
|
536
|
+
} else if (blockingStateFilter !== 'ALL') {
|
|
537
|
+
// Specific type selected: show only events matching that exact type
|
|
538
|
+
if (eventType !== blockingStateFilter) {
|
|
539
|
+
shouldShow = false;
|
|
540
|
+
}
|
|
541
|
+
} else {
|
|
542
|
+
// Blocking state filter is ALL — apply per-category filters
|
|
543
|
+
var governingFilter = null;
|
|
544
|
+
$.each(categoryFilters, function(_, f) {
|
|
545
|
+
if (f.categories.indexOf(eventCategory) !== -1) {
|
|
546
|
+
governingFilter = f;
|
|
547
|
+
}
|
|
548
|
+
});
|
|
549
|
+
if (governingFilter) {
|
|
550
|
+
if (governingFilter.value === 'NONE') {
|
|
551
|
+
shouldShow = false;
|
|
552
|
+
} else if (governingFilter.value !== 'ALL') {
|
|
553
|
+
if (eventType !== governingFilter.value) {
|
|
554
|
+
shouldShow = false;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
}
|
|
438
558
|
}
|
|
439
559
|
}
|
|
440
|
-
|
|
560
|
+
|
|
441
561
|
// Apply search filter if query exists
|
|
442
562
|
if (searchQuery && shouldShow) {
|
|
443
563
|
if (cardText.indexOf(searchQuery) === -1) {
|
|
444
564
|
shouldShow = false;
|
|
445
565
|
}
|
|
446
566
|
}
|
|
447
|
-
|
|
567
|
+
|
|
448
568
|
// Show or hide the card based on all filters
|
|
449
569
|
if (shouldShow) {
|
|
450
570
|
$card.show();
|
|
@@ -456,22 +576,15 @@
|
|
|
456
576
|
|
|
457
577
|
$(document).ready(function() {
|
|
458
578
|
disableLinks();
|
|
459
|
-
|
|
579
|
+
|
|
460
580
|
// Initialize filters with debounce for search
|
|
461
581
|
var searchTimeout;
|
|
462
|
-
$("#bundles, #payment_filter, #subscription_filter, #billing_filter").on('change', filterTimeline);
|
|
582
|
+
$("#bundles, #payment_filter, #subscription_filter, #billing_filter, #blocking_state_filter").on('change', filterTimeline);
|
|
463
583
|
$('#search').on('keyup', function() {
|
|
464
584
|
clearTimeout(searchTimeout);
|
|
465
585
|
searchTimeout = setTimeout(filterTimeline, 300);
|
|
466
586
|
});
|
|
467
587
|
|
|
468
|
-
$('#group-by').on('change', function() {
|
|
469
|
-
sortTimelineEntries($(this).val() === 'date');
|
|
470
|
-
});
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
588
|
// Clear all filters button
|
|
476
589
|
$('#clear-all-filters').click(function() {
|
|
477
590
|
$('#search').val('');
|
|
@@ -479,10 +592,11 @@
|
|
|
479
592
|
$('#payment_filter').val('all');
|
|
480
593
|
$('#subscription_filter').val('all');
|
|
481
594
|
$('#billing_filter').val('all');
|
|
595
|
+
$('#blocking_state_filter').val('all');
|
|
482
596
|
filterTimeline();
|
|
483
597
|
});
|
|
484
|
-
|
|
485
|
-
//
|
|
486
|
-
|
|
598
|
+
|
|
599
|
+
// Sort by date first, event type second, then apply filters
|
|
600
|
+
sortTimelineEntries();
|
|
487
601
|
});
|
|
488
602
|
<% end %>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<div class="billing-details-header">
|
|
4
4
|
<h2>Billing Information</h2>
|
|
5
5
|
<span>
|
|
6
|
-
<% if can?(:trigger, Kaui::Payment) || can?(:credit, Kaui::Account) || can?(:charge, Kaui::Account) %>
|
|
6
|
+
<% if can?(:trigger, Kaui::Payment) || can?(:credit, Kaui::Account) || can?(:charge, Kaui::Account) || can?(:update, Kaui::Account) %>
|
|
7
7
|
<div class="tag-bar tag-bar-breathe">
|
|
8
8
|
<div class="toggler">
|
|
9
9
|
<div class="toggle">
|
|
@@ -59,6 +59,18 @@
|
|
|
59
59
|
<% end %>
|
|
60
60
|
<% end %>
|
|
61
61
|
|
|
62
|
+
<% if can? :update, Kaui::Account %>
|
|
63
|
+
<%= link_to kaui_engine.block_account_path(@account.account_id) do %>
|
|
64
|
+
<%= render "kaui/components/button/button", {
|
|
65
|
+
label: "Create Blocking State",
|
|
66
|
+
icon: "kaui/plus.svg",
|
|
67
|
+
variant: "outline-secondary d-inline-flex align-items-center gap-1",
|
|
68
|
+
type: "button",
|
|
69
|
+
html_class: "kaui-dropdown custom-hover",
|
|
70
|
+
} %>
|
|
71
|
+
<% end %>
|
|
72
|
+
<% end %>
|
|
73
|
+
|
|
62
74
|
</div>
|
|
63
75
|
</div>
|
|
64
76
|
</div>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
<div class="info-wrapper">
|
|
8
8
|
|
|
9
|
-
<% if can?(:trigger, Kaui::Payment) || can?(:credit, Kaui::Account) || can?(:charge, Kaui::Account) %>
|
|
9
|
+
<% if can?(:trigger, Kaui::Payment) || can?(:credit, Kaui::Account) || can?(:charge, Kaui::Account) || can?(:update, Kaui::Account) %>
|
|
10
10
|
<div class="tag-bar tag-bar-breathe">
|
|
11
11
|
<div class="toggler">
|
|
12
12
|
<div class="toggle">
|
|
@@ -29,6 +29,10 @@
|
|
|
29
29
|
<%= link_to '<i class="fa fa-plus-square"></i> Create deposit'.html_safe,
|
|
30
30
|
deposit_engine.collection_index_path(:account_id => @account.account_id, :currency => @account.currency) %>
|
|
31
31
|
<% end %>
|
|
32
|
+
<% if can? :update, Kaui::Account %>
|
|
33
|
+
<%= link_to '<i class="fa fa-plus-square"></i> Create blocking state'.html_safe,
|
|
34
|
+
kaui_engine.block_account_path(@account.account_id) %>
|
|
35
|
+
<% end %>
|
|
32
36
|
</div>
|
|
33
37
|
</div>
|
|
34
38
|
</div>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<div class="register kaui-subscription-new">
|
|
2
|
+
<div class="d-flex justify-content-center flex-wrap" style="gap: 2rem; max-width: 60.5rem; margin: 0 auto;">
|
|
3
|
+
<h5 class="add-account-title border-bottom pb-3 mb-3" style="flex: 0 0 100%;">
|
|
4
|
+
<span class="icon-container">
|
|
5
|
+
<%= image_tag "kaui/timeline/block.svg", width: 20, height: 20 %>
|
|
6
|
+
</span>
|
|
7
|
+
Create blocking state
|
|
8
|
+
</h5>
|
|
9
|
+
<div style="max-width: 37.5rem; width: 100%;">
|
|
10
|
+
<%= form_tag do_block_account_path(:account_id => @account.account_id), :class => 'form-horizontal', :method => :put do %>
|
|
11
|
+
<%= render "kaui/components/blocking_state_form/fields", :applies_to_type => 'Account', :applies_to_id => @account.account_id %>
|
|
12
|
+
<% end %>
|
|
13
|
+
</div>
|
|
14
|
+
<%= render "kaui/components/blocking_state_form/about_panel" %>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
<%= form_for @allowed_user, :url => @allowed_user.persisted? ? admin_allowed_user_path(@allowed_user.id) : admin_allowed_users_path, :method => @allowed_user.persisted? ? :put : :post, :html => {:class => 'form-horizontal'} do |f| %>
|
|
2
2
|
<input type="hidden" id="killbillManaged" value="<%= @is_killbill_managed %>" />
|
|
3
3
|
<div class='form-group d-flex pb-3'>
|
|
4
|
-
|
|
4
|
+
<%# Not associated with a real attribute - use label_tag instead of f.label, which under
|
|
5
|
+
Rails 7.2 raises NoMethodError (undefined method `humanize' for nil) for a blank name,
|
|
6
|
+
since ActiveModel::Translation#human_attribute_name only handles a blank *namespaced*
|
|
7
|
+
attribute (e.g. "foo."), not a plain blank string. %>
|
|
8
|
+
<%= label_tag nil, ' ', :class => 'col-sm-3 control-label' %>
|
|
5
9
|
<div class="col-sm-9">
|
|
6
10
|
<div class="checkbox">
|
|
7
11
|
<label for="external" class="d-flex align-items-center gap-2 control-label">
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<div class="register kaui-subscription-new">
|
|
2
|
+
<div class="d-flex justify-content-center flex-wrap" style="gap: 2rem; max-width: 60.5rem; margin: 0 auto;">
|
|
3
|
+
<h5 class="add-account-title border-bottom pb-3 mb-3" style="flex: 0 0 100%;">
|
|
4
|
+
<span class="icon-container">
|
|
5
|
+
<%= image_tag "kaui/timeline/block.svg", width: 20, height: 20 %>
|
|
6
|
+
</span>
|
|
7
|
+
Create blocking state
|
|
8
|
+
</h5>
|
|
9
|
+
<div style="max-width: 37.5rem; width: 100%;">
|
|
10
|
+
<%= form_tag do_block_bundle_path(:id => @bundle.bundle_id, :account_id => @bundle.account_id), :class => 'form-horizontal', :method => :put do %>
|
|
11
|
+
<%= render "kaui/components/blocking_state_form/fields", :applies_to_type => 'Bundle', :applies_to_id => @bundle.bundle_id %>
|
|
12
|
+
<% end %>
|
|
13
|
+
</div>
|
|
14
|
+
<%= render "kaui/components/blocking_state_form/about_panel" %>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<div class="blocking-state-about-panel">
|
|
2
|
+
<div class="d-flex align-items-center gap-2 mb-2">
|
|
3
|
+
<div class="icon-container">
|
|
4
|
+
<%= image_tag "kaui/blocking-states/shield-white.svg", width: 20, height: 20 %>
|
|
5
|
+
</div>
|
|
6
|
+
<h6 class="mb-0"><%= t('blocking_state_about_panel.title') %></h6>
|
|
7
|
+
</div>
|
|
8
|
+
<p><%= t('blocking_state_about_panel.description') %></p>
|
|
9
|
+
</div>
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<div class="form-group d-flex pb-3">
|
|
2
|
+
<label class="col-sm-3 control-label">Applies to</label>
|
|
3
|
+
<div class="col-sm-9">
|
|
4
|
+
<p class="form-control-plaintext mb-0"><%= applies_to_type %> — <%= applies_to_id %></p>
|
|
5
|
+
</div>
|
|
6
|
+
</div>
|
|
7
|
+
<div class="form-group d-flex pb-3">
|
|
8
|
+
<%= label_tag :state_name, 'State', :class => 'col-sm-3 control-label' %>
|
|
9
|
+
<div class="col-sm-9">
|
|
10
|
+
<%= text_field_tag :state_name, nil, :class => 'form-control', :placeholder => 'e.g., OVERDUE_ENFORCEMENT' %>
|
|
11
|
+
<small class="form-text text-muted">The name of the state being applied, e.g. a step in an overdue enforcement process.</small>
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
<div class="form-group d-flex pb-3">
|
|
15
|
+
<%= label_tag :service, 'Service', :class => 'col-sm-3 control-label' %>
|
|
16
|
+
<div class="col-sm-9">
|
|
17
|
+
<%= text_field_tag :service, nil, :class => 'form-control' %>
|
|
18
|
+
<small class="form-text text-muted">The service responsible for setting and enforcing this blocking state.</small>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
<div class="form-group d-flex pb-3">
|
|
22
|
+
<label class="col-sm-3 control-label">Block</label>
|
|
23
|
+
<div class="col-sm-9">
|
|
24
|
+
<div class="d-flex gap-3">
|
|
25
|
+
<div class="form-check">
|
|
26
|
+
<%= check_box_tag :is_block_change, '1', false, :class => 'form-check-input' %>
|
|
27
|
+
<%= label_tag :is_block_change, 'Change', :class => 'form-check-label' %>
|
|
28
|
+
</div>
|
|
29
|
+
<div class="form-check">
|
|
30
|
+
<%= check_box_tag :is_block_entitlement, '1', false, :class => 'form-check-input' %>
|
|
31
|
+
<%= label_tag :is_block_entitlement, 'Entitlement', :class => 'form-check-label' %>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="form-check">
|
|
34
|
+
<%= check_box_tag :is_block_billing, '1', false, :class => 'form-check-input' %>
|
|
35
|
+
<%= label_tag :is_block_billing, 'Billing', :class => 'form-check-label' %>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
<small class="form-text text-muted">Change blocks plan/subscription changes, Entitlement blocks usage of the service, and Billing blocks invoicing.</small>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
<div class="form-group d-flex pb-3" id="form_effective_from_date">
|
|
42
|
+
<%= label_tag :requested_date, 'Effective date', :class => 'col-sm-3 control-label' %>
|
|
43
|
+
<div class="col-sm-9">
|
|
44
|
+
<div class="custom-date-input-wrapper kaui-button custom-hover" onclick="$(this).find('input').focus();">
|
|
45
|
+
<svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
46
|
+
<path d="M14.9167 12.5V18.3333M17.8333 15.4167H12" stroke="#A4A7AE" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
47
|
+
<path d="M14.0833 1.66675V5.00008M6.58325 1.66675V5.00008" stroke="#A4A7AE" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
48
|
+
<path d="M17.8333 10.8333V4.99992C17.8333 4.07944 17.0871 3.33325 16.1666 3.33325H4.49992C3.57944 3.33325 2.83325 4.07944 2.83325 4.99992V16.6666C2.83325 17.5871 3.57944 18.3333 4.49992 18.3333H10.3333" stroke="#A4A7AE" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
49
|
+
<path d="M2.83325 8.33325H17.8333" stroke="#A4A7AE" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
50
|
+
</svg>
|
|
51
|
+
<input class="form-control" name="requested_date" type="text" data-provide="datepicker" data-date-format="yyyy-mm-dd" data-date-today-highlight="true">
|
|
52
|
+
</div>
|
|
53
|
+
<small class="form-text text-muted">Defaults to now if left blank.</small>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
<div class="form-group d-flex pb-3 border-bottom mb-3">
|
|
57
|
+
<%= label_tag :comment, 'Comment', :class => 'col-sm-3 control-label' %>
|
|
58
|
+
<div class="col-sm-9">
|
|
59
|
+
<%= text_area_tag :comment, nil, :rows => 3, :class => 'form-control' %>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
<div class="form-group d-flex justify-content-end pb-3">
|
|
63
|
+
<%= render "kaui/components/button/button", {
|
|
64
|
+
label: 'Close',
|
|
65
|
+
variant: "outline-secondary d-inline-flex align-items-center gap-1",
|
|
66
|
+
type: "button",
|
|
67
|
+
html_class: "kaui-button custom-hover mx-2",
|
|
68
|
+
html_options: {
|
|
69
|
+
id: "closeButton",
|
|
70
|
+
onclick: "window.history.back();"
|
|
71
|
+
}
|
|
72
|
+
} %>
|
|
73
|
+
<%= render "kaui/components/button/button", {
|
|
74
|
+
label: 'Submit',
|
|
75
|
+
variant: "outline-secondary d-inline-flex align-items-center gap-1",
|
|
76
|
+
type: "submit",
|
|
77
|
+
html_class: "kaui-dropdown custom-hover"
|
|
78
|
+
} %>
|
|
79
|
+
</div>
|
|
@@ -243,6 +243,22 @@
|
|
|
243
243
|
} %>
|
|
244
244
|
<% end %>
|
|
245
245
|
|
|
246
|
+
<% if can?(:pause_resume, Kaui::Subscription) && sub.product_category != 'ADD_ON' %>
|
|
247
|
+
<% menu_items << {
|
|
248
|
+
label: "Create blocking state (bundle)",
|
|
249
|
+
path: kaui_engine.block_bundle_path(account_id: bundle.account_id, id: bundle.bundle_id),
|
|
250
|
+
icon: "kaui/subscription/pause.svg"
|
|
251
|
+
} %>
|
|
252
|
+
<% end %>
|
|
253
|
+
|
|
254
|
+
<% if can?(:pause_resume, Kaui::Subscription) %>
|
|
255
|
+
<% menu_items << {
|
|
256
|
+
label: "Create blocking state (subscription)",
|
|
257
|
+
path: kaui_engine.block_subscription_path(account_id: bundle.account_id, id: sub.subscription_id),
|
|
258
|
+
icon: "kaui/subscription/pause.svg"
|
|
259
|
+
} %>
|
|
260
|
+
<% end %>
|
|
261
|
+
|
|
246
262
|
<% if menu_items.any? %>
|
|
247
263
|
<%= render partial: "kaui/components/menu_dropdown/menu_dropdown", locals: {
|
|
248
264
|
variant: "btn-light",
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<div class="register kaui-subscription-new">
|
|
2
|
+
<div class="d-flex justify-content-center flex-wrap" style="gap: 2rem; max-width: 60.5rem; margin: 0 auto;">
|
|
3
|
+
<h5 class="add-account-title border-bottom pb-3 mb-3" style="flex: 0 0 100%;">
|
|
4
|
+
<span class="icon-container">
|
|
5
|
+
<%= image_tag "kaui/timeline/block.svg", width: 20, height: 20 %>
|
|
6
|
+
</span>
|
|
7
|
+
Create blocking state
|
|
8
|
+
</h5>
|
|
9
|
+
<div style="max-width: 37.5rem; width: 100%;">
|
|
10
|
+
<%= form_tag do_block_subscription_path(:id => @subscription.subscription_id, :account_id => @subscription.account_id), :class => 'form-horizontal', :method => :put do %>
|
|
11
|
+
<%= render "kaui/components/blocking_state_form/fields", :applies_to_type => 'Subscription', :applies_to_id => @subscription.subscription_id %>
|
|
12
|
+
<% end %>
|
|
13
|
+
</div>
|
|
14
|
+
<%= render "kaui/components/blocking_state_form/about_panel" %>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
data/config/locales/en.yml
CHANGED
|
@@ -44,6 +44,10 @@ en:
|
|
|
44
44
|
loading_data_from_server: "Loading data from server"
|
|
45
45
|
requested_amount_colon: "Requested amount: "
|
|
46
46
|
|
|
47
|
+
blocking_state_about_panel:
|
|
48
|
+
title: "About Blocking States"
|
|
49
|
+
description: "Blocking states restrict actions on accounts, bundles, or subscriptions. They are enforced by specific services such as entitlement, billing, or custom services."
|
|
50
|
+
|
|
47
51
|
advanced_search:
|
|
48
52
|
title: "Advanced Search"
|
|
49
53
|
search_field: "Search field"
|
data/config/routes.rb
CHANGED
|
@@ -40,6 +40,8 @@ Kaui::Engine.routes.draw do
|
|
|
40
40
|
post '/trigger_invoice' => 'accounts#trigger_invoice', :as => 'trigger_invoice'
|
|
41
41
|
put '/link_to_parent' => 'accounts#link_to_parent', :as => 'link_to_parent'
|
|
42
42
|
delete '/unlink_to_parent' => 'accounts#unlink_to_parent', :as => 'unlink_to_parent'
|
|
43
|
+
get '/block' => 'accounts#block', :as => 'block_account'
|
|
44
|
+
put '/do_block' => 'accounts#do_block', :as => 'do_block_account'
|
|
43
45
|
|
|
44
46
|
scope '/account_tags' do
|
|
45
47
|
get '/' => 'account_tags#index', :as => 'account_tags'
|
|
@@ -134,6 +136,8 @@ Kaui::Engine.routes.draw do
|
|
|
134
136
|
get '/:id/pause_resume', to: 'bundles#pause_resume', as: 'pause_resume_bundle'
|
|
135
137
|
put '/:id/do_transfer', to: 'bundles#do_transfer', as: 'do_transfer_bundle'
|
|
136
138
|
get '/:id/transfer', to: 'bundles#transfer', as: 'transfer_bundle'
|
|
139
|
+
put '/:id/do_block', to: 'bundles#do_block', as: 'do_block_bundle'
|
|
140
|
+
get '/:id/block', to: 'bundles#block', as: 'block_bundle'
|
|
137
141
|
get '/:id' => 'bundles#restful_show', :as => 'bundle'
|
|
138
142
|
end
|
|
139
143
|
|
|
@@ -141,6 +145,8 @@ Kaui::Engine.routes.draw do
|
|
|
141
145
|
post '/:id/tags' => 'subscriptions#update_tags', :as => 'update_subscriptions_tags'
|
|
142
146
|
get '/:id/edit_bcd' => 'subscriptions#edit_bcd', :as => 'edit_bcd'
|
|
143
147
|
put '/:id/update_bcd' => 'subscriptions#update_bcd', :as => 'update_bcd'
|
|
148
|
+
get '/:id/block' => 'subscriptions#block', :as => 'block_subscription'
|
|
149
|
+
put '/:id/do_block' => 'subscriptions#do_block', :as => 'do_block_subscription'
|
|
144
150
|
get '/:id/edit_quantity' => 'subscriptions#edit_quantity', :as => 'edit_quantity'
|
|
145
151
|
put '/:id/update_quantity' => 'subscriptions#update_quantity', :as => 'update_quantity'
|
|
146
152
|
get '/:id/record_usage' => 'subscriptions#record_usage', :as => 'record_usage'
|
data/lib/kaui/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kaui
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.0.
|
|
4
|
+
version: 4.0.26
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kill Bill core team
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-09-15 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: actionpack
|
|
@@ -66,6 +66,20 @@ dependencies:
|
|
|
66
66
|
- - ">="
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
68
|
version: '0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: csv
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0'
|
|
76
|
+
type: :runtime
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
69
83
|
- !ruby/object:Gem::Dependency
|
|
70
84
|
name: devise
|
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -226,14 +240,14 @@ dependencies:
|
|
|
226
240
|
requirements:
|
|
227
241
|
- - "~>"
|
|
228
242
|
- !ruby/object:Gem::Version
|
|
229
|
-
version: '7.
|
|
243
|
+
version: '7.2'
|
|
230
244
|
type: :runtime
|
|
231
245
|
prerelease: false
|
|
232
246
|
version_requirements: !ruby/object:Gem::Requirement
|
|
233
247
|
requirements:
|
|
234
248
|
- - "~>"
|
|
235
249
|
- !ruby/object:Gem::Version
|
|
236
|
-
version: '7.
|
|
250
|
+
version: '7.2'
|
|
237
251
|
- !ruby/object:Gem::Dependency
|
|
238
252
|
name: spinjs-rails
|
|
239
253
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -309,6 +323,7 @@ files:
|
|
|
309
323
|
- app/assets/images/kaui/account/purchase.svg
|
|
310
324
|
- app/assets/images/kaui/account/refresh.svg
|
|
311
325
|
- app/assets/images/kaui/arrow.svg
|
|
326
|
+
- app/assets/images/kaui/blocking-states/shield-white.svg
|
|
312
327
|
- app/assets/images/kaui/card.svg
|
|
313
328
|
- app/assets/images/kaui/copy.svg
|
|
314
329
|
- app/assets/images/kaui/dashboard/aviate.svg
|
|
@@ -376,6 +391,7 @@ files:
|
|
|
376
391
|
- app/assets/images/kaui/subscription/pause.svg
|
|
377
392
|
- app/assets/images/kaui/subscription/transfer.svg
|
|
378
393
|
- app/assets/images/kaui/timeline/authorize.svg
|
|
394
|
+
- app/assets/images/kaui/timeline/block.svg
|
|
379
395
|
- app/assets/images/kaui/timeline/capture.svg
|
|
380
396
|
- app/assets/images/kaui/timeline/chargeback.svg
|
|
381
397
|
- app/assets/images/kaui/timeline/credit.svg
|
|
@@ -541,6 +557,7 @@ files:
|
|
|
541
557
|
- app/views/kaui/accounts/_payment_methods.html.erb
|
|
542
558
|
- app/views/kaui/accounts/_personal_details.html.erb
|
|
543
559
|
- app/views/kaui/accounts/_personal_info.html.erb
|
|
560
|
+
- app/views/kaui/accounts/block.html.erb
|
|
544
561
|
- app/views/kaui/accounts/edit.html.erb
|
|
545
562
|
- app/views/kaui/accounts/index.html.erb
|
|
546
563
|
- app/views/kaui/accounts/new.html.erb
|
|
@@ -580,6 +597,7 @@ files:
|
|
|
580
597
|
- app/views/kaui/bundle_tags/edit.html.erb
|
|
581
598
|
- app/views/kaui/bundles/_bundle_details.html.erb
|
|
582
599
|
- app/views/kaui/bundles/_bundle_filterbar.html.erb
|
|
600
|
+
- app/views/kaui/bundles/block.html.erb
|
|
583
601
|
- app/views/kaui/bundles/index.html.erb
|
|
584
602
|
- app/views/kaui/bundles/pause_resume.html.erb
|
|
585
603
|
- app/views/kaui/bundles/transfer.html.erb
|
|
@@ -587,6 +605,8 @@ files:
|
|
|
587
605
|
- app/views/kaui/chargebacks/new.html.erb
|
|
588
606
|
- app/views/kaui/charges/_form.html.erb
|
|
589
607
|
- app/views/kaui/charges/new.html.erb
|
|
608
|
+
- app/views/kaui/components/blocking_state_form/_about_panel.html.erb
|
|
609
|
+
- app/views/kaui/components/blocking_state_form/_fields.html.erb
|
|
590
610
|
- app/views/kaui/components/breadcrumb/_breadcrumb.html.erb
|
|
591
611
|
- app/views/kaui/components/button/_button.html.erb
|
|
592
612
|
- app/views/kaui/components/dashboard/_card.html.erb
|
|
@@ -652,6 +672,7 @@ files:
|
|
|
652
672
|
- app/views/kaui/subscriptions/_form.html.erb
|
|
653
673
|
- app/views/kaui/subscriptions/_subscriptions_table.html.erb
|
|
654
674
|
- app/views/kaui/subscriptions/_view_json_modal.html.erb
|
|
675
|
+
- app/views/kaui/subscriptions/block.html.erb
|
|
655
676
|
- app/views/kaui/subscriptions/edit.html.erb
|
|
656
677
|
- app/views/kaui/subscriptions/edit_bcd.erb
|
|
657
678
|
- app/views/kaui/subscriptions/edit_quantity.erb
|
|
@@ -707,7 +728,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
707
728
|
requirements:
|
|
708
729
|
- - ">="
|
|
709
730
|
- !ruby/object:Gem::Version
|
|
710
|
-
version:
|
|
731
|
+
version: 3.1.0
|
|
711
732
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
712
733
|
requirements:
|
|
713
734
|
- - ">="
|