Merge pull request #9840 from colinux/maintenance-task-update-tdc
ETQ superadmin je peux mettre à jour le brouillon d'une révision à partir d'un CSV
This commit is contained in:
commit
01d12c9bb4
4 changed files with 231 additions and 0 deletions
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Maintenance
|
||||
class DeleteDraftRevisionTypeDeChampsTask < MaintenanceTasks::Task
|
||||
csv_collection
|
||||
|
||||
# See UpdateDraftRevisionTypeDeChampsTask for more information
|
||||
# Just add delete_flag with "true" to effectively remove the type de champ from the draft.
|
||||
|
||||
def process(row)
|
||||
return unless row["delete_flag"] == "true"
|
||||
|
||||
procedure_id = row["demarche_id"]
|
||||
typed_id = row["id"]
|
||||
|
||||
Rails.logger.info { "#{self.class.name}: Processing #{row.inspect}" }
|
||||
|
||||
revision = Procedure.find(procedure_id).draft_revision
|
||||
|
||||
stable_id = revision.types_de_champ.find { _1.to_typed_id == typed_id }&.stable_id
|
||||
|
||||
fail "TypeDeChamp not found ! #{typed_id}" if stable_id.nil?
|
||||
|
||||
coordinate, type_de_champ = revision.coordinate_and_tdc(stable_id)
|
||||
|
||||
if coordinate&.used_by_routing_rules?
|
||||
fail "#{typed_id} / #{type_de_champ.libelle} » est utilisé pour le routage, vous ne pouvez pas le supprimer."
|
||||
end
|
||||
|
||||
revision.remove_type_de_champ(stable_id)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,54 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Maintenance
|
||||
class UpdateDraftRevisionTypeDeChampsTask < MaintenanceTasks::Task
|
||||
csv_collection
|
||||
|
||||
# CSV structure:
|
||||
# demarche_id, id, new_libelle, new_description, new_required, new_position
|
||||
# 1234, QnbaF==, Nouveau libellé, Nouvelle description, true, 0
|
||||
# 1234, QNbZ0==, Un autre libellé, Encore une desc,, 1
|
||||
#
|
||||
# Remarques:
|
||||
# - Toutes les valeurs sont écrasées sur la draft revision
|
||||
# - Les positions doivent être dans l'ordre, sans trou, en suivant l'ordre de l'éditeur du formulair !
|
||||
# - Les positions commencent à 0, comme un index
|
||||
# - La position de l'ensemble du bloc répétable est celle du "parent"
|
||||
# - Les champs des blocs répétables suivent la position du parent (c'est notre code qui la réinitialise à 0)
|
||||
# - Ne permet pas de "sortir" des champs de blocs répétables, ni en ajouter (on peut juste réorganiser à l'intérieur du bloc)
|
||||
def process(row)
|
||||
procedure_id = row["demarche_id"]
|
||||
typed_id = row["id"]
|
||||
|
||||
Rails.logger.info { "#{self.class.name}: Processing #{row.inspect}" }
|
||||
|
||||
revision = Procedure.find(procedure_id).draft_revision
|
||||
|
||||
stable_id = revision.types_de_champ.find { _1.to_typed_id == typed_id }&.stable_id
|
||||
|
||||
fail "TypeDeChamp not found ! #{typed_id}" if stable_id.nil?
|
||||
|
||||
tdc = revision.find_and_ensure_exclusive_use(stable_id)
|
||||
|
||||
revision.move_type_de_champ(stable_id, compute_position(row, tdc.revision_type_de_champ))
|
||||
|
||||
tdc.update!(
|
||||
libelle: row["new_libelle"].strip,
|
||||
description: row["new_description"]&.strip.to_s, # we want empty string
|
||||
mandatory: row["new_required"] == "true"
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def compute_position(row, rtdc)
|
||||
position = Integer(row["new_position"])
|
||||
|
||||
if rtdc.child?
|
||||
position - rtdc.parent.position - 1
|
||||
else
|
||||
position
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,67 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
module Maintenance
|
||||
RSpec.describe DeleteDraftRevisionTypeDeChampsTask do
|
||||
let(:procedure) { create(:procedure, :published, types_de_champ_public:) }
|
||||
let(:types_de_champ_public) {
|
||||
[
|
||||
{ type: :text, libelle: "Text", stable_id: 11, mandatory: true },
|
||||
{ type: :number, libelle: "Number", description: "Old desc", stable_id: 12 },
|
||||
{
|
||||
type: :repetition, libelle: "Bloc", stable_id: 13, children: [
|
||||
{ type: :text, libelle: "RepText", stable_id: 131, description: "Remove me", mandatory: true },
|
||||
{ type: :number, libelle: "RepNum", stable_id: 132 }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
let(:csv) do
|
||||
<<~CSV
|
||||
demarche_id,id,new_libelle,new_description,new_required,new_position,delete_flag
|
||||
#{procedure.id},#{find_by_stable_id(12).to_typed_id},[NEW] Number,[NEW] Number desc,true,0,
|
||||
#{procedure.id},#{find_by_stable_id(13).to_typed_id},Bloc,[NEW] bloc desc,,1,
|
||||
#{procedure.id},#{find_by_stable_id(132).to_typed_id},[NEW] RepNum,,true,2,true
|
||||
#{procedure.id},#{find_by_stable_id(131).to_typed_id},[NEW] RepText,,,3,
|
||||
#{procedure.id},#{find_by_stable_id(11).to_typed_id},[supp] Text,,,4,true
|
||||
CSV
|
||||
end
|
||||
|
||||
let(:rows) do
|
||||
CSV.parse(csv, headers: true, skip_blanks: true).map(&:to_h)
|
||||
end
|
||||
|
||||
describe "#process" do
|
||||
subject(:process) do
|
||||
rows.each { described_class.process(_1) }
|
||||
procedure.reload
|
||||
end
|
||||
|
||||
it "delete the flagged rows" do
|
||||
process
|
||||
|
||||
tdc = find_by_stable_id(12)
|
||||
expect(tdc).not_to be_nil
|
||||
|
||||
tdc = find_by_stable_id(13)
|
||||
expect(tdc).not_to be_nil
|
||||
|
||||
tdc = find_by_stable_id(11)
|
||||
expect(tdc).to be_nil
|
||||
|
||||
tdc = find_by_stable_id(131)
|
||||
expect(tdc).not_to be_nil
|
||||
expect(tdc.revision_type_de_champ.position).to eq(0) # reindexed
|
||||
|
||||
tdc = find_by_stable_id(132)
|
||||
expect(tdc).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
def find_by_stable_id(stable_id)
|
||||
procedure.draft_revision.types_de_champ.find { _1.stable_id == stable_id }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,77 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Maintenance
|
||||
RSpec.describe UpdateDraftRevisionTypeDeChampsTask do
|
||||
let(:procedure) { create(:procedure, :published, types_de_champ_public:) }
|
||||
let(:types_de_champ_public) {
|
||||
[
|
||||
{ type: :text, libelle: "Text", stable_id: 11, mandatory: true },
|
||||
{ type: :number, libelle: "Number", description: "Old desc", stable_id: 12 },
|
||||
{
|
||||
type: :repetition, libelle: "Bloc", stable_id: 13, children: [
|
||||
{ type: :text, libelle: "RepText", stable_id: 131, description: "Remove me", mandatory: true },
|
||||
{ type: :number, libelle: "RepNum", stable_id: 132 }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
let(:csv) do
|
||||
<<~CSV
|
||||
demarche_id,id,new_libelle,new_description,new_required,new_position,delete_flag
|
||||
#{procedure.id},#{find_by_stable_id(12).to_typed_id},[NEW] Number,[NEW] Number desc,true,0,
|
||||
#{procedure.id},#{find_by_stable_id(13).to_typed_id},Bloc,[NEW] bloc desc,,1,
|
||||
#{procedure.id},#{find_by_stable_id(132).to_typed_id},[NEW] RepNum,,true,2,
|
||||
#{procedure.id},#{find_by_stable_id(131).to_typed_id},[NEW] RepText,,,3,
|
||||
#{procedure.id},#{find_by_stable_id(11).to_typed_id},[supp] Text,,,4,true
|
||||
CSV
|
||||
end
|
||||
|
||||
let(:rows) do
|
||||
CSV.parse(csv, headers: true, skip_blanks: true).map(&:to_h)
|
||||
end
|
||||
|
||||
describe "#process" do
|
||||
subject(:process) do
|
||||
rows.each { described_class.process(_1) }
|
||||
procedure.reload
|
||||
end
|
||||
|
||||
it "updates the type de champ" do
|
||||
process
|
||||
|
||||
tdc = find_by_stable_id(12)
|
||||
expect(tdc.revision_type_de_champ.position).to eq(0)
|
||||
expect(tdc.libelle).to eq("[NEW] Number")
|
||||
expect(tdc.description).to eq("[NEW] Number desc")
|
||||
expect(tdc.mandatory).to eq(true)
|
||||
|
||||
tdc = find_by_stable_id(13)
|
||||
expect(tdc.revision_type_de_champ.position).to eq(1)
|
||||
expect(tdc.libelle).to eq("Bloc")
|
||||
expect(tdc.description).to eq("[NEW] bloc desc")
|
||||
expect(tdc.mandatory).to eq(false)
|
||||
|
||||
tdc = find_by_stable_id(132)
|
||||
expect(tdc.revision_type_de_champ.position).to eq(0)
|
||||
expect(tdc.libelle).to eq("[NEW] RepNum")
|
||||
expect(tdc.mandatory).to eq(true)
|
||||
|
||||
tdc = find_by_stable_id(131)
|
||||
expect(tdc.revision_type_de_champ.position).to eq(1)
|
||||
expect(tdc.libelle).to eq("[NEW] RepText")
|
||||
expect(tdc.description).to eq("")
|
||||
expect(tdc.mandatory).to eq(false)
|
||||
|
||||
tdc = find_by_stable_id(11)
|
||||
expect(tdc.revision_type_de_champ.position).to eq(2)
|
||||
expect(tdc.libelle).to eq("[supp] Text")
|
||||
expect(tdc.mandatory).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
def find_by_stable_id(stable_id)
|
||||
procedure.draft_revision.types_de_champ.find { _1.stable_id == stable_id }
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue