freeagent-cli 0.1 → 0.2

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.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/exe/fa +42 -12
  4. data/lib/freeagent.rb +9 -2
  5. metadata +18 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b6aa92b15fccb2ce8b889419652ee23e76455f9dea0f84afef73dbb2d33af023
4
- data.tar.gz: 3329b71e37fcea5d277b3e05ba61972dd85f204c49bbe264568d555b15184d44
3
+ metadata.gz: 7abedc65bda2e935eac6777922e6b06f227745e2de0b1e60b8e1de95c72a0d83
4
+ data.tar.gz: b2c6ae0c9595a8087cf87360a8dc62ba9c5c4eb02da2e6b0a7cba346fb7f0a4b
5
5
  SHA512:
6
- metadata.gz: cdfb521afa51bb920e46965da8e965b9bb5d32b1a659a91746fda0801b790f9cac07e563dd8f5caefca026e3df35bc2345974d47d4a85ff694a33fe5518c8818
7
- data.tar.gz: 3c3a1be9095e29c94289320b3c471444166047fb5a766bb1daf88fa5ae83e35d22aed735363c5e07b17a81bb11ec28bd92f394cc47ab362fa2c3b3846346cfb6
6
+ metadata.gz: 29fd16c93ea509618580da1d8b6e45738cc25917a945d77e213ef53cd8e345c57e118a2cfe493d28b497ba7de9b5b658b57af6fb26edb58a2e4307ea859e1d0e
7
+ data.tar.gz: c648be179c9d9ab46a9831b4a2d3ca412fd47bb2c4db729f86737b588bf46819d1ac0dbc747841a9d0ac7db6f025e5be63c4f39773e2c6444c727ce5d9f198ff
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- The MIT License (MIT)
1
+ The MIT License (MIT)
2
2
 
3
3
  Copyright © 2025 Register Dynamics Limited.
4
4
 
data/exe/fa CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ require 'dotenv/load'
3
4
  require 'thor'
4
5
  require_relative '../lib/freeagent'
5
6
 
@@ -33,17 +34,18 @@ module Freeagent
33
34
  project = match :project, api.projects, project, :name
34
35
  task = match :task, api.tasks(project), task, :name
35
36
 
36
- api.timeslips(user, project, task, from, to).each do |timeslip|
37
- puts [Date::parse(timeslip.dated_on).strftime('%a %d %b %Y'), user.email, project.name, task.name, timeslip.hours].join("\t")
37
+ api.timeslips(user: user, project: project, task: task, from: from, to: to).each do |timeslip|
38
+ puts [Date::parse(timeslip.dated_on).strftime('%a %d %b %Y'), user.email, project.name, task.name, timeslip.hours, timeslip.comment].join("\t")
38
39
  end
39
40
  end
40
41
 
41
- desc 'create USER PROJECT TASK FROM TO', "Create timeslips"
42
+ desc 'create USER PROJECT TASK [FROM [TO]]', "Create timeslips"
42
43
  method_option :hours, aliases: '-h', type: :numeric, default: 8, desc: "Number of hours per day"
43
44
  method_option :weekends, aliases: '-w', type: :boolean, default: false, desc: "Create timeslips on Saturdays and Sundays"
44
- def create user, project, task, from, to
45
- from = Date::parse from
46
- to = Date::parse to
45
+ method_option :comment, aliases: '-c', type: :string, default: nil, desc: "Comment to add to any created timeslips"
46
+ def create user, project, task, from = nil, to = nil
47
+ from = from.nil? ? Date::today : Date::parse(from)
48
+ to = to.nil? ? from : Date::parse(to)
47
49
  user = match :user, api.users, user, :first_name, :last_name, :email
48
50
  project = match :project, api.projects, project, :name
49
51
  task = match :task, api.tasks(project), task, :name
@@ -51,21 +53,49 @@ module Freeagent
51
53
  puts "Creating timeslips for #{user.first_name} #{user.last_name} for task '#{task.name}' in project '#{project.name}' between #{from} and #{to} inclusive"
52
54
  timeslips = from.step(to).map do |date|
53
55
  next if (date.saturday? || date.sunday?) && !options[:weekends]
54
- {'task' => task.url, 'project' => project.url, 'user' => user.url, 'dated_on' => date.to_s, 'hours' => options[:hours]}
56
+ {'task' => task.url, 'project' => project.url, 'user' => user.url, 'dated_on' => date.to_s, 'hours' => options[:hours], 'comment' => options[:comment]}
55
57
  end.reject(&:nil?)
56
58
  api.batch_create_timeslips timeslips
57
59
  end
58
60
 
