Class: Ekylibre::AnimalGroupsExchanger

Inherits:
ActiveExchanger::Base show all
Defined in:
app/exchangers/ekylibre/animal_groups_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, deprecated?, exchanger_name, export, exporters, find, find_and_import, find_by, 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
# File 'app/exchangers/ekylibre/animal_groups_exchanger.rb', line 3

def check
  valid = true

  # Check building division presence
  unless building_division = BuildingDivision.first
    w.error 'Need almost one BuildingDivision'
    valid = false
  end

  rows = CSV.read(file, headers: true).delete_if { |r| r[0].blank? }
  w.count = rows.size
  rows.each_with_index do |row, index|
    line_number = index + 2
    prompt = "L#{line_number.to_s.yellow}"
    next if row[0].blank?
    r = OpenStruct.new(
      name: row[0],
      nature: row[1].to_s,
      member_nature: (row[2].blank? ? nil : row[2].to_sym),
      code: row[3],
      minimum_age: (row[4].blank? ? nil : row[4].to_i),
      maximum_age: (row[5].blank? ? nil : row[5].to_i),
      sex: (row[6].blank? ? nil : row[6].to_sym),
      place: (row[7].blank? ? nil : row[7].to_s),
      indicators_at: (row[8].blank? ? Time.zone.today : row[8]).to_datetime,
      indicators: row[9].blank? ? {} : row[9].to_s.strip.split(/[[:space:]]*\;[[:space:]]*/).collect { |i| i.split(/[[:space:]]*\:[[:space:]]*/) }.each_with_object({}) do |i, h|
        h[i.first.strip.downcase.to_sym] = i.second
        h
      end,
      activity_family_name: row[10].to_s,
      activity_name: row[11].to_s,
      campaign_year: row[12].to_i
    )

    unless variant = ProductNatureVariant.find_by(number: r.nature)
      unless variant = ProductNatureVariant.import_from_nomenclature(r.nature.to_sym)
        w.error "#{prompt} #{r.nature} does not exist in NOMENCLATURE or in DB"
        valid = false
      end
    end
    r.member_nature = "#{r.member_nature}_band".to_sym if r.member_nature.to_s =~ /^(fe)?male_young_pig$/
    r.member_nature = :young_rabbit if r.member_nature.to_s =~ /^(fe)?male_young_rabbit$/
    animal_variant = ProductNatureVariant.find_by(number: r.member_nature) ||
                     ProductNatureVariant.find_by(reference_name: r.member_nature) ||
                     ProductNatureVariant.import_from_nomenclature(r.member_nature)
    unless animal_variant
      w.error "#{prompt} #{r.member_nature} does not exist in NOMENCLATURE or in DB"
      valid = false
    end

    unless animal_container = Product.find_by(work_number: r.place)
      w.error "#{prompt} #{r.place} does not exist in DB"
      valid = false
    end

    next unless r.variant_reference_name
    next if variant = ProductNatureVariant.find_by(work_number: r.variant_reference_name)
    unless nomen = Nomen::ProductNatureVariant.find(r.variant_reference_name.downcase.to_sym)
      w.error "No variant exist in NOMENCLATURE for #{r.variant_reference_name.inspect}"
      valid = false
    end
  end
end

#importObject

Create or updates animal groups


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
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
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
# File 'app/exchangers/ekylibre/animal_groups_exchanger.rb', line 68

