Class: Workpattern::Workpattern

Inherits:
Object
  • Object
show all
Defined in:
lib/workpattern/workpattern.rb

Overview

Represents the working and resting periods across a given number of whole years. Each Workpattern has a unique name so it can be easily identified amongst all the other Workpattern objects.

This and the Clock class are the only two that should be referenced by calling applications when using this gem.

Since:

  • 0.2.0

Constant Summary collapse

@@workpatterns =

Holds collection of Workpattern objects

Since:

  • 0.2.0

Hash.new()

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name = DEFAULT_NAME, base = DEFAULT_BASE_YEAR, span = DEFAULT_SPAN) ⇒ Workpattern

The new Workpattern object is created with all working minutes.

Raises:

  • (NameError)

    if the given name already exists

Since:

  • 0.2.0


49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/workpattern/workpattern.rb', line 49

def initialize(name=DEFAULT_NAME,base=DEFAULT_BASE_YEAR,span=DEFAULT_SPAN)

  raise(NameError, "Workpattern '#{name}' already exists and can't be created again") if @@workpatterns.key?(name) 
    
  span < 0 ? offset = span.abs - 1 : offset = 0

  @name = name
  @base = base
  @span = span
  @from = DateTime.new(base.abs - offset)
  @to = DateTime.new(from.year + span.abs - 1,12,31,23,59)
  @weeks = SortedSet.new
  @weeks << Week.new(from,to,1)
       
  @@workpatterns[name]=self
end

Instance Attribute Details

#baseObject (readonly)

Starting year


30
# File 'lib/workpattern/workpattern.rb', line 30

attr_reader :name, :base, :span, :from, :to, :weeks

#fromObject (readonly)

First date in Workpattern


30
# File 'lib/workpattern/workpattern.rb', line 30

attr_reader :name, :base, :span, :from, :to, :weeks

#nameObject (readonly)

Name given to the Workpattern


30
31
32
# File 'lib/workpattern/workpattern.rb', line 30

def name
  @name
end

#spanObject (readonly)

Number of years


30
# File 'lib/workpattern/workpattern.rb', line 30

attr_reader :name, :base, :span, :from, :to, :weeks

#toObject (readonly)

Last date in Workpattern


30
# File 'lib/workpattern/workpattern.rb', line 30

attr_reader :name, :base, :span, :from, :to, :weeks

#weeksObject (readonly)

Since:

  • 0.2.0


30
# File 'lib/workpattern/workpattern.rb', line 30

attr_reader :name, :base, :span, :from, :to, :weeks

Class Method Details

.clearObject

Deletes all Workpattern objects

Since:

  • 0.2.0


68
69
70
# File 'lib/workpattern/workpattern.rb', line 68

def self.clear
  @@workpatterns.clear
end

.delete(name) ⇒ Boolean

Deletes the specific named Workpattern

Since:

  • 0.2.0


92
93
94
# File 'lib/workpattern/workpattern.rb', line 92

def self.delete(name)
  @@workpatterns.delete(name).nil? ? false : true
end

.get(name) ⇒ Object

Returns the specific named Workpattern

Raises:

  • (NameError)

    if a Workpattern of the supplied name does not exist

Since:

  • 0.2.0


83
84
85
86
# File 'lib/workpattern/workpattern.rb', line 83

def self.get(name)
  return @@workpatterns[name] if @@workpatterns.key?(name) 
  raise(NameError, "Workpattern '#{name}' doesn't exist so can't be retrieved")
end

.persistence?Boolean

Since:

  • 0.2.0


38
39
40
# File 'lib/workpattern/workpattern.rb', line 38

def self.persistence?
  @@persistence ||= nil
end

.persistence_class=(klass) ⇒ Object

Class for handling persistence in user's own way

Since:

  • 0.2.0


34
35
36
# File 'lib/workpattern/workpattern.rb', line 34

def self.persistence_class=(klass)
  @@persistence = klass
end

.to_aArray

Returns an Array containing all the Workpattern objects

Since:

  • 0.2.0


75
76
77
# File 'lib/workpattern/workpattern.rb', line 75

def self.to_a
  @@workpatterns.to_a
end

Instance Method Details

#calc(start, duration) ⇒ DateTime

Calculates the resulting date when the duration in minutes is added to the start date. The duration is always in whole minutes and subtracts from start when it is a negative number.

Since:

  • 0.2.0


187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/workpattern/workpattern.rb', line 187

