labimotion 1.4.0 → 2.0.0.rc8

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/lib/labimotion/apis/converter_api.rb +2 -2
  3. data/lib/labimotion/apis/generic_element_api.rb +1 -0
  4. data/lib/labimotion/apis/generic_klass_api.rb +3 -2
  5. data/lib/labimotion/apis/labimotion_api.rb +13 -0
  6. data/lib/labimotion/apis/standard_api.rb +25 -0
  7. data/lib/labimotion/apis/standard_layer_api.rb +87 -0
  8. data/lib/labimotion/apis/vocabulary_api.rb +93 -0
  9. data/lib/labimotion/constants.rb +25 -0
  10. data/lib/labimotion/entities/dataset_entity.rb +1 -1
  11. data/lib/labimotion/entities/element_entity.rb +1 -0
  12. data/lib/labimotion/entities/properties_entity.rb +229 -56
  13. data/lib/labimotion/entities/segment_entity.rb +0 -1
  14. data/lib/labimotion/entities/vocabulary_entity.rb +29 -0
  15. data/lib/labimotion/helpers/element_helpers.rb +10 -7
  16. data/lib/labimotion/helpers/generic_helpers.rb +6 -1
  17. data/lib/labimotion/helpers/param_helpers.rb +121 -82
  18. data/lib/labimotion/helpers/segment_helpers.rb +1 -1
  19. data/lib/labimotion/helpers/vocabulary_helpers.rb +16 -0
  20. data/lib/labimotion/libs/converter.rb +16 -35
  21. data/lib/labimotion/libs/data/mapper/Chemwiki.json +236 -0
  22. data/lib/labimotion/libs/data/mapper/Source.json +78 -0
  23. data/lib/labimotion/libs/data/vocab/Standard.json +385 -0
  24. data/lib/labimotion/libs/data/vocab/System.json +131 -0
  25. data/lib/labimotion/libs/dataset_builder.rb +70 -0
  26. data/lib/labimotion/libs/export_dataset.rb +343 -98
  27. data/lib/labimotion/libs/nmr_mapper.rb +204 -246
  28. data/lib/labimotion/libs/sample_association.rb +4 -0
  29. data/lib/labimotion/libs/vocabulary_handler.rb +118 -0
  30. data/lib/labimotion/models/concerns/attachment_converter.rb +5 -4
  31. data/lib/labimotion/models/concerns/datasetable.rb +1 -0
  32. data/lib/labimotion/models/concerns/generic_klass_revisions.rb +1 -0
  33. data/lib/labimotion/models/concerns/generic_revisions.rb +3 -0
  34. data/lib/labimotion/models/concerns/segmentable.rb +2 -0
  35. data/lib/labimotion/models/element.rb +3 -0
  36. data/lib/labimotion/models/std_layer.rb +9 -0
  37. data/lib/labimotion/models/std_layers_revision.rb +9 -0
  38. data/lib/labimotion/models/vocabulary.rb +12 -0
  39. data/lib/labimotion/utils/mapper_utils.rb +169 -0
  40. data/lib/labimotion/utils/utils.rb +21 -0
  41. data/lib/labimotion/version.rb +1 -1
  42. data/lib/labimotion.rb +13 -3
  43. metadata +25 -5
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ require 'labimotion/entities/application_entity'
4
+ module Labimotion
5
+ # Dataset entity
6
+ class VocabularyEntity < ApplicationEntity
7
+ expose :id, :identifier, :name, :label, :field_type, :opid, :term_id,
8
+ :field_id, :properties, :source, :source_id, :layer_id
9
+ expose :voc do |obj|
10
+ voc = (obj[:properties] && obj[:properties]['voc']) || {}
11
+
12
+ case voc['source']
13
+ when Labimotion::Prop::ELEMENT
14
+ voc['source_name'] = ElementKlass.find_by(identifier: voc['source_id'])&.label
15
+ # if voc['identifier'] == 'element.name'
16
+ # voc['source_name'] = ElementKlass.find_by(identifier: voc['source_id'])&.name
17
+ # end
18
+ when Labimotion::Prop::SEGMENT
19
+ voc['source_name'] = SegmentKlass.find_by(identifier: voc['source_id'])&.label
20
+ when Labimotion::Prop::DATASET
21
+ voc['source_name'] = DatasetKlass.find_by(identifier: voc['source_id'])&.label
22
+ end
23
+ voc
24
+ end
25
+ expose :ontology do |obj|
26
+ (obj[:properties] && obj[:properties]['ontology']) || {}
27
+ end
28
+ end
29
+ end
@@ -93,7 +93,8 @@ module Labimotion
93
93
  all_coll = Collection.get_all_collection_for_user(current_user.id)
