From 2ada1a2bbf0e51c773a7a94f527ff16281cd04bf Mon Sep 17 00:00:00 2001 From: Kyle Le Date: Sun, 25 Aug 2024 01:14:14 +0700 Subject: [PATCH 1/6] Fix table bugs and add Download CSV button --- app/controllers/kaui/accounts_controller.rb | 22 ++ app/controllers/kaui/invoices_controller.rb | 28 +- app/views/kaui/accounts/_edit_columns.erb | 186 +++++++++++- app/views/kaui/accounts/index.html.erb | 16 +- app/views/kaui/invoices/_edit_columns.erb | 310 ++++++++++++++++++++ app/views/kaui/invoices/index.html.erb | 31 +- config/routes.rb | 2 + lib/kaui.rb | 42 ++- 8 files changed, 608 insertions(+), 29 deletions(-) create mode 100644 app/views/kaui/invoices/_edit_columns.erb diff --git a/app/controllers/kaui/accounts_controller.rb b/app/controllers/kaui/accounts_controller.rb index efd0b470..e688cba3 100644 --- a/app/controllers/kaui/accounts_controller.rb +++ b/app/controllers/kaui/accounts_controller.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +require 'csv' module Kaui class AccountsController < Kaui::EngineController def index @@ -25,6 +26,7 @@ def index 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 @@ -45,6 +47,26 @@ def pagination paginate searcher, data_extractor, formatter end + def download_accounts + 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| + if attr == 'child' + account.parent_account_id.nil? ? '' : 'Child' + else + account&.send(attr.downcase) + end + end + csv << data + end + end + send_data csv_string, filename: "accounts-#{Date.today}.csv", type: 'text/csv' + end + def new @account = Kaui::Account.new end diff --git a/app/controllers/kaui/invoices_controller.rb b/app/controllers/kaui/invoices_controller.rb index 40b7554b..b0a937f2 100644 --- a/app/controllers/kaui/invoices_controller.rb +++ b/app/controllers/kaui/invoices_controller.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +require 'csv' module Kaui class InvoicesController < Kaui::EngineController def index @@ -12,6 +13,27 @@ 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_invoices + account_id = params.require(: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 + 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)) + + 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 @@ -24,7 +46,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 @@ -53,9 +75,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 diff --git a/app/views/kaui/accounts/_edit_columns.erb b/app/views/kaui/accounts/_edit_columns.erb index cef9c9e5..2ecb854c 100644 --- a/app/views/kaui/accounts/_edit_columns.erb +++ b/app/views/kaui/accounts/_edit_columns.erb @@ -1,4 +1,8 @@ + + + +<%= javascript_tag do %> +$(document).ready(function() { + $('#modalDownloadButton').click(function() { + $('#downloadCsvModal').modal('show'); + }); + $('#startDate, #endDate').datepicker(); + + $('#downloadCsvModal').on('show.bs.modal', function (e) { + $('#customDate').prop('checked', true); + $('#startDate, #endDate').prop('disabled', false); + $('#startDate').val(null); + $('#endDate').val(null); + }); + + $('#allInvoices').change(function() { + var isChecked = $(this).is(':checked'); + $('#startDate, #endDate').prop('disabled', true); + }); + + function setDateRange(option) { + var currentDate = new Date(); + var startDate, endDate; + + if (option === "week") { + startDate = new Date(currentDate.setDate(currentDate.getDate() - currentDate.getDay() + 1)); + currentDate = new Date(); + endDate = new Date(currentDate.setDate(currentDate.getDate() - currentDate.getDay() + 7)); + } else if (option === "month") { + startDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1); + endDate = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 0); + } else if (option === "year") { + startDate = new Date(currentDate.getFullYear(), 0, 1); + endDate = new Date(currentDate.getFullYear(), 11, 31); + } + + var startDateFormatted = startDate.toISOString().split('T')[0]; + var endDateFormatted = endDate.toISOString().split('T')[0]; + + $('#startDate').val(startDateFormatted); + $('#endDate').val(endDateFormatted); + $('#startDate, #endDate').prop('disabled', true); + } + + $('#thisWeek').change(function() { + if ($(this).is(':checked')) { + setDateRange("week"); + } + }); + + $('#thisMonth').change(function() { + if ($(this).is(':checked')) { + setDateRange("month"); + } + }); + + $('#thisYear').change(function() { + if ($(this).is(':checked')) { + setDateRange("year"); + } + }); + + $('#customDate').change(function() { + var isChecked = $(this).is(':checked'); + $('#startDate, #endDate').prop('disabled', false); + $('#startDate').val(null); + $('#endDate').val(null); + }); + + var downloadButton = document.getElementById('downloadButton'); + if (downloadButton) { + downloadButton.addEventListener('click', function() { + event.preventDefault(); // Prevent the default form submission if the button is a submit type + + // Retrieve the values and checked state + var startDate = $('#startDate').val(); + var endDate = $('#endDate').val(); + var downloadAll = $('#allInvoices').is(':checked'); + var thElements = document.querySelectorAll('#invoices-table th'); + var columnTitles = Array.from(thElements).map(function(th) { + return th.textContent.trim(); + }); + + var columnsString = columnTitles.join(',') + + if (downloadAll) { + window.open("<%= download_invoices_path %>?account_id=<%=@account.account_id%>&columnsString="+columnsString, '_blank'); + } else { + window.open("<%= download_invoices_path %>?account_id=<%=@account.account_id%>&columnsString="+columnsString+"&startDate="+startDate+"&endDate="+endDate, '_blank'); + } + }); + } + + updateDropdownOrder(); + + function loadState() { + var state = JSON.parse(localStorage.getItem('DataTables_invoices-table')); + return state || { columns: [], columnOrder: [] }; + } + + function updateDropdownOrder() { + var state = loadState(); + var columnOrder = state.ColReorder; + var $list = $('#column-visibility'); + var thElements = document.querySelectorAll('#invoices-table th'); + var $columnTitles = Array.from(thElements).map(function(th) { + return th.textContent.trim(); + }); + if (columnOrder !== undefined) { + $list.empty(); + columnOrder.forEach(function(colIdx, index) { + var $item = $('
  • ', { class: "list-group-item-manual", "data-id": index }); + var column = state.columns[colIdx]; + var col_name = $columnTitles[colIdx]; + var $label = $('