2021-05-21 18:25:18 +02:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
require 'integrity/archive_helper'
|
|
|
|
|
|
|
|
# Previously, the relation between an invoice and the bought objects where stored disparately:
|
|
|
|
# Invoice.invoiced_id & Invoice.invoiced_type saved the main object, and if a subscription was took at the same time of
|
|
|
|
# a reservation (the only case where two object were bought at the same time), the reservation was saved in
|
|
|
|
# Invoice.invoiced and the subscription was saved in InvoiceItem.subscription_id
|
|
|
|
#
|
|
|
|
# From this migration, everything will be saved in InvoiceItems.object_id & InvoiceItem.object_type. This will be more
|
|
|
|
# extensible and will allow to invoice more types of objects the future.
|
|
|
|
class AddObjectToInvoiceItem < ActiveRecord::Migration[5.2]
|
|
|
|
def up
|
2021-05-25 17:28:35 +02:00
|
|
|
# first check that there's no bogus invoices
|
|
|
|
raise InvalidInvoiceError if Invoice.where(invoiced_id: nil).where.not(invoiced_type: 'Error').count.positive?
|
|
|
|
|
|
|
|
# check the footprints
|
2021-05-21 18:25:18 +02:00
|
|
|
Integrity::ArchiveHelper.check_footprints
|
|
|
|
|
|
|
|
# if everything is ok, proceed with migration: remove and save periods in memory
|
|
|
|
periods = Integrity::ArchiveHelper.backup_and_remove_periods
|
|
|
|
|
|
|
|
add_reference :invoice_items, :object, polymorphic: true
|
|
|
|
add_column :invoice_items, :main, :boolean
|
|
|
|
# migrate data
|
|
|
|
Invoice.where.not(invoiced_type: 'Reservation').each do |invoice|
|
2021-05-27 11:31:07 +02:00
|
|
|
execute %(
|
|
|
|
UPDATE invoice_items
|
|
|
|
SET object_id = #{invoice.invoiced_id},
|
|
|
|
object_type = '#{invoice.invoiced_type}',
|
|
|
|
main = true
|
|
|
|
WHERE id = #{invoice.invoice_items.first.id}
|
2021-05-21 18:25:18 +02:00
|
|
|
)
|
|
|
|
end
|
|
|
|
Invoice.where(invoiced_type: 'Reservation').each do |invoice|
|
2021-05-27 11:31:07 +02:00
|
|
|
execute %(
|
|
|
|
UPDATE invoice_items
|
|
|
|
SET object_id = #{invoice.invoiced_id},
|
|
|
|
object_type = '#{invoice.invoiced_type}',
|
|
|
|
main = true
|
|
|
|
WHERE id = #{invoice.invoice_items.where(subscription_id: nil).first.id}
|
2021-05-21 18:25:18 +02:00
|
|
|
)
|
2021-05-25 17:28:35 +02:00
|
|
|
invoice.invoice_items.where(subscription_id: nil)[1..-1].each do |ii|
|
2021-05-27 11:31:07 +02:00
|
|
|
execute %(
|
|
|
|
UPDATE invoice_items
|
|
|
|
SET object_id = #{invoice.invoiced_id},
|
|
|
|
object_type = '#{invoice.invoiced_type}'
|
|
|
|
WHERE id = #{ii.id}
|
2021-05-25 17:28:35 +02:00
|
|
|
)
|
|
|
|
end
|
|
|
|
subscription_item = invoice.invoice_items.where.not(subscription_id: nil).first
|
|
|
|
next unless subscription_item
|
|
|
|
|
2021-05-27 11:31:07 +02:00
|
|
|
execute %(
|
|
|
|
UPDATE invoice_items
|
|
|
|
SET object_id = #{subscription_item.subscription_id},
|
|
|
|
object_type = 'Subscription'
|
|
|
|
WHERE id = #{subscription_item.id}
|
2021-05-25 17:28:35 +02:00
|
|
|
)
|
2021-05-21 18:25:18 +02:00
|
|
|
end
|
|
|
|
remove_column :invoice_items, :subscription_id
|
2021-05-25 17:28:35 +02:00
|
|
|
remove_reference :invoices, :invoiced, polymorphic: true
|
2021-05-21 18:25:18 +02:00
|
|
|
|
|
|
|
# chain records
|
|
|
|
puts 'Chaining all record. This may take a while...'
|
|
|
|
InvoiceItem.order(:id).all.each(&:chain_record)
|
|
|
|
Invoice.order(:id).all.each(&:chain_record)
|
|
|
|
|
|
|
|
# re-create all archives from the memory dump
|
|
|
|
Integrity::ArchiveHelper.restore_periods(periods)
|
|
|
|
end
|
|
|
|
|
|
|
|
def down
|
|
|
|
# first, check the footprints
|
|
|
|
Integrity::ArchiveHelper.check_footprints
|
|
|
|
|
|
|
|
# if everything is ok, proceed with migration: remove and save periods in memory
|
|
|
|
periods = Integrity::ArchiveHelper.backup_and_remove_periods
|
|
|
|
|
|
|
|
add_column :invoice_items, :subscription_id, :integer
|
|
|
|
add_reference :invoices, :invoiced, polymorphic: true
|
|
|
|
# migrate data
|
2021-05-25 17:28:35 +02:00
|
|
|
InvoiceItem.where(main: true).each do |ii|
|
2021-05-27 11:31:07 +02:00
|
|
|
execute %(
|
|
|
|
UPDATE invoices
|
|
|
|
SET invoiced_id = #{ii.object_id},
|
|
|
|
invoiced_type = '#{ii.object_type}'
|
|
|
|
WHERE id = #{ii.invoice.id}
|
2021-05-25 17:28:35 +02:00
|
|
|
)
|
|
|
|
end
|
|
|
|
InvoiceItem.where(object_type: 'Subscription').each do |ii|
|
2021-05-27 11:31:07 +02:00
|
|
|
execute %(
|
|
|
|
UPDATE invoice_items
|
|
|
|
SET subscription_id = #{ii.object_id}
|
|
|
|
WHERE id = #{ii.id}
|
2021-05-25 17:28:35 +02:00
|
|
|
)
|
|
|
|
end
|
2021-05-21 18:25:18 +02:00
|
|
|
remove_column :invoice_items, :main
|
2021-05-25 17:28:35 +02:00
|
|
|
remove_reference :invoice_items, :object, polymorphic: true
|
2021-05-21 18:25:18 +02:00
|
|
|
|
|
|
|
# chain records
|
|
|
|
puts 'Chaining all record. This may take a while...'
|
|
|
|
InvoiceItem.order(:id).all.each(&:chain_record)
|
|
|
|
Invoice.order(:id).all.each(&:chain_record)
|
|
|
|
|
|
|
|
# re-create all archives from the memory dump
|
|
|
|
Integrity::ArchiveHelper.restore_periods(periods)
|
|
|
|
end
|
|
|
|
end
|