Add remaining time calculation
This commit is contained in:
		| @@ -3,11 +3,30 @@ require "./spec_helper" | |||||||
| module Dayoff::Test | module Dayoff::Test | ||||||
|   extend self |   extend self | ||||||
|  |  | ||||||
|  |   def d(day) | ||||||
|  |     location = Time::Location.load("Europe/Moscow") | ||||||
|  |     Time.local(2019, 1, day, location: location) | ||||||
|  |   end | ||||||
|  |  | ||||||
|   def t(day, hour, min = 0) |   def t(day, hour, min = 0) | ||||||
|     location = Time::Location.load("Europe/Moscow") |     location = Time::Location.load("Europe/Moscow") | ||||||
|     Time.local(2019, 1, day, hour, min, location: location) |     Time.local(2019, 1, day, hour, min, location: location) | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  |   def create_profile | ||||||
|  |     storage = MemoryStorage.new | ||||||
|  |     storage.set_planned_dates [ | ||||||
|  |       PlannedDate.new(d(1), 8), | ||||||
|  |       PlannedDate.new(d(2), 8), | ||||||
|  |       PlannedDate.new(d(3), 8), | ||||||
|  |     ] | ||||||
|  |     storage.set_work_records [ | ||||||
|  |       WorkRecord.new(t(1, 10), t(1, 20)), | ||||||
|  |       WorkRecord.new(t(2, 10), t(2, 20)), | ||||||
|  |     ] | ||||||
|  |     Profile.new(storage) | ||||||
|  |   end | ||||||
|  |  | ||||||
|   describe Profile do |   describe Profile do | ||||||
|     it "can calc work hours" do |     it "can calc work hours" do | ||||||
|       storage = MemoryStorage.new |       storage = MemoryStorage.new | ||||||
| @@ -15,7 +34,7 @@ module Dayoff::Test | |||||||
|         WorkRecord.new(t(1, 10), t(1, 20)), |         WorkRecord.new(t(1, 10), t(1, 20)), | ||||||
|       ] |       ] | ||||||
|       prof = Profile.new(storage) |       prof = Profile.new(storage) | ||||||
|       prof.get_work_hours.should eq 10 |       prof.get_work_hours(t(2, 0)).total_hours.should eq 10 | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     it "can write new record" do |     it "can write new record" do | ||||||
| @@ -44,5 +63,26 @@ module Dayoff::Test | |||||||
|       records.size.should eq 2 |       records.size.should eq 2 | ||||||
|       records.last.finish_time.should eq finish_time |       records.last.finish_time.should eq finish_time | ||||||
|     end |     end | ||||||
|  |  | ||||||
|  |     it "can calc planned hours" do | ||||||
|  |       prof = create_profile | ||||||
|  |       s = prof.get_planned_hours t(3, 12) | ||||||
|  |       expected = 8 * 3 | ||||||
|  |       expected.should eq s.total_hours | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     it "can calc work hours" do | ||||||
|  |       prof = create_profile | ||||||
|  |       s = prof.get_work_hours t(3, 12) | ||||||
|  |       expected = 10 * 2 | ||||||
|  |       expected.should eq s.total_hours | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     it "can calc remaining time" do | ||||||
|  |       prof = create_profile | ||||||
|  |       s = prof.remaining_time t(3, 12) | ||||||
|  |       expected = 8 * 3 - 10 * 2 | ||||||
|  |       expected.should eq s.total_hours | ||||||
|  |     end | ||||||
|   end |   end | ||||||
| end | end | ||||||
|   | |||||||
| @@ -1,2 +1,2 @@ | |||||||
| require "spec" | require "spec" | ||||||
| require "../src/**" | require "../src/dayoff/**" | ||||||
|   | |||||||
| @@ -6,6 +6,22 @@ module Dayoff | |||||||
|       date: String, |       date: String, | ||||||
|       hours: Int32, |       hours: Int32, | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|  |     FORMAT = "%Y-%m-%d" | ||||||
|  |  | ||||||
|  |     def initialize(date : Time, hours : Int32) | ||||||
|  |       @date = date.to_s FORMAT | ||||||
|  |       @hours = hours | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def date_time : Time | ||||||
|  |       location = Time::Location.load("Europe/Moscow") | ||||||
|  |       Time.parse(@date, FORMAT, location) | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def time_span : Time::Span | ||||||
|  |       Time::Span.new(hours: hours, minutes: 0, seconds: 0) | ||||||
|  |     end | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   class WorkRecord |   class WorkRecord | ||||||
| @@ -26,12 +42,12 @@ module Dayoff | |||||||
|  |  | ||||||
|     def start_time : Time |     def start_time : Time | ||||||
|       location = Time::Location.load("Europe/Moscow") |       location = Time::Location.load("Europe/Moscow") | ||||||
|       Time.parse(start, FORMAT, location) |       Time.parse(@start, FORMAT, location) | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     def finish_time : Time |     def finish_time : Time | ||||||
|       location = Time::Location.load("Europe/Moscow") |       location = Time::Location.load("Europe/Moscow") | ||||||
|       Time.parse(finish.as(String), FORMAT, location) |       Time.parse(@finish.as(String), FORMAT, location) | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     def finish_time=(v : Time) |     def finish_time=(v : Time) | ||||||
| @@ -41,5 +57,31 @@ module Dayoff | |||||||
|     def started? : Bool |     def started? : Bool | ||||||
|       @finish.nil? |       @finish.nil? | ||||||
|     end |     end | ||||||
|  |  | ||||||
|  |     def finished? : Bool | ||||||
|  |       !@finish.nil? | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def finished_to_time?(time : Time) : Bool | ||||||
|  |       @finish && finish_time <= time | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def calc_span(time : Time) : Time::Span | ||||||
|  |       if @finish.nil? | ||||||
|  |         if start_time <= time | ||||||
|  |           time - start_time | ||||||
|  |         else | ||||||
|  |           Time::Span.zero | ||||||
|  |         end | ||||||
|  |       else | ||||||
|  |         if time > finish_time | ||||||
|  |           finish_time - start_time | ||||||
|  |         elsif time > start_time | ||||||
|  |           time - start_time | ||||||
|  |         else | ||||||
|  |           Time::Span.zero | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  |     end | ||||||
|   end |   end | ||||||
| end | end | ||||||
|   | |||||||
| @@ -19,22 +19,24 @@ module Dayoff | |||||||
|       @wrecords = @storage.get_work_records |       @wrecords = @storage.get_work_records | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     def get_planned_hours |     def get_planned_hours(on_time : Time) : Time::Span | ||||||
|       sum = 0 |       check_date = on_time.at_beginning_of_day | ||||||
|       @pdates.each do |wd| |       @pdates.reduce(Time::Span.zero) do |acc, wd| | ||||||
|         sum += wd.hours |         if wd.date_time <= check_date | ||||||
|       end |           acc + wd.time_span | ||||||
|       sum |         else | ||||||
|     end |           acc | ||||||
|  |         end | ||||||
|     def get_work_hours |  | ||||||
|       @wrecords.reduce 0 do |acc, wr| |  | ||||||
|         diff = wr.finish_time - wr.start_time |  | ||||||
|         acc + diff.total_hours.to_i32 |  | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     def start(time : Time) |     def get_work_hours(on_time : Time) : Time::Span | ||||||
|  |       @wrecords.reduce(Time::Span.zero) do |acc, wr| | ||||||
|  |         acc + wr.calc_span on_time | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def start(time : Time) : Nil | ||||||
|       @wrecords.each do |wr| |       @wrecords.each do |wr| | ||||||
|         if time <= wr.start_time || time <= wr.finish_time |         if time <= wr.start_time || time <= wr.finish_time | ||||||
|           raise CrossedTimeSpan.new |           raise CrossedTimeSpan.new | ||||||
| @@ -45,7 +47,7 @@ module Dayoff | |||||||
|       @storage.set_work_records @wrecords |       @storage.set_work_records @wrecords | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     def finish(time : Time) |     def finish(time : Time) : Nil | ||||||
|       started = @wrecords.find { |x| x.started? } |       started = @wrecords.find { |x| x.started? } | ||||||
|       if started.nil? |       if started.nil? | ||||||
|         raise StartedRecordNotFound.new |         raise StartedRecordNotFound.new | ||||||
| @@ -53,5 +55,11 @@ module Dayoff | |||||||
|       started.finish_time = time |       started.finish_time = time | ||||||
|       @storage.set_work_records @wrecords |       @storage.set_work_records @wrecords | ||||||
|     end |     end | ||||||
|  |  | ||||||
|  |     def remaining_time(on_time : Time) : Time::Span | ||||||
|  |       planned = get_planned_hours on_time | ||||||
|  |       worked = get_work_hours on_time | ||||||
|  |       planned - worked | ||||||
|  |     end | ||||||
|   end |   end | ||||||
| end | end | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user