labimotion 1.0.18 → 1.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/labimotion/apis/generic_element_api.rb +6 -1
- data/lib/labimotion/entities/element_entity.rb +13 -65
- data/lib/labimotion/entities/properties_entity.rb +72 -0
- data/lib/labimotion/entities/segment_entity.rb +1 -49
- data/lib/labimotion/helpers/element_helpers.rb +2 -2
- data/lib/labimotion/helpers/sample_association_helpers.rb +5 -103
- data/lib/labimotion/libs/sample_association.rb +125 -0
- data/lib/labimotion/models/concerns/segmentable.rb +2 -0
- data/lib/labimotion/version.rb +1 -1
- data/lib/labimotion.rb +3 -0
- metadata +5 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 81bff41ed125305e39e96062f4789d51afca7736e5a1f3d20b1168ed018dac49
         | 
| 4 | 
            +
              data.tar.gz: e755bb4cb53c46e133d4c4f6a79400ec9bf5abbefb6db708027d4d6f8a36232a
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: fa3fbcc006bd09ac31ed3086929fe16778aaf580ad855696bca1c4a42c21b97a53d2ee4c267fbb088dad89f70063d306c526789b31f5aaa79dd777296766d623
         | 
| 7 | 
            +
              data.tar.gz: baf3d2120168d03d921a4caeeb95ea8214fd7184c50736158176666564cf223b91b7dae5df4f1168c4f93d68dcc604bd0caf70a33d4303fd3233e65a2152281e
         | 
| @@ -310,7 +310,10 @@ module Labimotion | |
| 310 310 | 
             
                  end
         | 
| 311 311 | 
             
                  route_param :id do
         | 
| 312 312 | 
             
                    before do
         | 
| 313 | 
            -
                       | 
| 313 | 
            +
                      @element_policy = ElementPolicy.new(current_user, Element.find(params[:id]))
         | 
| 314 | 
            +
                      error!('401 Unauthorized', 401) unless current_user.matrix_check_by_name('genericElement') && @element_policy.read?
         | 
| 315 | 
            +
                    rescue ActiveRecord::RecordNotFound
         | 
| 316 | 
            +
                      error!('404 Not Found', 404)
         | 
| 314 317 | 
             
                    end
         | 
| 315 318 |  | 
| 316 319 | 
             
                    get do
         | 
| @@ -321,10 +324,12 @@ module Labimotion | |
| 321 324 | 
             
                          attachments: attach_thumbnail(element&.attachments)
         | 
| 322 325 | 
             
                        }
         | 
| 323 326 | 
             
                      else
         | 
| 327 | 
            +
                        #byebug
         | 
| 324 328 | 
             
                        {
         | 
| 325 329 | 
             
                          element: Labimotion::ElementEntity.represent(
         | 
| 326 330 | 
             
                            element,
         | 
| 327 331 | 
             
                            detail_levels: ElementDetailLevelCalculator.new(user: current_user, element: element).detail_levels,
         | 
| 332 | 
            +
                            policy: @element_policy
         | 
| 328 333 | 
             
                          ),
         | 
| 329 334 | 
             
                          attachments: attach_thumbnail(element&.attachments)
         | 
| 330 335 | 
             
                        }
         | 
| @@ -1,11 +1,13 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            require 'labimotion/entities/ | 
| 3 | 
            +
            require 'labimotion/entities/properties_entity'
         | 
| 4 4 | 
             
            ## TODO: Refactor labimotion to use the same entities as chemotion
         | 
| 5 5 | 
             
            module Labimotion
         | 
| 6 | 
            -
              class ElementEntity <  | 
| 6 | 
            +
              class ElementEntity < PropertiesEntity
         | 
| 7 7 | 
             
                with_options(anonymize_below: 0) do
         | 
| 8 | 
            -
                  expose! :can_copy
         | 
| 8 | 
            +
                  expose! :can_copy,        unless: :displayed_in_list
         | 
| 9 | 
            +
                  expose! :can_publish,     unless: :displayed_in_list
         | 
| 10 | 
            +
                  expose! :can_update,      unless: :displayed_in_list
         | 
| 9 11 | 
             
                  expose! :container,                           using: 'Entities::ContainerEntity'
         | 
| 10 12 | 
             
                  expose! :created_by
         | 
| 11 13 | 
             
                  expose! :id
         | 
| @@ -35,75 +37,21 @@ module Labimotion | |
| 35 37 | 
             
                  detail_levels[Labimotion::Element] < 10
         | 
| 36 38 | 
             
                end
         | 
| 37 39 |  | 
| 38 | 
            -
                # TODO: Refactor this method to something more readable/understandable
         | 
| 39 | 
            -
                def properties
         | 
| 40 | 
            -
                  (object.properties['layers']&.keys || []).each do |key|
         | 
| 41 | 
            -
                    # layer = object.properties[key]
         | 
| 42 | 
            -
                    field_sample_molecules = object.properties['layers'][key]['fields'].select { |ss| ss['type'] == 'drag_sample' || ss['type'] == 'drag_molecule' }
         | 
| 43 | 
            -
                    field_sample_molecules.each do |field|
         | 
| 44 | 
            -
                      idx = object.properties['layers'][key]['fields'].index(field)
         | 
| 45 | 
            -
                      sid = field.dig('value', 'el_id')
         | 
| 46 | 
            -
                      next unless sid.present?
         | 
| 47 | 
            -
             | 
| 48 | 
            -
                      el = field['type'] == 'drag_sample' ? Sample.find_by(id: sid) : Molecule.find_by(id: sid)
         | 
| 49 | 
            -
                      next unless el.present?
         | 
