aboutsummaryrefslogtreecommitdiffstats
path: root/app/models/calendar.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/calendar.rb')
-rw-r--r--app/models/calendar.rb117
1 files changed, 99 insertions, 18 deletions
diff --git a/app/models/calendar.rb b/app/models/calendar.rb
index 9c228ad69..d616bce10 100644
--- a/app/models/calendar.rb
+++ b/app/models/calendar.rb
@@ -3,18 +3,23 @@ class Calendar < ActiveRecord::Base
validates_presence_of :name, :short_name, :organisation
validates_uniqueness_of :short_name
- validate :date_not_in_date_ranges, :dates_uniqueness
after_initialize :init_dates_and_date_ranges
scope :contains_date, ->(date) { where('date ? = any (dates) OR date ? <@ any (date_ranges)', date, date) }
+ scope :shared, -> { where(shared: true) }
+ scope :by_organisation(org_id), -> { where(organisation_id: org_id) }
def init_dates_and_date_ranges
self.dates ||= []
self.date_ranges ||= []
end
+ def self.ransackable_scopes(auth_object = nil)
+ [:contains_date]
+ end
+ private_class_method :ransackable_scopes
class Period
include ActiveAttr::Model
@@ -23,7 +28,7 @@ class Calendar < ActiveRecord::Base
attribute :begin, type: Date
attribute :end, type: Date
- validates :begin, :end, presence: true
+ validates_presence_of :begin, :end
validate :check_end_greather_than_begin
def check_end_greather_than_begin
@@ -105,7 +110,7 @@ class Calendar < ActiveRecord::Base
periods.each do |period|
if period.intersect?(periods)
- period.errors.add(:base, I18n.t('calendars.errors.overlapped_period'))
+ period.errors.add(:base, I18n.t('calendars.errors.overlapped_periods'))
periods_are_valid = false
end
end
@@ -141,34 +146,110 @@ class Calendar < ActiveRecord::Base
private :clear_periods
- def self.new_from from
- from.dup.tap do |metadata|
- metadata.referential_id = nil
+### dates
+
+ class DateValue
+ include ActiveAttr::Model
+
+ attribute :id, type: Integer
+ attribute :value, type: Date
+
+ validates_presence_of :value
+
+ def self.from_date(index, date)
+ DateValue.new id: index, value: date
+ end
+
+ # Stuff required for coocon
+ def new_record?
+ !persisted?
end
+
+ def persisted?
+ id.present?
+ end
+
+ def mark_for_destruction
+ self._destroy = true
+ end
+
+ attribute :_destroy, type: Boolean
+ alias_method :marked_for_destruction?, :_destroy
end
- private
- def date_not_in_date_ranges
- errors.add(:dates, I18n.t('activerecord.errors.models.calendar.attributes.dates.date_in_date_ranges')) if dates && date_ranges && dates_and_date_ranges_overlap?
+ # Required by coocon
+ def build_date_value
+ DateValue.new
end
- def dates_and_date_ranges_overlap?
- overlap = false
- dates.each do |date|
+ def date_values
+ @date_values ||= init_date_values
+ end
+
+ def init_date_values
+ if dates
+ dates.each_with_index.map { |d, index| DateValue.from_date(index, d) }
+ else
+ []
+ end
+ end
+ private :init_date_values
+
+ validate :validate_date_values
+
+ def validate_date_values
+ date_values_are_valid = true
+
+ unless date_values.all?(&:valid?)
+ date_values_are_valid = false
+ end
+
+ 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|
- overlap = true if date_range.cover? date
+ if date_range.cover? date_value.value
+ 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
- overlap
+
+ unless date_values_are_valid
+ errors.add(:date_values, :invalid)
+ end
end
- def dates_uniqueness
- errors.add(:dates, I18n.t('activerecord.errors.models.calendar.attributes.dates.date_in_dates')) if dates && dates.length > dates.uniq.length
+ def date_values_attributes=(attributes = {})
+ @date_values = []
+ attributes.each do |index, date_value_attribute|
+ date_value = DateValue.new(date_value_attribute.merge(id: index))
+ @date_values << date_value unless date_value.marked_for_destruction?
+ end
+
+ dates_will_change!
end
- def self.ransackable_scopes(auth_object = nil)
- [:contains_date]
+ 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
class Range