94
94
  element.collections << all_coll
95
95
  element.save!
96
- element.properties = update_sample_association(params[:properties], current_user, element)
96
+ _properties = update_sample_association(params[:properties], current_user, element)
97
+ element.properties = update_vocabularies(_properties, current_user, element)
97
98
  element.container = update_datamodel(params[:container], current_user)
98
99
  element.save!
99
100
  update_element_labels(element, params[:user_labels], current_user.id)
@@ -112,7 +113,6 @@ module Labimotion
112
113
  params.delete(:properties)
113
114
  update_element_labels(element, params[:user_labels], current_user.id)
114
115
  params.delete(:user_labels)
115
-
116
116
  attributes = declared(params.except(:segments), include_missing: false)
117
117
  properties['pkg'] = Labimotion::Utils.pkg(properties['pkg'])
118
118
  if element.klass_uuid != properties['klass_uuid'] || element.properties != properties || element.name != params[:name]
@@ -123,15 +123,17 @@ module Labimotion
123
123
  properties.delete('flow') unless properties['flow'].nil?
124
124
  properties.delete('flowObject') unless properties['flowObject'].nil?
125
125
  properties.delete('select_options') unless properties['select_options'].nil?
126
-
127
126
  attributes['properties'] = properties
128
127
  attributes['properties']['uuid'] = uuid
129
128
  attributes['uuid'] = uuid
130
129
  attributes['klass_uuid'] = properties['klass_uuid']
131
-
132
- element.update(attributes)
130
+ element.update_columns(attributes)
133
131
  end
134
132
  element.save_segments(segments: params[:segments], current_user_id: current_user.id)
133
+ element.reload
134
+ element.properties = update_vocabularies(element.properties, current_user, element)
135
+ ## element.user_for_revision = current_user
136
+ element.save!
135
137
  element
136
138
  rescue StandardError => e
137
139
  Labimotion.log_exception(e, current_user)
@@ -321,7 +323,6 @@ module Labimotion
321
323
  return { status: 'success', message: "The element: #{attributes['name']} has been created using version: #{attributes['version']}!" }
322
324
  end
323
325
  end
324
-
325
326
  rescue StandardError => e
326
327
  Labimotion.log_exception(e, current_user)
327
328
  return { status: 'error', message: e.message }
@@ -351,7 +352,9 @@ module Labimotion
351
352
  _att
352
353
  end
353
354
  attachments
355
+ rescue StandardError => e
356
+ Labimotion.log_exception(e)
357
+ attachments
354
358
  end
355
-
356
359
  end
357
360
  end
@@ -9,7 +9,12 @@ module Labimotion
9
9
  extend Grape::API::Helpers
10
10
 
11
11
  def authenticate_admin!(type)
12
- error!('401 Unauthorized', 401) unless current_user.generic_admin[type]
12
+ unauthorized = -> { error!('401 Unauthorized', 401) }
13
+ if %w[standard_layers vocabularies].include?(type)
14
+ unauthorized.call unless current_user.generic_admin.values_at('elements', 'segments', 'datasets').any?
15
+ else
16
+ unauthorized.call unless current_user.generic_admin[type]
17
+ end
13
18
  end
14
19
 
15
20
  def fetch_klass(name, id)
@@ -6,94 +6,133 @@ module Labimotion
6
6
  ## Generic Helpers
7
7
  module ParamHelpers