59
- desc 'delete USER PROJECT TASK FROM TO', 'Delete timeslips'
60
- def delete user, project, task, from, to
61
- from = Date::parse from
62
- to = Date::parse to
61
+ desc 'fill USER PROJECT TASK [FROM [TO]]', 'Fill remaining hours with new timeslips'
62
+ method_option :hours, aliases: '-h', type: :numeric, default: 8, desc: "Number of hours per day"
63
+ method_option :weekends, aliases: '-w', type: :boolean, default: false, desc: "Create timeslips on Saturdays and Sundays"
64
+ method_option :comment, aliases: '-c', type: :string, default: nil, desc: "Comment to add to any created timeslips"
65
+ def fill user, project, task, from = nil, to = nil
66
+ from = from.nil? ? Date::today : Date::parse(from)
67
+ to = to.nil? ? from : Date::parse(to)
68
+ user = match :user, api.users, user, :first_name, :last_name, :email
69
+ project = match :project, api.projects, project, :name
70
+ task = match :task, api.tasks(project), task, :name
71
+
72
+ existing = api.timeslips(user: user, from: from, to: to).reduce(Hash.new) do |hash, timeslip|
73
+ date = Date::parse timeslip.dated_on
74
+ hash.update({date => (hash[date] || 0) + timeslip.hours.to_f})
75
+ end
76
+
77
+ puts "Filling timeslips for #{user.first_name} #{user.last_name} up to #{options[:hours]}hrs using task '#{task.name}' in project '#{project.name}' between #{from} and #{to} inclusive"
78
+ timeslips = from.step(to).map do |date|
79
+ next if (date.saturday? || date.sunday?) && !options[:weekends]
80
+ existing_hours = existing[date] || 0
81
+ adding_hours = options[:hours] - existing_hours
82
+ next if adding_hours <= 0
83
+
84
+ {'task' => task.url, 'project' => project.url, 'user' => user.url, 'dated_on' => date.to_s, 'hours' => adding_hours.to_s, 'comment' => options[:comment]}
85
+ end.reject(&:nil?)
86
+ api.batch_create_timeslips timeslips
87
+ end
88
+
89
+ desc 'delete USER PROJECT TASK [FROM [TO]]', 'Delete timeslips'
90
+ def delete user, project, task, from = nil, to = nil
91
+ from = from.nil? ? Date::today : Date::parse(from)
92
+ to = to.nil? ? from : Date::parse(to)
63
93
  user = match :user, api.users, user, :first_name, :last_name, :email
64
94
  project = match :project, api.projects, project, :name
65
95
  task = match :task, api.tasks(project), task, :name
66
96
 
67
97
  puts "Deleting timeslips for #{user.first_name} #{user.last_name} for task '#{task.name}' in project '#{project.name}' between #{from} and #{to} inclusive"
68
- api.timeslips(user, project, task, from, to).each do |timeslip|
98
+ api.timeslips(user: user, project: project, task: task, from: from, to: to).each do |timeslip|
69
99
  api.delete_timeslip(timeslip)
70
100
  end
71
101
  end
data/lib/freeagent.rb CHANGED
@@ -134,8 +134,15 @@ module Freeagent
134
134
  get_pages('tasks', project: project.url).flat_map(&:tasks)
135
135
  end
136
136
 
137
- def timeslips user, project, task, from, to
138
- get_pages('timeslips', user: user.url, project: project.url, task: task.url, from_date: from.to_s, to_date: to.to_s).flat_map(&:timeslips)
137
+ def timeslips user: nil, project: nil, task: nil, from: nil, to: nil
138
+ params = [
139
+ [:user, user && user.url],
140
+ [:project, project && project.url],
141
+ [:task, task && task.url],
142
+ [:from_date, from && from.to_s],
143
+ [:to_date, to && to.to_s],
144
+ ].reject {|(k, v)| v.nil?}.to_h
145
+ get_pages('timeslips', **params).flat_map(&:timeslips)
139
146
  end
140
147
 
141
148
  def create_timeslip user, project, task, dated, hours
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: freeagent-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.1'
4
+ version: '0.2'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Worthington
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: dotenv
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">"
60
+ - !ruby/object:Gem::Version
61
+ version: 2.1.2
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">"
67
+ - !ruby/object:Gem::Version
68
+ version: 2.1.2
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -87,12 +101,12 @@ files:
87
101
  - Rakefile
88
102
  - exe/fa
89
103
  - lib/freeagent.rb
90
- homepage: https://www.github.com/register-dynamics/freeagent-cli
104
+ homepage: https://github.com/register-dynamics/freeagent-cli.git
91
105
  licenses:
92
106
  - MIT
93
107
  metadata:
94
- homepage_uri: https://www.github.com/register-dynamics/freeagent-cli
95
- source_code_uri: https://www.github.com/register-dynamics/freeagent-cli
108
+ homepage_uri: https://github.com/register-dynamics/freeagent-cli.git
109
+ source_code_uri: https://github.com/register-dynamics/freeagent-cli.git
96
110
  post_install_message:
97
111
  rdoc_options: []
98
112
  require_paths: