Class: Ekylibre::InterventionsExchanger

Inherits:
ActiveExchanger::Base show all
Defined in:
app/exchangers/ekylibre/interventions_exchanger.rb

Instance Attribute Summary

Attributes inherited from ActiveExchanger::Base

#file, #supervisor

Instance Method Summary collapse

Methods inherited from ActiveExchanger::Base

build, check, check_by_default, exchanger_name, export, exporters, find, human_name, import, import!, importers, importers_selection, inherited, #initialize, register_exchanger

Constructor Details

This class inherits a constructor from ActiveExchanger::Base

Instance Method Details

#checkObject


3
4
5
6
7
8
9
10
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'app/exchangers/ekylibre/interventions_exchanger.rb', line 3

def check
  rows = CSV.read(file, headers: true, col_sep: ';').delete_if { |r| r[0].blank? }.sort { |a, b| [a[2].split(/\D/).reverse.join, a[0]] <=> [b[2].split(/\D/).reverse.join, b[0]] }
  valid = true
  w.count = rows.size
  rows.each_with_index do |row, index|
    line_number = index + 2
    prompt = "L#{line_number.to_s.yellow}"
    r = parse_row(row)
    if row[0].blank?
      w.info "#{prompt} Skipped"
      next
    end
    # info, warn, error
    # valid = false if error

    # PROCEDURE EXIST IN NOMENCLATURE
    #
    if r.procedure_name.blank?
      w.error "#{prompt} No procedure given"
      valid = false
    end
    # procedure_long_name = 'base-' + r.procedure_name.to_s + '-0'
    # procedure_nomen = Procedo[procedure_long_name]
    # unless procedure_nomen
    #  w.error "#{prompt} Invalid procedure name (#{r.procedure_name})"
    #  valid = false
    # end

    # PROCEDURE HAVE A DURATION
    #
    unless r.intervention_duration_in_hour.hours && r.intervention_duration_in_hour.hours.to_f > 0.0
      w.error "#{prompt} Need a duration > 0"
      valid = false
    end

    # PROCEDURE GIVE A CAMPAIGN WHO DOES NOT EXIST IN DB
    #
    unless campaign = Campaign.find_by_name(r.campaign_code)
      w.warn "#{prompt} #{r.campaign_code} will be created as a campaign"
    end

    # PROCEDURE GIVE SUPPORTS CODES BUT NOT EXIST IN DB
    #
    if r.support_codes
      supports = Product.where(work_number: r.support_codes)
      supports ||= CultivableZone.where(work_number: r.support_codes)
      unless supports
        w.warn "#{prompt} #{r.support_codes} does not exist in DB"
        w.warn "#{prompt} a standard activity will be set"
      end
    end

    # PROCEDURE GIVE VARIANT OR VARIETY CODES BUT NOT EXIST IN DB OR IN NOMENCLATURE
    #
    if r.target_variety
      unless Nomen::Variety.find(r.target_variety)
        w.error "#{prompt} #{r.target_variety} does not exist in NOMENCLATURE"
        valid = false
      end
    end
    if r.target_variant
      unless r.target_variant.is_a? ProductNatureVariant
        w.error "#{prompt} Invalid target variant: #{r.target_variant.inspect}"
        valid = false
      end
    end

    # PROCEDURE GIVE EQUIPMENTS CODES BUT NOT EXIST IN DB
    #
    if r.equipment_codes
      unless equipments = Equipment.where(work_number: r.equipment_codes)
        w.warn "#{prompt} #{r.equipment_codes} does not exist in DB"
      end
    end

    # PROCEDURE GIVE WORKERS CODES BUT NOT EXIST IN DB
    #
    if r.worker_codes
      unless workers = Worker.where(work_number: r.worker_codes)
        w.warn "#{prompt} #{r.worker_codes} does not exist in DB"
      end
    end

    # CHECK ACTORS
    #
    [r.first, r.second, r.third].each_with_index do |actor, i|
      next if actor.product_code.blank?

      # PROCEDURE GIVE PRODUCTS OR VARIANTS BUT NOT EXIST IN DB
      #
      if actor.product.is_a?(Product)
      # w.info "#{prompt} Actor ##{i + 1} exist in DB as a product (#{actor.product.name})"
      elsif actor.variant.is_a?(ProductNatureVariant)
      # w.info "#{prompt} Actor ##{i + 1} exist in DB as a variant (#{actor.variant.name})"
      elsif item = Nomen::ProductNatureVariants.find(actor.target_variant)
      # w.info "#{prompt} Actor ##{i + 1} exist in NOMENCLATURE as a variant (#{item.name})"
      else
        w.error "#{prompt} Actor ##{i + 1} (#{actor.product_code}) does not exist in DB as a product or as a variant in DB or NOMENCLATURE"
        valid = false
      end

      # PROCEDURE GIVE PRODUCTS OR VARIANTS BUT NOT EXIST IN DB
      #
      unit_name = actor.input_unit_name
      if Nomen::Units[unit_name]
      # w.info "#{prompt} #{unit_name} exist in NOMENCLATURE as a unit"
      elsif u = Nomen::Units.find_by(symbol: unit_name)
      # w.info "#{prompt} #{unit_name} exist in NOMENCLATURE as a symbol of #{u.name}"
      else
        w.error "#{prompt} Unknown unit: #{unit_name.inspect}"
        valid = false
      end
    end
  end
  valid