8
8
  extend Grape::API::Helpers
9
- ## Element Klass Params
10
- params :upload_element_klass_params do
11
- requires :name, type: String, desc: 'Klass Name'
12
- optional :label, type: String, desc: 'Klass label'
13
- optional :desc, type: String, desc: 'Klass desc'
14
- optional :klass_prefix, type: String, desc: 'Klass klass_prefix'
15
- optional :icon_name, type: String, desc: 'Klass icon_name'
16
- requires :properties_template, type: Hash, desc: 'Klass template'
17
- optional :properties_release, type: Hash, desc: 'Klass release'
18
- optional :released_at, type: DateTime, desc: 'Klass released_at'
19
- requires :uuid, type: String, desc: 'Klass uuid'
20
- requires :place, type: Integer, desc: 'Klass place'
21
- requires :identifier, type: String, desc: 'Klass identifier'
22
- optional :sync_time, type: DateTime, desc: 'Klass sync_time'
23
- optional :version, type: String, desc: 'Klass version'
24
- end
9
+ ## Element Klass Params
10
+ params :upload_element_klass_params do
11
+ requires :name, type: String, desc: 'Klass Name'
12
+ optional :label, type: String, desc: 'Klass label'
13
+ optional :desc, type: String, desc: 'Klass desc'
14
+ optional :klass_prefix, type: String, desc: 'Klass klass_prefix'
15
+ optional :icon_name, type: String, desc: 'Klass icon_name'
16
+ requires :properties_template, type: Hash, desc: 'Klass template'
17
+ optional :properties_release, type: Hash, desc: 'Klass release'
18
+ optional :released_at, type: DateTime, desc: 'Klass released_at'
19
+ requires :uuid, type: String, desc: 'Klass uuid'
20
+ requires :place, type: Integer, desc: 'Klass place'
21
+ requires :identifier, type: String, desc: 'Klass identifier'
22
+ optional :sync_time, type: DateTime, desc: 'Klass sync_time'
23
+ optional :version, type: String, desc: 'Klass version'
24
+ end
25
25
 
26
- params :create_element_klass_params do
27
- requires :name, type: String, desc: 'Element Klass Name'
28
- requires :label, type: String, desc: 'Element Klass Label'
29
- requires :klass_prefix, type: String, desc: 'Element Klass Short Label Prefix'
30
- optional :icon_name, type: String, desc: 'Element Klass Icon Name'
31
- optional :desc, type: String, desc: 'Element Klass Desc'
32
- optional :properties_template, type: Hash, desc: 'Element Klass properties template'
33
- end
26
+ params :create_element_klass_params do
27
+ requires :name, type: String, desc: 'Element Klass Name'
28
+ requires :label, type: String, desc: 'Element Klass Label'
29
+ requires :klass_prefix, type: String, desc: 'Element Klass Short Label Prefix'
30
+ optional :icon_name, type: String, desc: 'Element Klass Icon Name'
31
+ optional :desc, type: String, desc: 'Element Klass Desc'
32
+ optional :properties_template, type: Hash, desc: 'Element Klass properties template'
33
+ end
34
34
 
35
- params :update_element_klass_params do
36
- requires :id, type: Integer, desc: 'Element Klass ID'
37
- optional :label, type: String, desc: 'Element Klass Label'
38
- optional :klass_prefix, type: String, desc: 'Element Klass Short Label Prefix'
39
- optional :icon_name, type: String, desc: 'Element Klass Icon Name'
40
- optional :desc, type: String, desc: 'Element Klass Desc'
41
- optional :place, type: String, desc: 'Element Klass Place'
42
- end
35
+ params :update_element_klass_params do
36
+ requires :id, type: Integer, desc: 'Element Klass ID'
37
+ optional :label, type: String, desc: 'Element Klass Label'
38
+ optional :klass_prefix, type: String, desc: 'Element Klass Short Label Prefix'
39
+ optional :icon_name, type: String, desc: 'Element Klass Icon Name'
40
+ optional :desc, type: String, desc: 'Element Klass Desc'
41
+ optional :place, type: String, desc: 'Element Klass Place'
42
+ end
43
43
 
