From 21a5f5591abd3c6b0a1cd4869e56debc22f7e9ef Mon Sep 17 00:00:00 2001 From: Sylvain Date: Wed, 3 Apr 2019 17:57:21 +0200 Subject: [PATCH] [ongoing] generate achives async --- app/models/accounting_period.rb | 45 +++------------------------ app/workers/archive_worker.rb | 54 +++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 40 deletions(-) create mode 100644 app/workers/archive_worker.rb diff --git a/app/models/accounting_period.rb b/app/models/accounting_period.rb index 1194d4d7b..9a43a55d2 100644 --- a/app/models/accounting_period.rb +++ b/app/models/accounting_period.rb @@ -68,6 +68,10 @@ class AccountingPeriod < ActiveRecord::Base end end + def previous_period + AccountingPeriod.where('closed_at < ?', closed_at).order(closed_at: :desc).limit(1).last + end + private def vat_history @@ -81,47 +85,8 @@ class AccountingPeriod < ActiveRecord::Base key_dates.sort_by { |k| k[:date] } end - def to_json_archive(invoices, previous_file, last_checksum) - code_checksum = Checksum.code - ApplicationController.new.view_context.render( - partial: 'archive/accounting', - locals: { - invoices: invoices_with_vat(invoices), - period_total: period_total, - perpetual_total: perpetual_total, - period_footprint: footprint, - code_checksum: code_checksum, - last_archive_checksum: last_checksum, - previous_file: previous_file, - software_version: Version.current, - date: Time.now.iso8601 - }, - formats: [:json], - handlers: [:jbuilder] - ) - end - - def previous_period - AccountingPeriod.where('closed_at < ?', closed_at).order(closed_at: :desc).limit(1).last - end - def archive_closed_data - data = invoices.includes(:invoice_items).order(id: :asc) - previous_file = previous_period&.archive_file - last_archive_checksum = previous_file ? Checksum.file(previous_file) : nil - json_data = to_json_archive(data, previous_file, last_archive_checksum) - current_archive_checksum = Checksum.text(json_data) - date = DateTime.iso8601 - chained = Checksum.text("#{current_archive_checksum}#{last_archive_checksum}#{date}") - - Zip::OutputStream.open(archive_file) do |io| - io.put_next_entry(archive_json_file) - io.write(json_data) - io.put_next_entry('checksum.sha256') - io.write("#{current_archive_checksum}\t#{archive_json_file}") - io.put_next_entry('chained.sha256') - io.write("#{chained}\t#{date}") - end + ArchiveWorker.perform_async(id) end def price_without_taxe(invoice) diff --git a/app/workers/archive_worker.rb b/app/workers/archive_worker.rb new file mode 100644 index 000000000..6058aea18 --- /dev/null +++ b/app/workers/archive_worker.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +# Will generate a ZIP archive file containing all invoicing data for the given period. +# This file will be asynchronously generated by sidekiq and a notification will be sent to the requesting user when it's done. +class ArchiveWorker + include Sidekiq::Worker + + def perform(accounting_period_id) + period = AccountingPeriod.find(accounting_period_id) + + data = period.invoices.includes(:invoice_items).order(id: :asc) + previous_file = period.previous_period&.archive_file + last_archive_checksum = previous_file ? Checksum.file(previous_file) : nil + json_data = to_json_archive(period, data, previous_file, last_archive_checksum) + current_archive_checksum = Checksum.text(json_data) + date = DateTime.iso8601 + chained = Checksum.text("#{current_archive_checksum}#{last_archive_checksum}#{date}") + + Zip::OutputStream.open(period.archive_file) do |io| + io.put_next_entry(period.archive_json_file) + io.write(json_data) + io.put_next_entry('checksum.sha256') + io.write("#{current_archive_checksum}\t#{period.archive_json_file}") + io.put_next_entry('chained.sha256') + io.write("#{chained}\t#{date}") + end + + NotificationCenter.call type: :notify_admin_archive_complete, + receiver: period.closed_by, + attached_object: period + end + + private + + def to_json_archive(period, invoices, previous_file, last_checksum) + code_checksum = Checksum.code + ApplicationController.new.view_context.render( + partial: 'archive/accounting', + locals: { + invoices: period.invoices_with_vat(invoices), + period_total: period.period_total, + perpetual_total: period.perpetual_total, + period_footprint: period.footprint, + code_checksum: code_checksum, + last_archive_checksum: last_checksum, + previous_file: previous_file, + software_version: Version.current, + date: Time.now.iso8601 + }, + formats: [:json], + handlers: [:jbuilder] + ) + end +end