workpattern 0.3.4 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +8 -4
- data/.travis.yml +18 -3
- data/CHANGELOG.md +88 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +19 -4
- data/LICENSE.txt +21 -0
- data/README.md +56 -80
- data/Rakefile +9 -0
- data/lib/workpattern.rb +31 -91
- data/lib/workpattern/clock.rb +21 -20
- data/lib/workpattern/constants.rb +72 -0
- data/lib/workpattern/day.rb +211 -290
- data/lib/workpattern/version.rb +2 -4
- data/lib/workpattern/week.rb +239 -321
- data/lib/workpattern/week_pattern.rb +144 -0
- data/lib/workpattern/workpattern.rb +156 -187
- data/workpattern.gemspec +32 -18
- metadata +40 -28
- data/CHANGELOG +0 -35
- data/config/website.yml +0 -2
- data/lib/workpattern/hour.rb +0 -209
- data/lib/workpattern/utility/base.rb +0 -32
- data/test/test_clock.rb +0 -31
- data/test/test_day.rb +0 -522
- data/test/test_helper.rb +0 -3
- data/test/test_hour.rb +0 -389
- data/test/test_week.rb +0 -362
- data/test/test_workpattern.rb +0 -276
- data/test/test_workpattern_module.rb +0 -93
@@ -0,0 +1,144 @@
|
|
1
|
+
module Workpattern
|
2
|
+
class WeekPattern
|
3
|
+
def initialize(work_pattern)
|
4
|
+
@work_pattern = work_pattern
|
5
|
+
end
|
6
|
+
|
7
|
+
def work_pattern
|
8
|
+
@work_pattern
|
9
|
+
end
|
10
|
+
|
11
|
+
def weeks
|
12
|
+
work_pattern.weeks
|
13
|
+
end
|
14
|
+
|
15
|
+
def from
|
16
|
+
work_pattern.from
|
17
|
+
end
|
18
|
+
|
19
|
+
def to
|
20
|
+
work_pattern.to
|
21
|
+
end
|
22
|
+
# Applys a working or resting pattern to the <tt>Workpattern</tt> object.
|
23
|
+
#
|
24
|
+
# The #resting and #working methods are convenience methods that call
|
25
|
+
# this with the appropriate <tt>:work_type</tt> already set.
|
26
|
+
#
|
27
|
+
# @param [Hash] opts the options used to apply a workpattern
|
28
|
+
# @option opts [Date] :start The first date to apply the pattern. Defaults
|
29
|
+
# to the <tt>start</tt> attribute.
|
30
|
+
# @option opts [Date] :finish The last date to apply the pattern. Defaults
|
31
|
+
# to the <tt>finish</tt> attribute.
|
32
|
+
# @option opts [DAYNAMES] :days The specific day or days the pattern will
|
33
|
+
# apply to.It defaults to <tt>:all</tt>
|
34
|
+
# @option opts [(#hour, #min)] :start_time The first time in the selected
|
35
|
+
# days to apply the pattern. Defaults to <tt>00:00</tt>.
|
36
|
+
# @option opts [(#hour, #min)] :finish_time The last time in the selected
|
37
|
+
# days to apply the pattern. Defaults to <tt>23:59</tt>.
|
38
|
+
# @option opts [(WORK_TYPE || REST_TYPE)] :work_type Either working or resting.
|
39
|
+
# Defaults to working.
|
40
|
+
# @see #working
|
41
|
+
# @see #resting
|
42
|
+
#
|
43
|
+
def workpattern(opts = {}, persist = nil)
|
44
|
+
args = all_workpattern_options(opts)
|
45
|
+
|
46
|
+
persist.store(name: @name, workpattern: args) if !persist.nil?
|
47
|
+
|
48
|
+
args = standardise_args(args)
|
49
|
+
|
50
|
+
upd_start = work_pattern.to_utc(args[:start])
|
51
|
+
upd_finish = work_pattern.to_utc(args[:finish])
|
52
|
+
|
53
|
+
while upd_start <= upd_finish
|
54
|
+
|
55
|
+
current_wp = work_pattern.find_weekpattern(upd_start)
|
56
|
+
|
57
|
+
if current_wp.start == upd_start
|
58
|
+
if current_wp.finish > upd_finish
|
59
|
+
clone_wp = fetch_updatable_week_pattern(current_wp,
|
60
|
+
upd_finish + DAY,
|
61
|
+
current_wp.finish,
|
62
|
+
upd_start,
|
63
|
+
upd_finish)
|
64
|
+
update_and_store_week_pattern(clone_wp, args)
|
65
|
+
upd_start = upd_finish + DAY
|
66
|
+
else # (current_wp.finish == upd_finish)
|
67
|
+
current_wp.workpattern(args[:days], args[:from_time],
|
68
|
+
args[:to_time], args[:work_type])
|
69
|
+
upd_start = current_wp.finish + DAY
|
70
|
+
end
|
71
|
+
else
|
72
|
+
clone_wp = fetch_updatable_week_pattern(current_wp, current_wp.start,
|
73
|
+
upd_start - DAY, upd_start)
|
74
|
+
if clone_wp.finish > upd_finish
|
75
|
+
after_wp = fetch_updatable_week_pattern(clone_wp,
|
76
|
+
upd_start,
|
77
|
+
upd_finish,
|
78
|
+
upd_finish + DAY)
|
79
|
+
weeks << after_wp
|
80
|
+
end
|
81
|
+
update_and_store_week_pattern(clone_wp, args)
|
82
|
+
upd_start = clone_wp.finish + DAY
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def all_workpattern_options(opts)
|
90
|
+
|
91
|
+
args = { start: from, finish: to, days: :all,
|
92
|
+
from_time: FIRST_TIME_IN_DAY, to_time: LAST_TIME_IN_DAY,
|
93
|
+
work_type: WORK_TYPE }
|
94
|
+
|
95
|
+
args.merge! opts
|
96
|
+
end
|
97
|
+
|
98
|
+
def standardise_args(args)
|
99
|
+
|
100
|
+
args[:start] = dmy_date(args[:start])
|
101
|
+
args[:finish] = dmy_date(args[:finish])
|
102
|
+
|
103
|
+
args
|
104
|
+
end
|
105
|
+
|
106
|
+
# Clones the supplied Week Pattern then changes the dates on it
|
107
|
+
# The newly cloned Week pattern dates are also changed and it is
|
108
|
+
# returned by this method
|
109
|
+
#
|
110
|
+
def fetch_updatable_week_pattern(keep_week, keep_start, keep_finish,
|
111
|
+
change_start, change_finish = nil)
|
112
|
+
change_week = keep_week.duplicate
|
113
|
+
adjust_date_range(keep_week, keep_start, keep_finish)
|
114
|
+
if change_finish.nil?
|
115
|
+
adjust_date_range(change_week, change_start, change_week.finish)
|
116
|
+
else
|
117
|
+
adjust_date_range(change_week, change_start, change_finish)
|
118
|
+
end
|
119
|
+
change_week
|
120
|
+
end
|
121
|
+
|
122
|
+
def update_and_store_week_pattern(week_pattern, args)
|
123
|
+
week_pattern.workpattern(args[:days], args[:from_time],
|
124
|
+
args[:to_time], args[:work_type])
|
125
|
+
weeks << week_pattern
|
126
|
+
end
|
127
|
+
|
128
|
+
def adjust_date_range(week_pattern, start_date, finish_date)
|
129
|
+
week_pattern.start = start_date
|
130
|
+
week_pattern.finish = finish_date
|
131
|
+
end
|
132
|
+
|
133
|
+
# Strips off hours, minutes, seconds etc from a supplied <tt>Date</tt> or
|
134
|
+
# <tt>DateTime</tt>
|
135
|
+
#
|
136
|
+
# @param [DateTime] date
|
137
|
+
# @return [DateTime] with zero hours, minutes, seconds and so forth.
|
138
|
+
#
|
139
|
+
def dmy_date(date)
|
140
|
+
Time.gm(date.year, date.month, date.day)
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
end
|
@@ -1,19 +1,28 @@
|
|
1
1
|
module Workpattern
|
2
2
|
require 'set'
|
3
|
-
|
4
|
-
|
5
|
-
#
|
3
|
+
require 'tzinfo'
|
4
|
+
|
5
|
+
# Represents the working and resting periods across a given number of whole
|
6
|
+
# years. Each <tt>Workpattern</tt>has a unique name so it can be easily
|
7
|
+
# identified amongst all the other <tt>Workpattern</tt> objects.
|
6
8
|
#
|
7
|
-
# This and the <tt>Clock</tt> class are the only two that should be
|
9
|
+
# This and the <tt>Clock</tt> class are the only two that should be
|
10
|
+
# referenced by calling applications when
|
8
11
|
# using this gem.
|
9
12
|
#
|
10
|
-
# @since 0.2.0
|
11
|
-
#
|
12
13
|
class Workpattern
|
13
|
-
|
14
|
+
|
14
15
|
# Holds collection of <tt>Workpattern</tt> objects
|
15
|
-
@@workpatterns =
|
16
|
-
|
16
|
+
@@workpatterns = {}
|
17
|
+
|
18
|
+
def self.workpatterns
|
19
|
+
@@workpatterns
|
20
|
+
end
|
21
|
+
|
22
|
+
def workpatterns
|
23
|
+
@@workpatterns
|
24
|
+
end
|
25
|
+
|
17
26
|
# @!attribute [r] name
|
18
27
|
# Name given to the <tt>Workpattern</tt>
|
19
28
|
# @!attribute [r] base
|
@@ -28,83 +37,101 @@ module Workpattern
|
|
28
37
|
# The <tt>Week</tt> objects that make up this workpattern
|
29
38
|
#
|
30
39
|
attr_reader :name, :base, :span, :from, :to, :weeks
|
31
|
-
|
40
|
+
|
32
41
|
# Class for handling persistence in user's own way
|
33
42
|
#
|
34
43
|
def self.persistence_class=(klass)
|
35
|
-
@@
|
44
|
+
@@persist = klass
|
36
45
|
end
|
37
46
|
|
38
47
|
def self.persistence?
|
39
|
-
@@
|
48
|
+
@@persist ||= nil
|
49
|
+
end
|
50
|
+
|
51
|
+
# Holds local timezone info
|
52
|
+
@@tz = nil
|
53
|
+
|
54
|
+
# Converts a date like object into utc
|
55
|
+
#
|
56
|
+
def to_utc(date)
|
57
|
+
date.to_time.utc
|
58
|
+
end
|
59
|
+
# Converts a date like object into local time
|
60
|
+
#
|
61
|
+
def to_local(date)
|
62
|
+
date.to_time.getgm
|
63
|
+
end
|
64
|
+
|
65
|
+
# Retrieves the local timezone
|
66
|
+
def timezone
|
67
|
+
@@tz || @@tz = TZInfo::Timezone.get(Time.now.zone)
|
40
68
|
end
|
41
69
|
|
42
70
|
# The new <tt>Workpattern</tt> object is created with all working minutes.
|
43
71
|
#
|
44
72
|
# @param [String] name Every workpattern has a unique name
|
45
73
|
# @param [Integer] base Workpattern starts on the 1st January of this year.
|
46
|
-
# @param [Integer] span Workpattern spans this number of years ending on
|
74
|
+
# @param [Integer] span Workpattern spans this number of years ending on
|
75
|
+
# 31st December.
|
47
76
|
# @raise [NameError] if the given name already exists
|
48
77
|
#
|
49
|
-
def initialize(name=DEFAULT_NAME,base=DEFAULT_BASE_YEAR,span=DEFAULT_SPAN)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
if span < 0
|
54
|
-
offset = span.abs - 1
|
55
|
-
else
|
56
|
-
offset = 0
|
78
|
+
def initialize(name = DEFAULT_NAME, base = DEFAULT_BASE_YEAR, span = DEFAULT_SPAN)
|
79
|
+
if workpatterns.key?(name)
|
80
|
+
raise(NameError, "Workpattern '#{name}' already exists and can't be created again")
|
57
81
|
end
|
58
|
-
|
82
|
+
offset = span < 0 ? span.abs - 1 : 0
|
83
|
+
|
59
84
|
@name = name
|
60
85
|
@base = base
|
61
86
|
@span = span
|
62
|
-
@from =
|
63
|
-
@to =
|
87
|
+
@from = Time.gm(@base.abs - offset)
|
88
|
+
@to = Time.gm(@from.year + @span.abs - 1, 12, 31, 23, 59)
|
64
89
|
@weeks = SortedSet.new
|
65
|
-
@weeks << Week.new(@from
|
66
|
-
|
67
|
-
|
68
|
-
|
90
|
+
@weeks << Week.new(@from, @to)
|
91
|
+
|
92
|
+
workpatterns[@name] = self
|
93
|
+
@week_pattern = WeekPattern.new(self)
|
69
94
|
end
|
70
|
-
|
95
|
+
|
96
|
+
def week_pattern
|
97
|
+
@week_pattern
|
98
|
+
end
|
99
|
+
|
71
100
|
# Deletes all <tt>Workpattern</tt> objects
|
72
101
|
#
|
73
102
|
def self.clear
|
74
|
-
|
103
|
+
workpatterns.clear
|
75
104
|
end
|
76
|
-
|
105
|
+
|
77
106
|
# Returns an Array containing all the <tt>Workpattern</tt> objects
|
78
107
|
# @return [Array] all <tt>Workpattern</tt> objects
|
79
|
-
#
|
108
|
+
#
|
80
109
|
def self.to_a
|
81
|
-
|
110
|
+
workpatterns.to_a
|
82
111
|
end
|
83
|
-
|
112
|
+
|
84
113
|
# Returns the specific named <tt>Workpattern</tt>
|
85
114
|
# @param [String] name of the required <tt>Workpattern</tt>
|
86
|
-
# @raise [NameError] if a <tt>Workpattern</tt> of the supplied name does not
|
115
|
+
# @raise [NameError] if a <tt>Workpattern</tt> of the supplied name does not
|
116
|
+
# exist
|
87
117
|
#
|
88
118
|
def self.get(name)
|
89
|
-
return
|
119
|
+
return workpatterns[name] if workpatterns.key?(name)
|
90
120
|
raise(NameError, "Workpattern '#{name}' doesn't exist so can't be retrieved")
|
91
121
|
end
|
92
|
-
|
122
|
+
|
93
123
|
# Deletes the specific named <tt>Workpattern</tt>
|
94
124
|
# @param [String] name of the required <tt>Workpattern</tt>
|
95
|
-
# @return [Boolean] true if the named <tt>Workpattern</tt> existed or false
|
125
|
+
# @return [Boolean] true if the named <tt>Workpattern</tt> existed or false
|
126
|
+
# if it doesn't
|
96
127
|
#
|
97
128
|
def self.delete(name)
|
98
|
-
|
99
|
-
return false
|
100
|
-
else
|
101
|
-
return true
|
102
|
-
end
|
129
|
+
workpatterns.delete(name).nil? ? false : true
|
103
130
|
end
|
104
|
-
|
131
|
+
|
105
132
|
# Applys a working or resting pattern to the <tt>Workpattern</tt> object.
|
106
133
|
#
|
107
|
-
# The #resting and #working methods are convenience methods that call
|
134
|
+
# The #resting and #working methods are convenience methods that call
|
108
135
|
# this with the appropriate <tt>:work_type</tt> already set.
|
109
136
|
#
|
110
137
|
# @param [Hash] opts the options used to apply a workpattern
|
@@ -112,105 +139,78 @@ module Workpattern
|
|
112
139
|
# to the <tt>start</tt> attribute.
|
113
140
|
# @option opts [Date] :finish The last date to apply the pattern. Defaults
|
114
141
|
# to the <tt>finish</tt> attribute.
|
115
|
-
# @option opts [DAYNAMES] :days The specific day or days the pattern will
|
116
|
-
#
|
117
|
-
# @option opts [(#hour, #min)] :start_time The first time in the selected
|
118
|
-
#
|
119
|
-
# @option opts [(#hour, #min)] :finish_time The last time in the selected
|
120
|
-
#
|
121
|
-
# @option opts [(
|
142
|
+
# @option opts [DAYNAMES] :days The specific day or days the pattern will
|
143
|
+
# apply to.It defaults to <tt>:all</tt>
|
144
|
+
# @option opts [(#hour, #min)] :start_time The first time in the selected
|
145
|
+
# days to apply the pattern. Defaults to <tt>00:00</tt>.
|
146
|
+
# @option opts [(#hour, #min)] :finish_time The last time in the selected
|
147
|
+
# days to apply the pattern. Defaults to <tt>23:59</tt>.
|
148
|
+
# @option opts [(WORK_TYPE || REST_TYPE)] :work_type Either working or resting.
|
149
|
+
# Defaults to working.
|
122
150
|
# @see #working
|
123
151
|
# @see #resting
|
124
152
|
#
|
125
|
-
def workpattern(opts={})
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
args.merge! opts
|
132
|
-
|
133
|
-
@@persistence.store( name: @name, workpattern: args) if self.class.persistence?
|
134
|
-
|
135
|
-
args[:start] = dmy_date(args[:start])
|
136
|
-
args[:finish] = dmy_date(args[:finish])
|
137
|
-
from_time = hhmn_date(args[:from_time])
|
138
|
-
to_time = hhmn_date(args[:to_time])
|
139
|
-
|
140
|
-
upd_start=args[:start]
|
141
|
-
upd_finish=args[:finish]
|
142
|
-
while (upd_start <= upd_finish)
|
143
|
-
|
144
|
-
current_wp=find_weekpattern(upd_start)
|
145
|
-
if (current_wp.start == upd_start)
|
146
|
-
if (current_wp.finish > upd_finish)
|
147
|
-
clone_wp=clone_and_adjust_current_wp(current_wp, upd_finish+1,current_wp.finish,upd_start,upd_finish)
|
148
|
-
clone_wp.workpattern(args[:days],from_time,to_time,args[:work_type])
|
149
|
-
@weeks<< clone_wp
|
150
|
-
upd_start=upd_finish+1
|
151
|
-
else # (current_wp.finish == upd_finish)
|
152
|
-
current_wp.workpattern(args[:days],from_time,to_time,args[:work_type])
|
153
|
-
upd_start=current_wp.finish + 1
|
154
|
-
end
|
155
|
-
else
|
156
|
-
clone_wp=clone_and_adjust_current_wp(current_wp, current_wp.start,upd_start-1,upd_start)
|
157
|
-
if (clone_wp.finish <= upd_finish)
|
158
|
-
clone_wp.workpattern(args[:days],from_time,to_time,args[:work_type])
|
159
|
-
@weeks<< clone_wp
|
160
|
-
upd_start=clone_wp.finish+1
|
161
|
-
else
|
162
|
-
after_wp=clone_and_adjust_current_wp(clone_wp, upd_start,upd_finish,upd_finish+1)
|
163
|
-
@weeks<< after_wp
|
164
|
-
clone_wp.workpattern(args[:days],from_time,to_time,args[:work_type])
|
165
|
-
@weeks<< clone_wp
|
166
|
-
upd_start=clone_wp.finish+1
|
167
|
-
end
|
168
|
-
end
|
153
|
+
def workpattern(opts = {})
|
154
|
+
if self.class.persistence?
|
155
|
+
week_pattern.workpattern(opts, @@persistence)
|
156
|
+
else
|
157
|
+
week_pattern.workpattern(opts)
|
169
158
|
end
|
170
159
|
end
|
171
|
-
|
172
|
-
# Convenience method that calls <tt>#workpattern</tt> with the
|
160
|
+
|
161
|
+
# Convenience method that calls <tt>#workpattern</tt> with the
|
162
|
+
# <tt>:work_type</tt> specified as resting.
|
173
163
|
#
|
174
164
|
# @see #workpattern
|
175
165
|
#
|
176
|
-
def resting(args={})
|
177
|
-
args[:work_type]=
|
166
|
+
def resting(args = {})
|
167
|
+
args[:work_type] = REST_TYPE
|
178
168
|
workpattern(args)
|
179
169
|
end
|
180
|
-
|
181
|
-
# Convenience method that calls <tt>#workpattern</tt> with the
|
170
|
+
|
171
|
+
# Convenience method that calls <tt>#workpattern</tt> with the
|
172
|
+
# <tt>:work_type</tt> specified as working.
|
182
173
|
#
|
183
174
|
# @see #workpattern
|
184
175
|
#
|
185
|
-
def working(args={})
|
186
|
-
args[:work_type]=
|
176
|
+
def working(args = {})
|
177
|
+
args[:work_type] = WORK_TYPE
|
187
178
|
workpattern(args)
|
188
179
|
end
|
189
|
-
|
190
|
-
# Calculates the resulting date when the <tt>duration</tt> in minutes
|
191
|
-
#
|
192
|
-
#
|
180
|
+
|
181
|
+
# Calculates the resulting date when the <tt>duration</tt> in minutes
|
182
|
+
# is added to the <tt>start</tt> date.
|
183
|
+
# The <tt>duration</tt> is always in whole minutes and subtracts from
|
184
|
+
# <tt>start</tt> when it is a negative number.
|
193
185
|
#
|
194
186
|
# @param [DateTime] start date to add or subtract minutes
|
195
187
|
# @param [Integer] duration in minutes to add or subtract to date
|
196
|
-
# @return [DateTime] the date when <tt>duration</tt> is added to
|
188
|
+
# @return [DateTime] the date when <tt>duration</tt> is added to
|
189
|
+
# <tt>start</tt>
|
197
190
|
#
|
198
|
-
def calc(start,duration)
|
199
|
-
return start if duration==0
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
191
|
+
def calc(start, duration)
|
192
|
+
return start if duration == 0
|
193
|
+
a_day = SAME_DAY
|
194
|
+
|
195
|
+
utc_start = to_utc(start)
|
196
|
+
|
197
|
+
while duration != 0
|
198
|
+
|
199
|
+
if a_day == PREVIOUS_DAY
|
200
|
+
utc_start -= DAY
|
201
|
+
a_day = SAME_DAY
|
202
|
+
utc_start = Time.gm(utc_start.year, utc_start.month, utc_start.day,LAST_TIME_IN_DAY.hour, LAST_TIME_IN_DAY.min)
|
203
|
+
week = find_weekpattern(utc_start)
|
204
|
+
|
205
|
+
if week.working?(utc_start)
|
206
|
+
duration += 1
|
207
|
+
end
|
208
|
+
else
|
209
|
+
week = find_weekpattern(utc_start)
|
210
|
+
end
|
211
|
+
utc_start, duration, a_day = week.calc(utc_start, duration, a_day)
|
212
|
+
end
|
213
|
+
to_local(utc_start)
|
214
214
|
end
|
215
215
|
|
216
216
|
# Returns true if the given minute is working and false if it is resting.
|
@@ -219,85 +219,54 @@ module Workpattern
|
|
219
219
|
# @return [Boolean] true if working and false if resting
|
220
220
|
#
|
221
221
|
def working?(start)
|
222
|
-
|
223
|
-
|
224
|
-
|
222
|
+
utc_start = to_utc(start)
|
223
|
+
find_weekpattern(utc_start).working?(utc_start)
|
224
|
+
end
|
225
|
+
|
225
226
|
# Returns number of minutes between two dates
|
226
227
|
#
|
227
228
|
# @param [DateTime] start is the date to start from
|
228
229
|
# @param [DateTime] finish is the date to end with
|
229
230
|
# @return [Integer] number of minutes between the two dates
|
230
231
|
#
|
231
|
-
def diff(start,finish)
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
232
|
+
def diff(start, finish)
|
233
|
+
utc_start = to_utc(start)
|
234
|
+
utc_finish = to_utc(finish)
|
235
|
+
utc_start, utc_finish = utc_finish, utc_start if utc_finish < utc_start
|
236
|
+
minutes = 0
|
237
|
+
|
238
|
+
while utc_start != utc_finish
|
239
|
+
week = find_weekpattern(utc_start)
|
240
|
+
r_minutes, utc_start = week.diff(utc_start, utc_finish)
|
241
|
+
minutes += r_minutes
|
239
242
|
end
|
240
|
-
|
241
|
-
end
|
242
|
-
|
243
|
-
private
|
244
|
-
|
243
|
+
minutes
|
244
|
+
end
|
245
|
+
|
245
246
|
# Retrieve the correct <tt>Week</tt> pattern for the supplied date.
|
246
247
|
#
|
247
|
-
# If the supplied <tt>date</tt> is outside the span of the
|
248
|
-
# then it returns an all working <tt>Week</tt>
|
249
|
-
#
|
248
|
+
# If the supplied <tt>date</tt> is outside the span of the
|
249
|
+
# <tt>Workpattern</tt> object then it returns an all working <tt>Week</tt>
|
250
|
+
# object for the calculation.
|
251
|
+
#
|
250
252
|
# @param [DateTime] date whose containing <tt>Week</tt> pattern is required
|
251
|
-
# @return [Week] <tt>Week</tt> object that includes the supplied
|
253
|
+
# @return [Week] <tt>Week</tt> object that includes the supplied
|
254
|
+
# <tt>date</tt> in it's range
|
252
255
|
#
|
253
256
|
def find_weekpattern(date)
|
254
257
|
# find the pattern that fits the date
|
255
258
|
#
|
256
|
-
if date
|
257
|
-
result = Week.new(
|
258
|
-
elsif date
|
259
|
-
result = Week.new(@to+MINUTE,
|
259
|
+
if date < @from
|
260
|
+
result = Week.new(Time.at(0), @from - MINUTE, WORK_TYPE)
|
261
|
+
elsif date > to
|
262
|
+
result = Week.new(@to + MINUTE, Time.new(9999), WORK_TYPE)
|
260
263
|
else
|
261
|
-
|
262
|
-
date = DateTime.new(date.year,date.month,date.day)
|
263
264
|
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
end
|
268
|
-
|
269
|
-
# Strips off hours, minutes, seconds and so forth from a supplied <tt>Date</tt> or
|
270
|
-
# <tt>DateTime</tt>
|
271
|
-
#
|
272
|
-
# @param [DateTime] date
|
273
|
-
# @return [DateTime] with zero hours, minutes, seconds and so forth.
|
274
|
-
#
|
275
|
-
def dmy_date(date)
|
276
|
-
return DateTime.new(date.year,date.month,date.day)
|
277
|
-
end
|
278
|
-
|
279
|
-
# Extract the time into a <tt>Clock</tt> object
|
280
|
-
#
|
281
|
-
# @param [DateTime] date
|
282
|
-
# @return [Clock]
|
283
|
-
def hhmn_date(date)
|
284
|
-
return Clock.new(date.hour,date.min)
|
285
|
-
end
|
286
|
-
|
287
|
-
private
|
288
|
-
|
289
|
-
# Handles cloning of Week Pattern including date adjustments
|
290
|
-
#
|
291
|
-
def clone_and_adjust_current_wp(current_wp, current_start,current_finish,clone_start,clone_finish=nil)
|
292
|
-
clone_wp=current_wp.duplicate
|
293
|
-
current_wp.adjust(current_start,current_finish)
|
294
|
-
if (clone_finish.nil?)
|
295
|
-
clone_wp.adjust(clone_start,clone_wp.finish)
|
296
|
-
else
|
297
|
-
clone_wp.adjust(clone_start,clone_finish)
|
265
|
+
date = Time.gm(date.year, date.month, date.day)
|
266
|
+
|
267
|
+
result = @weeks.find { |week| week.start <= date && week.finish >= date }
|
298
268
|
end
|
299
|
-
|
269
|
+
result
|
300
270
|
end
|
301
271
|
end
|
302
272
|
end
|
303
|
-
|