summaryrefslogtreecommitdiff
path: root/app/services/target_nutrient_calculator.rb
diff options
context:
space:
mode:
authorMarius Peter <marius.peter@tutanota.com>2025-08-24 20:29:54 +0200
committerMarius Peter <marius.peter@tutanota.com>2025-08-24 20:29:54 +0200
commit52b044d6a4278c229992404ad5801769c2d13363 (patch)
treeb30b34da58f26117c035391d09366b190350b1e3 /app/services/target_nutrient_calculator.rb
First commit.
Vive le Castel Peter !
Diffstat (limited to 'app/services/target_nutrient_calculator.rb')
-rw-r--r--app/services/target_nutrient_calculator.rb33
1 files changed, 33 insertions, 0 deletions
diff --git a/app/services/target_nutrient_calculator.rb b/app/services/target_nutrient_calculator.rb
new file mode 100644
index 0000000..e6cd378
--- /dev/null
+++ b/app/services/target_nutrient_calculator.rb
@@ -0,0 +1,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