def calc(start,duration)
  return start if duration==0 
  midnight=false
  
  while (duration !=0)
    week=find_weekpattern(start)
    if (week.start==start) && (duration<0) && (!midnight)
      start=start.prev_day
      week=find_weekpattern(start)
      midnight=true
    end    
    
    start,duration,midnight=week.calc(start,duration,midnight)
  end 
  
  return start
end

#diff(start, finish) ⇒ Integer

Returns number of minutes between two dates

Since:

  • 0.2.0


220
221
222
223
224
225
226
227
228
229
230
# File 'lib/workpattern/workpattern.rb', line 220

def diff(start,finish)

  start,finish=finish,start if finish<start
  duration=0
  while(start!=finish) do
    week=find_weekpattern(start)
    result_duration,start=week.diff(start,finish)
    duration+=result_duration
  end
  return duration
end

#resting(args = {}) ⇒ Object

Convenience method that calls #workpattern with the :work_type specified as resting.

See Also:

Since:

  • 0.2.0


165
166
167
168
# File 'lib/workpattern/workpattern.rb', line 165

def resting(args={})
  args[:work_type]=REST
  workpattern(args)
end

#working(args = {}) ⇒ Object

Convenience method that calls #workpattern with the :work_type specified as working.

See Also:

Since:

  • 0.2.0


174
175
176
177
# File 'lib/workpattern/workpattern.rb', line 174

def working(args={})
  args[:work_type]=WORK
  workpattern(args)
end

#working?(start) ⇒ Boolean

Returns true if the given minute is working and false if it is resting.

Since:

  • 0.2.0


210
211
212
# File 'lib/workpattern/workpattern.rb', line 210

def working?(start)
  return find_weekpattern(start).working?(start)
end

#workpattern(opts = {}) ⇒ Object

Applys a working or resting pattern to the Workpattern object.

The #resting and #working methods are convenience methods that call this with the appropriate :work_type already set.

Options Hash (opts):

  • :start (Date)

    The first date to apply the pattern. Defaults to the start attribute.

  • :finish (Date)

    The last date to apply the pattern. Defaults to the finish attribute.

  • :days (DAYNAMES)

    The specific day or days the pattern will apply to. It defaults to :all

  • :start_time ((#hour, #min))

    The first time in the selected days to apply the pattern. Defaults to 00:00.

  • :finish_time ((#hour, #min))

    The last time in the selected days to apply the pattern. Defaults to 23:59.

  • :work_type ((WORK || REST))

    Either working or resting. Defaults to working.

See Also:

Since:

  • 0.2.0


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
150
151
152
153
154
155
156
157
158
159
# File 'lib/workpattern/workpattern.rb', line 116

def workpattern(opts={})

  args={:start => from, :finish => to, :days => :all,
      :from_time => FIRST_TIME_IN_DAY, :to_time => LAST_TIME_IN_DAY,
      :work_type => WORK}   
      
  args.merge! opts
 
  @@persistence.store( name: name, workpattern: args) if self.class.persistence?

  args[:start] = dmy_date(args[:start])
  args[:finish] = dmy_date(args[:finish])
  args[:from_time] = hhmn_date(args[:from_time])
  args[:to_time] = hhmn_date(args[:to_time])

  upd_start=args[:start]
  upd_finish=args[:finish]
  while (upd_start <= upd_finish)

    current_wp=find_weekpattern(upd_start)

    if (current_wp.start == upd_start)
      if (current_wp.finish > upd_finish)
        clone_wp=clone_and_adjust_current_wp(current_wp, upd_finish+1,current_wp.finish,upd_start,upd_finish)
        set_workpattern_and_store(clone_wp,args)
        upd_start=upd_finish+1
      else # (current_wp.finish == upd_finish)
        current_wp.workpattern(args[:days],args[:from_time],args[:to_time],args[:work_type])
        upd_start=current_wp.finish + 1 
      end
    else
      clone_wp=clone_and_adjust_current_wp(current_wp, current_wp.start,upd_start-1,upd_start)
      if (clone_wp.finish <= upd_finish)
        set_workpattern_and_store(clone_wp,args)
        upd_start=clone_wp.finish+1
      else
        after_wp=clone_and_adjust_current_wp(clone_wp, upd_start,upd_finish,upd_finish+1)
        weeks<< after_wp
        set_workpattern_and_store(clone_wp,args)
        upd_start=clone_wp.finish+1
      end
    end    
  end
end