summaryrefslogtreecommitdiff
path: root/app/models/target.rb
blob: 3063b4254ac2f9a5866f18d9c5c601e0d7782a7a (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
34
35
36
37
38
39
40
41
42
# app/models/target.rb
class Target < ApplicationRecord
  has_many :target_allocations, dependent: :destroy
  has_many :nutrient_profiles, through: :target_allocations

  accepts_nested_attributes_for :target_allocations, allow_destroy: true
  validate :percentages_sum_to_100

  def weighted_requirements
    totals = Hash.new(0.0)
    denom  = 100.0

    target_allocations.includes(:nutrient_profile).each do |alloc|
      profile = alloc.nutrient_profile
      next unless profile

      weight = (alloc.percentage || 0).to_f / denom
      next if weight <= 0

      # Prefer the helper, but gracefully fall back to slicing attributes.
      reqs = if profile.respond_to?(:requirements_hash)
               profile.requirements_hash
      else
               profile.attributes.slice(*NutrientProfile::NUTRIENT_KEYS.map(&:to_s))
      end

      reqs.each do |nutrient_key, value|
        next if value.nil?
        totals[nutrient_key.to_s] += value.to_f * weight
      end
    end

    totals
  end

  private

  def percentages_sum_to_100
    sum = target_allocations.reject(&:marked_for_destruction?).sum { |a| a.percentage.to_f }
    errors.add(:base, "La somme des pourcentages doit être égale à 100%") unless (sum - 100.0).abs <= 0.01
  end
end
Copyright 2019--2025 Marius PETER