af83/chouette-core

View on GitHub
app/models/concerns/date_support.rb

Summary

Maintainability
A
2 hrs
Test Coverage
module DateSupport
  extend ActiveSupport::Concern

  included do
    after_initialize :init_dates

    def init_dates
      self.dates ||= []
    end

    ### Calendar::DateValue
    # Required by coocon
    def build_date_value
      Calendar::DateValue.new
    end

    def date_values
      @date_values ||= init_date_values
    end

    def init_date_values
      if dates
        dates.each_with_index.map { |d, index| Calendar::DateValue.from_date(index, d) }
      else
        []
      end
    end
    private :init_date_values

    validate :validate_date_values

    def validate_date_values
      date_values_are_valid = date_values.all?(&:valid?)

      date_values.each do |date_value|
        if date_values.count { |d| d.value == date_value.value } > 1
          date_value.errors.add(:base, I18n.t('activerecord.errors.models.calendar.attributes.dates.date_in_dates'))
          date_values_are_valid = false
        end
        date_ranges.each do |date_range|
          if date_range.cover?(date_value.value)
            excluded_day = self.respond_to?(:valid_day?) && !self.valid_day?(date_value.value.wday)
            unless excluded_day
              date_value.errors.add(:base, I18n.t('activerecord.errors.models.calendar.attributes.dates.date_in_date_ranges'))
              date_values_are_valid = false
            end
          end
        end
      end

      unless date_values_are_valid
        errors.add(:date_values, :invalid)
      end
    end

    def date_values_attributes=(attributes = {})
      @date_values = []
      attributes.each do |index, date_value_attribute|
        date_value_attribute['value'] = flatten_date_array(date_value_attribute, 'value')
        date_value = Calendar::DateValue.new(date_value_attribute.merge(id: index))
        @date_values << date_value unless date_value.marked_for_destruction?
      end

      dates_will_change!
    end

    before_validation :fill_dates

    def fill_dates
      if @date_values
        self.dates = @date_values.map(&:value).compact.sort
      end
    end

    after_save :clear_date_values

    def clear_date_values
      @date_values = nil
    end

    private :clear_date_values
  end
end