| 50 | 
            -
                      next unless object.properties.dig('layers', key, 'fields', idx, 'value').present?
         | 
| 51 | 
            -
             | 
| 52 | 
            -
                      object.properties['layers'][key]['fields'][idx]['value']['el_label'] = el.short_label if field['type'] == 'drag_sample'
         | 
| 53 | 
            -
                      object.properties['layers'][key]['fields'][idx]['value']['el_tip'] = el.short_label if field['type'] == 'drag_sample'
         | 
| 54 | 
            -
                      object.properties['layers'][key]['fields'][idx]['value']['el_svg'] = field['type'] == 'drag_sample' ? el.get_svg_path : File.join('/images', 'molecules', el.molecule_svg_file)
         | 
| 55 | 
            -
                    end
         | 
| 56 | 
            -
             | 
| 57 | 
            -
                    field_tables = object.properties['layers'][key]['fields'].select { |ss| ss['type'] == 'table' }
         | 
| 58 | 
            -
                    field_tables.each do |field|
         | 
| 59 | 
            -
                      idx = object.properties['layers'][key]['fields'].index(field)
         | 
| 60 | 
            -
                      next unless field['sub_values'].present? && field['sub_fields'].present?
         | 
| 61 | 
            -
             | 
| 62 | 
            -
                      field_table_molecules = field['sub_fields'].select { |ss| ss['type'] == 'drag_molecule' }
         | 
| 63 | 
            -
                      object.properties['layers'][key]['fields'][idx] = set_table(field, field_table_molecules, 'Molecule') if field_table_molecules.present?
         | 
| 64 | 
            -
             | 
| 65 | 
            -
                      field_table_samples = field['sub_fields'].select { |ss| ss['type'] == 'drag_sample' }
         | 
| 66 | 
            -
                      object.properties['layers'][key]['fields'][idx] = set_table(field, field_table_samples, 'Sample') if field_table_samples.present?
         | 
| 67 | 
            -
                    end
         | 
| 68 | 
            -
                  end
         | 
| 69 | 
            -
                  object.properties
         | 
| 70 | 
            -
                end
         | 
| 71 | 
            -
             | 
| 72 40 | 
             
                def type
         | 
| 73 41 | 
             
                  object.element_klass.name # 'genericEl' #object.type
         | 
| 74 42 | 
             
                end
         | 
| 75 43 |  | 
| 76 | 
            -
                def  | 
| 77 | 
            -
                   | 
| 78 | 
            -
                  col_ids.each do |col_id|
         | 
| 79 | 
            -
                    field['sub_values'].each do |sub_value|
         | 
| 80 | 
            -
                      next unless sub_value[col_id].present? && sub_value[col_id]['value'].present? && sub_value[col_id]['value']['el_id'].present?
         | 
| 81 | 
            -
             | 
| 82 | 
            -
                      find_obj = obj.constantize.find_by(id: sub_value[col_id]['value']['el_id'])
         | 
| 83 | 
            -
                      next unless find_obj.present?
         | 
| 84 | 
            -
             | 
| 85 | 
            -
                      case obj
         | 
| 86 | 
            -
                      when 'Molecule'
         | 
| 87 | 
            -
                        sub_value[col_id]['value']['el_svg'] = File.join('/images', 'molecules', find_obj.molecule_svg_file)
         | 
| 88 | 
            -
                        sub_value[col_id]['value']['el_inchikey'] = find_obj.inchikey
         | 
| 89 | 
            -
                        sub_value[col_id]['value']['el_smiles'] = find_obj.cano_smiles
         | 
| 90 | 
            -
                        sub_value[col_id]['value']['el_iupac'] = find_obj.iupac_name
         | 
| 91 | 
            -
                        sub_value[col_id]['value']['el_molecular_weight'] = find_obj.molecular_weight
         | 
| 92 | 
            -
                      when 'Sample'
         | 
| 93 | 
            -
                        sub_value[col_id]['value']['el_svg'] = find_obj.get_svg_path
         | 
| 94 | 
            -
                        sub_value[col_id]['value']['el_label'] = find_obj.short_label
         | 
| 95 | 
            -
                        sub_value[col_id]['value']['el_short_label'] = find_obj.short_label
         | 
| 96 | 
            -
                        sub_value[col_id]['value']['el_name'] = find_obj.name
         | 
| 97 | 
            -
                        sub_value[col_id]['value']['el_external_label'] = find_obj.external_label
         | 
| 98 | 
            -
                        sub_value[col_id]['value']['el_molecular_weight'] = find_obj.decoupled ? find_obj.molecular_mass : find_obj.molecule.molecular_weight
         | 
| 99 | 
            -
                      end
         | 
| 100 | 
            -
                    end
         | 
| 101 | 
            -
                  end
         | 
| 102 | 
            -
                  field
         | 
| 44 | 
            +
                def can_update
         | 
| 45 | 
            +
                  self.options[:policy].try(:update?) || false
         | 
| 103 46 | 
             
                end
         | 
| 104 47 |  | 
| 105 48 | 
             
                def can_copy
         | 
| 106 | 
            -
                   | 
| 49 | 
            +
                  self.options[:policy].try(:copy?) || false
         | 
| 107 50 | 
             
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                def can_publish
         | 
| 53 | 
            +
                  self.options[:policy].try(:destroy?) || false
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 108 56 | 
             
              end
         | 
| 109 57 | 
             
            end
         | 
| @@ -0,0 +1,72 @@ | |
| 1 | 
            +
            require 'labimotion/entities/application_entity'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # Entity module
         | 
| 4 | 
            +
            module Labimotion
         | 