44
- ## Element Params
45
- params :create_element_params do
46
- requires :element_klass, type: Hash
47
- requires :name, type: String
48
- optional :properties, type: Hash
49
- optional :properties_release, type: Hash
50
- optional :collection_id, type: Integer
51
- requires :container, type: Hash
52
- optional :user_labels, type: Array
53
- optional :segments, type: Array, desc: 'Segments'
54
- end
44
+ ## Element Params
45
+ params :create_element_params do
46
+ requires :element_klass, type: Hash
47
+ requires :name, type: String
48
+ optional :properties, type: Hash
49
+ optional :properties_release, type: Hash
50
+ optional :collection_id, type: Integer
51
+ requires :container, type: Hash
52
+ optional :user_labels, type: Array
53
+ optional :segments, type: Array, desc: 'Segments'
54
+ end
55
55
 
56
- params :update_element_params do
57
- requires :id, type: Integer, desc: 'element id'
58
- optional :name, type: String
59
- requires :properties, type: Hash
60
- optional :properties_release, type: Hash
61
- requires :container, type: Hash
62
- optional :user_labels, type: Array
63
- optional :segments, type: Array, desc: 'Segments'
64
- end
56
+ params :update_element_params do
57
+ requires :id, type: Integer, desc: 'element id'
58
+ optional :name, type: String
59
+ requires :properties, type: Hash
60
+ optional :properties_release, type: Hash
61
+ requires :container, type: Hash
62
+ optional :user_labels, type: Array
63
+ optional :segments, type: Array, desc: 'Segments'
64
+ end
65
65
 
66
- ## Segment Klass Params
67
- params :upload_segment_klass_params do
68
- requires :label, type: String, desc: 'Klass label'
69
- optional :desc, type: String, desc: 'Klass desc'
70
- requires :properties_template, type: Hash, desc: 'Klass template'
71
- optional :properties_release, type: Hash, desc: 'Klass release'
72
- optional :released_at, type: DateTime, desc: 'Klass released_at'
73
- requires :uuid, type: String, desc: 'Klass uuid'
74
- requires :place, type: Integer, desc: 'Klass place'
75
- requires :identifier, type: String, desc: 'Klass identifier'
76
- optional :sync_time, type: DateTime, desc: 'Klass sync_time'
77
- optional :version, type: String, desc: 'Klass version'
78
- requires :element_klass, type: Hash do
79
- use :upload_element_klass_params
80
- end
66
+ ## Segment Klass Params
67
+ params :upload_segment_klass_params do
68
+ requires :label, type: String, desc: 'Klass label'
69
+ optional :desc, type: String, desc: 'Klass desc'
70
+ requires :properties_template, type: Hash, desc: 'Klass template'
71
+ optional :properties_release, type: Hash, desc: 'Klass release'
72
+ optional :released_at, type: DateTime, desc: 'Klass released_at'
73
+ requires :uuid, type: String, desc: 'Klass uuid'
74
+ requires :place, type: Integer, desc: 'Klass place'
75
+ requires :identifier, type: String, desc: 'Klass identifier'
76
+ optional :sync_time, type: DateTime, desc: 'Klass sync_time'
77
+ optional :version, type: String, desc: 'Klass version'
78
+ requires :element_klass, type: Hash do
79
+ use :upload_element_klass_params
81
80
  end
81
+ end
82
82
 
83
- params :update_segment_klass_params do
84
- requires :id, type: Integer, desc: 'Segment Klass ID'
85
- optional :label, type: String, desc: 'Segment Klass Label'
86
- optional :desc, type: String, desc: 'Segment Klass Desc'
87
- optional :place, type: String, desc: 'Segment Klass Place', default: '100'
88
- optional :identifier, type: String, desc: 'Segment Identifier'
89
- end
83
+ params :update_segment_klass_params do
84
+ requires :id, type: Integer, desc: 'Segment Klass ID'
85
+ optional :label, type: String, desc: 'Segment Klass Label'
86
+ optional :desc, type: String, desc: 'Segment Klass Desc'
87
+ optional :place, type: String, desc: 'Segment Klass Place', default: '100'
88
+ optional :identifier, type: String, desc: 'Segment Identifier'
89
+ end
90
90
 
