Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix table bugs and add Download CSV button #412

Merged
merged 8 commits into from
Sep 18, 2024
Merged
108 changes: 108 additions & 0 deletions app/controllers/kaui/account_timelines_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require 'csv'

module Kaui
class AccountTimelinesController < Kaui::EngineController
def show
Expand Down Expand Up @@ -30,8 +32,114 @@ def show
@selected_bundle = params.key?(:external_key) ? @bundle_names[params[:external_key]] : nil
end

def download
timeline = Kaui::AccountTimeline.find_by_account_id(params.require(:account_id), 'FULL', options_for_klient)
start_date = params[:startDate].present? ? Date.parse(params[:startDate]) : nil
end_date = params[:endDate].present? ? Date.parse(params[:endDate]) : nil
event_type = params[:eventType]
@account = timeline.account
@bundles = timeline.bundles
@invoices = timeline.invoices
@payments = timeline.payments
extract_invoices_by_id(@invoices)

# Lookup all bundle names
@bundle_names = {}
@bundle_names_by_invoice_id = {}
@bundle_keys_by_invoice_id = {}
@bundles.each do |bundle|
load_bundle_name_for_timeline(bundle.external_key)
end
@invoices.each do |invoice|
@bundle_names_by_invoice_id[invoice.invoice_id] = Set.new
@bundle_keys_by_invoice_id[invoice.invoice_id] = Set.new
(invoice.bundle_keys || '').split(',').each do |bundle_key|
load_bundle_name_for_timeline(bundle_key)
@bundle_names_by_invoice_id[invoice.invoice_id] << @bundle_names[bundle_key]
@bundle_keys_by_invoice_id[invoice.invoice_id] << bundle_key
end
end

@selected_bundle = params.key?(:external_key) ? @bundle_names[params[:external_key]] : nil

csv_string = CSV.generate(headers: true) do |csv|
csv << ['Effective Date', 'Bundles', 'Even Type', 'Details', 'Reason Code/ Comments']
if %w[INVOICE ALL].include?(event_type)
@invoices.each do |invoice_stub|
invoice = invoice_stub.invoice_id.present? && @invoices_by_id.has_key?(invoice_stub.invoice_id) ? @invoices_by_id[invoice_stub.invoice_id] : invoice_stub
target_date = invoice.target_date.present? ? invoice.target_date : '[unknown]'
bundle_keys = invoice_stub.bundle_keys.present? ? invoice_stub.bundle_keys.split(',').map { |bundle_key| @bundle_names[bundle_key] }.join(', ') : ''
invoice_details = []
invoice_details << "Amount: #{invoice.amount_to_money} (#{@account.currency})"
invoice_details << "Balance: #{invoice.balance_to_money} (#{@account.currency})"
invoice_details << "Credit adjustment: #{invoice.credit_adjustment_to_money} (#{@account.currency})" if invoice.credit_adj.present? && invoice.credit_adj > 0
invoice_details << "Refund adjustment: #{invoice.refund_adjustment_to_money} (#{@account.currency})" if invoice.refund_adj.present? && invoice.refund_adj < 0
invoice_details << "Invoice #: #{invoice.invoice_number}"
audit_logs = invoice_stub.audit_logs.present? ? invoice_stub.audit_logs.map { |entry| Kaui::AuditLog.description(entry) }.join(', ') : ''
csv << [target_date, bundle_keys, 'INVOICE', invoice_details.join('; '), audit_logs] if filter_date(target_date, start_date, end_date)
end
end
if %w[PAYMENT ALL].include?(event_type)
@payments.each do |payment|
invoice = if payment.target_invoice_id.present?
@invoices_by_id[payment.target_invoice_id]
else
nil
end

payment.transactions.each do |transaction|
effective_date = transaction.effective_date.present? ? transaction.effective_date : '[unknown]'
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(', ') : ''
transaction_type = transaction.transaction_type
details = []
details << "Amount: #{Kaui::Transaction.amount_to_money(transaction)} (#{transaction.currency})" unless transaction.transaction_type == 'VOID'
details << "Status: #{transaction.status}"
details << "Payment #: #{payment.payment_number}"
details << "Invoice #: #{invoice.invoice_number}" unless invoice.nil?

