From d85f599d0790698c90eefe4bbe5ceb79d7f07045 Mon Sep 17 00:00:00 2001 From: vangberg Date: Wed, 26 Aug 2026 11:01:37 +0200 Subject: [PATCH] Create batch placements directly --- app/models/tutorial/batch.rb | 56 ++++++-- app/views/tutorials/batch/_01.html.erb | 12 +- ...CR_UploadBatch-Luteria-Incertae_sedis.xlsx | Bin 0 -> 18771 bytes .../files/SCR_UploadBatch-Nanoclepta.xlsx | Bin 0 -> 17009 bytes test/fixtures/names.yml | 15 +++ test/models/tutorial_test.rb | 124 +++++++++++++++++- test/system/tutorials_test.rb | 96 +++++++++++++- 7 files changed, 284 insertions(+), 19 deletions(-) create mode 100644 test/fixtures/files/SCR_UploadBatch-Luteria-Incertae_sedis.xlsx create mode 100644 test/fixtures/files/SCR_UploadBatch-Nanoclepta.xlsx diff --git a/app/models/tutorial/batch.rb b/app/models/tutorial/batch.rb index e115b03d..c1bbc2d5 100644 --- a/app/models/tutorial/batch.rb +++ b/app/models/tutorial/batch.rb @@ -77,7 +77,15 @@ def param_names def ephemeral_names @ephemeral_names ||= param_names.map do |i| - Name.new(i) + name_attributes = i.except('parent', 'incertae_sedis') + placement_attributes = { + parent: i['parent'], incertae_sedis: i['incertae_sedis'], + incertae_sedis_text: i['description'], preferred: true + } + + Name.new(name_attributes).tap do |name| + name.placements.build(placement_attributes.merge(name: name)) + end rescue => e $stderr.puts e nil @@ -113,15 +121,20 @@ def check_ephemeral_names(user) @check_ephemeral_names ||= :pending return ephemeral_names if @check_ephemeral_names == :done - name_names = ephemeral_names.map(&:name) ephemeral_names.each do |name| + placement = name.placements.first + # Is the information complete? Tutorial::Batch.name_keys_base.each do |i| + next if i == :parent + unless name.send(i).present? name.errors.add(i, :missing, message: 'is missing') end end + placement.validate # Populate placement.errors for the review step + # Is the etymology present? unless name.etymology? name.errors.add( @@ -139,8 +152,8 @@ def check_ephemeral_names(user) end # Is the parent already registered? - if name.parent && !name_exists?(name.parent.name) - name.errors.add( + if placement.parent && !name_exists?(placement.parent.name) + placement.errors.add( :parent, :does_not_exist, message: 'does not exist and is not proposed in this list' ) @@ -305,7 +318,8 @@ def batch_step_01(params, user) # Remove foreign keys in first pass par = par_ori.dup %w[ - parent nomenclatural_type_entry nomenclatural_type_type + parent incertae_sedis + nomenclatural_type_entry nomenclatural_type_type nomenclatural_type_id nomenclatural_type ].each { |i| par.delete(i) } @@ -333,12 +347,21 @@ def batch_step_01(params, user) # Parents if par['parent'] - new_par[:parent] = Name.find_by_variants(par['parent'].name) - unless new_par[:parent] - name = Name.new(default_pars.merge(name: par['parent'].name)) - name.save! - new_par[:parent_id] = name.id + parent = Name.find_by_variants(par['parent'].name) + unless parent + parent = Name.new(default_pars.merge(name: par['parent'].name)) + parent.save! end + save_batch_placement( + Name.find_by_variants(par['name']), + parent: parent, incertae_sedis: nil + ) + elsif par['incertae_sedis'] + save_batch_placement( + Name.find_by_variants(par['name']), parent: nil, + incertae_sedis: par['incertae_sedis'], + incertae_sedis_text: par['description'] + ) end # Nomenclatural types @@ -377,4 +400,17 @@ def batch_step_02(params, user) @next_action = [:new_register, tutorial: self] end + private + + def save_batch_placement(name, attributes) + # Reuse matching alternatives and demote the current placement before + # promotion so the name never attempts to save two preferred placements. + placement = name.placements.find_or_initialize_by( + attributes.slice(:parent, :incertae_sedis) + ) + name.placements.where(preferred: true).where.not(id: placement.id) + .find_each { |current| current.update!(preferred: false) } + placement.update!(attributes.merge(preferred: true)) + end + end diff --git a/app/views/tutorials/batch/_01.html.erb b/app/views/tutorials/batch/_01.html.erb index c854a844..2867f341 100644 --- a/app/views/tutorials/batch/_01.html.erb +++ b/app/views/tutorials/batch/_01.html.erb @@ -9,6 +9,7 @@
<% @tutorial.check_ephemeral_names(current_user) %> <% @tutorial.ephemeral_names.each_with_index do |name, idx| %> + <% placement = name&.placements&.first %>
<% id = "batch-names-#{idx}" %> <% if name.nil? || name&.name.nil? %> @@ -32,13 +33,14 @@ @@ -66,11 +68,12 @@ <% end %> <%= modal_button(id, as_anchor: true) do %>Record details<% end %> - <% if name.errors.any? %> + <% if name.errors.any? || placement.errors.any? %>

Issues detected in preliminary check:

    - <% name.errors.full_messages.each do |error| %> + <% (name.errors.full_messages + + placement.errors.full_messages).each do |error| %>
  • <%= error %>
  • <% end %>
@@ -166,4 +169,3 @@ Please note that any errors saved will have to be individually resolved. This process may take up to a couple of minutes, please be patient.

- diff --git a/test/fixtures/files/SCR_UploadBatch-Luteria-Incertae_sedis.xlsx b/test/fixtures/files/SCR_UploadBatch-Luteria-Incertae_sedis.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..25682a222978e43b886e3a8039c988a2a4b8f690 GIT binary patch literal 18771 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 literal 0 HcmV?d00001 diff --git a/test/fixtures/files/SCR_UploadBatch-Nanoclepta.xlsx b/test/fixtures/files/SCR_UploadBatch-Nanoclepta.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..49207a08d6f9bc192badd5feb2178fbd64b6b47d GIT binary patch literal 17009 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 Qz