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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
module TimetableSupport
extend ActiveSupport::Concern
def presenter
@presenter ||= ::TimeTablePresenter.new( self)
end
def periods_max_date
return nil if self.periods.empty?
min_start = self.periods.map(&:period_start).compact.min
max_end = self.periods.map(&:period_end).compact.max
result = nil
if max_end && min_start
max_end.downto( min_start) do |date|
if self.valid_days.include?(date.cwday) && !self.excluded_date?(date)
result = date
break
end
end
end
result
end
def periods_min_date
return nil if self.periods.empty?
min_start = self.periods.map(&:period_start).compact.min
max_end = self.periods.map(&:period_end).compact.max
result = nil
if max_end && min_start
min_start.upto(max_end) do |date|
if self.valid_days.include?(date.cwday) && !self.excluded_date?(date)
result = date
break
end
end
end
result
end
def bounding_dates
bounding_min = self.all_dates.select{|d| d.in_out}.map(&:date).compact.min
bounding_max = self.all_dates.select{|d| d.in_out}.map(&:date).compact.max
unless self.periods.empty?
bounding_min = periods_min_date if periods_min_date &&
(bounding_min.nil? || (periods_min_date < bounding_min))
bounding_max = periods_max_date if periods_max_date &&
(bounding_max.nil? || (bounding_max < periods_max_date))
end
[bounding_min, bounding_max].compact
end
def month_inspect(date)
(date.beginning_of_month..date.end_of_month).map do |d|
{
day: I18n.l(d, format: '%A'),
date: d.to_s,
wday: d.wday,
wnumber: d.strftime("%W").to_s,
mday: d.mday,
include_date: include_in_dates?(d),
excluded_date: excluded_date?(d)
}
end
end
def include_in_dates?(day)
self.dates.any?{ |d| d.date === day && d.in_out == true }
end
def excluded_date?(day)
self.dates.any?{ |d| d.date === day && d.in_out == false }
end
def include_in_overlap_dates?(day)
return false if self.excluded_date?(day)
self.all_dates.any?{ |d| d.date === day} \
&& self.periods.any?{ |period| period.period_start <= day && day <= period.period_end && valid_days.include?(day.cwday) }
end
def include_in_periods?(day)
self.periods.any?{ |period| period.period_start <= day &&
day <= period.period_end &&
valid_days.include?(day.cwday) &&
! excluded_date?(day) }
end
def state_update_periods state_periods
state_periods.each do |item|
period = self.find_period_by_id(item['id']) if item['id']
next if period && item['deleted'] && self.destroy_period(period)
period ||= self.build_period
period.period_start = Date.parse(item['period_start'])
period.period_end = Date.parse(item['period_end'])
period.save if period.is_a?(ActiveRecord::Base) && period.changed?
item['id'] = period.id
end
state_periods.delete_if {|item| item['deleted']}
end
def state_update state
update_attributes(self.class.state_permited_attributes(state))
self.tag_list = state['tags'].collect{|t| t['name']}.join(', ') if state['tags']
self.calendar_id = nil if self.respond_to?(:calendar_id) && !state['calendar']
days = state['day_types'].split(',')
Date::DAYNAMES.map(&:underscore).each do |name|
prefix = human_attribute_name(name).first(2)
send("#{name}=", days.include?(prefix))
end
cmonth = Date.parse(state['current_periode_range'])
state['current_month'].each do |d|
date = Date.parse(d['date'])
checked = d['include_date'] || d['excluded_date']
in_out = d['include_date'] ? true : false
date_id = saved_dates.key(date)
time_table_date = self.find_date_by_id(date_id) if date_id
next if !checked && !time_table_date
# Destroy date if no longer checked
next if !checked && destroy_date(time_table_date)
# Create new date
unless time_table_date
time_table_date = self.create_date in_out: in_out, date: date
end
# Update in_out
self.update_in_out time_table_date, in_out
end
self.state_update_periods state['time_table_periods']
self.save
end
end
|