Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

correctif(data): tâche rake recréant les champs manquant à un dossier ayant subi une perte de données #9610

Merged
merged 7 commits into from
Oct 19, 2023
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class PhoneFixer
class DataFixer::ChampsPhoneInvalid
def self.fix(phones_string)
phone_candidates = phones_string
.split(/-/)
Expand Down
40 changes: 40 additions & 0 deletions app/lib/data_fixer/dossier_champs_missing.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# some race condition (regarding double submit of dossier.passer_en_construction!) might remove champs
# until now we haven't decided to push a stronger fix than an UI change
# so we might have to recreate some deleted champs and notify administration
class DataFixer::DossierChampsMissing
def fix
fixed_on_origin = apply_fix(@original_dossier)

fixed_on_other = Dossier.where(editing_fork_origin_id: @original_dossier.id)
.map(&method(:apply_fix))

[fixed_on_origin, fixed_on_other.sum].sum
end

private

attr_reader :original_dossier

def initialize(dossier:)
@original_dossier = dossier
end

def apply_fix(dossier)
dossier_champs = dossier.champs_public.includes(:type_de_champ)
revision_type_de_champ = TypeDeChamp.joins(:revision_type_de_champ).where(revision_type_de_champ: { revision: dossier.revision })

dossier_tdc_stable_ids = dossier_champs.map(&:type_de_champ).map(&:stable_id)

missing_tdcs = revision_type_de_champ.filter { !dossier_tdc_stable_ids.include?(_1.stable_id) }
missing_tdcs.map do |missing_champ|
dossier.champs_public << missing_champ.build_champ
end

if !missing_tdcs.empty?
dossier.save!
missing_tdcs.size
else
0
end
end
end
44 changes: 44 additions & 0 deletions lib/tasks/data_fixer.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
require Rails.root.join("lib", "tasks", "task_helper")

namespace :data_fixer do
desc <<~EOD
Given a procedure_id in argument, run the DataFixer::ChampsPhoneInvalid.
ex: rails data_fixer:fix_phones\[1\]
EOD
task :fix_phones, [:procedure_id] => :environment do |_t, args|
procedure = Procedure.find(args[:procedure_id])

phone_champs = Champ
.where(dossier_id: procedure.dossiers.pluck(:id))
.where(type: "Champs::PhoneChamp")

invalid_phone_champs = phone_champs.reject(&:valid?)

fixable_phone_champs = invalid_phone_champs.filter { |phone| DataFixer::ChampsPhoneInvalid.fixable?(phone.value) }

fixable_phone_champs.each do |phone|
fixable_phone_value = phone.value
fixed_phone_value = DataFixer::ChampsPhoneInvalid.fix(fixable_phone_value)
if phone.update(value: fixed_phone_value)
rake_puts "Invalid phone #{fixable_phone_value} is fixed as #{fixed_phone_value}"
else
rake_puts "Failed to fix #{fixable_phone_value}"
end
end
end

desc <<~EOD
Given a dossier_id in argument, run the DossierChampsMissing.
ex: rails data_fixer:dossier_missing_champ\[1\]
EOD
task :dossier_missing_champ, [:dossier_id] => :environment do |_t, args|
dossier = Dossier.find(args[:dossier_id])
result = DataFixer::DossierChampsMissing.new(dossier:).fix

if result > 0
rake_puts "Dossier#[#{args[:dossier_id]}] fixed"
else
rake_puts "Dossier#[#{args[:dossier_id]}] not fixed"
end
end
end
29 changes: 0 additions & 29 deletions lib/tasks/phone_fixer.rake

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
describe PhoneFixer do
describe DataFixer::ChampsPhoneInvalid do
describe '#fix' do
subject { described_class.fix(phone_str) }

Expand Down
36 changes: 36 additions & 0 deletions spec/lib/data_fixer/dossier_champs_missing_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
describe DataFixer::DossierChampsMissing do
describe '#fix' do
let(:procedure) { create(:procedure, :with_datetime, :with_dossier_link) }
let(:dossier) { create(:dossier, procedure:) }

context 'when dossier does not have a fork' do
before { dossier.champs_public.first.destroy }
subject { described_class.new(dossier:).fix }

it 'add missing champs to the dossier' do
expect { subject }.to change { dossier.champs_public.count }.from(1).to(2)
end

it 'returns number of added champs' do
expect(subject).to eq(1)
end
end

context 'when dossier have a fork' do
before { dossier.champs_public.first.destroy }
let(:create_fork) { dossier.find_or_create_editing_fork(dossier.user) }
subject do
create_fork
described_class.new(dossier:).fix
end

it 'add missing champs to the fork too' do
expect { subject }.to change { create_fork.champs_public.count }.from(1).to(2)
end

it 'sums number of added champs for dossier and editing_fork_origin_id' do
expect(subject).to eq(2)
end
end
end
end