timet 1.3.2 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -0
- data/README.md +3 -2
- data/lib/timet/application.rb +36 -53
- data/lib/timet/application_helper.rb +63 -5
- data/lib/timet/color_codes.rb +9 -1
- data/lib/timet/database.rb +57 -23
- data/lib/timet/table.rb +300 -0
- data/lib/timet/tag_distribution.rb +61 -0
- data/lib/timet/{formatter.rb → time_block_chart.rb} +76 -152
- data/lib/timet/time_report.rb +20 -44
- data/lib/timet/time_report_helper.rb +0 -66
- data/lib/timet/version.rb +2 -2
- metadata +5 -4
- data/lib/timet/status_helper.rb +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5e9f44f4ee2f1ae5aab382b308364ffeaffa5e09bf21d1578e8f5267ff715f0f
|
4
|
+
data.tar.gz: 13becd17288c93925e91a3c49dcdc7f4f7e7afe41d1469a10a7f931930b2d26d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 27fca2e9adef3a4695a497b21106a400e7448caff946efccba034f9bbfcb29962822a632f17e3ab51856de764826257f5d6b33458d69fd9b56eebeb91946e5b8
|
7
|
+
data.tar.gz: df46d99862c3366f63f4ad007fbece638f88ca997fa2085070a78c065306b23888ecbbd5b610ba99582898395201dd00a1a8871de0ef8983d24c9ec3edefe32b
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,29 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [1.4.0] - 2024-10-29
|
4
|
+
|
5
|
+
**Improvements:**
|
6
|
+
|
7
|
+
- Introduced constants for fixed tag size and block character in the `TagDistribution` module.
|
8
|
+
- Refactored `process_and_print_tags` to use constants directly and ensure tags are truncated to fit within the defined size.
|
9
|
+
- Simplified `calculate_value_and_bar_length` method to directly calculate percentage value and bar length using `MAX_BAR_LENGTH`.
|
10
|
+
- Renamed `summary` to `report` in `application.rb` for clarity.
|
11
|
+
- Integrated `Formatter` functionality into `Table` and `TimeBlockChart` modules.
|
12
|
+
- Added new methods in `Table` for formatting specific parts of the table row.
|
13
|
+
- Enhanced `TimeBlockChart` with new methods for formatting and printing date information.
|
14
|
+
- Integrated `Table` and `TimeBlockChart` into `TimeReport` for a more modular structure.
|
15
|
+
- Removed redundant methods from `TimeReportHelper` and ensured all necessary methods are included in the appropriate modules.
|
16
|
+
- Added a `blue` method to the `String` class to apply blue color to text and applied it to the total time display in `TimeReport`.
|
17
|
+
- Refactored database initialization and column addition logic to improve reusability and maintainability.
|
18
|
+
- Refactored Pomodoro session handling and table formatting to improve readability and functionality.
|
19
|
+
- Refactored `summary` method to use `time_scope` instead of `filter` for clarity.
|
20
|
+
- Refactored insertion logic to improve clarity and prevent redundant checks.
|
21
|
+
- Refactored tag distribution formatting into a separate `TagDistribution` module for better code organization.
|
22
|
+
|
23
|
+
**Bug fixes:**
|
24
|
+
|
25
|
+
- Fixed a typo in the table header title.
|
26
|
+
|
3
27
|
## [1.3.2] - 2024-10-25
|
4
28
|
|
5
29
|
**Improvements:**
|
data/README.md
CHANGED
@@ -106,7 +106,7 @@ gem install timet
|
|
106
106
|
+-------+------------+--------+----------+----------+----------+--------------------------+
|
107
107
|
```
|
108
108
|
---
|
109
|
-
- **timet resume**:
|
109
|
+
- **timet resume [id]**: This command allows users to quickly resume tracking a task that was previously in progress. If an id is provided, it resumes the tracking session for the specified task. If no id is provided, it resumes the last completed task.
|
110
110
|
|
111
111
|
```
|
112
112
|
Tracked time report [today]:
|
@@ -177,9 +177,10 @@ gem install timet
|
|
177
177
|
| `timet summary resume (r)` | Resume tracking the last task. | `timet su r` |
|
178
178
|
| `timet delete [id]` | Delete a task by its ID. | `timet d [id]` |
|
179
179
|
| `timet cancel` | Cancel active time tracking. | `timet c` |
|
180
|
-
| `timet edit [id]` | Update a task's notes, tag, start or end fields. | `timet e [
|
180
|
+
| `timet edit [id]` | Update a task's notes, tag, start or end fields. | `timet e [id]` |
|
181
181
|
| `timet su [date]` | Display a report of tracked time for a specific date. | `timet su 2024-01-03` |
|
182
182
|
| `timet su [start_date]..[end_date]` | Display a report of tracked time for a date range. | `timet su 2024-01-02..2024-01-03` |
|
183
|
+
| `timet resume [id]` | Resume tracking a task by ID or the last completed task. | `timet resume [id]` |
|
183
184
|
|
184
185
|
### Date Range in Summary
|
185
186
|
|
data/lib/timet/application.rb
CHANGED
@@ -69,10 +69,10 @@ module Timet
|
|
69
69
|
notes = options[:notes] || notes
|
70
70
|
pomodoro = (options[:pomodoro] || pomodoro).to_i
|
71
71
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
72
|
+
return puts 'A task is currently being tracked.' unless VALID_STATUSES_FOR_INSERTION.include?(@db.item_status)
|
73
|
+
|
74
|
+
@db.insert_item(start_time, tag, notes, pomodoro)
|
75
|
+
play_sound_and_notify(pomodoro * 60, tag) if pomodoro.positive?
|
76
76
|
summary
|
77
77
|
end
|
78
78
|
|
@@ -85,13 +85,13 @@ module Timet
|
|
85
85
|
# @example Stop the current tracking session
|
86
86
|
# stop
|
87
87
|
#
|
88
|
-
# @note The method checks if the last tracking item is in progress by calling `@db.
|
88
|
+
# @note The method checks if the last tracking item is in progress by calling `@db.item_status`.
|
89
89
|
# @note If the last item is in progress, it fetches the last item's ID using `@db.fetch_last_id` and updates it
|
90
90
|
# with the current timestamp.
|
91
91
|
# @note The method then fetches the last item using `@db.last_item` and generates a summary if the result
|
92
92
|
# is not nil.
|
93
93
|
def stop(display = nil)
|
94
|
-
return unless @db.
|
94
|
+
return unless @db.item_status == :in_progress
|
95
95
|
|
96
96
|
last_id = @db.fetch_last_id
|
97
97
|
@db.update_item(last_id, 'end', TimeHelper.current_timestamp)
|
@@ -99,7 +99,7 @@ module Timet
|
|
99
99
|
summary unless display
|
100
100
|
end
|
101
101
|
|
102
|
-
desc 'resume (r)', 'resume last task'
|
102
|
+
desc 'resume (r) [id]', 'resume last task'
|
103
103
|
# Resumes the last tracking session if it was completed.
|
104
104
|
#
|
105
105
|
# @return [void] This method does not return a value; it performs side effects such as resuming a tracking session
|
@@ -108,35 +108,38 @@ module Timet
|
|
108
108
|
# @example Resume the last tracking session
|
109
109
|
# resume
|
110
110
|
#
|
111
|
-
# @
|
111
|
+
# @example Resume a specific task by ID
|
112
|
+
# resume(123)
|
113
|
+
#
|
114
|
+
# @note The method checks the status of the last tracking item using `@db.item_status`.
|
112
115
|
# @note If the last item is in progress, it prints a message indicating that a task is currently being tracked.
|
113
|
-
# @note If the last item is complete, it fetches the last item using `@db.last_item`,
|
116
|
+
# @note If the last item is complete, it fetches the last item using `@db.find_item` or `@db.last_item`,
|
117
|
+
# retrieves the tag and notes,
|
114
118
|
# and calls the `start` method to resume the tracking session.
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
+
#
|
120
|
+
# @param id [Integer, nil] The ID of the tracking item to resume. If nil, the last item is used.
|
121
|
+
#
|
122
|
+
# @see Database#item_status
|
123
|
+
# @see Database#find_item
|
124
|
+
# @see #start
|
125
|
+
def resume(id = nil)
|
126
|
+
case @db.item_status(id)
|
119
127
|
when :in_progress
|
120
128
|
puts 'A task is currently being tracked.'
|
121
129
|
when :complete
|
122
|
-
|
123
|
-
if last_item
|
124
|
-
tag = last_item[FIELD_INDEX['tag']]
|
125
|
-
notes = last_item[FIELD_INDEX['notes']]
|
126
|
-
start(tag, notes)
|
127
|
-
end
|
130
|
+
resume_complete_task(id)
|
128
131
|
end
|
129
132
|
end
|
130
133
|
|
131
|
-
desc 'summary (su) [
|
132
|
-
'[
|
134
|
+
desc 'summary (su) [time_scope] [tag] --csv=csv_filename',
|
135
|
+
'[time_scope] => [today (t), yesterday (y), week (w), month (m), [start_date]..[end_date]] [tag]'
|
133
136
|
option :csv, type: :string, desc: 'Export to CSV file'
|
134
|
-
# Generates a summary of tracking items based on the provided
|
137
|
+
# Generates a summary of tracking items based on the provided time_scope and tag, and optionally exports the summary
|
135
138
|
# to a CSV file.
|
136
139
|
#
|
137
|
-
# @param
|
138
|
-
# 'yesterday', 'week', 'month', or a date range in the format '[start_date]..[end_date]'.
|
139
|
-
# @param tag [String, nil] The tag to
|
140
|
+
# @param time_scope [String, nil] The time_scope to apply when generating the summary. Possible values include
|
141
|
+
# 'today', 'yesterday', 'week', 'month', or a date range in the format '[start_date]..[end_date]'.
|
142
|
+
# @param tag [String, nil] The tag to time_scope the tracking items by.
|
140
143
|
#
|
141
144
|
# @return [void] This method does not return a value; it performs side effects such as displaying the summary and
|
142
145
|
# exporting to CSV if specified.
|
@@ -150,19 +153,19 @@ module Timet
|
|
150
153
|
# @example Generate a summary for a date range and export to CSV
|
151
154
|
# summary('2023-01-01..2023-01-31', nil, csv: 'summary.csv')
|
152
155
|
#
|
153
|
-
# @note The method initializes a `TimeReport` object with the database,
|
156
|
+
# @note The method initializes a `TimeReport` object with the database, time_scope, tag, and optional CSV filename.
|
154
157
|
# @note The method calls `display` on the `TimeReport` object to show the summary.
|
155
158
|
# @note If a CSV filename is provided and there are items to export, the method calls `export_sheet` to export the
|
156
159
|
# summary to a CSV file.
|
157
160
|
# @note If no items are found to export, it prints a message indicating that no items were found.
|
158
|
-
def summary(
|
161
|
+
def summary(time_scope = nil, tag = nil)
|
159
162
|
csv_filename = options[:csv]&.split('.')&.first
|
160
|
-
|
163
|
+
report = TimeReport.new(@db, time_scope, tag, csv_filename)
|
161
164
|
|
162
|
-
|
163
|
-
items =
|
165
|
+
report.display
|
166
|
+
items = report.items
|
164
167
|
if csv_filename && items.any?
|
165
|
-
|
168
|
+
report.export_sheet
|
166
169
|
elsif items.empty?
|
167
170
|
puts 'No items found to export'
|
168
171
|
end
|
@@ -245,13 +248,13 @@ module Timet
|
|
245
248
|
# cancel
|
246
249
|
#
|
247
250
|
# @note The method fetches the ID of the last tracking item using `@db.fetch_last_id`.
|
248
|
-
# @note It checks if the last item is in progress by comparing `@db.
|
251
|
+
# @note It checks if the last item is in progress by comparing `@db.item_status` with `:complete`.
|
249
252
|
# @note If the last item is in progress, it deletes the item and prints a confirmation message using
|
250
253
|
# `delete_item_and_print_message(id, "Canceled active time tracking #{id}")`.
|
251
254
|
# @note If there is no active time tracking, it prints a message indicating that there is no active time tracking.
|
252
255
|
def cancel
|
253
256
|
id = @db.fetch_last_id
|
254
|
-
return puts 'There is no active time tracking' if @db.
|
257
|
+
return puts 'There is no active time tracking' if @db.item_status == :complete
|
255
258
|
|
256
259
|
delete_item_and_print_message(id, "Canceled active time tracking #{id}")
|
257
260
|
end
|
@@ -281,25 +284,5 @@ module Timet
|
|
281
284
|
def version
|
282
285
|
puts Timet::VERSION
|
283
286
|
end
|
284
|
-
|
285
|
-
private
|
286
|
-
|
287
|
-
# Deletes a tracking item from the database by its ID and prints a confirmation message.
|
288
|
-
#
|
289
|
-
# @param id [Integer] The ID of the tracking item to be deleted.
|
290
|
-
# @param message [String] The message to be printed after the item is deleted.
|
291
|
-
#
|
292
|
-
# @return [void] This method does not return a value; it performs side effects such as deleting the tracking item
|
293
|
-
# and printing a message.
|
294
|
-
#
|
295
|
-
# @example Delete a tracking item with ID 1 and print a confirmation message
|
296
|
-
# delete_item_and_print_message(1, 'Deleted item 1')
|
297
|
-
#
|
298
|
-
# @note The method deletes the tracking item from the database using `@db.delete_item(id)`.
|
299
|
-
# @note After deleting the item, the method prints the provided message using `puts message`.
|
300
|
-
def delete_item_and_print_message(id, message)
|
301
|
-
@db.delete_item(id)
|
302
|
-
puts message
|
303
|
-
end
|
304
287
|
end
|
305
288
|
end
|
@@ -109,10 +109,10 @@ module Timet
|
|
109
109
|
# @param tag [String] A tag or label for the session, used in the notification message.
|
110
110
|
# @return [void]
|
111
111
|
def run_linux_session(time, tag)
|
112
|
-
notification_command = "notify-send --icon=clock '
|
112
|
+
notification_command = "notify-send --icon=clock '#{show_message(tag)}'"
|
113
113
|
command = "sleep #{time} && tput bel && tt stop 0 && #{notification_command} &"
|
114
114
|
pid = spawn(command)
|
115
|
-
Process.
|
115
|
+
Process.detach(pid)
|
116
116
|
end
|
117
117
|
|
118
118
|
# Runs a Pomodoro session on a macOS system.
|
@@ -120,11 +120,69 @@ module Timet
|
|
120
120
|
# @param time [Integer] The duration of the Pomodoro session in seconds.
|
121
121
|
# @param _tag [String] A tag or label for the session, not used in the notification message on macOS.
|
122
122
|
# @return [void]
|
123
|
-
def run_mac_session(time,
|
124
|
-
notification_command = "osascript -e 'display notification \"
|
123
|
+
def run_mac_session(time, tag)
|
124
|
+
notification_command = "osascript -e 'display notification \"#{show_message(tag)}\"'"
|
125
125
|
command = "sleep #{time} && afplay /System/Library/Sounds/Basso.aiff && tt stop 0 && #{notification_command} &"
|
126
126
|
pid = spawn(command)
|
127
|
-
Process.
|
127
|
+
Process.detach(pid)
|
128
|
+
end
|
129
|
+
|
130
|
+
# Generates a message indicating that a Pomodoro session is complete and it's time for a break.
|
131
|
+
#
|
132
|
+
# @param tag [String] The tag associated with the completed Pomodoro session.
|
133
|
+
# @return [String] A message indicating the completion of the Pomodoro session and suggesting a break.
|
134
|
+
#
|
135
|
+
# @example
|
136
|
+
# show_message("work")
|
137
|
+
# # => "Pomodoro session complete (work). Time for a break."
|
138
|
+
#
|
139
|
+
def show_message(tag)
|
140
|
+
"Pomodoro session complete (#{tag}). Time for a break."
|
141
|
+
end
|
142
|
+
|
143
|
+
# Deletes a tracking item from the database by its ID and prints a confirmation message.
|
144
|
+
#
|
145
|
+
# @param id [Integer] The ID of the tracking item to be deleted.
|
146
|
+
# @param message [String] The message to be printed after the item is deleted.
|
147
|
+
#
|
148
|
+
# @return [void] This method does not return a value; it performs side effects such as deleting the tracking item
|
149
|
+
# and printing a message.
|
150
|
+
#
|
151
|
+
# @example Delete a tracking item with ID 1 and print a confirmation message
|
152
|
+
# delete_item_and_print_message(1, 'Deleted item 1')
|
153
|
+
#
|
154
|
+
# @note The method deletes the tracking item from the database using `@db.delete_item(id)`.
|
155
|
+
# @note After deleting the item, the method prints the provided message using `puts message`.
|
156
|
+
def delete_item_and_print_message(id, message)
|
157
|
+
@db.delete_item(id)
|
158
|
+
puts message
|
159
|
+
end
|
160
|
+
|
161
|
+
# Resumes a tracking session for a completed task.
|
162
|
+
#
|
163
|
+
# @param id [Integer, nil] The ID of the tracking item to resume. If nil, the last completed item is used.
|
164
|
+
#
|
165
|
+
# @return [void] This method does not return a value; it performs side effects such as resuming a tracking session.
|
166
|
+
#
|
167
|
+
# @example Resume the last completed task
|
168
|
+
# resume_complete_task
|
169
|
+
#
|
170
|
+
# @example Resume a specific task by ID
|
171
|
+
# resume_complete_task(123)
|
172
|
+
#
|
173
|
+
# @note The method fetches the specified or last completed item using `@db.find_item` or `@db.last_item`.
|
174
|
+
# @note If the item is found, it retrieves the tag and notes and calls the `start` method to resume the
|
175
|
+
# tracking session.
|
176
|
+
#
|
177
|
+
# @see Database#find_item
|
178
|
+
# @see Database#last_item
|
179
|
+
# @see #start
|
180
|
+
def resume_complete_task(id)
|
181
|
+
item = id ? @db.find_item(id) : @db.last_item
|
182
|
+
return unless item
|
183
|
+
|
184
|
+
tag, notes = item.values_at(Application::FIELD_INDEX['tag'], Application::FIELD_INDEX['notes'])
|
185
|
+
start(tag, notes)
|
128
186
|
end
|
129
187
|
end
|
130
188
|
end
|
data/lib/timet/color_codes.rb
CHANGED
@@ -5,7 +5,7 @@ module Timet
|
|
5
5
|
class ColorCodes
|
6
6
|
RESET = "\u001b[0m"
|
7
7
|
UNDERLINE = "\e[4m"
|
8
|
-
BLINK = "\e[5m
|
8
|
+
BLINK = "\e[5m"
|
9
9
|
|
10
10
|
def self.reset
|
11
11
|
RESET
|
@@ -27,6 +27,10 @@ end
|
|
27
27
|
|
28
28
|
# Extend String class globally
|
29
29
|
class String
|
30
|
+
def white
|
31
|
+
"#{Timet::ColorCodes.color(246)}#{self}#{Timet::ColorCodes.reset}"
|
32
|
+
end
|
33
|
+
|
30
34
|
def gray
|
31
35
|
"#{Timet::ColorCodes.color(242)}#{self}#{Timet::ColorCodes.reset}"
|
32
36
|
end
|
@@ -35,6 +39,10 @@ class String
|
|
35
39
|
"#{Timet::ColorCodes.color(1)}#{self}#{Timet::ColorCodes.reset}"
|
36
40
|
end
|
37
41
|
|
42
|
+
def blue
|
43
|
+
"#{Timet::ColorCodes.color(12)}#{self}#{Timet::ColorCodes.reset}"
|
44
|
+
end
|
45
|
+
|
38
46
|
def underline
|
39
47
|
"#{Timet::ColorCodes.underline}#{self}#{Timet::ColorCodes.reset}"
|
40
48
|
end
|
data/lib/timet/database.rb
CHANGED
@@ -1,12 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'sqlite3'
|
4
|
-
require_relative 'status_helper'
|
5
4
|
module Timet
|
6
5
|
# Provides database access for managing time tracking data.
|
7
6
|
class Database
|
8
|
-
include StatusHelper
|
9
|
-
|
10
7
|
# The default path to the SQLite database file.
|
11
8
|
DEFAULT_DATABASE_PATH = File.join(Dir.home, '.timet.db')
|
12
9
|
|
@@ -28,7 +25,9 @@ module Timet
|
|
28
25
|
def initialize(database_path = DEFAULT_DATABASE_PATH)
|
29
26
|
@db = SQLite3::Database.new(database_path)
|
30
27
|
create_table
|
31
|
-
|
28
|
+
|
29
|
+
add_column('items', 'notes', 'TEXT')
|
30
|
+
add_column('items', 'pomodoro', 'INTEGER')
|
32
31
|
end
|
33
32
|
|
34
33
|
# Creates the items table if it doesn't already exist.
|
@@ -51,23 +50,27 @@ module Timet
|
|
51
50
|
SQL
|
52
51
|
end
|
53
52
|
|
54
|
-
# Adds a new column
|
55
|
-
#
|
56
|
-
# @
|
57
|
-
# the column.
|
58
|
-
#
|
59
|
-
# @
|
60
|
-
#
|
61
|
-
#
|
62
|
-
# @
|
63
|
-
|
64
|
-
|
65
|
-
|
53
|
+
# Adds a new column to the specified table if it does not already exist.
|
54
|
+
#
|
55
|
+
# @param table_name [String] The name of the table to which the column will be added.
|
56
|
+
# @param new_column_name [String] The name of the new column to be added.
|
57
|
+
# @param date_type [String] The data type of the new column (e.g., 'INTEGER', 'TEXT', 'BOOLEAN').
|
58
|
+
# @return [void] This method does not return a value; it performs side effects such as adding the column and
|
59
|
+
# printing a message.
|
60
|
+
#
|
61
|
+
# @example Add a new 'completed' column to the 'tasks' table
|
62
|
+
# add_column('tasks', 'completed', 'INTEGER')
|
63
|
+
#
|
64
|
+
# @note The method first checks if the column already exists in the table using `pragma_table_info`.
|
65
|
+
# @note If the column exists, the method returns without making any changes.
|
66
|
+
# @note If the column does not exist, the method executes an SQL `ALTER TABLE` statement to add the column.
|
67
|
+
# @note The method prints a message indicating that the column has been added.
|
68
|
+
def add_column(table_name, new_column_name, date_type)
|
66
69
|
result = execute_sql("SELECT count(*) FROM pragma_table_info('items') where name='#{new_column_name}'")
|
67
70
|
column_exists = result[0][0].positive?
|
68
71
|
return if column_exists
|
69
72
|
|
70
|
-
execute_sql("ALTER TABLE #{table_name} ADD COLUMN #{new_column_name}
|
73
|
+
execute_sql("ALTER TABLE #{table_name} ADD COLUMN #{new_column_name} #{date_type}")
|
71
74
|
puts "Column '#{new_column_name}' added to table '#{table_name}'."
|
72
75
|
end
|
73
76
|
|
@@ -84,8 +87,8 @@ module Timet
|
|
84
87
|
# insert_item(1633072800, 'work', 'Completed task X')
|
85
88
|
#
|
86
89
|
# @note The method executes SQL to insert a new row into the 'items' table.
|
87
|
-
def insert_item(start, tag, notes)
|
88
|
-
execute_sql('INSERT INTO items (start, tag, notes) VALUES (?, ?, ?)', [start, tag, notes])
|
90
|
+
def insert_item(start, tag, notes, pomodoro = nil)
|
91
|
+
execute_sql('INSERT INTO items (start, tag, notes, pomodoro) VALUES (?, ?, ?, ?)', [start, tag, notes, pomodoro])
|
89
92
|
end
|
90
93
|
|
91
94
|
# Updates an existing item in the items table.
|
@@ -152,12 +155,15 @@ module Timet
|
|
152
155
|
# @return [Symbol] The status of the last item. Possible values are :no_items, :in_progress, or :complete.
|
153
156
|
#
|
154
157
|
# @example Determine the status of the last item
|
155
|
-
#
|
158
|
+
# item_status
|
156
159
|
#
|
157
160
|
# @note The method executes SQL to fetch the last item and determines its status using the `StatusHelper` module.
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
+
#
|
162
|
+
# @param id [Integer, nil] The ID of the item to check. If nil, the last item in the table is used.
|
163
|
+
#
|
164
|
+
def item_status(id = nil)
|
165
|
+
id = fetch_last_id if id.nil?
|
166
|
+
determine_status(find_item(id))
|
161
167
|
end
|
162
168
|
|
163
169
|
# Finds an item in the items table by its ID.
|
@@ -235,5 +241,33 @@ module Timet
|
|
235
241
|
|
236
242
|
format '%<hours>02d:%<minutes>02d:%<seconds>02d', hours: hours, minutes: minutes, seconds: seconds
|
237
243
|
end
|
244
|
+
|
245
|
+
# Determines the status of a time tracking result based on the presence and end time of items.
|
246
|
+
#
|
247
|
+
# @param result [Array] The result set containing time tracking items.
|
248
|
+
#
|
249
|
+
# @return [Symbol] The status of the time tracking result. Possible values are
|
250
|
+
# :no_items, :in_progress, or :complete.
|
251
|
+
#
|
252
|
+
# @example Determine the status of an empty result set
|
253
|
+
# StatusHelper.determine_status([]) # => :no_items
|
254
|
+
#
|
255
|
+
# @example Determine the status of a result set with an in-progress item
|
256
|
+
# StatusHelper.determine_status([[1, nil]]) # => :in_progress
|
257
|
+
#
|
258
|
+
# @example Determine the status of a result set with a completed item
|
259
|
+
# StatusHelper.determine_status([[1, 1633072800]]) # => :complete
|
260
|
+
#
|
261
|
+
# @note The method checks if the result set is empty and returns :no_items if true.
|
262
|
+
# @note If the last item in the result set has no end time, it returns :in_progress.
|
263
|
+
# @note If the last item in the result set has an end time, it returns :complete.
|
264
|
+
def determine_status(result)
|
265
|
+
return :no_items if result.nil?
|
266
|
+
|
267
|
+
last_item_end = result[2]
|
268
|
+
return :in_progress unless last_item_end
|
269
|
+
|
270
|
+
:complete
|
271
|
+
end
|
238
272
|
end
|
239
273
|
end
|