91
- params :create_segment_klass_params do
92
- requires :label, type: String, desc: 'Segment Klass Label'
93
- requires :element_klass, type: Integer, desc: 'Element Klass Id'
94
- optional :desc, type: String, desc: 'Segment Klass Desc'
95
- optional :place, type: String, desc: 'Segment Klass Place', default: '100'
96
- optional :properties_template, type: Hash, desc: 'Element Klass properties template'
97
- end
91
+ params :create_segment_klass_params do
92
+ requires :label, type: String, desc: 'Segment Klass Label'
93
+ requires :element_klass, type: Integer, desc: 'Element Klass Id'
94
+ optional :desc, type: String, desc: 'Segment Klass Desc'
95
+ optional :place, type: String, desc: 'Segment Klass Place', default: '100'
96
+ optional :properties_template, type: Hash, desc: 'Element Klass properties template'
97
+ end
98
+
99
+ params :create_std_layer_params do
100
+ requires :name, type: String, desc: 'Element Klass Name'
101
+ requires :label, type: String, desc: 'Element Klass Label'
102
+ requires :klass_prefix, type: String, desc: 'Element Klass Short Label Prefix'
103
+ optional :icon_name, type: String, desc: 'Element Klass Icon Name'
104
+ optional :desc, type: String, desc: 'Element Klass Desc'
105
+ optional :properties_template, type: Hash, desc: 'Element Klass properties template'
106
+ end
107
+
108
+ params :std_layer_save do
109
+ requires :key, type: String, desc: 'key'
110
+ requires :cols, type: Integer, desc: 'key'
111
+ requires :label, type: String, desc: 'Label'
112
+ optional :position, type: Integer, desc: 'position'
113
+ optional :wf_position, type: Integer, desc: 'wf position'
114
+ optional :fields, type: Array, desc: 'fields'
115
+ optional :select_options, type: Hash, desc: 'selections'
116
+ end
117
+
118
+ params :std_layer_criteria do
119
+ requires :name, type: String, desc: 'Layer name'
120
+ end
121
+
122
+ params :vocab_save do
123
+ optional :name, type: String, desc: 'field'
124
+ optional :label, type: String, desc: 'Label'
125
+ optional :term_id, type: String, desc: 'ontology term_id'
126
+ requires :ontology, type: Hash, desc: 'ontology'
127
+ optional :source, type: String, desc: 'source'
128
+ optional :source_id, type: String, desc: 'source_id'
129
+ optional :layer_id, type: String, desc: 'layer_id'
130
+ optional :sub_fields, type: Array, desc: 'sub_fields'
131
+ optional :text_sub_fields, type: Array, desc: 'text_sub_fields'
132
+ requires :field_type, type: String, desc: 'field type'
133
+ requires :voc, type: Hash, desc: 'vocabulary references'
134
+ optional :select_options, type: Hash, desc: 'selections'
135
+ optional :option_layers, type: String, desc: 'option'
136
+ end
98
137
  end
99
- end
138
+ end
@@ -72,7 +72,7 @@ module Labimotion
72
72
  # el_attributes['properties_template'] = response['element_klass']['properties_release']
73
73
  # Labimotion::ElementKlass.create!(el_attributes)
74
74
  attributes['element_klass_id'] = element_klass.id
75
- segment_klass = Labimotion::SegmentKlass.find_by(identifier: attributes['identifier'])
75
+ segment_klass = Labimotion::SegmentKlass.find_by(identifier: attributes['identifier']) if attributes['identifier'].present?
76
76
  if segment_klass.present?
77
77
  if segment_klass['uuid'] == attributes['uuid'] && segment_klass['version'] == attributes['version']