| 5 | 
            +
              class PropertiesEntity < Labimotion::ApplicationEntity
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                # TODO: Refactor this method to something more readable/understandable
         | 
| 8 | 
            +
                def properties
         | 
| 9 | 
            +
                  (object&.properties.is_a?(Hash) && object.properties['layers']&.keys || []).each do |key|
         | 
| 10 | 
            +
                    # layer = object.properties[key]
         | 
| 11 | 
            +
                    field_sample_molecules = object.properties['layers'][key]['fields'].select { |ss| ss['type'] == 'drag_sample' || ss['type'] == 'drag_molecule' }
         | 
| 12 | 
            +
                    field_sample_molecules.each do |field|
         | 
| 13 | 
            +
                      idx = object.properties['layers'][key]['fields'].index(field)
         | 
| 14 | 
            +
                      sid = field.dig('value', 'el_id')
         | 
| 15 | 
            +
                      next unless sid.present?
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                      el = field['type'] == 'drag_sample' ? Sample.find_by(id: sid) : Molecule.find_by(id: sid)
         | 
| 18 | 
            +
                      next unless el.present?
         | 
| 19 | 
            +
                      next unless object.properties.dig('layers', key, 'fields', idx, 'value').present?
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                      object.properties['layers'][key]['fields'][idx]['value']['el_label'] = el.short_label if field['type'] == 'drag_sample'
         | 
| 22 | 
            +
                      object.properties['layers'][key]['fields'][idx]['value']['el_tip'] = el.short_label if field['type'] == 'drag_sample'
         | 
| 23 | 
            +
                      object.properties['layers'][key]['fields'][idx]['value']['el_svg'] = field['type'] == 'drag_sample' ? el.get_svg_path : File.join('/images', 'molecules', el.molecule_svg_file)
         | 
| 24 | 
            +
                    end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                    field_tables = object.properties['layers'][key]['fields'].select { |ss| ss['type'] == 'table' }
         | 
| 27 | 
            +
                    field_tables.each do |field|
         | 
| 28 | 
            +
                      idx = object.properties['layers'][key]['fields'].index(field)
         | 
| 29 | 
            +
                      next unless field['sub_values'].present? && field['sub_fields'].present?
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                      field_table_molecules = field['sub_fields'].select { |ss| ss['type'] == 'drag_molecule' }
         | 
| 32 | 
            +
                      object.properties['layers'][key]['fields'][idx] = set_table(field, field_table_molecules, 'Molecule') if field_table_molecules.present?
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                      field_table_samples = field['sub_fields'].select { |ss| ss['type'] == 'drag_sample' }
         | 
| 35 | 
            +
                      object.properties['layers'][key]['fields'][idx] = set_table(field, field_table_samples, 'Sample') if field_table_samples.present?
         | 
| 36 | 
            +
                    end
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
                  object.properties
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
             | 
| 42 | 
            +
                def set_table(field, field_table_objs, obj)
         | 
| 43 | 
            +
                  col_ids = field_table_objs.map { |x| x.values[0] }
         | 
| 44 | 
            +
                  col_ids.each do |col_id|
         | 
| 45 | 
            +
                    field['sub_values'].each do |sub_value|
         | 
| 46 | 
            +
                      next unless sub_value[col_id].present? && sub_value[col_id]['value'].present? && sub_value[col_id]['value']['el_id'].present?
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                      find_obj = obj.constantize.find_by(id: sub_value[col_id]['value']['el_id'])
         | 
| 49 | 
            +
                      next unless find_obj.present?
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                      case obj
         | 
| 52 | 
            +
                      when 'Molecule'
         | 
| 53 | 
            +
                        sub_value[col_id]['value']['el_svg'] = File.join('/images', 'molecules', find_obj.molecule_svg_file)
         | 
| 54 | 
            +
                        sub_value[col_id]['value']['el_inchikey'] = find_obj.inchikey
         | 
| 55 | 
            +
                        sub_value[col_id]['value']['el_smiles'] = find_obj.cano_smiles
         | 
| 56 | 
            +
                        sub_value[col_id]['value']['el_iupac'] = find_obj.iupac_name
         | 
| 57 | 
            +
                        sub_value[col_id]['value']['el_molecular_weight'] = find_obj.molecular_weight
         | 
| 58 | 
            +
                      when 'Sample'
         | 
| 59 | 
            +
                        sub_value[col_id]['value']['el_svg'] = find_obj.get_svg_path
         | 
| 60 | 
            +
                        sub_value[col_id]['value']['el_label'] = find_obj.short_label
         | 
| 61 | 
            +
                        sub_value[col_id]['value']['el_short_label'] = find_obj.short_label
         | 
| 62 | 
            +
                        sub_value[col_id]['value']['el_name'] = find_obj.name
         | 
| 63 | 
            +
                        sub_value[col_id]['value']['el_external_label'] = find_obj.external_label
         | 
| 64 | 
            +
                        sub_value[col_id]['value']['el_molecular_weight'] = find_obj.decoupled ? find_obj.molecular_mass : find_obj.molecule.molecular_weight
         | 
| 65 | 
            +
                      end
         | 
| 66 | 
            +
                    end
         | 
| 67 | 
            +
                  end
         | 
| 68 | 
            +
                  field
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
              end
         | 
| 72 | 
            +
            end
         | 
| @@ -3,60 +3,12 @@ | |
| 3 3 | 
             
            require 'labimotion/entities/application_entity'
         | 
| 4 4 | 
             
            module Labimotion
         | 
| 5 5 | 
             
              ## Segment entity
         | 
| 6 | 
            -
              class SegmentEntity <  | 
| 6 | 
            +
              class SegmentEntity < PropertiesEntity
         | 