audit_logs = transaction.audit_logs.present? ? transaction.audit_logs.map { |entry| Kaui::AuditLog.description(entry) }.chunk { |x| x }.map(&:first).join(', ') : ''

csv << [effective_date, bundle_keys, transaction_type, details.join('; '), audit_logs] if filter_date(effective_date, start_date, end_date)
end
end
end

if %w[ENTITLEMENT ALL].include?(event_type)
@bundles.each do |bundle|
bundle.subscriptions.each do |sub|
sub.events.each do |event|
# Skip SERVICE_STATE_CHANGE events
next if event.event_type == 'SERVICE_STATE_CHANGE'

effective_date = event.effective_date.present? ? event.effective_date : '[unknown]'
bundle_keys = @bundle_names[bundle.external_key]
event_type = event.event_type
phase = event.phase
audit_logs = event.audit_logs.present? ? event.audit_logs.map { |entry| Kaui::AuditLog.description(entry) }.join(', ') : ''

csv << [effective_date, bundle_keys, event_type, phase, audit_logs] if filter_date(effective_date, start_date, end_date)
end
end
end
end
end

send_data csv_string, filename: "account-timelines-#{Date.today}.csv", type: 'text/csv'
end

private

def filter_date(target_date, start_date, end_date)
return true if start_date.nil? || end_date.nil?

target_date = begin
Date.parse(target_date)
rescue StandardError
nil
end
target_date >= start_date && target_date <= end_date
end

def load_bundle_name_for_timeline(bundle_key)
@bundle_names[bundle_key] ||= Kaui.bundle_key_display_string.call(bundle_key)
end
Expand Down
24 changes: 22 additions & 2 deletions app/controllers/kaui/accounts_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true

require 'csv'
module Kaui
class AccountsController < Kaui::EngineController
def index
Expand All @@ -16,15 +17,18 @@ def index
return
end

@dropdown_default = default_columns(Kaui.account_search_columns.call()[2], Kaui::Account::SENSIVITE_DATA_FIELDS)

@ordering = params[:ordering] || (@search_query.blank? ? 'desc' : 'asc')
@offset = params[:offset] || 0
@limit = params[:limit] || 50
tungleduyxyz marked this conversation as resolved.
Show resolved Hide resolved
@limit = params[:limit] || 4

@max_nb_records = @search_query.blank? ? Kaui::Account.list_or_search(nil, 0, 0, options_for_klient).pagination_max_nb_records : 0
end

def pagination
cached_options_for_klient = options_for_klient

searcher = lambda do |search_key, offset, limit|
Kaui::Account.list_or_search(search_key, offset, limit, cached_options_for_klient)
end
Expand All @@ -42,7 +46,23 @@ def pagination
Kaui.account_search_columns.call(account, view_context)[1]
end

paginate searcher, data_extractor, formatter
paginate searcher, data_extractor, formatter, default_columns(Kaui.account_search_columns.call()[2], Kaui::Account::SENSIVITE_DATA_FIELDS)
end

def download
columns = params.require(:columnsString).split(',').map { |attr| attr.split.join('_').downcase }
accounts = Kaui::Account.list_or_search(nil, 0, 1000, options_for_klient)

csv_string = CSV.generate(headers: true) do |csv|
csv << columns
accounts.each do |account|
data = columns.map do |attr|
account&.send(attr.downcase)
end
csv << data
end
end
send_data csv_string, filename: "accounts-#{Date.today}.csv", type: 'text/csv'
end

def new
Expand Down
25 changes: 25 additions & 0 deletions app/controllers/kaui/audit_logs_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# frozen_string_literal: true
require 'csv'

module Kaui
class AuditLogsController < Kaui::EngineController
Expand Down Expand Up @@ -42,6 +43,30 @@ def index
@audit_logs_json = @audit_logs_json.to_json
end

def download
account_id = params.require(:account_id)
start_date = params[:startDate]
end_date = params[:endDate]
start_date = Date.parse(start_date) rescue nil
end_date = Date.parse(end_date) rescue nil

account = Kaui::Account.find_by_id_or_key(account_id, false, false, options_for_klient)
audit_logs = account.audit(options_for_klient)

