Skip to content

Commit 8c0d36a

Browse files
committed
feat(time): additional filter args for report download
1 parent 957729e commit 8c0d36a

File tree

5 files changed

+140
-10
lines changed

5 files changed

+140
-10
lines changed

README.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,18 @@ Use this command to download a time report from Toggl in CSV format:
7979

8080
```bash
8181
$ compiler-admin time download -h
82-
usage: compiler-admin time download [-h] [--start YYYY-MM-DD] [--end YYYY-MM-DD] [--output OUTPUT]
82+
usage: compiler-admin time download [-h] [--start YYYY-MM-DD] [--end YYYY-MM-DD] [--output OUTPUT] [--client CLIENT_ID] [--project PROJECT_ID]
83+
[--task TASK_ID] [--user USER_ID]
8384
8485
options:
85-
-h, --help show this help message and exit
86-
--start YYYY-MM-DD The start date of the reporting period. Defaults to the beginning of the prior month.
87-
--end YYYY-MM-DD The end date of the reporting period. Defaults to the end of the prior month.
88-
--output OUTPUT The path to the file where converted data should be written. Defaults to stdout.
86+
-h, --help show this help message and exit
87+
--start YYYY-MM-DD The start date of the reporting period. Defaults to the beginning of the prior month.
88+
--end YYYY-MM-DD The end date of the reporting period. Defaults to the end of the prior month.
89+
--output OUTPUT The path to the file where converted data should be written. Defaults to stdout.
90+
--client CLIENT_ID An ID for a Toggl Client to filter for in reports. Can be supplied more than once.
91+
--project PROJECT_ID An ID for a Toggl Project to filter for in reports. Can be supplied more than once.
92+
--task TASK_ID An ID for a Toggl Project Task to filter for in reports. Can be supplied more than once.
93+
--user USER_ID An ID for a Toggl User to filter for in reports. Can be supplied more than once.
8994
```
9095
9196
### Converting an hours report

compiler_admin/commands/time/download.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,17 @@
55

66

77
def download(args: Namespace, *extras):
8-
download_time_entries(args.start, args.end, args.output, TOGGL_COLUMNS)
8+
params = dict(start_date=args.start, end_date=args.end, output_path=args.output, output_cols=TOGGL_COLUMNS)
9+
10+
if args.client_ids:
11+
params.update(dict(client_ids=args.client_ids))
12+
if args.project_ids:
13+
params.update(dict(project_ids=args.project_ids))
14+
if args.task_ids:
15+
params.update(dict(task_ids=args.task_ids))
16+
if args.user_ids:
17+
params.update(dict(user_ids=args.user_ids))
18+
19+
download_time_entries(**params)
920

1021
return RESULT_SUCCESS

compiler_admin/main.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,38 @@ def setup_time_command(cmd_parsers: _SubParsersAction):
9494
time_download.add_argument(
9595
"--output", default=sys.stdout, help="The path to the file where converted data should be written. Defaults to stdout."
9696
)
97+
time_download.add_argument(
98+
"--client",
99+
dest="client_ids",
100+
metavar="CLIENT_ID",
101+
action="append",
102+
type=int,
103+
help="An ID for a Toggl Client to filter for in reports. Can be supplied more than once.",
104+
)
105+
time_download.add_argument(
106+
"--project",
107+
dest="project_ids",
108+
metavar="PROJECT_ID",
109+
action="append",
110+
type=int,
111+
help="An ID for a Toggl Project to filter for in reports. Can be supplied more than once.",
112+
)
113+
time_download.add_argument(
114+
"--task",
115+
dest="task_ids",
116+
metavar="TASK_ID",
117+
action="append",
118+
type=int,
119+
help="An ID for a Toggl Project Task to filter for in reports. Can be supplied more than once.",
120+
)
121+
time_download.add_argument(
122+
"--user",
123+
dest="user_ids",
124+
metavar="USER_ID",
125+
action="append",
126+
type=int,
127+
help="An ID for a Toggl User to filter for in reports. Can be supplied more than once.",
128+
)
97129

