Files
nairobi/app/models/budget/phase.rb
decabeza c0c458bb38 Remove summary in phases form
Since it does not appear in the phases anymore.

Also, the rake unifies the fields of the budget summary with the budget
description.
2021-03-11 19:37:58 +01:00

109 lines
3.5 KiB
Ruby

class Budget
class Phase < ApplicationRecord
PHASE_KINDS = %w[informing accepting reviewing selecting valuating publishing_prices balloting
reviewing_ballots finished].freeze
PUBLISHED_PRICES_PHASES = %w[publishing_prices balloting reviewing_ballots finished].freeze
DESCRIPTION_MAX_LENGTH = 2000
translates :summary, touch: true
translates :description, touch: true
include Globalizable
include Sanitizable
belongs_to :budget, touch: true
belongs_to :next_phase, class_name: self.name, inverse_of: :prev_phase
has_one :prev_phase, class_name: self.name, foreign_key: :next_phase_id, inverse_of: :next_phase
validates_translation :description, length: { maximum: DESCRIPTION_MAX_LENGTH }
validates :budget, presence: true
validates :kind, presence: true, uniqueness: { scope: :budget }, inclusion: { in: ->(*) { PHASE_KINDS }}
validate :invalid_dates_range?
validate :prev_phase_dates_valid?
validate :next_phase_dates_valid?
after_save :adjust_date_ranges
scope :enabled, -> { where(enabled: true) }
scope :published, -> { enabled.where.not(kind: "drafting") }
PHASE_KINDS.each do |phase|
define_singleton_method(phase) { find_by(kind: phase) }
end
def self.kind_or_later(phase)
PHASE_KINDS[PHASE_KINDS.index(phase)..-1]
end
def name
Class.new.extend(ActionView::Helpers::TranslationHelper).t("budgets.phase.#{kind}")
end
def next_enabled_phase
next_phase&.enabled? ? next_phase : next_phase&.next_enabled_phase
end
def prev_enabled_phase
prev_phase&.enabled? ? prev_phase : prev_phase&.prev_enabled_phase
end
def invalid_dates_range?
if starts_at.present? && ends_at.present? && starts_at >= ends_at
errors.add(:starts_at, I18n.t("budgets.phases.errors.dates_range_invalid"))
end
end
def valuating_or_later?
in_phase_or_later?("valuating")
end
def publishing_prices_or_later?
in_phase_or_later?("publishing_prices")
end
def balloting_or_later?
in_phase_or_later?("balloting")
end
def current?
budget.current_phase == self
end
private
def adjust_date_ranges
if enabled?
next_enabled_phase&.update_column(:starts_at, ends_at)
prev_enabled_phase&.update_column(:ends_at, starts_at)
elsif saved_change_to_enabled?
next_enabled_phase&.update_column(:starts_at, starts_at)
end
end
def prev_phase_dates_valid?
if enabled? && starts_at.present? && prev_enabled_phase.present?
prev_enabled_phase.assign_attributes(ends_at: starts_at)
if prev_enabled_phase.invalid_dates_range?
phase_name = prev_enabled_phase.name
error = I18n.t("budgets.phases.errors.prev_phase_dates_invalid", phase_name: phase_name)
errors.add(:starts_at, error)
end
end
end
def next_phase_dates_valid?
if enabled? && ends_at.present? && next_enabled_phase.present?
next_enabled_phase.assign_attributes(starts_at: ends_at)
if next_enabled_phase.invalid_dates_range?
phase_name = next_enabled_phase.name
error = I18n.t("budgets.phases.errors.next_phase_dates_invalid", phase_name: phase_name)
errors.add(:ends_at, error)
end
end
end
def in_phase_or_later?(phase)
self.class.kind_or_later(phase).include?(kind)
end
end
end