csv_file = CSV.generate do |csv|
csv << Kaui.account_audit_logs_columns.call()[0]
audit_logs.each do |log|
change_date = Date.parse(log.change_date) rescue nil
if start_date && end_date && change_date
next unless change_date > start_date && change_date < end_date
end
csv << [log.change_date, log.object_id, log.object_type, log.change_type, log.changed_by, log.reason_code, log.comments, log.user_token]
end
end

send_data csv_file, type: 'text/csv', filename: "audit_logs_#{account_id}.csv"
end

def history
json_response do
account_id = params.require(:account_id)
Expand Down
9 changes: 7 additions & 2 deletions app/controllers/kaui/engine_controller_util.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def get_layout
end
# rubocop:enable Lint/UselessAssignment, Naming/AccessorMethodName

def paginate(searcher, data_extractor, formatter)
def paginate(searcher, data_extractor, formatter, table_default_columns = [])
search_key = (params[:search] || {})[:value].presence
offset = (params[:start] || 0).to_i
limit = (params[:length] || 10).to_i
Expand All @@ -30,7 +30,8 @@ def paginate(searcher, data_extractor, formatter)
# We need to fill-in a number to make DataTables happy
recordsTotal: pages.nil? ? 0 : (pages.pagination_max_nb_records || SIMPLE_PAGINATION_THRESHOLD),
recordsFiltered: pages.nil? ? 0 : (pages.pagination_total_nb_records || SIMPLE_PAGINATION_THRESHOLD),
data: []
data: [],
columns: table_default_columns
}
json[:error] = error unless error.nil?

Expand Down Expand Up @@ -151,5 +152,9 @@ def json_response
end
render json: response, status: response_status
end

def default_columns(fields, sensivite_fields)
fields.map { |field| { "data": fields.index(field), "visible": !(sensivite_fields.include? field) } }
end
end
end
34 changes: 29 additions & 5 deletions app/controllers/kaui/invoices_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true

require 'csv'
module Kaui
class InvoicesController < Kaui::EngineController
def index
Expand All @@ -12,6 +13,31 @@ def index
@max_nb_records = @search_query.blank? ? Kaui::Invoice.list_or_search(nil, 0, 0, options_for_klient).pagination_max_nb_records : 0
end

def download
account_id = params[:account_id]
start_date = params[:startDate]
end_date = params[:endDate]
columns = params.require(:columnsString).split(',').map { |attr| attr.split.join('_').downcase }
kb_params = {}
kb_params[:startDate] = Date.parse(start_date).strftime('%Y-%m-%d') if start_date
kb_params[:endDate] = Date.parse(end_date).strftime('%Y-%m-%d') if end_date
if account_id.present?
account = Kaui::Account.find_by_id_or_key(account_id, false, false, options_for_klient)
invoices = account.invoices(options_for_klient.merge(params: kb_params))
else
invoices = Kaui::Invoice.list_or_search(nil, 0, 0, options_for_klient.merge(params: kb_params))
tungleduyxyz marked this conversation as resolved.
Show resolved Hide resolved
end

csv_string = CSV.generate(headers: true) do |csv|
csv << columns

invoices.each do |invoice|
csv << columns.map { |attr| invoice&.send(attr.downcase) }
end
end
send_data csv_string, filename: "invoices-#{Date.today}.csv", type: 'text/csv'
end

def pagination
cached_options_for_klient = options_for_klient

Expand All @@ -24,7 +50,7 @@ def pagination
if account.nil?
Kaui::Invoice.list_or_search(search_key, offset, limit, cached_options_for_klient)
else
Kaui::Account.paginated_invoices(search_key, offset, limit, 'NONE', cached_options_for_klient.merge({ params: { includeVoidedInvoices: true } })).map! { |invoice| Kaui::Invoice.build_from_raw_invoice(invoice) }
Kaui::Account.paginated_invoices(search_key, offset, limit, 'NONE', cached_options_for_klient).map! { |invoice| Kaui::Invoice.build_from_raw_invoice(invoice) }
end
end

