From 067b898352cd1e3fb01d76fa739618c2bd2981f5 Mon Sep 17 00:00:00 2001 From: Daniel Gilchrist Date: Fri, 1 Aug 2025 15:03:40 +0100 Subject: [PATCH 1/7] Time Worked - Better handle forgetting to clock out on a previous day --- .ameba.yml | 2 + spec/commands/time_worked/week_spec.cr | 57 +++++++++++++++++++++ src/tanda_cli/executors/time_worked/base.cr | 46 +++++++++++++++-- src/tanda_cli/executors/time_worked/week.cr | 4 +- src/tanda_cli/representers/shift.cr | 5 +- 5 files changed, 108 insertions(+), 6 deletions(-) diff --git a/.ameba.yml b/.ameba.yml index 7781700..ffcda9e 100644 --- a/.ameba.yml +++ b/.ameba.yml @@ -40,3 +40,5 @@ Lint/NotNil: Documentation/DocumentationAdmonition: Enabled: false +Metrics/CyclomaticComplexity: + Enabled: false diff --git a/spec/commands/time_worked/week_spec.cr b/spec/commands/time_worked/week_spec.cr index c398a71..a79aae6 100644 --- a/spec/commands/time_worked/week_spec.cr +++ b/spec/commands/time_worked/week_spec.cr @@ -252,6 +252,63 @@ describe TandaCLI::Commands::TimeWorked::Week do context.stdout.to_s.should eq(expected) end end + + it "Display assumes expected finish date for clock out if forgotten" do + WebMock + .stub(:get, endpoint(Regex.new("/shifts"))) + .to_return( + status: 200, + body: [ + build_shift( + id: 1, + start: Time.local(2024, 12, 23, 8, 30), + finish: nil, + break_start: Time.local(2024, 12, 23, 12), + break_finish: Time.local(2024, 12, 23, 12, 30) + ), + build_shift( + id: 2, + start: Time.local(2024, 12, 24, 8, 30), + finish: nil, + break_start: Time.local(2024, 12, 24, 12), + break_finish: Time.local(2024, 12, 24, 12, 30) + ), + ].to_json, + ) + + travel_to(Time.local(2024, 12, 24, 14)) + + context = run(["time_worked", "week", "--display"]) + + expected = <<-OUTPUT.gsub("", " ") + 鈿狅笍 Warning: Missing finish time for Monday, assuming regular hours finish time + Time worked: 8 hours and 0 minutes + 馃搮 Monday, 23 Dec 2024 + 馃晸 8:30 am - 5:00 pm + 馃毀 Pending + 鈽曪笍 Breaks: + 馃晸 12:00 pm - 12:30 pm + 鈴革笍 30 minutes + 馃挵 false + + Worked so far: 5 hours and 0 minutes + 馃搮 Tuesday, 24 Dec 2024 + 馃晸 8:30 am - + 馃毀 Pending + 鈽曪笍 Breaks: + 馃晸 12:00 pm - 12:30 pm + 鈴革笍 30 minutes + 馃挵 false + + Time left today: 3 hours and 0 minutes + You can clock out at: 5:00 pm + + You've worked 13 hours and 0 minutes this week + + OUTPUT + + context.stdout.to_s.should eq(expected) + end end private def build_shift(id, start, finish, break_start, break_finish) diff --git a/src/tanda_cli/executors/time_worked/base.cr b/src/tanda_cli/executors/time_worked/base.cr index 97c36bd..9c97dd1 100644 --- a/src/tanda_cli/executors/time_worked/base.cr +++ b/src/tanda_cli/executors/time_worked/base.cr @@ -6,6 +6,7 @@ module TandaCLI module TimeWorked abstract class Base alias RegularHoursScheduleBreak = Configuration::Serialisable::Organisation::RegularHoursSchedule::Break + alias RegularHoursSchedule = Configuration::Serialisable::Organisation::RegularHoursSchedule def initialize(@context : Context, @display : Bool, @offset : Int32?); end @@ -23,7 +24,7 @@ module TandaCLI .select(&.visible?) end - private def calculate_time_worked(shifts : Array(Types::Shift)) : Tuple(Time::Span, Time::Span) + private def calculate_time_worked(shifts : Array(Types::Shift), regular_hours_schedules : Array(RegularHoursSchedule)? = nil) : Tuple(Time::Span, Time::Span) total_time_worked = Time::Span.zero total_leave_hours = Time::Span.zero @@ -42,7 +43,11 @@ module TandaCLI time_worked = shift.time_worked(treat_paid_breaks_as_unpaid) worked_so_far = shift.worked_so_far(treat_paid_breaks_as_unpaid) - print_shift(shift, time_worked, worked_so_far) if display? + if time_worked.nil? && shift.finish_time.nil? && regular_hours_schedules + time_worked = calculate_expected_time_worked(shift, treat_paid_breaks_as_unpaid, regular_hours_schedules) + end + + print_shift(shift, time_worked, worked_so_far, regular_hours_schedules) if display? total_time = time_worked || worked_so_far total_time_worked += total_time if total_time @@ -51,14 +56,22 @@ module TandaCLI {total_time_worked, total_leave_hours} end - private def print_shift(shift : Types::Shift, time_worked : Time::Span?, worked_so_far : Time::Span?) + private def print_shift(shift : Types::Shift, time_worked : Time::Span?, worked_so_far : Time::Span?, regular_hours_schedules : Array(RegularHoursSchedule)? = nil) if time_worked @context.display.puts "#{"Time worked:".colorize.white.bold} #{time_worked.hours} hours and #{time_worked.minutes} minutes" elsif worked_so_far @context.display.puts "#{"Worked so far:".colorize.white.bold} #{worked_so_far.hours} hours and #{worked_so_far.minutes} minutes" end - Representers::Shift.new(shift).display(@context.display) + expected_finish_time = nil + if shift.finish_time.nil? && regular_hours_schedules + schedule = regular_hours_schedules.find(&.day_of_week.==(shift.day_of_week)) + if schedule && shift.date.date != Utils::Time.now.date + expected_finish_time = Utils::Time.pretty_time(schedule.finish_time) + end + end + + Representers::Shift.new(shift, expected_finish_time).display(@context.display) @context.display.puts end @@ -73,6 +86,31 @@ module TandaCLI Representers::LeaveRequest::DailyBreakdown.new(breakdown, leave_request).display(@context.display) @context.display.puts end + + private def calculate_expected_time_worked(shift : Types::Shift, treat_paid_breaks_as_unpaid : Bool, regular_hours_schedules : Array(RegularHoursSchedule)) : Time::Span? + start_time = shift.start_time + return unless start_time + + schedule = regular_hours_schedules.find(&.day_of_week.==(shift.day_of_week)) + return unless schedule + return if shift.date.date == Utils::Time.now.date + + if display? + @context.display.puts "#{"鈿狅笍 Warning:".colorize.yellow.bold} Missing finish time for #{shift.date.to_s("%A")}, assuming regular hours finish time" + end + + expected_finish = Time.local( + shift.date.year, + shift.date.month, + shift.date.day, + schedule.finish_time.hour, + schedule.finish_time.minute, + location: Utils::Time.location + ) + + unpaid_break_time = (treat_paid_breaks_as_unpaid ? shift.valid_breaks : shift.valid_breaks.reject(&.paid?)).sum(&.ongoing_length).minutes + (expected_finish - start_time) - unpaid_break_time + end end end end diff --git a/src/tanda_cli/executors/time_worked/week.cr b/src/tanda_cli/executors/time_worked/week.cr index c2c978b..6fc5b7b 100644 --- a/src/tanda_cli/executors/time_worked/week.cr +++ b/src/tanda_cli/executors/time_worked/week.cr @@ -17,7 +17,9 @@ module TandaCLI from ||= to.at_beginning_of_week(start_day) shifts = fetch_visible_shifts(from, to) - total_time_worked, total_leave_hours = calculate_time_worked(shifts) + organisation = @context.config.current_organisation! + regular_hours_schedules = organisation.regular_hours_schedules + total_time_worked, total_leave_hours = calculate_time_worked(shifts, regular_hours_schedules) if total_time_worked.zero? && total_leave_hours.zero? @context.display.puts "You haven't clocked in this week" else diff --git a/src/tanda_cli/representers/shift.cr b/src/tanda_cli/representers/shift.cr index 2da8c14..3ae2723 100644 --- a/src/tanda_cli/representers/shift.cr +++ b/src/tanda_cli/representers/shift.cr @@ -8,11 +8,14 @@ require "../types/shift_break" module TandaCLI module Representers struct Shift < Base(Types::Shift) + def initialize(@object : Types::Shift, @expected_finish_time : String? = nil) + end + private def build_display(builder : Builder) builder << "馃搮 #{@object.pretty_date}\n" pretty_start = @object.pretty_start_time - pretty_finish = @object.pretty_finish_time + pretty_finish = @object.pretty_finish_time || @expected_finish_time builder << "馃晸 #{pretty_start} - #{pretty_finish}\n" if pretty_start || pretty_finish builder << "馃毀 #{@object.status}\n" From 2baf3eb0e20da18fd61aff360c98222f017c8122 Mon Sep 17 00:00:00 2001 From: Daniel Gilchrist Date: Wed, 6 Aug 2025 16:54:46 +0100 Subject: [PATCH 2/7] Highlight finish time if filled from regular hours --- src/tanda_cli/representers/shift.cr | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tanda_cli/representers/shift.cr b/src/tanda_cli/representers/shift.cr index 3ae2723..763f6f1 100644 --- a/src/tanda_cli/representers/shift.cr +++ b/src/tanda_cli/representers/shift.cr @@ -16,6 +16,7 @@ module TandaCLI pretty_start = @object.pretty_start_time pretty_finish = @object.pretty_finish_time || @expected_finish_time + pretty_finish = pretty_finish.colorize.yellow if pretty_finish && @expected_finish_time builder << "馃晸 #{pretty_start} - #{pretty_finish}\n" if pretty_start || pretty_finish builder << "馃毀 #{@object.status}\n" From ba5e0f3f7dd99ed8f6f768b7cdb39aeb98c91d28 Mon Sep 17 00:00:00 2001 From: Daniel Gilchrist Date: Sat, 16 Aug 2025 10:09:43 +0100 Subject: [PATCH 3/7] Add a test for overtime --- spec/commands/time_worked/week_spec.cr | 57 ++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/spec/commands/time_worked/week_spec.cr b/spec/commands/time_worked/week_spec.cr index a79aae6..4533f4a 100644 --- a/spec/commands/time_worked/week_spec.cr +++ b/spec/commands/time_worked/week_spec.cr @@ -309,6 +309,63 @@ describe TandaCLI::Commands::TimeWorked::Week do context.stdout.to_s.should eq(expected) end + + it "Shows overtime if previous day filled and past expected finish" do + WebMock + .stub(:get, endpoint(Regex.new("/shifts"))) + .to_return( + status: 200, + body: [ + build_shift( + id: 1, + start: Time.local(2024, 12, 23, 8, 30), + finish: nil, + break_start: Time.local(2024, 12, 23, 12), + break_finish: Time.local(2024, 12, 23, 12, 30) + ), + build_shift( + id: 2, + start: Time.local(2024, 12, 24, 8, 30), + finish: nil, + break_start: Time.local(2024, 12, 24, 12), + break_finish: Time.local(2024, 12, 24, 12, 30) + ), + ].to_json, + ) + + travel_to(Time.local(2024, 12, 24, 19)) + + context = run(["time_worked", "week", "--display"]) + + expected = <<-OUTPUT.gsub("", " ") + 鈿狅笍 Warning: Missing finish time for Monday, assuming regular hours finish time + Time worked: 8 hours and 0 minutes + 馃搮 Monday, 23 Dec 2024 + 馃晸 8:30 am - 5:00 pm + 馃毀 Pending + 鈽曪笍 Breaks: + 馃晸 12:00 pm - 12:30 pm + 鈴革笍 30 minutes + 馃挵 false + + Worked so far: 10 hours and 0 minutes + 馃搮 Tuesday, 24 Dec 2024 + 馃晸 8:30 am - + 馃毀 Pending + 鈽曪笍 Breaks: + 馃晸 12:00 pm - 12:30 pm + 鈴革笍 30 minutes + 馃挵 false + + Overtime this week: 2 hours and 0 minutes + Overtime since: 5:00 pm + + You've worked 18 hours and 0 minutes this week + + OUTPUT + + context.stdout.to_s.should eq(expected) + end end private def build_shift(id, start, finish, break_start, break_finish) From 1927cd18f84a54b4d19817aa490b1285a06208dd Mon Sep 17 00:00:00 2001 From: Daniel Gilchrist Date: Sat, 16 Aug 2025 10:39:58 +0100 Subject: [PATCH 4/7] Handle filling in breaks and next day --- spec/commands/time_worked/week_spec.cr | 73 +++++++++++++++++---- src/tanda_cli/executors/time_worked/base.cr | 10 ++- src/tanda_cli/representers/shift.cr | 23 ++++--- src/tanda_cli/types/shift.cr | 3 +- 4 files changed, 85 insertions(+), 24 deletions(-) diff --git a/spec/commands/time_worked/week_spec.cr b/spec/commands/time_worked/week_spec.cr index 4533f4a..6dd0f16 100644 --- a/spec/commands/time_worked/week_spec.cr +++ b/spec/commands/time_worked/week_spec.cr @@ -366,6 +366,55 @@ describe TandaCLI::Commands::TimeWorked::Week do context.stdout.to_s.should eq(expected) end + + it "Doesn't show time left or overtime if next day with assumed regular hours without breaks" do + WebMock + .stub(:get, endpoint(Regex.new("/shifts"))) + .to_return( + status: 200, + body: [ + build_shift( + id: 1, + start: Time.local(2024, 12, 23, 8, 30), + finish: nil, + break_start: nil, + break_finish: nil + ), + build_shift( + id: 2, + start: Time.local(2024, 12, 24, 8, 30), + finish: nil, + break_start: nil, + break_finish: nil + ), + ].to_json, + ) + + travel_to(Time.local(2024, 12, 25, 1)) + + context = run(["time_worked", "week", "--display"]) + + expected = <<-OUTPUT.gsub("", " ") + 鈿狅笍 Warning: Missing finish time for Monday, assuming regular hours finish time + Time worked: 8 hours and 0 minutes + 馃搮 Monday, 23 Dec 2024 + 馃晸 8:30 am - 5:00 pm + 馃毀 Pending + 鈽曪笍 30 minutes + + 鈿狅笍 Warning: Missing finish time for Tuesday, assuming regular hours finish time + Time worked: 8 hours and 0 minutes + 馃搮 Tuesday, 24 Dec 2024 + 馃晸 8:30 am - 5:00 pm + 馃毀 Pending + 鈽曪笍 30 minutes + + You've worked 16 hours and 0 minutes this week + + OUTPUT + + context.stdout.to_s.should eq(expected) + end end private def build_shift(id, start, finish, break_start, break_finish) @@ -379,17 +428,19 @@ private def build_shift(id, start, finish, break_start, break_finish) break_finish: break_finish.try(&.to_unix), break_length: 30, breaks: [ - { - id: 1, - selected_automatic_break_rule_id: nil, - shift_id: id, - start: break_start.try(&.to_unix), - finish: break_finish.try(&.to_unix), - length: 30, - paid: false, - updated_at: 1735259689, - }, - ], + if break_start || break_finish + { + id: 1, + selected_automatic_break_rule_id: nil, + shift_id: id, + start: break_start.try(&.to_unix), + finish: break_finish.try(&.to_unix), + length: 30, + paid: false, + updated_at: 1735259689, + } + end, + ].compact, finish: finish.try(&.to_unix), department_id: 1, sub_cost_centre: nil, diff --git a/src/tanda_cli/executors/time_worked/base.cr b/src/tanda_cli/executors/time_worked/base.cr index 9c97dd1..01c4c8d 100644 --- a/src/tanda_cli/executors/time_worked/base.cr +++ b/src/tanda_cli/executors/time_worked/base.cr @@ -64,14 +64,16 @@ module TandaCLI end expected_finish_time = nil + expected_break_length = nil if shift.finish_time.nil? && regular_hours_schedules schedule = regular_hours_schedules.find(&.day_of_week.==(shift.day_of_week)) if schedule && shift.date.date != Utils::Time.now.date expected_finish_time = Utils::Time.pretty_time(schedule.finish_time) + expected_break_length = schedule.break_length end end - Representers::Shift.new(shift, expected_finish_time).display(@context.display) + Representers::Shift.new(shift, expected_finish_time, expected_break_length).display(@context.display) @context.display.puts end @@ -108,8 +110,10 @@ module TandaCLI location: Utils::Time.location ) - unpaid_break_time = (treat_paid_breaks_as_unpaid ? shift.valid_breaks : shift.valid_breaks.reject(&.paid?)).sum(&.ongoing_length).minutes - (expected_finish - start_time) - unpaid_break_time + actual_break_time = (treat_paid_breaks_as_unpaid ? shift.valid_breaks : shift.valid_breaks.reject(&.paid?)).sum(&.ongoing_length).minutes + expected_break_time = schedule.break_length + total_break_time = actual_break_time + expected_break_time + (expected_finish - start_time) - total_break_time end end end diff --git a/src/tanda_cli/representers/shift.cr b/src/tanda_cli/representers/shift.cr index 763f6f1..5c856db 100644 --- a/src/tanda_cli/representers/shift.cr +++ b/src/tanda_cli/representers/shift.cr @@ -8,7 +8,7 @@ require "../types/shift_break" module TandaCLI module Representers struct Shift < Base(Types::Shift) - def initialize(@object : Types::Shift, @expected_finish_time : String? = nil) + def initialize(@object : Types::Shift, @expected_finish_time : String? = nil, @expected_break_length : Time::Span? = nil) end private def build_display(builder : Builder) @@ -21,18 +21,23 @@ module TandaCLI builder << "馃毀 #{@object.status}\n" - build_shift_breaks(builder) if @object.valid_breaks.present? + build_shift_breaks(builder) if @object.valid_breaks.present? || @expected_break_length build_notes(builder) if @object.notes.present? end private def build_shift_breaks(builder : Builder) - builder << "鈽曪笍 Breaks:\n".colorize.white.bold - valid_breaks = @object.valid_breaks - last_break_index = valid_breaks.size - 1 - - valid_breaks.sort_by(&.id).each_with_index do |shift_break, index| - ShiftBreak.new(shift_break).build(builder) - builder << '\n' if index != last_break_index + expected_break_length = @expected_break_length + + if (breaks = @object.valid_breaks).present? + builder << "鈽曪笍 Breaks:\n".colorize.white.bold + last_break_index = breaks.size - 1 + + breaks.sort_by(&.id).each_with_index do |shift_break, index| + ShiftBreak.new(shift_break).build(builder) + builder << '\n' if index != last_break_index + end + elsif expected_break_length && !expected_break_length.zero? + builder << "鈽曪笍 #{expected_break_length.total_minutes.to_i} minutes".colorize.yellow end end diff --git a/src/tanda_cli/types/shift.cr b/src/tanda_cli/types/shift.cr index eb94f21..97819d3 100644 --- a/src/tanda_cli/types/shift.cr +++ b/src/tanda_cli/types/shift.cr @@ -101,8 +101,9 @@ module TandaCLI def ongoing? : Bool return false unless start_time + return false unless finish_time.nil? - finish_time.nil? + date.date == Utils::Time.now.date end def ongoing_break? : Bool From a57fa6ee8372bfd6f697219168b28a522bf7c217 Mon Sep 17 00:00:00 2001 From: Daniel Gilchrist Date: Sun, 17 Aug 2025 12:24:07 +0100 Subject: [PATCH 5/7] Fix issue with expected break time being counted even if there were breaks --- src/tanda_cli/executors/time_worked/base.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tanda_cli/executors/time_worked/base.cr b/src/tanda_cli/executors/time_worked/base.cr index 01c4c8d..bf49fc3 100644 --- a/src/tanda_cli/executors/time_worked/base.cr +++ b/src/tanda_cli/executors/time_worked/base.cr @@ -111,7 +111,7 @@ module TandaCLI ) actual_break_time = (treat_paid_breaks_as_unpaid ? shift.valid_breaks : shift.valid_breaks.reject(&.paid?)).sum(&.ongoing_length).minutes - expected_break_time = schedule.break_length + expected_break_time = actual_break_time == 0.minutes ? schedule.break_length : 0.minutes total_break_time = actual_break_time + expected_break_time (expected_finish - start_time) - total_break_time end From 04dca3a2be1239d3bf6a65aa607506d3ae205454 Mon Sep 17 00:00:00 2001 From: Daniel Gilchrist Date: Tue, 23 Dec 2025 14:43:39 +0000 Subject: [PATCH 6/7] Fix tests after rebase --- spec/commands/time_worked/week_spec.cr | 154 ++++++++++++------------- 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/spec/commands/time_worked/week_spec.cr b/spec/commands/time_worked/week_spec.cr index 6dd0f16..288e487 100644 --- a/spec/commands/time_worked/week_spec.cr +++ b/spec/commands/time_worked/week_spec.cr @@ -276,38 +276,38 @@ describe TandaCLI::Commands::TimeWorked::Week do ].to_json, ) - travel_to(Time.local(2024, 12, 24, 14)) - - context = run(["time_worked", "week", "--display"]) - - expected = <<-OUTPUT.gsub("", " ") - 鈿狅笍 Warning: Missing finish time for Monday, assuming regular hours finish time - Time worked: 8 hours and 0 minutes - 馃搮 Monday, 23 Dec 2024 - 馃晸 8:30 am - 5:00 pm - 馃毀 Pending - 鈽曪笍 Breaks: - 馃晸 12:00 pm - 12:30 pm - 鈴革笍 30 minutes - 馃挵 false - - Worked so far: 5 hours and 0 minutes - 馃搮 Tuesday, 24 Dec 2024 - 馃晸 8:30 am - - 馃毀 Pending - 鈽曪笍 Breaks: - 馃晸 12:00 pm - 12:30 pm - 鈴革笍 30 minutes - 馃挵 false - - Time left today: 3 hours and 0 minutes - You can clock out at: 5:00 pm - - You've worked 13 hours and 0 minutes this week - - OUTPUT - - context.stdout.to_s.should eq(expected) + travel_to(Time.local(2024, 12, 24, 14)) do + context = run(["time_worked", "week", "--display"]) + + expected = <<-OUTPUT.gsub("", " ") + 鈿狅笍 Warning: Missing finish time for Monday, assuming regular hours finish time + Time worked: 8 hours and 0 minutes + 馃搮 Monday, 23 Dec 2024 + 馃晸 8:30 am - 5:00 pm + 馃毀 Pending + 鈽曪笍 Breaks: + 馃晸 12:00 pm - 12:30 pm + 鈴革笍 30 minutes + 馃挵 false + + Worked so far: 5 hours and 0 minutes + 馃搮 Tuesday, 24 Dec 2024 + 馃晸 8:30 am - + 馃毀 Pending + 鈽曪笍 Breaks: + 馃晸 12:00 pm - 12:30 pm + 鈴革笍 30 minutes + 馃挵 false + + Time left today: 3 hours and 0 minutes + You can clock out at: 5:00 pm + + You've worked 13 hours and 0 minutes this week + + OUTPUT + + context.stdout.to_s.should eq(expected) + end end it "Shows overtime if previous day filled and past expected finish" do @@ -333,38 +333,38 @@ describe TandaCLI::Commands::TimeWorked::Week do ].to_json, ) - travel_to(Time.local(2024, 12, 24, 19)) - - context = run(["time_worked", "week", "--display"]) + travel_to(Time.local(2024, 12, 24, 19)) do + context = run(["time_worked", "week", "--display"]) - expected = <<-OUTPUT.gsub("", " ") - 鈿狅笍 Warning: Missing finish time for Monday, assuming regular hours finish time - Time worked: 8 hours and 0 minutes - 馃搮 Monday, 23 Dec 2024 - 馃晸 8:30 am - 5:00 pm - 馃毀 Pending - 鈽曪笍 Breaks: - 馃晸 12:00 pm - 12:30 pm - 鈴革笍 30 minutes - 馃挵 false + expected = <<-OUTPUT.gsub("", " ") + 鈿狅笍 Warning: Missing finish time for Monday, assuming regular hours finish time + Time worked: 8 hours and 0 minutes + 馃搮 Monday, 23 Dec 2024 + 馃晸 8:30 am - 5:00 pm + 馃毀 Pending + 鈽曪笍 Breaks: + 馃晸 12:00 pm - 12:30 pm + 鈴革笍 30 minutes + 馃挵 false - Worked so far: 10 hours and 0 minutes - 馃搮 Tuesday, 24 Dec 2024 - 馃晸 8:30 am - - 馃毀 Pending - 鈽曪笍 Breaks: - 馃晸 12:00 pm - 12:30 pm - 鈴革笍 30 minutes - 馃挵 false + Worked so far: 10 hours and 0 minutes + 馃搮 Tuesday, 24 Dec 2024 + 馃晸 8:30 am - + 馃毀 Pending + 鈽曪笍 Breaks: + 馃晸 12:00 pm - 12:30 pm + 鈴革笍 30 minutes + 馃挵 false - Overtime this week: 2 hours and 0 minutes - Overtime since: 5:00 pm + Overtime this week: 2 hours and 0 minutes + Overtime since: 5:00 pm - You've worked 18 hours and 0 minutes this week + You've worked 18 hours and 0 minutes this week - OUTPUT + OUTPUT - context.stdout.to_s.should eq(expected) + context.stdout.to_s.should eq(expected) + end end it "Doesn't show time left or overtime if next day with assumed regular hours without breaks" do @@ -390,30 +390,30 @@ describe TandaCLI::Commands::TimeWorked::Week do ].to_json, ) - travel_to(Time.local(2024, 12, 25, 1)) - - context = run(["time_worked", "week", "--display"]) + travel_to(Time.local(2024, 12, 25, 1)) do + context = run(["time_worked", "week", "--display"]) - expected = <<-OUTPUT.gsub("", " ") - 鈿狅笍 Warning: Missing finish time for Monday, assuming regular hours finish time - Time worked: 8 hours and 0 minutes - 馃搮 Monday, 23 Dec 2024 - 馃晸 8:30 am - 5:00 pm - 馃毀 Pending - 鈽曪笍 30 minutes + expected = <<-OUTPUT.gsub("", " ") + 鈿狅笍 Warning: Missing finish time for Monday, assuming regular hours finish time + Time worked: 8 hours and 0 minutes + 馃搮 Monday, 23 Dec 2024 + 馃晸 8:30 am - 5:00 pm + 馃毀 Pending + 鈽曪笍 30 minutes - 鈿狅笍 Warning: Missing finish time for Tuesday, assuming regular hours finish time - Time worked: 8 hours and 0 minutes - 馃搮 Tuesday, 24 Dec 2024 - 馃晸 8:30 am - 5:00 pm - 馃毀 Pending - 鈽曪笍 30 minutes + 鈿狅笍 Warning: Missing finish time for Tuesday, assuming regular hours finish time + Time worked: 8 hours and 0 minutes + 馃搮 Tuesday, 24 Dec 2024 + 馃晸 8:30 am - 5:00 pm + 馃毀 Pending + 鈽曪笍 30 minutes - You've worked 16 hours and 0 minutes this week + You've worked 16 hours and 0 minutes this week - OUTPUT + OUTPUT - context.stdout.to_s.should eq(expected) + context.stdout.to_s.should eq(expected) + end end end From a4d29a774005e005958167c2375252147400bd1a Mon Sep 17 00:00:00 2001 From: Daniel Gilchrist Date: Fri, 13 Feb 2026 17:43:47 +0000 Subject: [PATCH 7/7] Fix output --- src/tanda_cli/representers/shift.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tanda_cli/representers/shift.cr b/src/tanda_cli/representers/shift.cr index 5c856db..3f785d4 100644 --- a/src/tanda_cli/representers/shift.cr +++ b/src/tanda_cli/representers/shift.cr @@ -37,7 +37,7 @@ module TandaCLI builder << '\n' if index != last_break_index end elsif expected_break_length && !expected_break_length.zero? - builder << "鈽曪笍 #{expected_break_length.total_minutes.to_i} minutes".colorize.yellow + builder << "鈽曪笍 #{expected_break_length.total_minutes.to_i} minutes\n".colorize.yellow end end