| 7 7 | 
             
                expose :id, :segment_klass_id, :element_type, :element_id, :properties, :properties_release, :uuid, :klass_uuid, :klass_label
         | 
| 8 8 |  | 
| 9 9 | 
             
                def klass_label
         | 
| 10 10 | 
             
                  object.segment_klass.label
         | 
| 11 11 | 
             
                end
         | 
| 12 12 |  | 
| 13 | 
            -
                def properties # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/MethodLength
         | 
| 14 | 
            -
                  return unless object.respond_to?(:properties)
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                  return if object&.properties.dig('layers').blank?
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                  object&.properties['layers'].each_key do |key|  # rubocop:disable Metrics/BlockLength
         | 
| 19 | 
            -
                    next if object&.properties.dig('layers', key, 'fields').blank?
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                    field_sample_molecules = object&.properties['layers'][key]['fields'].select { |ss| ss['type'] == 'drag_molecule' }
         | 
| 22 | 
            -
                    field_sample_molecules.each do |field|
         | 
| 23 | 
            -
                      idx = object&.properties['layers'][key]['fields'].index(field)
         | 
| 24 | 
            -
                      sid = field.dig('value', 'el_id')
         | 
| 25 | 
            -
                      next if sid.blank?
         | 
| 26 | 
            -
             | 
| 27 | 
            -
                      el = Molecule.find_by(id: sid)
         | 
| 28 | 
            -
                      next if el.blank?
         | 
| 29 | 
            -
             | 
| 30 | 
            -
                      next if object&.properties.dig('layers', key, 'fields', idx, 'value').blank?
         | 
| 31 | 
            -
             | 
| 32 | 
            -
                      object&.properties['layers'][key]['fields'][idx]['value']['el_svg'] = File.join('/images', 'molecules', el.molecule_svg_file)
         | 
| 33 | 
            -
                    end
         | 
| 34 | 
            -
             | 
| 35 | 
            -
                    field_tables = object.properties['layers'][key]['fields'].select { |ss| ss['type'] == 'table' }
         | 
| 36 | 
            -
                    field_tables.each do |field|
         | 
| 37 | 
            -
                      next unless field['sub_values'].present? && field['sub_fields'].present?
         | 
| 38 | 
            -
             | 
| 39 | 
            -
                      field_table_molecules = field['sub_fields'].select { |ss| ss['type'] == 'drag_molecule' }
         | 
| 40 | 
            -
                      next if field_table_molecules.blank?
         | 
| 41 | 
            -
             | 
| 42 | 
            -
                      col_ids = field_table_molecules.map { |x| x.values[0] }
         | 
| 43 | 
            -
                      col_ids.each do |col_id|
         | 
| 44 | 
            -
                        field['sub_values'].each do |sub_value|
         | 
| 45 | 
            -
                          next unless sub_value[col_id].present? && sub_value[col_id]['value'].present? && sub_value[col_id]['value']['el_id'].present?
         | 
| 46 | 
            -
             | 
| 47 | 
            -
                          find_mol = Molecule.find_by(id: sub_value[col_id]['value']['el_id'])
         | 
| 48 | 
            -
                          next if find_mol.blank?
         | 
| 49 | 
            -
             | 
| 50 | 
            -
                          sub_value[col_id]['value']['el_svg'] = File.join('/images', 'molecules', find_mol.molecule_svg_file)
         | 
| 51 | 
            -
                          sub_value[col_id]['value']['el_inchikey'] = find_mol.inchikey
         | 
| 52 | 
            -
                          sub_value[col_id]['value']['el_smiles'] = find_mol.cano_smiles
         | 
| 53 | 
            -
                          sub_value[col_id]['value']['el_iupac'] = find_mol.iupac_name
         | 
| 54 | 
            -
                          sub_value[col_id]['value']['el_molecular_weight'] = find_mol.molecular_weight
         | 
| 55 | 
            -
                        end
         | 
| 56 | 
            -
                      end
         | 
| 57 | 
            -
                    end
         | 
| 58 | 
            -
                  end
         | 
| 59 | 
            -
                  object&.properties
         | 
| 60 | 
            -
                end
         | 
| 61 13 | 
             
              end
         | 
| 62 14 | 
             
            end
         | 
| @@ -92,7 +92,7 @@ module Labimotion | |
| 92 92 | 
             
                  all_coll = Collection.get_all_collection_for_user(current_user.id)
         | 
| 93 93 | 
             
                  element.collections << all_coll
         | 
| 94 94 | 
             
                  element.save!
         | 
