Class: Procedo::Engine::Intervention::ProductParameter

Inherits:
Parameter
  • Object
show all
Defined in:
lib/procedo/engine/intervention/product_parameter.rb

Direct Known Subclasses

Agent, Quantified, Target

Instance Attribute Summary collapse

Attributes inherited from Parameter

#group, #id, #intervention, #name, #reference, #type

Instance Method Summary collapse

Methods inherited from Parameter

#dependents, #param_name, #root?

Methods included from Reassignable

#assign, #assign!, #reassign, #reassign!

Constructor Details

#initialize(intervention, id, attributes = {}) ⇒ ProductParameter

Returns a new instance of ProductParameter.


11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 11

def initialize(intervention, id, attributes = {})
  super(intervention, id, attributes)
  if @attributes[:product_id].present?
    @product = Product.find_by(id: @attributes[:product_id])
  end
  if attributes[:working_zone].present?
    @working_zone = Charta.from_geojson(attributes[:working_zone])
    @working_zone = @working_zone.convert_to(:multi_polygon)
  end
  if intervention && intervention.working_periods.present?
    first_period_key = intervention.working_periods.keys.sort_by(&:to_i).first
    @read_at = intervention.working_periods[first_period_key].started_at
  end
  @readings = {}.with_indifferent_access
  if @attributes[:readings_attributes]
    @attributes[:readings_attributes].each do |id, attributes|
      add_reading(id, attributes)
    end
  end
  if attributes[:assembly_id].present?
    @assembly = Product.find_by(id: attributes[:assembly_id])
  end
  if attributes[:component_id].present?
    @component = ProductNatureVariantComponent.find_by(id: attributes[:component_id])
  end
end

Instance Attribute Details

#assemblyObject

Returns the value of attribute assembly


7
8
9
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 7

def assembly
  @assembly
end

#componentObject

Returns the value of attribute component


7
8
9
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 7

def component
  @component
end

#productObject

Returns the value of attribute product


7
8
9
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 7

def product
  @product
end

#read_atObject (readonly)

Returns the value of attribute read_at


7
8
9
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 7

def read_at
  @read_at
end

#readingsObject (readonly)

Returns the value of attribute readings


7
8
9
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 7

def readings
  @readings
end

#working_zoneObject

Returns the value of attribute working_zone


7
8
9
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 7

def working_zone
  @working_zone
end

Instance Method Details

#add_reading(id, attributes = {}) ⇒ Object


69
70
71
72
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 69

def add_reading(id, attributes = {})
  reading = Procedo::Engine::Intervention::Reading.new(self, id, attributes)
  @readings[reading.id] = reading
end

#assembly?Boolean

Returns:

  • (Boolean)

94
95
96
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 94

def assembly?
  @assembly.present?
end

#assembly_idObject


81
82
83
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 81

def assembly_id
  @assembly ? @assembly.id : nil
end

#assembly_id=(id) ⇒ Object


85
86
87
88
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 85

def assembly_id=(id)
  @assembly = id.blank? ? nil : Product.find_by!(id: id)
  impact_dependencies! :assembly
end

#component?Boolean

Returns:

  • (Boolean)

111
112
113
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 111

def component?
  @component.present?
end

#component_idObject


98
99
100
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 98

def component_id
  @component ? @component.id : nil
end

#component_id=(id) ⇒ Object


102
103
104
105
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 102

def component_id=(id)
  @component_id = id.blank? ? nil : ProductNatureVariant.find_by!(id: id)
  impact_dependencies! :component
end

#compute_attribute(attribute) ⇒ Object


244
245
246
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 244

def compute_attribute(attribute)
  intervention.interpret(attribute.default_value_tree, env)
end

#compute_reading(reading) ⇒ Object


248
249
250
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 248

def compute_reading(reading)
  intervention.interpret(reading.default_value_tree, env)
end

#envObject


271
272
273
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 271

def env
  super.merge(product: product, working_zone: working_zone, read_at: read_at)
end

#impact_dependencies!(field = nil) ⇒ Object


166
167
168
169
170
171
172
173
174
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 166

def impact_dependencies!(field = nil)
  super(field)
  impact_on_attributes(field)
  impact_on_readings(field)
  impact_on_components(field)
  impact_on_parameters(field)
  reassign(:assembly)
  reassign(:component)
end

#impact_on_attributes(field = nil) ⇒ Object

Impact changes on attributes of parameter based on given field


177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 177

def impact_on_attributes(field = nil)
  reference.attributes.each do |attribute|
    next unless field != attribute.name
    if attribute.default_value? && attribute.default_value_with_environment_variable?(field, :self)

      next if attribute.condition? && !usable_attribute?(attribute)
      value = compute_attribute(attribute)
      next if value.blank? || value == send(attribute.name)
      value = Charta.new_geometry(value) if value && attribute.name == :working_zone

      assign(attribute.name, value)
    end

    if attribute.compute_filter? && attribute.compute_filter_with_environment_variable?(field, :self)
      attribute.computed_filter = intervention.interpret(attribute.compute_filter_tree, env)
    end
  end
end

#impact_on_components(_field = nil) ⇒ Object


207
208
209
210
211
212
213
214
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 207

def impact_on_components(_field = nil)
  reference.components.each do |component_parameter|
    inputs = intervention.parameters_of_name(component_parameter.name)
    inputs.each do |input|
      input.assign(:assembly, intervention.interpret(input.reference.component_of_tree, env))
    end
  end