78
78
  return { status: 'success', message: "This segment: #{attributes['label']} has the latest version!" }
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Labimotion
4
+ # Helper for associated sample
5
+ module VocabularyHelpers
6
+ extend Grape::API::Helpers
7
+
8
+ def update_vocabularies(properties, current_user, element)
9
+ Labimotion::VocabularyHandler.update_vocabularies(properties, current_user, element)
10
+ rescue StandardError => e
11
+ Labimotion.log_exception(e, current_user)
12
+ properties
13
+ end
14
+
15
+ end
16
+ end
@@ -28,7 +28,7 @@ module Labimotion
28
28
  dsr = []
29
29
  ols = nil
30
30
  Zip::File.open(att.attachment_attacher.file.url) do |zip_file|
31
- res = Labimotion::Converter.collect_metadata(zip_file) if att.filename.split('.')&.last == 'zip'
31
+ res = Labimotion::Converter.collect_metadata(zip_file, current_user) if att.filename.split('.')&.last == 'zip'
32
32
  ols = res[:o] unless res&.dig(:o).nil?
33
33
  dsr.push(res[:d]) unless res&.dig(:d).nil?
34
34
  end
@@ -92,7 +92,7 @@ module Labimotion
92
92
  { a: oa, f: folder }
93
93
  end
94
94
 
95
- def self.collect_metadata(zip_file) # rubocop: disable Metrics/PerceivedComplexity
95
+ def self.collect_metadata(zip_file, current_user = {}) # rubocop: disable Metrics/PerceivedComplexity
96
96
  dsr = []
97
97
  ols = nil
98
98
  zip_file.each do |entry|
@@ -114,7 +114,7 @@ module Labimotion
114
114
  { d: dsr, o: ols }
115
115
  end
116
116
 
117
- def self.handle_response(oat, response) # rubocop: disable Metrics/PerceivedComplexity
117
+ def self.handle_response(oat, response, current_user = {}) # rubocop: disable Metrics/PerceivedComplexity
118
118
  dsr = []
119
119
  ols = nil
120
120
 
@@ -123,10 +123,8 @@ module Labimotion
123
123
  tmp_file.write(response.parsed_response)
124
124
  tmp_file.rewind
125
125
 
126
- name = response&.headers && response&.headers['content-disposition']&.split('=')&.last
127
126
  filename = oat.filename
128
- name = "#{File.basename(filename, '.*')}.zip" if name.nil?
129
-
127
+ name = "#{File.basename(filename, '.*')}.zip"
130
128
  att = Attachment.new(
131
129
  filename: name,
132
130
  file_path: tmp_file.path,
@@ -140,7 +138,7 @@ module Labimotion
140
138
 
141
139
  att.save! if att.valid?
142
140
 
143
- process_ds(att.id)
141
+ process_ds(att.id, current_user)
144
142
  rescue StandardError => e
145
143
  raise e
146
144
  ensure
@@ -148,7 +146,7 @@ module Labimotion
148
146
  end
149
147
  end
150
148
 
151
- def self.process(data)
149
+ def self.process(data, current_user = {}) # rubocop: disable Metrics/PerceivedComplexity
152
150
  return data[:a].con_state if data[:a]&.attachable_type != 'Container'
153
151
  response = nil
154
152
  begin
@@ -165,25 +163,25 @@ module Labimotion
165
163
  )
166
164
  end
167
165
  if response.ok?
168
- Labimotion::Converter.handle_response(data[:a], response)
166
+ Labimotion::Converter.handle_response(data[:a], response, current_user)
169
167
  Labimotion::ConState::PROCESSED
170
168
  else
171
169
  Labimotion::Converter.logger.error ["Converter Response Error: id: [#{data[:a]&.id}], filename: [#{data[:a]&.filename}], response: #{response}"].join($INPUT_RECORD_SEPARATOR)
172
170
  Labimotion::ConState::ERROR
173
171
  end
174
172
  rescue StandardError => e
175
- Labimotion::Converter.logger.error ["process fail: #{id}", e.message, *e.backtrace].join($INPUT_RECORD_SEPARATOR)
173
+ Labimotion::Converter.logger.error ["process fail: #{data[:a]&.id}", e.message, *e.backtrace].join($INPUT_RECORD_SEPARATOR)
176
174
  Labimotion::ConState::ERROR
