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

#impact, #param_name, #root?

Constructor Details

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


11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 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])
  end
  @readings = {}.with_indifferent_access
  if @attributes[:readings_attributes]
    @attributes[:readings_attributes].each do |id, attributes|
      add_reading(id, attributes)
    end
  end
end

Instance Attribute Details

#productObject

Returns the value of attribute product


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

def product
  @product
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


45
46
47
48
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 45

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

#compute_attribute(attribute) ⇒ Object


155
156
157
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 155

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

#compute_reading(reading) ⇒ Object


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

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

#envObject


181
182
183
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 181

def env
  { self: self, product: product, working_zone: working_zone }
end

#impact_dependencies!(field) ⇒ Object


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

def impact_dependencies!(field)
  super(field)
  impact_on_attributes(field)
  impact_on_readings(field)
  impact_on_parameters(field)
end

#impact_on_attributes(field) ⇒ Object

Impact changes on attributes of parameter based on given field


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 82

def impact_on_attributes(field)
  reference.attributes.each do |attribute|
    next unless field != attribute.name
    next unless attribute.default_value?
    next unless attribute.default_value_with_environment_variable?(field, :self)
    next if attribute.condition? && !usable_attribute?(attribute)
    # value = send(attribute.name)
    # next unless value.blank?
    value = compute_attribute(attribute)
    next if value.blank? || value == send(attribute.name)
    # puts "Update #{attribute.name}"
    value = Charta.new_geometry(value) if value && attribute.name == :working_zone
    send(attribute.name.to_s + '=', value)
  end
end

#impact_on_parameters(_field) ⇒ Object


115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 115

def impact_on_parameters(_field)
  procedure.parameters.each do |parameter|
    next unless parameter.is_a?(Procedo::Procedure::ProductParameter)
    intervention_parameters = intervention.parameters_of_name(parameter.name)
    intervention_parameters.each do |ip|
      # Impact handlers
      if parameter.quantified? && ip.quantity_handler
        handler = parameter.handler(ip.quantity_handler)
        if handler && handler.depend_on?(reference_name)
          # puts "Impact #{parameter.name} #{handler.name} quantity_value"
          ip.quantity_value = ip.quantity_value
        end
      end
      # Impact attributes
      parameter.attributes.each do |attribute|
        next unless attribute.depend_on?(reference_name)
        next unless ip.usable_attribute?(attribute)
        value = ip.compute_attribute(attribute)
        if value != ip.send(attribute.name)
          # puts "Impact #{parameter.name} #{attribute.name} attribute"
          ip.impact(attribute.name)
        end
      end
      # Impact readings
      parameter.readings.each do |reading|
        next unless reading.depend_on?(reference_name)
        next unless ip.usable_reading?(reading)
        value = ip.compute_reading(reading)
        ir = ip.reading(reading.name)
        # puts value.inspect.green
        # puts ir.value.inspect.blue
        if value != ir.value
          # puts "Impact #{parameter.name} #{reading.name} reading: #{ir.value.inspect}"
          ir.value = value
        end
      end
    end
  end
end

#impact_on_readings(field) ⇒ Object

Impact changes on readings of parameter based on given field


99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 99

def impact_on_readings(field)
  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)
    # next unless ir.value.blank?
    value = compute_reading(ref_reading)
    if value != ir.value
      # puts "Update reading #{ref_reading.name}"
      ir.value = value
    end
    ir.impact_dependencies!
  end
end

#impact_with(steps) ⇒ Object


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

def impact_with(steps)
  raise 'Invalid steps: ' + steps.inspect if steps.size != 1
  impact(steps.first)
end

#product_idObject


27
28
29
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 27

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

#product_id=(id) ⇒ Object


35
36
37
38
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 35

def product_id=(id)
  @product = Product.find_by!(id: id)
  impact_dependencies!(:product)
end

#reading(indicator_name) ⇒ Object


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

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

#to_hashObject


57
58
59
60
61
62
63
64
65
66
67
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 57

def to_hash
  hash = super
  hash[:product_id] = product_id
  hash[:working_zone] = @working_zone ? @working_zone.to_json : nil
  @readings.each do |id, reading|
    next unless reference.reading(reading.name)
    hash[:readings_attributes] ||= {}
    hash[:readings_attributes][id] = reading.to_hash
  end
  hash
end

#usable_attribute?(attribute) ⇒ Boolean

Test if a attribute is usable


170
171
172
173
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 170

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


164
165
166
167
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 164

def usable_handler?(handler)
  return true unless handler.condition?
  intervention.interpret(handler.condition_tree, env)
end

#usable_reading?(reading) ⇒ Boolean

Test if a reading is usable


176
177
178
179
# File 'lib/procedo/engine/intervention/product_parameter.rb', line 176

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