kaui 3.0.3 → 3.0.4
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/controllers/kaui/account_timelines_controller.rb +121 -0
- data/app/controllers/kaui/accounts_controller.rb +46 -8
- data/app/controllers/kaui/audit_logs_controller.rb +37 -0
- data/app/controllers/kaui/bundles_controller.rb +5 -1
- data/app/controllers/kaui/engine_controller.rb +3 -28
- data/app/controllers/kaui/engine_controller_util.rb +8 -2
- data/app/controllers/kaui/invoices_controller.rb +54 -29
- data/app/controllers/kaui/payments_controller.rb +65 -9
- data/app/controllers/kaui/sessions_controller.rb +7 -0
- data/app/helpers/kaui/exception_helper.rb +25 -0
- data/app/helpers/kaui/subscription_helper.rb +4 -0
- data/app/models/kaui/account.rb +2 -0
- data/app/models/kaui/invoice.rb +2 -0
- data/app/views/kaui/account_timelines/_multi_functions_bar.html.erb +184 -0
- data/app/views/kaui/account_timelines/show.html.erb +2 -0
- data/app/views/kaui/accounts/_account_info.html.erb +7 -0
- data/app/views/kaui/accounts/_multi_functions_bar.html.erb +347 -0
- data/app/views/kaui/accounts/index.html.erb +46 -33
- data/app/views/kaui/audit_logs/_multi_functions_bar.html.erb +218 -0
- data/app/views/kaui/audit_logs/index.html.erb +1 -0
- data/app/views/kaui/bundles/index.html.erb +34 -0
- data/app/views/kaui/errors/500.html.erb +29 -0
- data/app/views/kaui/invoices/_multi_functions_bar.html.erb +340 -0
- data/app/views/kaui/invoices/index.html.erb +41 -19
- data/app/views/kaui/payments/_multi_functions_bar.html.erb +344 -0
- data/app/views/kaui/payments/index.html.erb +64 -25
- data/config/locales/en.yml +3 -0
- data/config/routes.rb +7 -0
- data/lib/kaui/error_handler.rb +37 -0
- data/lib/kaui/version.rb +1 -1
- data/lib/kaui.rb +105 -29
- metadata +10 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 381a1791f9fc6c1d64886d34dca17905a83ec38322043735a2437d83d8516d35
|
|
4
|
+
data.tar.gz: ee79517525bb910a58c1996621171c0600c113e98215e016f283f5d3ee9d2c0e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bce25f97853968fb171263eb1513ca6588d4884e0045232880bc24bc10cd55057b36e72cd89a7ef86996c4c9ec045a0b37aa7f39a35c2c9dfe0137866e1d7255
|
|
7
|
+
data.tar.gz: 371aa14f4390357331e257e9735a1c4f2ac940069b041f7bf595f68c960fec3c3ca32af274ba39b3abf4047a5e8d789590bbb6b90b079a11236bd7ee1b89de1a
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'csv'
|
|
4
|
+
|
|
3
5
|
module Kaui
|
|
4
6
|
class AccountTimelinesController < Kaui::EngineController
|
|
5
7
|
def show
|
|
@@ -30,8 +32,127 @@ module Kaui
|
|
|
30
32
|
@selected_bundle = params.key?(:external_key) ? @bundle_names[params[:external_key]] : nil
|
|
31
33
|
end
|
|
32
34
|
|
|
35
|
+
def download
|
|
36
|
+
timeline = Kaui::AccountTimeline.find_by_account_id(params.require(:account_id), 'FULL', options_for_klient)
|
|
37
|
+
start_date = params[:startDate]
|
|
38
|
+
end_date = params[:endDate]
|
|
39
|
+
start_date = begin
|
|
40
|
+
Date.parse(start_date)
|
|
41
|
+
rescue StandardError
|
|
42
|
+
nil
|
|
43
|
+
end
|
|
44
|
+
end_date = begin
|
|
45
|
+
Date.parse(end_date)
|
|
46
|
+
rescue StandardError
|
|
47
|
+
nil
|
|
48
|
+
end
|
|
49
|
+
start_date = params[:startDate].present? ? Date.parse(params[:startDate]) : nil
|
|
50
|
+
end_date = params[:endDate].present? ? Date.parse(params[:endDate]) : nil
|
|
51
|
+
|
|
52
|
+
event_type = params[:eventType]
|
|
53
|
+
@account = timeline.account
|
|
54
|
+
@bundles = timeline.bundles
|
|
55
|
+
@invoices = timeline.invoices
|
|
56
|
+
@payments = timeline.payments
|
|
57
|
+
extract_invoices_by_id(@invoices)
|
|
58
|
+
|
|
59
|
+
# Lookup all bundle names
|
|
60
|
+
@bundle_names = {}
|
|
61
|
+
@bundle_names_by_invoice_id = {}
|
|
62
|
+
@bundle_keys_by_invoice_id = {}
|
|
63
|
+
@bundles.each do |bundle|
|
|
64
|
+
load_bundle_name_for_timeline(bundle.external_key)
|
|
65
|
+
end
|
|
66
|
+
@invoices.each do |invoice|
|
|
67
|
+
@bundle_names_by_invoice_id[invoice.invoice_id] = Set.new
|
|
68
|
+
@bundle_keys_by_invoice_id[invoice.invoice_id] = Set.new
|
|
69
|
+
(invoice.bundle_keys || '').split(',').each do |bundle_key|
|
|
70
|
+
load_bundle_name_for_timeline(bundle_key)
|
|
71
|
+
@bundle_names_by_invoice_id[invoice.invoice_id] << @bundle_names[bundle_key]
|
|
72
|
+
@bundle_keys_by_invoice_id[invoice.invoice_id] << bundle_key
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
@selected_bundle = params.key?(:external_key) ? @bundle_names[params[:external_key]] : nil
|
|
77
|
+
|
|
78
|
+
csv_string = CSV.generate(headers: true) do |csv|
|
|
79
|
+
csv << ['Effective Date', 'Bundles', 'Even Type', 'Details', 'Reason Code/ Comments']
|
|
80
|
+
if %w[INVOICE ALL].include?(event_type)
|
|
81
|
+
@invoices.each do |invoice_stub|
|
|
82
|
+
invoice = invoice_stub.invoice_id.present? && @invoices_by_id.key?(invoice_stub.invoice_id) ? @invoices_by_id[invoice_stub.invoice_id] : invoice_stub
|
|
83
|
+
target_date = invoice.target_date.present? ? invoice.target_date : '[unknown]'
|
|
84
|
+
bundle_keys = invoice_stub.bundle_keys.present? ? invoice_stub.bundle_keys.split(',').map { |bundle_key| @bundle_names[bundle_key] }.join(', ') : ''
|
|
85
|
+
invoice_details = []
|
|
86
|
+
invoice_details << "Amount: #{invoice.amount_to_money} (#{@account.currency})"
|
|
87
|
+
invoice_details << "Balance: #{invoice.balance_to_money} (#{@account.currency})"
|
|
88
|
+
invoice_details << "Credit adjustment: #{invoice.credit_adjustment_to_money} (#{@account.currency})" if invoice.credit_adj.present? && invoice.credit_adj.positive?
|
|
89
|
+
invoice_details << "Refund adjustment: #{invoice.refund_adjustment_to_money} (#{@account.currency})" if invoice.refund_adj.present? && invoice.refund_adj.negative?
|
|
90
|
+
invoice_details << "Invoice #: #{invoice.invoice_number}"
|
|
91
|
+
audit_logs = invoice_stub.audit_logs.present? ? invoice_stub.audit_logs.map { |entry| Kaui::AuditLog.description(entry) }.join(', ') : ''
|
|
92
|
+
csv << [target_date, bundle_keys, 'INVOICE', invoice_details.join('; '), audit_logs] if filter_date(target_date, start_date, end_date)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
if %w[PAYMENT ALL].include?(event_type)
|
|
96
|
+
@payments.each do |payment|
|
|
97
|
+
invoice = if payment.target_invoice_id.present?
|
|
98
|
+
@invoices_by_id[payment.target_invoice_id]
|
|
99
|
+
else
|
|
100
|
+
nil
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
payment.transactions.each do |transaction|
|
|
104
|
+
effective_date = transaction.effective_date.present? ? transaction.effective_date : '[unknown]'
|
|
105
|
+
bundle_keys = @bundle_keys_by_invoice_id[payment.target_invoice_id].present? ? @bundle_keys_by_invoice_id[payment.target_invoice_id].map { |bundle_key| @bundle_names[bundle_key] }.join(', ') : ''
|
|
106
|
+
transaction_type = transaction.transaction_type
|
|
107
|
+
details = []
|
|
108
|
+
details << "Amount: #{Kaui::Transaction.amount_to_money(transaction)} (#{transaction.currency})" unless transaction.transaction_type == 'VOID'
|
|
109
|
+
details << "Status: #{transaction.status}"
|
|
110
|
+
details << "Payment #: #{payment.payment_number}"
|
|
111
|
+
details << "Invoice #: #{invoice.invoice_number}" unless invoice.nil?
|
|
112
|
+
|
|
113
|
+
audit_logs = transaction.audit_logs.present? ? transaction.audit_logs.map { |entry| Kaui::AuditLog.description(entry) }.chunk { |x| x }.map(&:first).join(', ') : ''
|
|
114
|
+
|
|
115
|
+
csv << [effective_date, bundle_keys, transaction_type, details.join('; '), audit_logs] if filter_date(effective_date, start_date, end_date)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
if %w[ENTITLEMENT ALL].include?(event_type)
|
|
121
|
+
@bundles.each do |bundle|
|
|
122
|
+
bundle.subscriptions.each do |sub|
|
|
123
|
+
sub.events.each do |event|
|
|
124
|
+
# Skip SERVICE_STATE_CHANGE events
|
|
125
|
+
next if event.event_type == 'SERVICE_STATE_CHANGE'
|
|
126
|
+
|
|
127
|
+
effective_date = event.effective_date.present? ? event.effective_date : '[unknown]'
|
|
128
|
+
bundle_keys = @bundle_names[bundle.external_key]
|
|
129
|
+
event_type = event.event_type
|
|
130
|
+
phase = event.phase
|
|
131
|
+
audit_logs = event.audit_logs.present? ? event.audit_logs.map { |entry| Kaui::AuditLog.description(entry) }.join(', ') : ''
|
|
132
|
+
|
|
133
|
+
csv << [effective_date, bundle_keys, event_type, phase, audit_logs] if filter_date(effective_date, start_date, end_date)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
send_data csv_string, filename: "account-timelines-#{Date.today}.csv", type: 'text/csv'
|
|
141
|
+
end
|
|
142
|
+
|
|
33
143
|
private
|
|
34
144
|
|
|
145
|
+
def filter_date(target_date, start_date, end_date)
|
|
146
|
+
return true if start_date.nil? || end_date.nil?
|
|
147
|
+
|
|
148
|
+
target_date = begin
|
|
149
|
+
Date.parse(target_date)
|
|
150
|
+
rescue StandardError
|
|
151
|
+
nil
|
|
152
|
+
end
|
|
153
|
+
target_date >= start_date && target_date <= end_date
|
|
154
|
+
end
|
|
155
|
+
|
|
35
156
|
def load_bundle_name_for_timeline(bundle_key)
|
|
36
157
|
@bundle_names[bundle_key] ||= Kaui.bundle_key_display_string.call(bundle_key)
|
|
37
158
|
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'csv'
|
|
3
4
|
module Kaui
|
|
4
5
|
class AccountsController < Kaui::EngineController
|
|
5
6
|
def index
|
|
@@ -16,6 +17,8 @@ module Kaui
|
|
|
16
17
|
return
|
|
17
18
|
end
|
|
18
19
|
|
|
20
|
+
@dropdown_default = default_columns(Kaui.account_search_columns.call[2], Kaui::Account::SENSIVITE_DATA_FIELDS)
|
|
21
|
+
|
|
19
22
|
@ordering = params[:ordering] || (@search_query.blank? ? 'desc' : 'asc')
|
|
20
23
|
@offset = params[:offset] || 0
|
|
21
24
|
@limit = params[:limit] || 50
|
|
@@ -39,17 +42,47 @@ module Kaui
|
|
|
39
42
|
end
|
|
40
43
|
|
|
41
44
|
formatter = lambda do |account|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
child_label = account.parent_account_id.nil? ? '' : view_context.content_tag(:span, 'Child', class: %w[label label-info account-child-label])
|
|
45
|
-
end
|
|
45
|
+
Kaui.account_search_columns.call(account, view_context)[1]
|
|
46
|
+
end
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
paginate searcher, data_extractor, formatter, default_columns(Kaui.account_search_columns.call[2], Kaui::Account::SENSIVITE_DATA_FIELDS)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def download
|
|
52
|
+
start_date = params[:startDate]
|
|
53
|
+
end_date = params[:endDate]
|
|
54
|
+
all_fields_checked = params[:allFieldsChecked] == 'true'
|
|
55
|
+
|
|
56
|
+
columns = if all_fields_checked
|
|
57
|
+
KillBillClient::Model::AccountAttributes.instance_variable_get('@json_attributes')
|
|
58
|
+
else
|
|
59
|
+
params.require(:columnsString).split(',').map { |attr| attr.split.join('_').downcase }
|
|
60
|
+
end
|
|
61
|
+
start_date = begin
|
|
62
|
+
Date.parse(start_date)
|
|
63
|
+
rescue StandardError
|
|
64
|
+
nil
|
|
65
|
+
end
|
|
66
|
+
end_date = begin
|
|
67
|
+
Date.parse(end_date)
|
|
68
|
+
rescue StandardError
|
|
69
|
+
nil
|
|
50
70
|
end
|
|
71
|
+
accounts = Kaui::Account.list_or_search(nil, 0, MAXIMUM_NUMBER_OF_RECORDS_DOWNLOAD, options_for_klient)
|
|
72
|
+
|
|
73
|
+
csv_string = CSV.generate(headers: true) do |csv|
|
|
74
|
+
csv << columns
|
|
75
|
+
accounts.each do |account|
|
|
76
|
+
change_date = Date.parse(account.reference_time)
|
|
77
|
+
data = columns.map do |attr|
|
|
78
|
+
account&.send(attr.downcase)
|
|
79
|
+
end
|
|
80
|
+
next if start_date && end_date && change_date && (change_date < start_date || change_date > end_date)
|
|
51
81
|
|
|
52
|
-
|
|
82
|
+
csv << data
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
send_data csv_string, filename: "accounts-#{Date.today}.csv", type: 'text/csv'
|
|
53
86
|
end
|
|
54
87
|
|
|
55
88
|
def new
|
|
@@ -331,6 +364,11 @@ module Kaui
|
|
|
331
364
|
end
|
|
332
365
|
end
|
|
333
366
|
|
|
367
|
+
def export_account
|
|
368
|
+
data = KillBillClient::Model::Export.find_by_account_id(params[:account_id], current_user.kb_username, options_for_klient)
|
|
369
|
+
send_data data, filename: "account#{params[:account_id]}.txt", type: :txt
|
|
370
|
+
end
|
|
371
|
+
|
|
334
372
|
private
|
|
335
373
|
|
|
336
374
|
def email_notification_plugin_available?(options_for_klient)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'csv'
|
|
4
|
+
|
|
3
5
|
module Kaui
|
|
4
6
|
class AuditLogsController < Kaui::EngineController
|
|
5
7
|
OBJECT_WITH_HISTORY = %w[ACCOUNT ACCOUNT_EMAIL BLOCKING_STATES BUNDLE CUSTOM_FIELD INVOICE INVOICE_ITEM PAYMENT_ATTEMPT PAYMENT PAYMENT_METHOD SUBSCRIPTION SUBSCRIPTION_EVENT TRANSACTION TAG TAG_DEFINITION].freeze
|
|
@@ -42,6 +44,41 @@ module Kaui
|
|
|
42
44
|
@audit_logs_json = @audit_logs_json.to_json
|
|
43
45
|
end
|
|
44
46
|
|
|
47
|
+
def download
|
|
48
|
+
account_id = params.require(:account_id)
|
|
49
|
+
start_date = params[:startDate]
|
|
50
|
+
end_date = params[:endDate]
|
|
51
|
+
start_date = begin
|
|
52
|
+
Date.parse(start_date)
|
|
53
|
+
rescue StandardError
|
|
54
|
+
nil
|
|
55
|
+
end
|
|
56
|
+
end_date = begin
|
|
57
|
+
Date.parse(end_date)
|
|
58
|
+
rescue StandardError
|
|
59
|
+
nil
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
account = Kaui::Account.find_by_id_or_key(account_id, false, false, options_for_klient)
|
|
63
|
+
audit_logs = account.audit(options_for_klient)
|
|
64
|
+
|
|
65
|
+
csv_file = CSV.generate do |csv|
|
|
66
|
+
csv << Kaui.account_audit_logs_columns.call[0]
|
|
67
|
+
audit_logs.each do |log|
|
|
68
|
+
change_date = begin
|
|
69
|
+
Date.parse(log.change_date)
|
|
70
|
+
rescue StandardError
|
|
71
|
+
nil
|
|
72
|
+
end
|
|
73
|
+
next if start_date && end_date && change_date && !(change_date > start_date && change_date < end_date)
|
|
74
|
+
|
|
75
|
+
csv << [log.change_date, log.object_id, log.object_type, log.change_type, log.changed_by, log.reason_code, log.comments, log.user_token]
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
send_data csv_file, type: 'text/csv', filename: "audit_logs_#{account_id}.csv"
|
|
80
|
+
end
|
|
81
|
+
|
|
45
82
|
def history
|
|
46
83
|
json_response do
|
|
47
84
|
account_id = params.require(:account_id)
|
|
@@ -5,8 +5,10 @@ module Kaui
|
|
|
5
5
|
# rubocop:disable Lint/HashCompareByIdentity
|
|
6
6
|
def index
|
|
7
7
|
cached_options_for_klient = options_for_klient
|
|
8
|
+
@per_page = (params[:per_page] || 10).to_i
|
|
9
|
+
@page = (params[:page] || 1).to_i
|
|
8
10
|
|
|
9
|
-
fetch_bundles = promise { @account.
|
|
11
|
+
fetch_bundles = promise { Kaui::Account.paginated_bundles(@account.account_id, (@page - 1) * @per_page, @per_page, 'NONE', cached_options_for_klient) }
|
|
10
12
|
fetch_bundle_tags = promise do
|
|
11
13
|
all_bundle_tags = @account.all_tags(:BUNDLE, false, 'NONE', cached_options_for_klient)
|
|
12
14
|
all_bundle_tags.each_with_object({}) do |entry, hsh|
|
|
@@ -35,6 +37,8 @@ module Kaui
|
|
|
35
37
|
fetch_available_subscription_tags = promise { Kaui::TagDefinition.all_for_subscription(cached_options_for_klient) }
|
|
36
38
|
|
|
37
39
|
@bundles = wait(fetch_bundles)
|
|
40
|
+
@total_pages = (@bundles.pagination_max_nb_records.to_f / @per_page).ceil
|
|
41
|
+
|
|
38
42
|
@tags_per_bundle = wait(fetch_bundle_tags)
|
|
39
43
|
@tags_per_subscription = wait(fetch_subscription_tags)
|
|
40
44
|
@custom_fields_per_bundle = wait(fetch_bundle_fields)
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
require_relative '../../../lib/kaui/error_handler'
|
|
2
|
+
|
|
1
3
|
class Kaui::EngineController < ApplicationController
|
|
2
4
|
|
|
3
5
|
include Kaui::EngineControllerUtil
|
|
6
|
+
include Kaui::ErrorHandler
|
|
4
7
|
|
|
5
8
|
before_action :authenticate_user!, :check_for_redirect_to_tenant_screen, :populate_account_details
|
|
6
9
|
|
|
@@ -59,25 +62,6 @@ class Kaui::EngineController < ApplicationController
|
|
|
59
62
|
end
|
|
60
63
|
end
|
|
61
64
|
|
|
62
|
-
# Note! Order matters, StandardError needs to be first
|
|
63
|
-
rescue_from(StandardError) do |error|
|
|
64
|
-
flash[:error] = "Error: #{as_string(error)}"
|
|
65
|
-
try_to_redirect_to_account_path = !params[:controller].ends_with?('accounts')
|
|
66
|
-
perform_redirect_after_error try_to_redirect_to_account_path
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
rescue_from(ActionController::ParameterMissing) do |parameter_missing_exception|
|
|
70
|
-
log_rescue_error parameter_missing_exception
|
|
71
|
-
flash[:error] = "Required parameter missing: #{parameter_missing_exception.param}"
|
|
72
|
-
perform_redirect_after_error
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
rescue_from(KillBillClient::API::ResponseError) do |killbill_exception|
|
|
76
|
-
flash[:error] = "Error while communicating with the Kill Bill server: #{as_string(killbill_exception)}"
|
|
77
|
-
try_to_redirect_to_account_path = !killbill_exception.is_a?(KillBillClient::API::Unauthorized) && !(killbill_exception.is_a?(KillBillClient::API::NotFound) && params[:controller].ends_with?('accounts'))
|
|
78
|
-
perform_redirect_after_error try_to_redirect_to_account_path
|
|
79
|
-
end
|
|
80
|
-
|
|
81
65
|
private
|
|
82
66
|
|
|
83
67
|
def current_tenant_user
|
|
@@ -95,13 +79,4 @@ class Kaui::EngineController < ApplicationController
|
|
|
95
79
|
end
|
|
96
80
|
result
|
|
97
81
|
end
|
|
98
|
-
|
|
99
|
-
def perform_redirect_after_error(try_to_redirect_to_account_path = true)
|
|
100
|
-
account_id = nested_hash_value(params.permit!.to_h, :account_id)
|
|
101
|
-
if try_to_redirect_to_account_path && account_id.present?
|
|
102
|
-
redirect_to kaui_engine.account_path(account_id)
|
|
103
|
-
else
|
|
104
|
-
redirect_to kaui_engine.home_path
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
82
|
end
|
|
@@ -4,6 +4,7 @@ module Kaui
|
|
|
4
4
|
module EngineControllerUtil
|
|
5
5
|
# See DefaultPaginationSqlDaoHelper.java
|
|
6
6
|
SIMPLE_PAGINATION_THRESHOLD = 20_000
|
|
7
|
+
MAXIMUM_NUMBER_OF_RECORDS_DOWNLOAD = 1000
|
|
7
8
|
|
|
8
9
|
protected
|
|
9
10
|
|
|
@@ -13,7 +14,7 @@ module Kaui
|
|
|
13
14
|
end
|
|
14
15
|
# rubocop:enable Lint/UselessAssignment, Naming/AccessorMethodName
|
|
15
16
|
|
|
16
|
-
def paginate(searcher, data_extractor, formatter)
|
|
17
|
+
def paginate(searcher, data_extractor, formatter, table_default_columns = [])
|
|
17
18
|
search_key = (params[:search] || {})[:value].presence
|
|
18
19
|
offset = (params[:start] || 0).to_i
|
|
19
20
|
limit = (params[:length] || 10).to_i
|
|
@@ -30,7 +31,8 @@ module Kaui
|
|
|
30
31
|
# We need to fill-in a number to make DataTables happy
|
|
31
32
|
recordsTotal: pages.nil? ? 0 : (pages.pagination_max_nb_records || SIMPLE_PAGINATION_THRESHOLD),
|
|
32
33
|
recordsFiltered: pages.nil? ? 0 : (pages.pagination_total_nb_records || SIMPLE_PAGINATION_THRESHOLD),
|
|
33
|
-
data: []
|
|
34
|
+
data: [],
|
|
35
|
+
columns: table_default_columns
|
|
34
36
|
}
|
|
35
37
|
json[:error] = error unless error.nil?
|
|
36
38
|
|
|
@@ -151,5 +153,9 @@ module Kaui
|
|
|
151
153
|
end
|
|
152
154
|
render json: response, status: response_status
|
|
153
155
|
end
|
|
156
|
+
|
|
157
|
+
def default_columns(fields, sensivite_fields)
|
|
158
|
+
fields.map { |field| { data: fields.index(field), visible: !(sensivite_fields.include? field) } }
|
|
159
|
+
end
|
|
154
160
|
end
|
|
155
161
|
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'csv'
|
|
3
4
|
module Kaui
|
|
4
5
|
class InvoicesController < Kaui::EngineController
|
|
5
6
|
def index
|
|
@@ -12,6 +13,37 @@ module Kaui
|
|
|
12
13
|
@max_nb_records = @search_query.blank? ? Kaui::Invoice.list_or_search(nil, 0, 0, options_for_klient).pagination_max_nb_records : 0
|
|
13
14
|
end
|
|
14
15
|
|
|
16
|
+
def download
|
|
17
|
+
account_id = params[:account_id]
|
|
18
|
+
start_date = params[:startDate]
|
|
19
|
+
end_date = params[:endDate]
|
|
20
|
+
all_fields_checked = params[:allFieldsChecked] == 'true'
|
|
21
|
+
columns = if all_fields_checked
|
|
22
|
+
KillBillClient::Model::InvoiceAttributes.instance_variable_get('@json_attributes') - Kaui::Invoice::TABLE_IGNORE_COLUMNS
|
|
23
|
+
else
|
|
24
|
+
params.require(:columnsString).split(',').map { |attr| attr.split.join('_').downcase }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
kb_params = {}
|
|
28
|
+
kb_params[:startDate] = Date.parse(start_date).strftime('%Y-%m-%d') if start_date
|
|
29
|
+
kb_params[:endDate] = Date.parse(end_date).strftime('%Y-%m-%d') if end_date
|
|
30
|
+
if account_id.present?
|
|
31
|
+
account = Kaui::Account.find_by_id_or_key(account_id, false, false, options_for_klient)
|
|
32
|
+
invoices = account.invoices(options_for_klient.merge(params: kb_params))
|
|
33
|
+
else
|
|
34
|
+
invoices = Kaui::Invoice.list_or_search(nil, 0, MAXIMUM_NUMBER_OF_RECORDS_DOWNLOAD, options_for_klient.merge(params: kb_params))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
csv_string = CSV.generate(headers: true) do |csv|
|
|
38
|
+
csv << columns
|
|
39
|
+
|
|
40
|
+
invoices.each do |invoice|
|
|
41
|
+
csv << columns.map { |attr| invoice&.send(attr.downcase) }
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
send_data csv_string, filename: "invoices-#{Date.today}.csv", type: 'text/csv'
|
|
45
|
+
end
|
|
46
|
+
|
|
15
47
|
def pagination
|
|
16
48
|
cached_options_for_klient = options_for_klient
|
|
17
49
|
|
|
@@ -24,39 +56,32 @@ module Kaui
|
|
|
24
56
|
if account.nil?
|
|
25
57
|
Kaui::Invoice.list_or_search(search_key, offset, limit, cached_options_for_klient)
|
|
26
58
|
else
|
|
27
|
-
|
|
59
|
+
Kaui::Account.paginated_invoices(search_key, offset, limit, 'NONE', cached_options_for_klient).map! { |invoice| Kaui::Invoice.build_from_raw_invoice(invoice) }
|
|
28
60
|
end
|
|
29
61
|
end
|
|
30
62
|
|
|
31
63
|
account_id = (params[:search] || {})[:value]
|
|
32
|
-
if account_id.blank?
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
][column]
|
|
54
|
-
end
|
|
55
|
-
formatter = lambda do |invoice|
|
|
56
|
-
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))]
|
|
57
|
-
row += Kaui.account_invoices_columns.call(invoice, view_context)[1]
|
|
58
|
-
row
|
|
59
|
-
end
|
|
64
|
+
data_extractor = if account_id.blank?
|
|
65
|
+
lambda do |invoice, column|
|
|
66
|
+
[
|
|
67
|
+
invoice.invoice_number.to_i,
|
|
68
|
+
invoice.invoice_date
|
|
69
|
+
][column]
|
|
70
|
+
end
|
|
71
|
+
else
|
|
72
|
+
lambda do |invoice, column|
|
|
73
|
+
[
|
|
74
|
+
invoice.invoice_number.to_i,
|
|
75
|
+
invoice.invoice_date,
|
|
76
|
+
invoice.amount,
|
|
77
|
+
invoice.balance,
|
|
78
|
+
invoice.status
|
|
79
|
+
][column]
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
formatter = lambda do |invoice|
|
|
84
|
+
Kaui.account_invoices_columns.call(invoice, view_context)[1]
|
|
60
85
|
end
|
|
61
86
|
|
|
62
87
|
paginate searcher, data_extractor, formatter
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'csv'
|
|
4
|
+
|
|
3
5
|
module Kaui
|
|
4
6
|
class PaymentsController < Kaui::EngineController
|
|
5
7
|
def index
|
|
@@ -12,7 +14,68 @@ module Kaui
|
|
|
12
14
|
@max_nb_records = @search_query.blank? ? Kaui::Payment.list_or_search(nil, 0, 0, options_for_klient).pagination_max_nb_records : 0
|
|
13
15
|
end
|
|
14
16
|
|
|
17
|
+
def download
|
|
18
|
+
account_id = params[:account_id]
|
|
19
|
+
start_date = params[:startDate]
|
|
20
|
+
end_date = params[:endDate]
|
|
21
|
+
all_fields_checked = params[:allFieldsChecked] == 'true'
|
|
22
|
+
columns = if all_fields_checked
|
|
23
|
+
KillBillClient::Model::PaymentAttributes.instance_variable_get('@json_attributes') - %w[transactions audit_logs]
|
|
24
|
+
else
|
|
25
|
+
params.require(:columnsString).split(',').map { |attr| attr.split.join('_').downcase }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
kb_params = {}
|
|
29
|
+
kb_params[:startDate] = Date.parse(start_date).strftime('%Y-%m-%d') if start_date
|
|
30
|
+
kb_params[:endDate] = Date.parse(end_date).strftime('%Y-%m-%d') if end_date
|
|
31
|
+
if account_id.present?
|
|
32
|
+
account = Kaui::Account.find_by_id_or_key(account_id, false, false, options_for_klient)
|
|
33
|
+
payments = account.payments(options_for_klient).map! { |payment| Kaui::Payment.build_from_raw_payment(payment) }
|
|
34
|
+
else
|
|
35
|
+
payments = Kaui::Payment.list_or_search(nil, 0, MAXIMUM_NUMBER_OF_RECORDS_DOWNLOAD, options_for_klient.merge(params: kb_params))
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
payments.each do |payment|
|
|
39
|
+
created_date = nil
|
|
40
|
+
payment.transactions.each do |transaction|
|
|
41
|
+
transaction_date = Date.parse(transaction.effective_date)
|
|
42
|
+
created_date ||= transaction_date if transaction_date < created_date
|
|
43
|
+
end
|
|
44
|
+
payment.payment_date = created_date
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
csv_string = CSV.generate(headers: true) do |csv|
|
|
48
|
+
csv << columns
|
|
49
|
+
|
|
50
|
+
payments.each do |payment|
|
|
51
|
+
next if start_date && end_date && (payment.payment_date < Date.parse(start_date) || payment.payment_date > Date.parse(end_date))
|
|
52
|
+
|
|
53
|
+
data = columns.map do |attr|
|
|
54
|
+
case attr
|
|
55
|
+
when 'payment_number'
|
|
56
|
+
payment.payment_number
|
|
57
|
+
when 'payment_date'
|
|
58
|
+
view_context.format_date(payment.payment_date, account&.time_zone)
|
|
59
|
+
when 'total_authed_amount_to_money'
|
|
60
|
+
view_context.humanized_money_with_symbol(payment.total_authed_amount_to_money)
|
|
61
|
+
when 'paid_amount_to_money'
|
|
62
|
+
view_context.humanized_money_with_symbol(payment.paid_amount_to_money)
|
|
63
|
+
when 'returned_amount_to_money'
|
|
64
|
+
view_context.humanized_money_with_symbol(payment.returned_amount_to_money)
|
|
65
|
+
when 'status'
|
|
66
|
+
payment.transactions.empty? ? nil : payment.transactions[-1].status
|
|
67
|
+
else
|
|
68
|
+
payment&.send(attr.downcase)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
csv << data
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
send_data csv_string, filename: "payments-#{Date.today}.csv", type: 'text/csv'
|
|
75
|
+
end
|
|
76
|
+
|
|
15
77
|
def pagination
|
|
78
|
+
account = nil
|
|
16
79
|
searcher = lambda do |search_key, offset, limit|
|
|
17
80
|
if Kaui::Payment::TRANSACTION_STATUSES.include?(search_key)
|
|
18
81
|
# Search is done by payment state on the server side, see http://docs.killbill.io/latest/userguide_payment.html#_payment_states
|
|
@@ -30,6 +93,7 @@ module Kaui
|
|
|
30
93
|
rescue StandardError
|
|
31
94
|
nil
|
|
32
95
|
end
|
|
96
|
+
|
|
33
97
|
payments = if account.nil?
|
|
34
98
|
Kaui::Payment.list_or_search(search_key, offset, limit, options_for_klient)
|
|
35
99
|
else
|
|
@@ -62,15 +126,7 @@ module Kaui
|
|
|
62
126
|
end
|
|
63
127
|
|
|
64
128
|
formatter = lambda do |payment|
|
|
65
|
-
[
|
|
66
|
-
view_context.link_to(payment.payment_number, view_context.url_for(controller: :payments, action: :show, account_id: payment.account_id, id: payment.payment_id)),
|
|
67
|
-
view_context.format_date(payment.payment_date, @account.time_zone),
|
|
68
|
-
view_context.humanized_money_with_symbol(payment.total_authed_amount_to_money),
|
|
69
|
-
view_context.humanized_money_with_symbol(payment.paid_amount_to_money),
|
|
70
|
-
view_context.humanized_money_with_symbol(payment.returned_amount_to_money),
|
|
71
|
-
payment.transactions.empty? ? nil : view_context.colored_transaction_status(payment.transactions[-1].status),
|
|
72
|
-
payment.payment_external_key
|
|
73
|
-
]
|
|
129
|
+
Kaui.account_payments_columns.call(account, payment, view_context)[1]
|
|
74
130
|
end
|
|
75
131
|
|
|
76
132
|
paginate searcher, data_extractor, formatter
|
|
@@ -3,12 +3,19 @@
|
|
|
3
3
|
module Kaui
|
|
4
4
|
# Subclassed to specify the correct layout
|
|
5
5
|
class SessionsController < Devise::SessionsController
|
|
6
|
+
include Kaui::ExceptionHelper
|
|
7
|
+
|
|
6
8
|
layout Kaui.config[:layout]
|
|
7
9
|
|
|
8
10
|
skip_before_action :check_for_redirect_to_tenant_screen, raise: false
|
|
9
11
|
|
|
10
12
|
# The sign-in flow eventually calls authenticate! from config/initializers/killbill_authenticatable.rb
|
|
11
13
|
|
|
14
|
+
rescue_from(StandardError) do |exception|
|
|
15
|
+
@error = standardize_exception(exception)
|
|
16
|
+
render 'kaui/errors/500', status: 500, layout: false
|
|
17
|
+
end
|
|
18
|
+
|
|
12
19
|
protected
|
|
13
20
|
|
|
14
21
|
# Override after_sign_in_path_for to not have to rely on the default 'root' config which we want to keep on home#index
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Kaui
|
|
4
|
+
module ExceptionHelper
|
|
5
|
+
def standardize_exception(exception)
|
|
6
|
+
if defined?(JRUBY_VERSION)
|
|
7
|
+
case exception
|
|
8
|
+
when ActiveRecord::JDBCError
|
|
9
|
+
return I18n.translate('errors.messages.unable_to_connect_database')
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
case exception
|
|
14
|
+
when ActiveRecord::DatabaseConnectionError
|
|
15
|
+
I18n.translate('errors.messages.unable_to_connect_database')
|
|
16
|
+
when Errno::ECONNREFUSED, Errno::EBADF
|
|
17
|
+
I18n.translate('errors.messages.unable_to_connect_killbill')
|
|
18
|
+
when ->(e) { e.class.name.start_with?('KillBillClient::API') }
|
|
19
|
+
I18n.translate('errors.messages.error_communicating_killbill')
|
|
20
|
+
else
|
|
21
|
+
nil
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
data/app/models/kaui/account.rb
CHANGED
|
@@ -4,6 +4,8 @@ module Kaui
|
|
|
4
4
|
class Account < KillBillClient::Model::Account
|
|
5
5
|
attr_accessor :phone, :bill_cycle_day_local
|
|
6
6
|
|
|
7
|
+
SENSIVITE_DATA_FIELDS = %w[name email].freeze
|
|
8
|
+
|
|
7
9
|
def check_account_details_phone
|
|
8
10
|
return true if phone =~ /\A(?:\+?\d{1,3}\s*-?)?\(?(?:\d{3})?\)?[- ]?\d{3}[- ]?\d{4}\z/i
|
|
9
11
|
|
data/app/models/kaui/invoice.rb
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
module Kaui
|
|
4
4
|
class Invoice < KillBillClient::Model::Invoice
|
|
5
|
+
TABLE_IGNORE_COLUMNS = %w[amount balance credit_adj refund_adj items is_parent_invoice parent_invoice_id parent_account_id].freeze
|
|
6
|
+
|
|
5
7
|
def self.build_from_raw_invoice(raw_invoice)
|
|
6
8
|
result = Kaui::Invoice.new
|
|
7
9
|
KillBillClient::Model::InvoiceAttributes.instance_variable_get('@json_attributes').each do |attr|
|