diff --git a/CHANGELOG.md b/CHANGELOG.md index 7232a85b1..b308779e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog Fab-manager +- Fix a bug: unable to export statistics + ## v5.5.1 2022 November 15 - Fix a bug: free disk space not verified in some cases diff --git a/app/controllers/api/exports_controller.rb b/app/controllers/api/exports_controller.rb index 2b8ab1980..55e0062a2 100644 --- a/app/controllers/api/exports_controller.rb +++ b/app/controllers/api/exports_controller.rb @@ -8,16 +8,17 @@ class API::ExportsController < API::ApiController def download authorize @export - mime_type = if @export.extension == 'xlsx' + mime_type = case @export.extension + when 'xlsx' 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - elsif @export.extension == 'csv' + when 'csv' 'text/csv' else 'application/octet-stream' end if FileTest.exist?(@export.file) - send_file File.join(Rails.root, @export.file), + send_file Rails.root.join(@export.file), type: mime_type, disposition: 'attachment' else @@ -28,14 +29,7 @@ class API::ExportsController < API::ApiController def status authorize Export - exports = Export.where( - category: params[:category], - export_type: params[:type], - query: params[:query], - key: params[:key], - extension: params[:extension] - ) - export = retrieve_last_export(exports, params[:category], params[:type]) + export = ExportService.last_export("#{params[:category]}/#{params[:type]}", params[:query], params[:key], params[:extension]) if export.nil? || !FileTest.exist?(export.file) render json: { exists: false, id: nil }, status: :ok @@ -46,41 +40,6 @@ class API::ExportsController < API::ApiController private - def retrieve_last_export(export, category, type) - case category - when 'users' - case type - when 'subscriptions' - export = export.where('created_at > ?', Subscription.maximum('updated_at')) - when 'reservations' - export = export.where('created_at > ?', Reservation.maximum('updated_at')) - when 'members' - export = export.where('created_at > ?', User.members.maximum('updated_at')) - else - raise ArgumentError, "Unknown export users/#{type}" - end - when 'availabilities' - case type - when 'index' - export = export.where('created_at > ?', [Availability.maximum('updated_at'), Reservation.maximum('updated_at')].max) - else - raise ArgumentError, "Unknown type availabilities/#{type}" - end - when 'accounting' - case type - when 'acd' - export = export.where('created_at > ?', Invoice.maximum('updated_at')) - when 'vat' - export = export.where('created_at > ?', Invoice.maximum('updated_at')) - else - raise ArgumentError, "Unknown type accounting/#{type}" - end - else - raise ArgumentError, "Unknown category #{category}" - end - export.last - end - def set_export @export = Export.find(params[:id]) end diff --git a/app/controllers/api/statistics_controller.rb b/app/controllers/api/statistics_controller.rb index d657df10a..ac2d2bd4a 100644 --- a/app/controllers/api/statistics_controller.rb +++ b/app/controllers/api/statistics_controller.rb @@ -19,7 +19,8 @@ class API::StatisticsController < API::ApiController def export_#{path} # def export_account authorize :statistic, :export_#{path}? # authorize :statistic, :export_account? - @export = Statistics::QueryService.export('#{path}', params) # @export = Statistics::QueryService.export('account', params) + @export = Statistics::QueryService.export('#{path}', params, # @export = Statistics::QueryService.export('account', params, + current_user) if @export.is_a?(Export) if @export.save render json: { export_id: @export.id }, status: :ok @@ -32,13 +33,13 @@ class API::StatisticsController < API::ApiController disposition: 'attachment' end end - }, __FILE__, __LINE__ - 22 + }, __FILE__, __LINE__ - 23 end def export_global authorize :statistic, :export_global? - @export = Statistics::QueryService.export(global, params) + @export = Statistics::QueryService.export('global', params, current_user) if @export.is_a?(Export) if @export.save render json: { export_id: @export.id }, status: :ok diff --git a/app/services/export_service.rb b/app/services/export_service.rb index 0ffea8daa..a77d07c57 100644 --- a/app/services/export_service.rb +++ b/app/services/export_service.rb @@ -4,16 +4,20 @@ class ExportService class << self # Check if the last export of the provided type is still accurate or if it must be regenerated - def last_export(type) + def last_export(type, query = nil, key = nil, extension = nil) case type when 'users/members' - last_export_members + last_export_members(query, key, extension) when 'users/reservations' - last_export_reservations + last_export_reservations(query, key, extension) when 'users/subscription' - last_export_subscriptions + last_export_subscriptions(query, key, extension) + when 'availabilities/index' + last_export_availabilities(query, key, extension) + when %r{accounting/.*} + last_export_accounting(type, query, key, extension) when %r{statistics/.*} - last_export_statistics(type.split('/')[1]) + last_export_statistics(type, query, key, extension) else raise TypeError "unknown export type: #{type}" end @@ -21,19 +25,29 @@ class ExportService private - def last_export_subscriptions - Export.where(category: 'users', export_type: 'subscriptions') - .where('created_at > ?', Subscription.maximum('updated_at')) - .last + def query_last_export(category, export_type, query = nil, key = nil, extension = nil) + export = Export.where(category: category, export_type: export_type) + export.where(query: query) unless query.nil? + export.where(key: key) unless key.nil? + export.where(extension: extension) unless extension.nil? + export end - def last_export_reservations - Export.where(category: 'users', export_type: 'reservations') - .where('created_at > ?', Reservation.maximum('updated_at')) - .last + def last_export_subscriptions(query, key, extension) + query_last_export('users', 'subscriptions', query, key, extension) + .where('created_at > ?', Subscription.maximum('updated_at')) + .order(created_at: :desc) + .first end - def last_export_members + def last_export_reservations(query, key, extension) + query_last_export('users', 'reservations', query, key, extension) + .where('created_at > ?', Reservation.maximum('updated_at')) + .order(created_at: :desc) + .first + end + + def last_export_members(query, key, extension) last_update = [ User.members.maximum('updated_at'), Profile.where(user_id: User.members).maximum('updated_at'), @@ -42,14 +56,30 @@ class ExportService Subscription.maximum('updated_at') || DateTime.current ].max - Export.where(category: 'users', export_type: 'members') - .where('created_at > ?', last_update) - .last + query_last_export('users', 'members', query, key, extension) + .where('created_at > ?', last_update) + .order(created_at: :desc) + .first end - def last_export_statistics(type) - Export.where(category: 'statistics', export_type: type, query: params[:body], key: params[:type_key]) - .last + def last_export_availabilities(query, key, extension) + query_last_export('availabilities', 'index', query, key, extension) + .where('created_at > ?', [Availability.maximum('updated_at'), Reservation.maximum('updated_at')].max) + .order(created_at: :desc) + .first + end + + def last_export_accounting(type, query, key, extension) + query_last_export('accounting', type.split('/')[1], query, key, extension) + .where('created_at > ?', Invoice.maximum('updated_at')) + .order(created_at: :desc) + .first + end + + def last_export_statistics(type, query, key, extension) + query_last_export('statistics', type.split('/')[1], query, key, extension) + .order(created_at: :desc) + .first end end end diff --git a/app/services/statistics/query_service.rb b/app/services/statistics/query_service.rb index 34b817f74..745a84ff7 100644 --- a/app/services/statistics/query_service.rb +++ b/app/services/statistics/query_service.rb @@ -21,8 +21,8 @@ class Statistics::QueryService results end - def export(statistic_index, params) - export = ExportService.last_export("statistics/#{statistic_index}") + def export(statistic_index, params, current_user) + export = ExportService.last_export("statistics/#{statistic_index}", params[:body], params[:type_key]) if export.nil? || !FileTest.exist?(export.file) Export.new(category: 'statistics', export_type: statistic_index,