end

#importObject


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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'app/exchangers/ekylibre/interventions_exchanger.rb', line 120

def import
  rows = CSV.read(file, headers: true, col_sep: ';').delete_if { |r| r[0].blank? }.sort { |a, b| [a[2].split(/\D/).reverse.join, a[0]] <=> [b[2].split(/\D/).reverse.join, b[0]] }
  w.count = rows.size

  information_import_context = "Import Ekylibre interventions on #{Time.zone.now.l}"

  # Load hash to transcode old procedure
  # transcode procedure_name from old procedure
  here = Pathname.new(__FILE__).dirname
  procedures_transcode = {}.with_indifferent_access
  CSV.foreach(here.join('procedures.csv'), headers: true) do |row|
    procedures_transcode[row[0]] = row[1].to_sym
  end

  rows.each_with_index do |row, _index|
    line_number = _index + 2
    r = parse_row(row)

    # Check duration
    if r.intervention_duration_in_hour.hours
      r.intervention_stopped_at = r.intervention_started_at + r.intervention_duration_in_hour.hours
    else
      w.warn "Need a duration for intervention ##{r.intervention_number}"
      raise "Need a duration for intervention ##{r.intervention_number}"
    end

    w.debug r.supports.inspect.red

    # Get supports
    # Supports are Product : LandParcel, Plant, Animal...link to Campaign and ActivityProduction
    r.production_supports = []
    # Case A
    if r.supports.any?
      # find all supports who match : cultivation_variety / cultivation_variant or just storage given
      # a same cultivable zone could be a support of many productions
      # ex : corn_crop, zea_mays_lg452, ZC42 have to return all supports with corn_crop of variety zea_mays_lg452 in ZC42
      p_ids = []
      for product in r.supports
        # case A1 : CZ
        if product.is_a?(CultivableZone)
          ap = ActivityProduction.of_campaign(r.campaign).where(cultivable_zone: product)
          ap = ap.of_cultivation_variety(r.target_variety) if r.target_variety
          ps = ap.map(&:support)
        # case A2 : Product
        elsif product.is_a?(Product)
          ps = [product]
        end
        p_ids << ps.map(&:id)
      end
      w.debug p_ids.inspect.blue
      supports = Product.find(p_ids)
    # r.production_supports = ActivityProduction.of_campaign(r.campaign).find(ps_ids)
    # Case B
    elsif r.support_codes.present?
      activity = Activity.where(family: r.support_codes.flatten.first.downcase.to_sym).first
      production = Production.where(activity: activity, campaign: r.campaign).first if activity && r.campaign
    # Case C
    else
      activity = Activity.where(nature: :auxiliary, with_supports: false, with_cultivation: false).first
      production = Production.where(activity: activity, campaign: r.campaign).first if activity && r.campaign
    end

    w.debug supports.inspect.yellow

    raise "stop #{r.target_variety}" unless supports.any?

    # case 1 supports exists
    if supports.any?
      # w.info r.to_h.to_yaml
      w.info "----------- L#{line_number.to_s.yellow} : #{r.intervention_number} / #{supports.map(&:name).to_sentence} -----------".blue
      w.info ' procedure : ' + r.procedure_name.inspect.green
      w.info ' started_at : ' + r.intervention_started_at.inspect.yellow if r.intervention_started_at
      w.info ' first product : ' + r.first.product.name.inspect.red if r.first.product
      w.info ' first product quantity : ' + r.first.product.input_population.to_s + ' ' + r.first.product.input_unit_name.to_s.inspect.red if r.first.product_input_population
      w.info ' second product : ' + r.second.product.name.inspect.red if r.second.product
      w.info ' third product : ' + r.third.product.name.inspect.red if r.third.product
      w.info ' target variety : ' + r.target_variety.inspect.yellow if r.target_variety
      w.info ' supports : ' + supports.map(&:name).to_sentence.inspect.yellow if supports
      w.info ' workers_name : ' + r.workers.map(&:name).inspect.yellow if r.workers
      w.info ' equipments_name : ' + r.equipments.map(&:name).inspect.yellow if r.equipments

      # plants = find_plants(support: support, variety: r.target_variety, at: r.intervention_started_at)
      # w.info ' #{plants.count} plants : ' + plants.map(&:name).inspect.yellow if plants
      targets = supports

      intervention = qualify_intervention(r, targets, procedures_transcode)
    # intervention = send("record_#{r.procedure_name}", r, targets)
    else
      w.warn "Cannot add intervention #{r.intervention_number} without support"
    end

    if intervention
      intervention.description ||= ''
      intervention.description += ' - ' + information_import_context + ' - N° : ' + r.intervention_number.to_s
      intervention.save!
      w.info "Intervention n°#{intervention.id} - #{intervention.name} has been created".green
    else
      w.warn 'Intervention is in a black hole'.red
    end

    w.check_point
  end
end