labimotion 1.4.1 → 2.0.0.rc6

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/lib/labimotion/apis/generic_element_api.rb +1 -0
  3. data/lib/labimotion/apis/generic_klass_api.rb +3 -2
  4. data/lib/labimotion/apis/labimotion_api.rb +13 -0
  5. data/lib/labimotion/apis/standard_api.rb +25 -0
  6. data/lib/labimotion/apis/standard_layer_api.rb +87 -0
  7. data/lib/labimotion/apis/vocabulary_api.rb +93 -0
  8. data/lib/labimotion/constants.rb +21 -0
  9. data/lib/labimotion/entities/dataset_entity.rb +1 -1
  10. data/lib/labimotion/entities/element_entity.rb +1 -0
  11. data/lib/labimotion/entities/properties_entity.rb +229 -56
  12. data/lib/labimotion/entities/segment_entity.rb +0 -1
  13. data/lib/labimotion/entities/vocabulary_entity.rb +28 -0
  14. data/lib/labimotion/helpers/element_helpers.rb +8 -6
  15. data/lib/labimotion/helpers/generic_helpers.rb +6 -1
  16. data/lib/labimotion/helpers/param_helpers.rb +121 -82
  17. data/lib/labimotion/helpers/segment_helpers.rb +1 -1
  18. data/lib/labimotion/helpers/vocabulary_helpers.rb +16 -0
  19. data/lib/labimotion/libs/converter.rb +12 -33
  20. data/lib/labimotion/libs/data/mapper/Chemwiki.json +236 -0
  21. data/lib/labimotion/libs/data/mapper/Source.json +78 -0
  22. data/lib/labimotion/libs/data/vocab/Standard.json +385 -0
  23. data/lib/labimotion/libs/data/vocab/System.json +131 -0
  24. data/lib/labimotion/libs/dataset_builder.rb +70 -0
  25. data/lib/labimotion/libs/export_dataset.rb +165 -66
  26. data/lib/labimotion/libs/nmr_mapper.rb +204 -246
  27. data/lib/labimotion/libs/sample_association.rb +4 -0
  28. data/lib/labimotion/libs/vocabulary_handler.rb +118 -0
  29. data/lib/labimotion/models/concerns/attachment_converter.rb +5 -4
  30. data/lib/labimotion/models/concerns/datasetable.rb +1 -0
  31. data/lib/labimotion/models/concerns/segmentable.rb +2 -0
  32. data/lib/labimotion/models/element.rb +3 -0
  33. data/lib/labimotion/models/std_layer.rb +9 -0
  34. data/lib/labimotion/models/std_layers_revision.rb +9 -0
  35. data/lib/labimotion/models/vocabulary.rb +12 -0
  36. data/lib/labimotion/utils/mapper_utils.rb +169 -0
  37. data/lib/labimotion/utils/utils.rb +22 -0
  38. data/lib/labimotion/version.rb +1 -1
  39. data/lib/labimotion.rb +13 -3
  40. metadata +25 -5
@@ -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,16 @@ 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
130
  element.update(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.save!
135
136
  element
136
137
  rescue StandardError => e
137
138
  Labimotion.log_exception(e, current_user)
@@ -321,7 +322,6 @@ module Labimotion
321
322
  return { status: 'success', message: "The element: #{attributes['name']} has been created using version: #{attributes['version']}!" }
322
323
  end
323
324
  end
324
-
325
325
  rescue StandardError => e
326
326
  Labimotion.log_exception(e, current_user)
327
327
  return { status: 'error', message: e.message }
@@ -351,7 +351,9 @@ module Labimotion
351
351
  _att
352
352
  end
353
353
  attachments
354
+ rescue StandardError => e
355
+ Labimotion.log_exception(e)
356
+ attachments
354
357
  end
355
-
356
358
  end
357
359
  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
127
  name = "#{File.basename(filename, '.*')}.zip"
129
-
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: [#{data[:a]&.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
@@ -243,27 +241,8 @@ module Labimotion
243
241
  fi['device'] = ds[:device] || ds[:value]
244
242
  new_prop[Labimotion::Prop::LAYERS][ds[:layer]][Labimotion::Prop::FIELDS][idx] = fi
245
243
  end
246
- new_prop.dig(Labimotion::Prop::LAYERS, 'general', Labimotion::Prop::FIELDS)&.each_with_index do |fi, idx|
247
- if fi['field'] == 'creator' && current_user.present?
248
- fi['value'] = current_user.name
249
- fi['system'] = current_user.name
250
- new_prop[Labimotion::Prop::LAYERS]['general'][Labimotion::Prop::FIELDS][idx] = fi
251
- end
252
- end
253
244
  element = Container.find(dataset.element_id)&.root_element
254
- element.present? && element&.class&.name == 'Sample' && new_prop.dig(Labimotion::Prop::LAYERS, 'sample_details', Labimotion::Prop::FIELDS)&.each_with_index do |fi, idx|
255
- if fi['field'] == 'id'
256
- fi['value'] = element.id
257
- fi['system'] = element.id
258
- new_prop[Labimotion::Prop::LAYERS]['sample_details'][Labimotion::Prop::FIELDS][idx] = fi
259
- end
260
-
261
- if fi['field'] == 'label'
262
- fi['value'] = element.short_label
263
- fi['system'] = element.short_label
264
- new_prop[Labimotion::Prop::LAYERS]['sample_details'][Labimotion::Prop::FIELDS][idx] = fi
265
- end
266
- end
245
+ new_prop = Labimotion::VocabularyHandler.update_vocabularies(new_prop, current_user, element)
267
246
  dataset.properties = new_prop
268
247
  dataset.save!
269
248
  end
@@ -325,13 +304,13 @@ module Labimotion
325
304
  res
326
305
  end
327
306
 
328
- def self.metadata(id)
307
+ def self.metadata(id, current_user)
329
308
  att = Attachment.find(id)
330
309
  return if att.nil? || att.attachable_id.nil? || att.attachable_type != Labimotion::Prop::CONTAINER
331
310
 
332
311
  ds = Labimotion::Dataset.find_by(element_type: Labimotion::Prop::CONTAINER, element_id: att.attachable_id)
333
312
  att.update_column(:con_state, Labimotion::ConState::COMPLETED) if ds.present?
334
- process_ds(att.id) if ds.nil?
313
+ process_ds(att.id, current_user) if ds.nil?
335
314
  end
336
315
  end
337
316
  end