Expand All @@ -39,7 +65,7 @@ def pagination
end
formatter = lambda do |invoice|
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))]
row += Kaui.invoice_search_columns.call(invoice, view_context, cached_options_for_klient)[1]
tungleduyxyz marked this conversation as resolved.
Show resolved Hide resolved
row += Kaui.invoice_search_columns.call(invoice, view_context)[1]
row
end
else
Expand All @@ -53,9 +79,7 @@ def pagination
][column]
end
formatter = lambda do |invoice|
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))]
row += Kaui.account_invoices_columns.call(invoice, view_context)[1]
row
Kaui.account_invoices_columns.call(invoice, view_context)[1]
end
end

Expand Down
64 changes: 55 additions & 9 deletions app/controllers/kaui/payments_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# frozen_string_literal: true
require 'csv'

module Kaui
class PaymentsController < Kaui::EngineController
Expand All @@ -12,7 +13,59 @@ def index
@max_nb_records = @search_query.blank? ? Kaui::Payment.list_or_search(nil, 0, 0, options_for_klient).pagination_max_nb_records : 0
end

def download
account_id = params[:account_id]
start_date = params[:startDate]
end_date = params[:endDate]
columns = params.require(:columnsString).split(',').map { |attr| attr.split.join('_').downcase }
kb_params = {}
kb_params[:startDate] = Date.parse(start_date).strftime('%Y-%m-%d') if start_date
kb_params[:endDate] = Date.parse(end_date).strftime('%Y-%m-%d') if end_date
if account_id.present?
account = Kaui::Account.find_by_id_or_key(account_id, false, false, options_for_klient)
payments = account.payments(options_for_klient).map! { |payment| Kaui::Payment.build_from_raw_payment(payment) }
else
payments = Kaui::Payment.list_or_search(nil, 0, 0, options_for_klient.merge(params: kb_params))
end
payments.each do |payment|
created_date = nil
payment.transactions.each do |transaction|
transaction_date = Date.parse(transaction.effective_date)
created_date = transaction_date if created_date.nil? || (transaction_date < created_date)
end
payment.payment_date = created_date
end

csv_string = CSV.generate(headers: true) do |csv|
csv << columns

payments.each do |payment|
data = columns.map do |attr|
case attr
when 'payment_number'
payment.payment_number
when 'payment_date'
view_context.format_date(payment.payment_date, account&.time_zone)
when 'total_authed_amount_to_money'
view_context.humanized_money_with_symbol(payment.total_authed_amount_to_money)
when 'paid_amount_to_money'
view_context.humanized_money_with_symbol(payment.paid_amount_to_money)
when 'returned_amount_to_money'
view_context.humanized_money_with_symbol(payment.returned_amount_to_money)
when 'status'
payment.transactions.empty? ? nil : payment.transactions[-1].status
else
payment&.send(attr.downcase)
end
end
csv << data
end
end
send_data csv_string, filename: "payments-#{Date.today}.csv", type: 'text/csv'
end

def pagination
account = nil
searcher = lambda do |search_key, offset, limit|
if Kaui::Payment::TRANSACTION_STATUSES.include?(search_key)
# Search is done by payment state on the server side, see http://docs.killbill.io/latest/userguide_payment.html#_payment_states
Expand All @@ -30,6 +83,7 @@ def pagination
rescue StandardError
nil
end

payments = if account.nil?
Kaui::Payment.list_or_search(search_key, offset, limit, options_for_klient)
else
Expand Down Expand Up @@ -62,15 +116,7 @@ def pagination
end

formatter = lambda do |payment|
[
view_context.link_to(payment.payment_number, view_context.url_for(controller: :payments, action: :show, account_id: payment.account_id, id: payment.payment_id)),
view_context.format_date(payment.payment_date, @account.time_zone),
view_context.humanized_money_with_symbol(payment.total_authed_amount_to_money),
view_context.humanized_money_with_symbol(payment.paid_amount_to_money),
view_context.humanized_money_with_symbol(payment.returned_amount_to_money),
payment.transactions.empty? ? nil : view_context.colored_transaction_status(payment.transactions[-1].status),
payment.payment_external_key
]
Kaui.account_payments_columns.call(account, payment, view_context)[1]
end

paginate searcher, data_extractor, formatter
Expand Down
Loading
Loading