| 95 | 
            -
                  element.properties = update_sample_association( | 
| 95 | 
            +
                  element.properties = update_sample_association(params[:properties], current_user, element)
         | 
| 96 96 | 
             
                  element.container = update_datamodel(params[:container], current_user)
         | 
| 97 97 | 
             
                  element.save!
         | 
| 98 98 | 
             
                  element.save_segments(segments: params[:segments], current_user_id: current_user.id)
         | 
| @@ -105,7 +105,7 @@ module Labimotion | |
| 105 105 | 
             
                def update_element_by_id(current_user, params)
         | 
| 106 106 | 
             
                  element = Labimotion::Element.find(params[:id])
         | 
| 107 107 | 
             
                  update_datamodel(params[:container], current_user)
         | 
| 108 | 
            -
                  properties = update_sample_association( | 
| 108 | 
            +
                  properties = update_sample_association(params[:properties], current_user, element)
         | 
| 109 109 | 
             
                  params.delete(:container)
         | 
| 110 110 | 
             
                  params.delete(:properties)
         | 
| 111 111 | 
             
                  attributes = declared(params.except(:segments), include_missing: false)
         | 
| @@ -6,119 +6,21 @@ module Labimotion | |
| 6 6 | 
             
                extend Grape::API::Helpers
         | 
| 7 7 |  | 
| 8 8 | 
             
                def build_sample(sid, cols, current_user, cr_opt)
         | 
| 9 | 
            -
                   | 
| 10 | 
            -
             | 
| 11 | 
            -
                  case cr_opt
         | 
| 12 | 
            -
                  when 0
         | 
| 13 | 
            -
                    subsample = parent_sample
         | 
| 14 | 
            -
                    collections = Collection.where(id: cols).where.not(id: subsample.collections.pluck(:id))
         | 
| 15 | 
            -
                    subsample.collections << collections unless collections.empty?
         | 
| 16 | 
            -
                  when 1
         | 
| 17 | 
            -
                    subsample = parent_sample.create_subsample(current_user, cols, true)
         | 
| 18 | 
            -
                  when 2
         | 
| 19 | 
            -
                    subsample = parent_sample.dup
         | 
| 20 | 
            -
                    subsample.parent = nil
         | 
| 21 | 
            -
                    collections = (Collection.where(id: cols) | Collection.where(user_id: current_user.id, label: 'All', is_locked: true))
         | 
| 22 | 
            -
                    subsample.collections << collections
         | 
| 23 | 
            -
                    subsample.container = Container.create_root_container
         | 
| 24 | 
            -
                  else
         | 
| 25 | 
            -
                    return nil
         | 
| 26 | 
            -
                  end
         | 
| 27 | 
            -
             | 
| 28 | 
            -
                  return nil if subsample.nil?
         | 
| 29 | 
            -
             | 
| 30 | 
            -
                  subsample.save!
         | 
| 31 | 
            -
                  subsample.reload
         | 
| 32 | 
            -
                  subsample
         | 
| 9 | 
            +
                  Labimotion::SampleAssociation.build_sample(sid, cols, current_user, cr_opt)
         | 
| 33 10 | 
             
                rescue StandardError => e
         | 
| 34 11 | 
             
                  Labimotion.log_exception(e, current_user)
         | 
| 35 12 | 
             
                  nil
         | 
| 36 13 | 
             
                end
         | 
| 37 14 |  | 
| 38 | 
            -
                def build_table_sample( | 
| 39 | 
            -
                   | 
| 40 | 
            -
                  field_tables.each do |field|
         | 
| 41 | 
            -
                    next unless field['sub_values'].present? && field['sub_fields'].present?
         | 
| 42 | 
            -
             | 
| 43 | 
            -
                    field_table_samples = field['sub_fields'].select { |ss| ss['type'] == 'drag_sample' }
         | 
| 44 | 
            -
                    next unless field_table_samples.present?
         | 
| 45 | 
            -
             | 
| 46 | 
            -
                    col_ids = field_table_samples.map { |x| x.values[0] }
         | 
| 47 | 
            -
                    col_ids.each do |col_id|
         | 
| 48 | 
            -
                      field['sub_values'].each do |sub_value|
         | 
| 49 | 
            -
                        next unless sub_value[col_id].present? && sub_value[col_id]['value'].present? && sub_value[col_id]['value']['el_id'].present?
         | 
| 50 | 
            -
             | 
| 51 | 
            -
                        svalue = sub_value[col_id]['value']
         | 
| 52 | 
            -
                        sid = svalue['el_id']
         | 
| 53 | 
            -
                        next unless sid.present?
         | 
| 54 | 
            -
             | 
| 55 | 
            -
                        sds << sid unless svalue['is_new']
         | 
| 56 | 
            -
                        next unless svalue['is_new']
         | 
| 57 | 
            -
             | 
| 58 | 
            -
                        cr_opt = svalue['cr_opt']
         | 
| 59 | 
            -
             | 
| 60 | 
            -
                        subsample = build_sample(sid, element.collections, current_user, cr_opt) unless sid.nil? || cr_opt.nil?
         | 
| 61 | 
            -
                        next if subsample.nil?
         | 
| 62 | 
            -
             | 
| 63 | 
            -
                        sds << subsample.id
         | 
| 64 | 
            -
                        sub_value[col_id]['value']['el_id'] = subsample.id
         | 
| 65 | 
            -
                        sub_value[col_id]['value']['is_new'] = false
         | 
| 66 | 
            -
                        Labimotion::ElementsSample.find_or_create_by(element_id: element.id, sample_id: subsample.id)
         | 
| 67 | 
            -
                      end
         | 
| 68 | 
            -
                    end
         | 
| 69 | 
            -
                  end
         | 
| 70 | 
            -
                  sds
         | 
| 15 | 
            +
                def build_table_sample(field_tables, current_user, element)
         | 
| 16 | 
            +
                  Labimotion::SampleAssociation.build_table_sample(field_tables, current_user, element)
         | 
| 71 17 | 
             
                rescue StandardError => e
         | 
| 72 18 | 
             
                  Labimotion.log_exception(e, current_user)
         | 
| 73 19 | 
             
                  []
         | 
| 74 20 | 
             
                end
         | 
| 75 21 |  | 
| 76 | 
            -
                def update_sample_association( | 
| 77 | 
            -
                   | 
| 78 | 
            -
                  els = []
         | 
| 79 | 
            -
                  properties['layers'].keys.each do |key|
         | 
| 80 | 
            -
                    layer = properties['layers'][key]
         | 
| 81 | 
            -
                    field_samples = layer['fields'].select { |ss| ss['type'] == 'drag_sample' }
         | 
| 82 | 
            -
                    field_samples.each do |field|
         | 
| 83 | 
            -
                      idx = properties['layers'][key]['fields'].index(field)
         | 
| 84 | 
            -
                      sid = field.dig('value', 'el_id')
         | 
| 85 | 
            -
                      next if sid.blank?
         | 
| 86 | 
            -
             | 
| 87 | 
            -
                      sds << sid unless properties.dig('layers', key, 'fields', idx, 'value', 'is_new') == true
         | 
| 88 | 
            -
                      next unless properties.dig('layers', key, 'fields', idx, 'value', 'is_new') == true
         | 
| 89 | 
            -
             | 
| 90 | 
            -
                      cr_opt = field.dig('value', 'cr_opt')
         | 
| 91 | 
            -
             | 
| 92 | 
            -
                      subsample = build_sample(sid, element.collections, current_user, cr_opt) unless sid.nil? || cr_opt.nil?
         | 
| 93 | 
            -
                      next if subsample.nil?
         | 
| 94 | 
            -
             | 
| 95 | 
            -
                      sds << subsample.id
         | 
| 96 | 
            -
                      properties['layers'][key]['fields'][idx]['value']['el_id'] = subsample.id
         | 
| 97 | 
            -
                      properties['layers'][key]['fields'][idx]['value']['el_label'] = subsample.short_label
         | 
| 98 | 
            -
                      properties['layers'][key]['fields'][idx]['value']['el_tip'] = subsample.short_label
         | 
| 99 | 
            -
                      properties['layers'][key]['fields'][idx]['value']['is_new'] = false
         | 
| 100 | 
            -
                      Labimotion::ElementsSample.find_or_create_by(element_id: element.id, sample_id: subsample.id)
         | 
| 101 | 
            -
                    end
         | 
| 102 | 
            -
                    field_tables = properties['layers'][key]['fields'].select { |ss| ss['type'] == 'table' }
         | 
| 103 | 
            -
                    sds << build_table_sample(element, field_tables)
         | 
| 104 | 
            -
             | 
| 105 | 
            -
                    field_elements = layer['fields'].select { |ss| ss['type'] == 'drag_element' }
         | 
| 106 | 
            -
                    field_elements.each do |field|
         | 
| 107 | 
            -
                      idx = properties['layers'][key]['fields'].index(field)
         | 
| 108 | 
            -
                      sid = field.dig('value', 'el_id')
         | 
| 109 | 
            -
                      next if sid.blank? || sid == element.id
         | 
| 110 | 
            -
             | 
| 111 | 
            -
                      el = Labimotion::Element.find_by(id: sid)
         | 
| 112 | 
            -
                      next if el.nil?
         | 
| 113 | 
            -
             | 
| 114 | 
            -
                      Labimotion::ElementsElement.find_or_create_by(parent_id: element.id, element_id: el.id)
         | 
| 115 | 
            -
                      els << el.id
         | 
| 116 | 
            -
                    end
         | 
| 117 | 
            -
             | 
| 118 | 
            -
                  end
         | 
| 119 | 
            -
                  Labimotion::ElementsSample.where(element_id: element.id).where.not(sample_id: sds)&.destroy_all
         | 
| 120 | 
            -
                  Labimotion::ElementsElement.where(parent_id: element.id).where.not(element_id: els&.flatten)&.destroy_all
         | 
| 121 | 
            -
                  properties
         | 
| 22 | 
            +
                def update_sample_association(properties, current_user, element)
         | 
| 23 | 
            +
                  Labimotion::SampleAssociation.update_sample_association(properties, current_user, element)
         | 
| 122 24 | 
             
                rescue StandardError => e
         | 
| 123 25 | 
             
                  Labimotion.log_exception(e, current_user)
         | 
| 124 26 | 
             
                end
         | 
| @@ -0,0 +1,125 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Labimotion
         | 
| 4 | 
            +
              class SampleAssociation
         | 
| 5 | 
            +
                def self.build_sample(sid, cols, current_user, cr_opt)
         | 
| 6 | 
            +
                  parent_sample = Sample.find(sid)
         | 
| 7 | 
            +
                  case cr_opt
         | 
| 8 | 
            +
                  when 0
         | 
| 9 | 
            +
                    subsample = parent_sample
         | 
| 10 | 
            +
                    collections = Collection.where(id: cols).where.not(id: subsample.collections.pluck(:id))
         | 
| 11 | 
            +
                    subsample.collections << collections unless collections.empty?
         | 
| 12 | 
            +
                  when 1
         | 
| 13 | 
            +
                    subsample = parent_sample.create_subsample(current_user, cols, true)
         | 
| 14 | 
            +
                  when 2
         | 
| 15 | 
            +
                    subsample = parent_sample.dup
         | 
| 16 | 
            +
                    subsample.parent = nil
         | 
| 17 | 
            +
                    collections = (Collection.where(id: cols) | Collection.where(user_id: current_user.id, label: 'All', is_locked: true))
         | 
| 18 | 
            +
                    subsample.collections << collections
         | 
| 19 | 
            +
                    subsample.container = Container.create_root_container
         | 
| 20 | 
            +
                  else
         | 
| 21 | 
            +
                    return nil
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  return nil if subsample.nil?
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  subsample.save!
         | 
| 27 | 
            +
                  subsample.reload
         | 
| 28 | 
            +
                  subsample
         | 
| 29 | 
            +
                rescue StandardError => e
         | 
| 30 | 
            +
                  Labimotion.log_exception(e, current_user)
         | 
| 31 | 
            +
                  nil
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                def self.build_table_sample(field_tables, current_user, element = nil)
         | 
| 35 | 
            +
                  sds = []
         | 
| 36 | 
            +
                  field_tables.each do |field|
         | 
| 37 | 
            +
                    next unless field['sub_values'].present? && field['sub_fields'].present?
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    field_table_samples = field['sub_fields'].select { |ss| ss['type'] == 'drag_sample' }
         | 
| 40 | 
            +
                    next unless field_table_samples.present?
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                    col_ids = field_table_samples.map { |x| x.values[0] }
         | 
| 43 | 
            +
                    col_ids.each do |col_id|
         | 
| 44 | 
            +
                      field['sub_values'].each do |sub_value|
         | 
| 45 | 
            +
                        next unless sub_value[col_id].present? && sub_value[col_id]['value'].present? && sub_value[col_id]['value']['el_id'].present?
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                        svalue = sub_value[col_id]['value']
         | 
| 48 | 
            +
                        sid = svalue['el_id']
         | 
| 49 | 
            +
                        next unless sid.present?
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                        sds << sid unless svalue['is_new']
         | 
| 52 | 
            +
                        next unless svalue['is_new']
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                        cr_opt = svalue['cr_opt']
         | 
| 55 | 
            +
                        next if element.nil?
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                        subsample = Labimotion::SampleAssociation.build_sample(sid, element.collections, current_user, cr_opt) unless sid.nil? || cr_opt.nil?
         | 
| 58 | 
            +
                        next if subsample.nil?
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                        sds << subsample.id
         | 
| 61 | 
            +
                        sub_value[col_id]['value']['el_id'] = subsample.id
         | 
| 62 | 
            +
                        sub_value[col_id]['value']['is_new'] = false
         | 
| 63 | 
            +
                        Labimotion::ElementsSample.find_or_create_by(element_id: element.id, sample_id: subsample.id)
         | 
| 64 | 
            +
                      end
         | 
| 65 | 
            +
                    end
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
                  sds
         | 
| 68 | 
            +
                rescue StandardError => e
         | 
| 69 | 
            +
                  Labimotion.log_exception(e, current_user)
         | 
| 70 | 
            +
                  []
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                def self.update_sample_association(properties, current_user, element = nil)
         | 
| 74 | 
            +
                  sds = []
         | 
| 75 | 
            +
                  els = []
         | 
| 76 | 
            +
                  properties['layers'].keys.each do |key|
         | 
| 77 | 
            +
                    layer = properties['layers'][key]
         | 
| 78 | 
            +
                    field_samples = layer['fields'].select { |ss| ss['type'] == 'drag_sample' }
         | 
| 79 | 
            +
                    field_samples.each do |field|
         | 
| 80 | 
            +
                      idx = properties['layers'][key]['fields'].index(field)
         | 
| 81 | 
            +
                      sid = field.dig('value', 'el_id')
         | 
| 82 | 
            +
                      next if sid.blank?
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                      sds << sid unless properties.dig('layers', key, 'fields', idx, 'value', 'is_new') == true
         | 
| 85 | 
            +
                      next unless properties.dig('layers', key, 'fields', idx, 'value', 'is_new') == true
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                      cr_opt = field.dig('value', 'cr_opt')
         | 
| 88 | 
            +
                      subsample = Labimotion::SampleAssociation.build_sample(sid, element&.collections, current_user, cr_opt) unless sid.nil? || cr_opt.nil?
         | 
| 89 | 
            +
                      next if subsample.nil?
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                      sds << subsample.id
         | 
| 92 | 
            +
                      properties['layers'][key]['fields'][idx]['value']['el_id'] = subsample.id
         | 
| 93 | 
            +
                      properties['layers'][key]['fields'][idx]['value']['el_label'] = subsample.short_label
         | 
| 94 | 
            +
                      properties['layers'][key]['fields'][idx]['value']['el_tip'] = subsample.short_label
         | 
| 95 | 
            +
                      properties['layers'][key]['fields'][idx]['value']['is_new'] = false
         | 
| 96 | 
            +
                      Labimotion::ElementsSample.find_or_create_by(element_id: element.id, sample_id: subsample.id) if element.present?
         | 
| 97 | 
            +
                    end
         | 
| 98 | 
            +
                    field_tables = properties['layers'][key]['fields'].select { |ss| ss['type'] == 'table' }
         | 
| 99 | 
            +
                    sds << Labimotion::SampleAssociation.build_table_sample(field_tables, current_user, element) if element.present?
         | 
| 100 | 
            +
                    field_elements = layer['fields'].select { |ss| ss['type'] == 'drag_element' }
         | 
| 101 | 
            +
                    field_elements.each do |field|
         | 
| 102 | 
            +
                      idx = properties['layers'][key]['fields'].index(field)
         | 
| 103 | 
            +
                      sid = field.dig('value', 'el_id')
         | 
| 104 | 
            +
                      next if element.nil? || sid.blank? || sid == element.id
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                      el = Labimotion::Element.find_by(id: sid)
         | 
| 107 | 
            +
                      next if el.nil?
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                      Labimotion::ElementsElement.find_or_create_by(parent_id: element.id, element_id: el.id)
         | 
| 110 | 
            +
                      els << el.id
         | 
| 111 | 
            +
                    end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                  end
         | 
| 114 | 
            +
                  if element.present?
         | 
| 115 | 
            +
                    es_list = Labimotion::ElementsSample.where(element_id: element.id).where.not(sample_id: sds)
         | 
| 116 | 
            +
                    ee_list = Labimotion::ElementsElement.where(parent_id: element.id).where.not(element_id: els&.flatten)
         | 
| 117 | 
            +
                    es_list.destroy_all if es_list.present?
         | 
| 118 | 
            +
                    ee_list.destroy_all if ee_list.present?
         | 
| 119 | 
            +
                  end
         | 
| 120 | 
            +
                  properties
         | 
| 121 | 
            +
                rescue StandardError => e
         | 
| 122 | 
            +
                  Labimotion.log_exception(e, current_user)
         | 
| 123 | 
            +
                end
         | 
| 124 | 
            +
              end
         | 
| 125 | 
            +
            end
         | 
| @@ -41,6 +41,7 @@ module Labimotion | |
| 41 41 |  | 
| 42 42 | 
             
                def save_segments(**args) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
         | 
| 43 43 | 
             
                  return if args[:segments].nil?
         | 
| 44 | 
            +
             | 
| 44 45 | 
             
                  segments = []
         | 
| 45 46 | 
             
                  args[:segments]&.each do |seg|
         | 
| 46 47 | 
             
                    klass = Labimotion::SegmentKlass.find_by(id: seg['segment_klass_id'])
         | 
| @@ -50,6 +51,7 @@ module Labimotion | |
| 50 51 | 
             
                    props['identifier'] = klass.identifier if klass.identifier.present?
         | 
| 51 52 | 
             
                    props['uuid'] = uuid
         | 
| 52 53 | 
             
                    props['klass'] = 'Segment'
         | 
| 54 | 
            +
                    props = Labimotion::SampleAssociation.update_sample_association(props, args[:current_user_id])
         | 
| 53 55 | 
             
                    segment = Labimotion::Segment.find_by(element_type: Labimotion::Utils.element_name(self.class.name), element_id: self.id, segment_klass_id: seg['segment_klass_id'])
         | 
| 54 56 | 
             
                    if segment.present? && (segment.klass_uuid != props['klass_uuid'] || segment.properties != props)
         | 
| 55 57 | 
             
                      segment.update!(properties_release: klass.properties_release, properties: props, uuid: uuid, klass_uuid: props['klass_uuid'])
         | 
    
        data/lib/labimotion/version.rb
    CHANGED
    
    
    
        data/lib/labimotion.rb
    CHANGED
    
    | @@ -22,6 +22,8 @@ module Labimotion | |
| 22 22 | 
             
              autoload :ConverterAPI, 'labimotion/apis/converter_api'
         | 
| 23 23 |  | 
| 24 24 | 
             
              ######## Entities
         | 
| 25 | 
            +
              autoload :PropertiesEntity, 'labimotion/entities/properties_entity'
         | 
| 26 | 
            +
             | 
| 25 27 | 
             
              autoload :ElementEntity, 'labimotion/entities/element_entity'
         | 
| 26 28 | 
             
              autoload :ElnElementEntity, 'labimotion/entities/eln_element_entity'
         | 
| 27 29 |  | 
| @@ -56,6 +58,7 @@ module Labimotion | |
| 56 58 | 
             
              autoload :NmrMapperRepo, 'labimotion/libs/nmr_mapper_repo' ## for Chemotion Repository
         | 
| 57 59 | 
             
              autoload :TemplateHub, 'labimotion/libs/template_hub'
         | 
| 58 60 | 
             
              autoload :ExportDataset, 'labimotion/libs/export_dataset'
         | 
| 61 | 
            +
              autoload :SampleAssociation, 'labimotion/libs/sample_association'
         | 
| 59 62 |  | 
| 60 63 | 
             
              ######## Utils
         | 
| 61 64 | 
             
              autoload :ConState, 'labimotion/utils/con_state'
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: labimotion
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1.0. | 
| 4 | 
            +
              version: 1.0.19
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Chia-Lin Lin
         | 
| @@ -9,7 +9,7 @@ authors: | |
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2023- | 
| 12 | 
            +
            date: 2023-11-14 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: rails
         | 
| @@ -52,6 +52,7 @@ files: | |
| 52 52 | 
             
            - lib/labimotion/entities/generic_klass_entity.rb
         | 
| 53 53 | 
             
            - lib/labimotion/entities/generic_public_entity.rb
         | 
| 54 54 | 
             
            - lib/labimotion/entities/klass_revision_entity.rb
         | 
| 55 | 
            +
            - lib/labimotion/entities/properties_entity.rb
         | 
| 55 56 | 
             
            - lib/labimotion/entities/segment_entity.rb
         | 
| 56 57 | 
             
            - lib/labimotion/entities/segment_klass_entity.rb
         | 
| 57 58 | 
             
            - lib/labimotion/entities/segment_revision_entity.rb
         | 
| @@ -66,6 +67,7 @@ files: | |
| 66 67 | 
             
            - lib/labimotion/libs/converter.rb
         | 
| 67 68 | 
             
            - lib/labimotion/libs/export_dataset.rb
         | 
| 68 69 | 
             
            - lib/labimotion/libs/nmr_mapper.rb
         | 
| 70 | 
            +
            - lib/labimotion/libs/sample_association.rb
         | 
| 69 71 | 
             
            - lib/labimotion/libs/template_hub.rb
         | 
| 70 72 | 
             
            - lib/labimotion/models/collections_element.rb
         | 
| 71 73 | 
             
            - lib/labimotion/models/concerns/attachment_converter.rb
         | 
| @@ -97,7 +99,7 @@ files: | |
| 97 99 | 
             
            - lib/labimotion/version.rb
         | 
| 98 100 | 
             
            homepage: https://gitlab.kit.edu/kit/labimotion/labimotion
         | 
| 99 101 | 
             
            licenses:
         | 
| 100 | 
            -
            -  | 
| 102 | 
            +
            - AGPL-3.0
         | 
| 101 103 | 
             
            metadata: {}
         | 
| 102 104 | 
             
            post_install_message: 
         | 
| 103 105 | 
             
            rdoc_options: []
         |