177
175
  ensure
178
176
  FileUtils.rm_f(ofile)
179
177
  end
180
178
  end
181
179
 
182
- def self.jcamp_converter(id)
180
+ def self.jcamp_converter(id, current_user = {})
183
181
  data = Labimotion::Converter.vor_conv(id)
184
182
  return if data.nil?
185
183
 
186
- Labimotion::Converter.process(data)
184
+ Labimotion::Converter.process(data, current_user)
187
185
  rescue StandardError => e
188
186
  Labimotion::Converter.logger.error ["jcamp_converter fail: #{id}", e.message, *e.backtrace].join($INPUT_RECORD_SEPARATOR)
189
187
  Labimotion::ConState::ERROR
@@ -232,36 +230,19 @@ module Labimotion
232
230
  new_prop = dataset.properties
233
231
  dsr.each do |ds|
234
232
  layer = layers[ds[:layer]]
235
- next if layer.nil? || layer[Labimotion::Prop::FIELDS].nil?
233
+ next if layer.blank? || layer[Labimotion::Prop::FIELDS].blank?
236
234
 
237
235
  fields = layer[Labimotion::Prop::FIELDS].select{ |f| f['field'] == ds[:field] }
238
236
  fi = fields&.first
237
+ next if fi.blank?
238
+
239
239
  idx = layer[Labimotion::Prop::FIELDS].find_index(fi)
240
240
  fi['value'] = ds[:value]
241
241
  fi['device'] = ds[:device] || ds[:value]
242
242
  new_prop[Labimotion::Prop::LAYERS][ds[:layer]][Labimotion::Prop::FIELDS][idx] = fi
243
243
  end
244
- new_prop.dig(Labimotion::Prop::LAYERS, 'general', Labimotion::Prop::FIELDS)&.each_with_index do |fi, idx|
245
- if fi['field'] == 'creator' && current_user.present?
246
- fi['value'] = current_user.name
247
- fi['system'] = current_user.name
248
- new_prop[Labimotion::Prop::LAYERS]['general'][Labimotion::Prop::FIELDS][idx] = fi
249
- end
250
- end
251
244
  element = Container.find(dataset.element_id)&.root_element
252
- element.present? && element&.class&.name == 'Sample' && new_prop.dig(Labimotion::Prop::LAYERS, 'sample_details', Labimotion::Prop::FIELDS)&.each_with_index do |fi, idx|
253
- if fi['field'] == 'id'
254
- fi['value'] = element.id
255
- fi['system'] = element.id
256
- new_prop[Labimotion::Prop::LAYERS]['sample_details'][Labimotion::Prop::FIELDS][idx] = fi
257
- end
258
-
259
- if fi['field'] == 'label'
260
- fi['value'] = element.short_label
261
- fi['system'] = element.short_label
262
- new_prop[Labimotion::Prop::LAYERS]['sample_details'][Labimotion::Prop::FIELDS][idx] = fi
263
- end
264
- end
245
+ new_prop = Labimotion::VocabularyHandler.update_vocabularies(new_prop, current_user, element)
265
246
  dataset.properties = new_prop
266
247
  dataset.save!
267
248
  end
@@ -323,13 +304,13 @@ module Labimotion
323
304
  res
324
305
  end
325
306
 
326
- def self.metadata(id)
307
+ def self.metadata(id, current_user)
327
308
  att = Attachment.find(id)
328
309
  return if att.nil? || att.attachable_id.nil? || att.attachable_type != Labimotion::Prop::CONTAINER
329
310
 
330
311
  ds = Labimotion::Dataset.find_by(element_type: Labimotion::Prop::CONTAINER, element_id: att.attachable_id)
331
312
  att.update_column(:con_state, Labimotion::ConState::COMPLETED) if ds.present?
332
- process_ds(att.id) if ds.nil?
313
+ process_ds(att.id, current_user) if ds.nil?
333
314
  end
334
315
  end
335
316
  end