From 5fca8370ffa92b22e9345ffe5279f5a07fbe034c Mon Sep 17 00:00:00 2001 From: Sylvain Date: Mon, 24 May 2021 11:38:25 +0200 Subject: [PATCH] use integrity checking refactored lib --- ...30_migrate_invoice_to_invoicing_profile.rb | 68 ++----------------- .../20200511075933_fix_accounting_periods.rb | 65 ++---------------- 2 files changed, 12 insertions(+), 121 deletions(-) diff --git a/db/migrate/20190522115230_migrate_invoice_to_invoicing_profile.rb b/db/migrate/20190522115230_migrate_invoice_to_invoicing_profile.rb index b99519b52..45b263fd9 100644 --- a/db/migrate/20190522115230_migrate_invoice_to_invoicing_profile.rb +++ b/db/migrate/20190522115230_migrate_invoice_to_invoicing_profile.rb @@ -1,14 +1,16 @@ # frozen_string_literal: true +require 'integrity/archive_helper' + # migrate the invoices from being attached to a user to invoicing_profiles which are GDPR compliant class MigrateInvoiceToInvoicingProfile < ActiveRecord::Migration[4.2] def up # first, check the footprints - check_footprints + Integrity::ArchiveHelper.check_footprints # if everything is ok, proceed with migration # remove and save periods in memory - periods = backup_and_remove_periods + periods = Integrity::ArchiveHelper.backup_and_remove_periods # migrate invoices puts 'Migrating invoices. This may take a while...' Invoice.order(:id).all.each do |i| @@ -24,14 +26,14 @@ class MigrateInvoiceToInvoicingProfile < ActiveRecord::Migration[4.2] InvoiceItem.order(:id).all.each(&:chain_record) Invoice.order(:id).all.each(&:chain_record) # write memory dump into database - restore_periods(periods) + Integrity::ArchiveHelper.restore_periods(periods) end def down # here we don't check footprints to save processing time and because this is pointless when reverting the migrations # remove and save periods in memory - periods = backup_and_remove_periods + periods = Integrity::ArchiveHelper.backup_and_remove_periods # reset invoices Invoice.order(:created_at).all.each do |i| i.update_column('user_id', i.invoicing_profile.user_id) @@ -44,62 +46,6 @@ class MigrateInvoiceToInvoicingProfile < ActiveRecord::Migration[4.2] InvoiceItem.order(:id).all.each(&:chain_record) Invoice.order(:id).all.each(&:chain_record) # write memory dump into database - restore_periods(periods) - end - - def check_footprints - if AccountingPeriod.count.positive? - last_period = AccountingPeriod.order(start_at: 'DESC').first - puts "Checking invoices footprints from #{last_period.end_at}. This may take a while..." - Invoice.where('created_at > ?', last_period.end_at).order(:id).each do |i| - raise "Invalid footprint for invoice #{i.id}" unless i.check_footprint - end - else - puts 'Checking all invoices footprints. This may take a while...' - Invoice.order(:id).all.each do |i| - raise "Invalid footprint for invoice #{i.id}" unless i.check_footprint - end - end - end - - # will return an array of hash containing the removed periods data - def backup_and_remove_periods - return [] unless AccountingPeriod.count.positive? - - puts 'Removing accounting archives...' - # 1. remove protection for AccountingPeriods - execute("DROP RULE IF EXISTS accounting_periods_del_protect ON #{AccountingPeriod.arel_table.name};") - # 2. backup AccountingPeriods in memory - periods = [] - AccountingPeriod.all.each do |p| - periods.push( - start_at: p.start_at, - end_at: p.end_at, - closed_at: p.closed_at, - closed_by: p.closed_by - ) - end - # 3. Delete periods from database - AccountingPeriod.all.each do |ap| - execute("DELETE FROM accounting_periods WHERE ID=#{ap.id};") - end - periods - end - - def restore_periods(periods) - return unless periods.size.positive? - - # 1. recreate AccountingPeriods - puts 'Recreating accounting archives. This may take a while...' - periods.each do |p| - AccountingPeriod.create!( - start_at: p[:start_at], - end_at: p[:end_at], - closed_at: p[:closed_at], - closed_by: p[:closed_by] - ) - end - # 2. reset protection for AccountingPeriods - execute("CREATE RULE accounting_periods_del_protect AS ON DELETE TO #{AccountingPeriod.arel_table.name} DO INSTEAD NOTHING;") + Integrity::ArchiveHelper.restore_periods(periods) end end diff --git a/db/migrate/20200511075933_fix_accounting_periods.rb b/db/migrate/20200511075933_fix_accounting_periods.rb index d2a3038bb..d7adee682 100644 --- a/db/migrate/20200511075933_fix_accounting_periods.rb +++ b/db/migrate/20200511075933_fix_accounting_periods.rb @@ -1,72 +1,17 @@ # frozen_string_literal: true +require 'integrity/archive_helper' + # regenerate the accounting periods affected by the current bug (period totals are wrong due to wrong VAT computation) class FixAccountingPeriods < ActiveRecord::Migration[5.2] def change # first, check the footprints - check_footprints + Integrity::ArchiveHelper.check_footprints # if everything is ok, proceed with migration # remove periods (backup their parameters in memory) - periods = backup_and_remove_periods + periods = Integrity::ArchiveHelper.backup_and_remove_periods(range_start: '2019-08-01', range_end: '2020-05-12') # recreate periods from memory dump - restore_periods(periods) + Integrity::ArchiveHelper.restore_periods(periods) end - - def check_footprints - if AccountingPeriod.count.positive? - last_period = AccountingPeriod.order(start_at: :desc).first - puts "Checking invoices footprints from #{last_period.end_at}. This may take a while..." - Invoice.where('created_at > ?', last_period.end_at).order(:id).each do |i| - raise "Invalid footprint for invoice #{i.id}" unless i.check_footprint - end - else - puts 'Checking all invoices footprints. This may take a while...' - Invoice.order(:id).all.each do |i| - raise "Invalid footprint for invoice #{i.id}" unless i.check_footprint - end - end - end - - # will return an array of hash containing the removed periods data - def backup_and_remove_periods - return [] unless AccountingPeriod.where("created_at > '2019-08-01' AND created_at < '2020-05-12'").count.positive? - - puts 'Removing erroneous accounting archives...' - # 1. remove protection for AccountingPeriods - execute("DROP RULE IF EXISTS accounting_periods_del_protect ON #{AccountingPeriod.arel_table.name};") - # 2. backup AccountingPeriods in memory - periods = [] - AccountingPeriod.where("created_at > '2019-08-01'").each do |p| - periods.push( - start_at: p.start_at, - end_at: p.end_at, - closed_at: p.closed_at, - closed_by: p.closed_by - ) - end - # 3. Delete periods from database - AccountingPeriod.where("created_at > '2019-08-01'").each do |ap| - execute("DELETE FROM accounting_periods WHERE ID=#{ap.id};") - end - periods - end - - def restore_periods(periods) - return unless periods.size.positive? - - # 1. recreate AccountingPeriods - puts 'Recreating accounting archives. This may take a while...' - periods.each do |p| - AccountingPeriod.create!( - start_at: p[:start_at], - end_at: p[:end_at], - closed_at: p[:closed_at], - closed_by: p[:closed_by] - ) - end - # 2. reset protection for AccountingPeriods - execute("CREATE RULE accounting_periods_del_protect AS ON DELETE TO #{AccountingPeriod.arel_table.name} DO INSTEAD NOTHING;") - end - end