end

#impact_on_parameters(_field) ⇒ Object


216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 216

def impact_on_parameters(_field)
  procedure.product_parameters(true).each do |parameter|
    (intervention.parameters_of_name(parameter.name) - [self]).each do |ip|
      # Impact handlers
      if parameter.quantified? && ip.quantity_handler
        handler = parameter.handler(ip.quantity_handler)
        if handler && handler.depend_on?(reference_name)
          ip.reassign(:quantity_value)
        end
      end
      # Impact attributes
      parameter.attributes.each do |attribute|
        next unless attribute.depend_on?(reference_name) &&
                    ip.usable_attribute?(attribute)
        ip.assign(attribute.name, ip.compute_attribute(attribute))
      end
      # Impact readings
      parameter.readings.each do |reading|
        next unless reading.depend_on?(reference_name) &&
                    ip.usable_reading?(reading)
        ip.reading(reading.name).assign(:value, ip.compute_reading(reading))
      end
      # Impact components
      ip.impact_on_components(_field)
    end
  end
end

#impact_on_readings(field = nil) ⇒ Object

Impact changes on readings of parameter based on given field


197
198
199
200
201
202
203
204
205
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 197

def impact_on_readings(field = nil)
  reference.readings.each do |ref_reading|
    ir = reading(ref_reading.name)
    next unless ir && ref_reading.default_value?
    next unless ref_reading.default_value_with_environment_variable?(field, :self)
    next if ref_reading.condition? && !usable_reading?(ref_reading)
    ir.assign(:value, compute_reading(ref_reading))
  end
end

#impact_with(steps) ⇒ Object


159
160
161
162
163
164
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 159

def impact_with(steps)
  if steps.size != 1
    raise ArgumentError, 'Invalid steps: got ' + steps.inspect
  end
  reassign!(steps.first)
end

#product?Boolean

Returns:

  • (Boolean)

50
51
52
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 50

def product?
  @product.present?
end

#product_idObject


42
43
44
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 42

def product_id
  @product ? @product.id : nil
end

#product_id=(id) ⇒ Object


54
55
56
57
58
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 54

def product_id=(id)
  @product = id.blank? ? nil : Product.find_by!(id: id)
  # Can impact on own attributes, own readings, and other parameters
  impact_dependencies!(:product)
end

#read_at?Boolean

Returns:

  • (Boolean)

38
39
40
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 38

def read_at?
  @read_at.present?
end

#reading(indicator_name) ⇒ Object


74
75
76
77
78
79
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 74

def reading(indicator_name)
  @readings.each do |_id, reading|
    return reading if reading.name.to_s == indicator_name.to_s
  end
  nil
end

#to_attributesObject


139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 139

def to_attributes
  hash = super
  hash[:product_id] = product_id if product?
  hash[:working_zone] = @working_zone.to_json if working_zone?
  @readings.each do |id, reading|
    next unless reference.reading(reading.name)
    hash[:readings_attributes] ||= {}
    hash[:readings_attributes][id] = reading.to_hash
  end
  reference.attributes.each do |attribute|
    next unless attribute.compute_filter?
    hash[:attributes] ||= {}
    hash[:attributes][attribute.name] ||= {}
    hash[:attributes][attribute.name][:dynascope] = attribute.scope_hash
  end
  hash[:assembly_id] = assembly_id if assembly?
  hash[:component_id] = component_id if component?
  hash
end

#to_hashObject


115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 115

def to_hash
  hash = super
  hash[:product_id] = product_id if product?
  hash[:working_zone] = @working_zone.to_json if working_zone?
  @readings.each do |id, reading|
    next unless reference.reading(reading.name)
    hash[:readings_attributes] ||= {}
    hash[:readings_attributes][id] = reading.to_hash
  end
  reference.attributes.each do |attribute|
    next unless attribute.compute_filter?
    hash[:attributes] ||= {}
    hash[:attributes][attribute.name] ||= {}
    hash[:attributes][attribute.name][:dynascope] = attribute.scope_hash
  end
  hash[:assembly_id] = assembly_id if assembly?
  hash[:component_id] = component_id if component?
  hash[:errors] = {}
  if reference.display_status.to_s.to_sym == :miscibility
    hash[:errors][:miscibility] = true unless product? && product.france_maaid
  end
  hash
end

#usable_attribute?(attribute) ⇒ Boolean

Test if a attribute is usable

Returns:

  • (Boolean)

260
261
262
263
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 260

def usable_attribute?(attribute)
  return true unless attribute.condition?
  intervention.interpret(attribute.condition_tree, env)
end

#usable_handler?(handler) ⇒ Boolean

Test if a handler is usable

Returns:

  • (Boolean)

253
254
255
256
257
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 253

def usable_handler?(handler)
  return true unless handler.condition?
  return false if handler.condition_variables.any? { |dependency| intervention.interpret(dependency, env).nil? }
  intervention.interpret(handler.condition_tree, env)
end

#usable_reading?(reading) ⇒ Boolean

Test if a reading is usable

Returns:

  • (Boolean)

266
267
268
269
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 266

def usable_reading?(reading)
  return true unless reading.condition?
  intervention.interpret(reading.condition_tree, env)
end

#working_zone?Boolean

Returns:

  • (Boolean)

60
61
62
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 60

def working_zone?
  @working_zone.present?
end