def import
  rows = CSV.read(file, headers: true).delete_if { |r| r[0].blank? }
  w.count = rows.size

  rows.each do |row|
    r = OpenStruct.new(
      name: row[0],
      nature: row[1].to_s,
      member_nature: (row[2].blank? ? nil : row[2].to_sym),
      code: row[3],
      minimum_age: (row[4].blank? ? nil : row[4].to_i),
      maximum_age: (row[5].blank? ? nil : row[5].to_i),
      sex: (row[6].blank? ? nil : row[6].to_sym),
      place: (row[7].blank? ? nil : row[7].to_s),
      indicators_at: (row[8].blank? ? Time.zone.today : row[8]).to_datetime,
      indicators: row[9].blank? ? {} : row[9].to_s.strip.split(/[[:space:]]*\;[[:space:]]*/).collect { |i| i.split(/[[:space:]]*\:[[:space:]]*/) }.each_with_object({}) do |i, h|
        h[i.first.strip.downcase.to_sym] = i.second
        h
      end,
      activity_family_name: row[10].to_s,
      activity_name: row[11].to_s,
      campaign_year: row[12].to_i
    )

    unless variant = ProductNatureVariant.find_by(work_number: r.nature)
      variant = ProductNatureVariant.import_from_nomenclature(r.nature.to_sym)
    end

    r.member_nature = "#{r.member_nature}_band".to_sym if r.member_nature.to_s =~ /^(fe)?male_young_pig$/
    r.member_nature = :young_rabbit if r.member_nature.to_s =~ /^(fe)?male_young_rabbit$/
    animal_variant = ProductNatureVariant.find_by(work_number: r.member_nature) ||
                     ProductNatureVariant.find_by(reference_name: r.member_nature) ||
                     ProductNatureVariant.import_from_nomenclature(r.member_nature)
    animal_variant ||= ProductNatureVariant.import_from_nomenclature(r.member_nature)

    # get animal default container
    animal_container = BuildingDivision.find_by(work_number: r.place)

    # find or create animal_group
    if animal_group = AnimalGroup.find_by(work_number: r.code)
      animal_group.name = r.name
      animal_group.member_variant ||= animal_variant
      animal_group.initial_container ||= animal_container
      animal_group.default_storage ||= animal_container
      animal_group.save!
    else
      animal_group = AnimalGroup.create!(
        name: r.name,
        work_number: r.code,
        initial_born_at: r.indicators_at,
        initial_population: 1.0,
        variant: variant,
        initial_container: animal_container,
        default_storage: animal_container
      )
      # create indicators linked to animal group
      r.indicators.each do |indicator, value|
        if indicator.to_sym == :population
          animal_group.move!(value, at: r.indicators_at)
        else
          animal_group.read!(indicator, value, at: r.indicators_at, force: true)
        end
      end
      # animal_group.initial_population = animal_group.population
      animal_group.save!
    end

    # Check if animals exist with given sex and age
    if r.minimum_age && r.maximum_age && r.sex
      max_born_at = Time.zone.now - r.minimum_age.days if r.minimum_age
      min_born_at = Time.zone.now - r.maximum_age.days if r.maximum_age
      animals = Animal.indicate(sex: r.sex.to_s).where(born_at: min_born_at..max_born_at).reorder(:name)

      # find support for intervention changing or create it
      unless ap = ActivityProduction.where(support_id: animal_group.id).first
        # campaign = Campaign.find_or_create_by!(harvest_year: r.campaign_year)
        family = Nomen::ActivityFamily.find(:animal_farming)
        r.activity_name = family.human_name if r.activity_name.blank?
        unless activity = Activity.find_by(name: r.activity_name)
          # family = Activity.find_best_family(animal_group.derivative_of, animal_group.variety)
          unless family
            w.error 'Cannot determine activity'
            raise ActiveExchanger::Error, "Cannot determine activity with support #{support_variant ? support_variant.variety.inspect : '?'} and cultivation #{cultivation_variant ? cultivation_variant.variety.inspect : '?'} in production #{sheet_name}"
          end
          activity = Activity.create!(
            name: r.activity_name,
            family: family.name,
            nature: family.nature,
            production_cycle: :perennial
          )
        end
        # get first harvest_year of first campaign
        first_year_of_campaign = Campaign.first_of_all.harvest_year if Campaign.first_of_all
        if animals.any?
          ap = ActivityProduction.create!(
            activity: activity,
            support_id: animal_group.id,
            size_value: animals.count,
            support_nature: :animal_group,
            started_on: first_year_of_campaign ? Date.civil(first_year_of_campaign, 1, 1) : Date.civil(1970, 1, 1),
            usage: :milk
          )
        end
      end

      # if animals and production_support, add animals to the target distribution
      if animals.any? && ap.present?
        animals.each do |animal|
          animal.update(activity_production: ap)
          animal.memberships.where(group: animal_group, started_at: animal.born_at + r.minimum_age, nature: :interior).first_or_create!
          animal.localizations.where(started_at: animal.born_at + r.minimum_age, nature: :interior, container: animal_container).first_or_create!
        end
        # TODO: how to add animals to a group
        # animal_group.add_animals(animals, started_at: Time.zone.now - 1.hour, stopped_at: Time.zone.now, production_support_id: ps.id, container_id: animal_container.id, variant_id: animal_variant.id, worker_id: Worker.first.id)
      end

    end

    w.check_point
  end
end

#update_animal_evolutionObject

puts animals in a group by default


191
192
193
# File 'app/exchangers/ekylibre/animal_groups_exchanger.rb', line 191

def update_animal_evolution
  # TODO: change default variant of animal if needed
end

#update_animal_placeObject

puts animals in a place by default


196
197
198
# File 'app/exchangers/ekylibre/animal_groups_exchanger.rb', line 196

def update_animal_place
  # TODO: change default place of animal if needed
end