summaryrefslogtreecommitdiff
path: root/app/services/target_nutrient_calculator.rb
blob: e6cd3787e0809036a5970c9c2cb1a34d6bc3f603 (plain)
1
2
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
class TargetNutrientCalculator
  # Derive nutrient columns from the NutrientMeasurement table
  NUTRIENT_COLUMNS = (NutrientMeasurement.column_names - %w[id measured_on created_at updated_at])
                      .map!(&:to_sym)
                      .freeze

  # Returns an unsaved NutrientMeasurement with target concentrations (e.g., mg/L)
  def self.call
    rafts = Raft.includes(:crop).where.not(crop_id: nil)
    total = rafts.count
    return empty_measurement if total.zero?

    sums = Hash.new(0.0)

    rafts.each do |raft|
      NUTRIENT_COLUMNS.each do |col|
        v = raft.crop.public_send(col)
        sums[col] += v.to_f if v
      end
    end

    targets = sums.transform_values { |s| s / total }
    NutrientMeasurement.new({ measured_on: Date.current }.merge(targets))
  end

  private

  def empty_measurement
    NutrientMeasurement.new(
      { measured_on: Date.current }.merge(NUTRIENT_COLUMNS.index_with { 0.0 })
    )
  end
end
Copyright 2019--2025 Marius PETER