98130

99131
def setup_user_command(cmd_parsers: _SubParsersAction):

tests/commands/time/test_download.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,42 @@ def mock_download_time_entries(mocker):
1313

1414
def test_download_default(mock_download_time_entries):
1515
date = datetime.now()
16-
args = Namespace(start=date, end=date, output="output")
16+
args = Namespace(
17+
start=date,
18+
end=date,
19+
output="output",
20+
client_ids=None,
21+
project_ids=None,
22+
task_ids=None,
23+
user_ids=None,
24+
)
1725

1826
res = download(args)
1927

2028
assert res == RESULT_SUCCESS
21-
mock_download_time_entries.assert_called_once_with(args.start, args.end, args.output, TOGGL_COLUMNS)
29+
mock_download_time_entries.assert_called_once_with(
30+
start_date=args.start,
31+
end_date=args.end,
32+
output_path=args.output,
33+
output_cols=TOGGL_COLUMNS,
34+
)
35+
36+
37+
def test_download_ids(mock_download_time_entries):
38+
date = datetime.now()
39+
ids = [1, 2, 3]
40+
args = Namespace(start=date, end=date, output="output", client_ids=ids, project_ids=ids, task_ids=ids, user_ids=ids)
41+
42+
res = download(args)
43+
44+
assert res == RESULT_SUCCESS
45+
mock_download_time_entries.assert_called_once_with(
46+
start_date=args.start,
47+
end_date=args.end,
48+
output_path=args.output,
49+
output_cols=TOGGL_COLUMNS,
50+
client_ids=ids,
51+
project_ids=ids,
52+
task_ids=ids,
53+
user_ids=ids,
54+
)

tests/test_main.py

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,17 +122,62 @@ def test_main_time_download_default(mock_commands_time, mock_start, mock_end):
122122
call_args = mock_commands_time.call_args.args
123123
assert (
124124
Namespace(
125-
func=mock_commands_time, command="time", subcommand="download", start=mock_start, end=mock_end, output=sys.stdout
125+
func=mock_commands_time,
126+
command="time",
127+
subcommand="download",
128+
start=mock_start,
129+
end=mock_end,
130+
output=sys.stdout,
131+
client_ids=None,
132+
project_ids=None,
133+
task_ids=None,
134+
user_ids=None,
126135
)
127136
in call_args
128137
)
129138

130139

131140
def test_main_time_download_args(mock_commands_time):
132-
main(argv=["time", "download", "--start", "2024-01-01", "--end", "2024-01-31", "--output", "file.csv"])
141+
main(
142+
argv=[
143+
"time",
144+
"download",
145+
"--start",
146+
"2024-01-01",
147+
"--end",
148+
"2024-01-31",
149+
"--output",
150+
"file.csv",
151+
"--client",
152+
"1",
153+
"--client",
154+
"2",
155+
"--client",
156+
"3",
157+
"--project",
158+
"1",
159+
"--project",
160+
"2",
161+
"--project",
162+
"3",
163+
"--task",
164+
"1",
165+
"--task",
166+
"2",
167+
"--task",
168+
"3",
169+
"--user",
170+
"1",
171+
"--user",
172+
"2",
173+
"--user",
174+
"3",
175+
]
176+
)
133177

134178
expected_start = TZINFO.localize(datetime(2024, 1, 1))
135179
expected_end = TZINFO.localize(datetime(2024, 1, 31))
180+
ids = [1, 2, 3]
136181

137182
mock_commands_time.assert_called_once()
138183
call_args = mock_commands_time.call_args.args
@@ -144,6 +189,10 @@ def test_main_time_download_args(mock_commands_time):
144189
start=expected_start,
145190
end=expected_end,
146191
output="file.csv",
192+
client_ids=ids,
193+
project_ids=ids,
194+
task_ids=ids,
195+
user_ids=ids,
147196
)
148197
in call_args
149198
)

0 commit comments

Comments
 (0)