dovico 1.1.0 → 1.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b6d0fc89e13ae40ce8fba111ea73420cb03dced3
4
- data.tar.gz: 2e41cc97b937deb844a8d6da1c24eb3e3f2d3483
3
+ metadata.gz: 641eaa573848e60b70368be58db24872e2237a24
4
+ data.tar.gz: ca2e3477d9d1a70545e95d223aed5101796aec50
5
5
  SHA512:
6
- metadata.gz: 44898ec1528b4f6e4c40cba7d2e44ff3b6b8101cc6b00b39ff5736e80ac87dd6fb0853b459fb8c34e56c8e2068479e4401da83ff3a547447c65b9feebdd9d64a
7
- data.tar.gz: 60fa2fd23b39d6a76ed0279a655efce636b3406aafefdfb8b6a04bd1b410190af5610b6b5d383d8a58065aa8c07298571e3549f01708b9d275a8b5948301942e
6
+ metadata.gz: 4b837afe730bbc5fe4a057c2b71ba8910a73cb50d0de4cc5dd9a738d0eecc79d19c7c108709f9d6f2bf4559e22cf93ba223e8d6af0fb6fc7a84a6cc2acd0a3b3
7
+ data.tar.gz: 8a7550467aaafa92c599e1f9aa556a534ca15cdb35c0a095523cb4f5e50b97bf8e2755648cefae7590f8f44688a10bc9782ba5fdf40d31f880489dd7d0337a52
data/CHANGELOG.md CHANGED
@@ -1,4 +1,11 @@
1
1
  # Next version
2
+ - Your contribution!
3
+
4
+ # Version 1.2.0
5
+ - Update [README.md](README.md)
6
+ - Add `--clear` option to delete time entries
7
+ - Fix a typo on Projet URL
8
+ - Fix formatting tasks list when mutliple tasks are associated to an assignment
2
9
 
3
10
  # Version 1.1.0
4
11
  - Remove `bin/console` from the Gem
data/README.md CHANGED
@@ -2,9 +2,16 @@
2
2
 
3
3
  Repository for Dovico API management.
4
4
 
5
+ # Requirements
6
+ - Ruby 2.2.2 or newer
7
+
5
8
  # Installation
9
+ `gem install dovico`
10
+
11
+ # Configuration
12
+
6
13
  ## Dovico authentication
7
- Dovico provide a way to generate a 3rd party token. This token provide a full access to your account:
14
+ Dovico provide a way to generate a 3rd party token. This token provides a full access to your account:
8
15
  - Do not expose your token.
9
16
  - If you believe your token has been exposed publicly, regenerate a new one. The previous token will be invalidated.
10
17
 
@@ -22,15 +29,11 @@ user_token: "<token you have copied from dovico.net page>"
22
29
  client_token: "<token given by your company's dovico admin>"
23
30
  ~~~
24
31
 
25
- ## Install required libraries
26
- * Install Ruby 2.4.0
27
- * `make install`
28
-
29
32
  ## Setup your default timesheet
30
- * List the available tasks with `make tasks`
33
+ * List the available tasks with `dovico --tasks`
31
34
 
32
35
  ~~~
33
- $ make tasks
36
+ $ dovico --tasks
34
37
  == List of available projects ==
35
38
  Project | Task | Description
36
39
  1200 | 100 | Sauron Project: Forge the One Ring
@@ -74,30 +77,79 @@ assignments:
74
77
 
75
78
  # Usage
76
79
  ## Display informations on your account
77
- `make myself`
80
+ `dovico --myself`
81
+
82
+ ~~~
83
+ $ dovico --myself
84
+ Informations about yourself
85
+ - ID: 42
86
+ - First Name: Gandalf
87
+ - Last Name: The White
88
+ ~~~
78
89
 
79
90
  ## Display the list of the tasks
80
- `make tasks`
91
+ `dovico --tasks`
92
+ ~~~
93
+ $ dovico --tasks
94
+ == List of available projects ==
95
+ Project | Task | Description
96
+ 1200 | 100 | Sauron Project: Forge the One Ring
97
+ 1200 | 110 | Sauron Project: Attack Gondor
98
+ 1400 | 100 | Gandalf Project: Meet Bilbo
99
+ 1400 | 120 | Gandalf Project: Convince Frodo
100
+ 1600 | 100 | Frodo Project: Go home
101
+ ~~~
81
102
 
82
103
  ## Fill the timesheet
104
+ `dovico --fill [date options]`
105
+
106
+ The date options are detailed below. All the other commands use the same format for these date options.
107
+
83
108
  ### For the current week
84
- `make current_week`
109
+ `dovico --fill --current_week`
85
110
 
86
111
  ### For today
87
- `make today`
112
+ `dovico --fill --today`
88
113
 
89
114
  ### For a specific [commercial week](http://www.epochconverter.com/weeks/)
90
- `make week WEEK=49`
115
+ `dovicon --fill --week=49`
91
116
 
92
117
  Year can be set too:
93
- `make week YEAR=2015 WEEK=40`
118
+ `dovico --fill --year=2015 --week=40`
94
119
 
95
120
  ### For a specific day
96
- `make day DAY=2017-12-31`
121
+ `dovico --fill --day=2017-12-31`
97
122
 
98
- # Restrictions and known issues
99
- * The client can't edit already created timesheets for now.
123
+ ## Show the timesheet
124
+ `dovico --show [date options]`
125
+
126
+ ~~~
127
+ $ dovico --show --start=2017-01-02 --end=2017-01-12
128
+ == List of Time Entries between 2017-01-02 and 2017-01-06 ==
129
+ 2017-01-02 [××××××××××××××] : [not_submitted] 7h Sauron Project: Forge the One Ring
130
+ 2017-01-03 [××××××××××××××] : [not_submitted] 7h Sauron Project: Attack Gondor
131
+ 2017-01-12 [××××] : [under_review] 2h Gandalf Project: Meet Bilbo
132
+ 2017-01-12 [××××××××] : [under_review] 4h Gandalf Project: Convince Frodo
133
+ 2017-01-12 [××] : [under_review] 1h Frodo Project: Go home
134
+ ~~~
135
+
136
+ ## Submit the timesheet
137
+ `dovico --submit [date options]`
138
+
139
+ Once submitted, the timesheet can't be edited.
140
+
141
+ ## Delete timesheet
142
+ `dovico --clear [date options]`
143
+
144
+ A confirmation will be asked before the deletion.
145
+ ~~~
146
+ $ dovico --clear --day=2017-01-05
147
+ • 1 Time Entries to be deleted. Are you sure? (yes/no)
148
+ yes
149
+ ✓ 1 Time Entries deleted
150
+ ~~~
100
151
 
152
+ # Contributing
101
153
  You are warmly welcome to contribute to the project!
102
154
 
103
155
  # Dovico API Documentation
@@ -22,6 +22,7 @@ Gem::Specification.new do |s|
22
22
  s.add_dependency 'easy_app_helper'
23
23
  s.add_dependency 'active_attr'
24
24
  s.add_dependency 'typhoeus'
25
+ s.add_dependency 'highline'
25
26
 
26
27
  s.add_development_dependency 'pry'
27
28
  s.add_development_dependency 'guard'
@@ -24,6 +24,10 @@ module Dovico
24
24
  perform!(:put, path, params: params, body: body)
25
25
  end
26
26
 
27
+ def delete(path, params: {}, body: nil)
28
+ perform!(:delete, path, params: params, body: body)
29
+ end
30
+
27
31
  private
28
32
 
29
33
  attr_accessor :client_token, :user_token
@@ -60,7 +64,11 @@ module Dovico
60
64
  raise "Error during HTTP request"
61
65
  end
62
66
 
63
- JSON.parse(response.body)
67
+ if response.body.length > 0
68
+ JSON.parse(response.body)
69
+ else
70
+ nil
71
+ end
64
72
  end
65
73
  end
66
74
  end
data/lib/dovico/app.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'easy_app_helper'
2
+ require 'highline'
2
3
 
3
4
  module Dovico
4
5
  class App
@@ -37,7 +38,10 @@ EOL
37
38
  config.add_command_line_section('Submit the timesheets') do |slop|
38
39
  slop.on :submit, 'Submit timesheets', argument: false
39
40
  end
40
- config.add_command_line_section('Date options (required for --show, --fill and --submit)') do |slop|
41
+ config.add_command_line_section('Clear the timesheets') do |slop|
42
+ slop.on :clear, 'Clear the timesheets', argument: false
43
+ end
44
+ config.add_command_line_section('Date options (required for --show, --fill, --submit and --clear)') do |slop|
41
45
  slop.on :current_week, 'Current week', argument: false
42
46
  slop.on :today, 'Current day', argument: false
43
47
  slop.on :day, 'Specific day', argument: true
@@ -65,6 +69,10 @@ EOL
65
69
  display_tasks
66
70
  end
67
71
 
72
+ if config[:clear]
73
+ clear_time_entries(start_date, end_date)
74
+ end
75
+
68
76
  if config[:show]
69
77
  display_time_entries(start_date, end_date)
70
78
  end
@@ -112,8 +120,22 @@ EOL
112
120
  puts ""
113
121
  end
114
122
 
123
+ def clear_time_entries(start_date, end_date)
124
+ time_entries = TimeEntry.search(start_date, end_date)
125
+ if highline.agree("• #{time_entries.count} Time Entries to be deleted. Are you sure? (yes/no)")
126
+ time_entries.each do |time_entry|
127
+ time_entry.delete!
128
+ end
129
+ puts "✓ #{time_entries.count} Time Entries deleted"
130
+ end
131
+ end
132
+
115
133
  def display_help
116
134
  puts config.command_line_help
117
135
  end
136
+
137
+ def highline
138
+ @highline ||= HighLine.new
139
+ end
118
140
  end
119
141
  end
@@ -1,6 +1,7 @@
1
1
  module Dovico
2
2
  class ConfigParser
3
- AVAILABLE_ACTIONS = [:myself, :tasks, :show, :fill, :submit]
3
+ AVAILABLE_ACTIONS = [:myself, :tasks, :show, :fill, :submit, :clear]
4
+ DATE_REQUIRED_ACTIONS = [:show, :fill, :submit, :clear]
4
5
 
5
6
  def initialize(config)
6
7
  @config = config
@@ -12,7 +13,7 @@ module Dovico
12
13
  true
13
14
  elsif AVAILABLE_ACTIONS.map{|action| config[action] }.compact.empty?
14
15
  true
15
- elsif (config[:fill] || config[:submit]) && !(@start_date && @end_date)
16
+ elsif !(@start_date && @end_date) && !DATE_REQUIRED_ACTIONS.map{|action| config[action] }.compact.empty?
16
17
  true
17
18
  else
18
19
  false
@@ -2,7 +2,7 @@ require 'active_attr'
2
2
 
3
3
  module Dovico
4
4
  class Assignment
5
- URL_PATH = 'Assignments/'
5
+ URL_PATH = 'Assignments'
6
6
 
7
7
  include ActiveAttr::Model
8
8
 
@@ -2,7 +2,7 @@ require 'active_attr'
2
2
 
3
3
  module Dovico
4
4
  class Employee
5
- URL_PATH = 'Employees/'
5
+ URL_PATH = 'Employees'
6
6
 
7
7
  include ActiveAttr::Model
8
8
 
@@ -16,15 +16,19 @@ module Dovico
16
16
  projects = projects_search["Assignments"].map {|project_hash| parse(project_hash) }
17
17
 
18
18
  projects.each do |project|
19
- tasks_search = ApiClient.get("#{URL_PATH}#{project.assignement_id}")
20
- project.tasks = tasks_search["Assignments"].map {|task_hash| Task.parse(task_hash) }
19
+ tasks_search = ApiClient.get("#{URL_PATH}/#{project.assignement_id}")
20
+ tasks = tasks_search["Assignments"].map {|task_hash| Task.parse(task_hash) }
21
+
22
+ project.tasks = tasks.sort_by do |task|
23
+ task.id
24
+ end
21
25
  end
22
26
 
23
27
  projects
24
28
  end
25
29
 
26
30
  def self.format_all
27
- text = " Project | Task | Description"
31
+ text = " Project | Task | Description\n"
28
32
  text += all.map(&:to_s).join("\n")
29
33
  end
30
34
 
@@ -32,9 +36,9 @@ module Dovico
32
36
  text = ''
33
37
 
34
38
  if tasks.count > 0
35
- tasks.each do |task|
36
- text += sprintf ' %7d | %4d | %s: %s', id, task.id, name, task.name
37
- end
39
+ text += tasks.map do |task|
40
+ sprintf " %7d | %4d | %s: %s", id, task.id, name, task.name
41
+ end.join("\n")
38
42
  else
39
43
  text += sprintf " %7d | | %s (No tasks linked)", id, name
40
44
  end
@@ -2,7 +2,7 @@ require 'active_attr'
2
2
 
3
3
  module Dovico
4
4
  class TimeEntry
5
- URL_PATH = 'TimeEntries/'
5
+ URL_PATH = 'TimeEntries'
6
6
 
7
7
  include ActiveAttr::Model
8
8
 
@@ -41,7 +41,7 @@ module Dovico
41
41
 
42
42
  def self.search(start_date, end_date)
43
43
  api_response = ApiClient.get(
44
- "#{URL_PATH}",
44
+ URL_PATH,
45
45
  params: {
46
46
  daterange: "#{start_date} #{end_date}"
47
47
  },
@@ -75,6 +75,10 @@ module Dovico
75
75
  ApiClient.put(URL_PATH, body: [to_api].to_json)
76
76
  end
77
77
 
78
+ def delete!
79
+ ApiClient.delete("#{URL_PATH}/#{id}")
80
+ end
81
+
78
82
  def to_api
79
83
  {
80
84
  "ID": id,
@@ -1,3 +1,3 @@
1
1
  module Dovico
2
- VERSION = '1.1.0'
2
+ VERSION = '1.2.0'
3
3
  end
@@ -77,5 +77,15 @@ module Dovico
77
77
  expect(response).to eq({"Stubbed": "Response"}.stringify_keys)
78
78
  end
79
79
  end
80
+
81
+ describe ".delete" do
82
+ it 'perform a DELETE request' do
83
+ stub_request(:delete, "#{Dovico::ApiClient::API_URL}TimeEntries/42?version=#{Dovico::ApiClient::API_VERSION}")
84
+ .to_return(body: '')
85
+
86
+ response = Dovico::ApiClient.delete('TimeEntries/42')
87
+ expect(response).to eq(nil)
88
+ end
89
+ end
80
90
  end
81
91
  end
@@ -20,7 +20,14 @@ module Dovico
20
20
  "Assignments": [project_api_hash]
21
21
  }.stringify_keys
22
22
  end
23
- let(:task_api_hash) do
23
+ let(:task_api_hash_1) do
24
+ {
25
+ "ItemID": "995",
26
+ "AssignmentID": "E456",
27
+ "Name": "Task write specs, second part",
28
+ }.stringify_keys
29
+ end
30
+ let(:task_api_hash_2) do
24
31
  {
25
32
  "ItemID": "789",
26
33
  "AssignmentID": "E456",
@@ -31,14 +38,14 @@ module Dovico
31
38
  end
32
39
  let(:tasks_api_hash) do
33
40
  {
34
- "Assignments": [task_api_hash]
41
+ "Assignments": [task_api_hash_1, task_api_hash_2]
35
42
  }.stringify_keys
36
43
  end
37
44
 
38
45
  describe ".all" do
39
46
  before do
40
47
  allow(ApiClient).to receive(:get).with(Dovico::Project::URL_PATH).and_return(projects_api_hash)
41
- allow(ApiClient).to receive(:get).with("#{Dovico::Project::URL_PATH}T456").and_return(tasks_api_hash)
48
+ allow(ApiClient).to receive(:get).with("#{Dovico::Project::URL_PATH}/T456").and_return(tasks_api_hash)
42
49
  end
43
50
 
44
51
  it "lists all the assignements" do
@@ -50,7 +57,7 @@ module Dovico
50
57
  expect(project.id).to eq('123')
51
58
  expect(project.name).to eq('Project Dovico API Client')
52
59
 
53
- expect(project.tasks.count).to eq(1)
60
+ expect(project.tasks.count).to eq(2)
54
61
  task = project.tasks.first
55
62
  expect(task.id).to eq('789')
56
63
  expect(task.name).to eq('Task write specs')
@@ -60,11 +67,16 @@ module Dovico
60
67
  describe ".format_all" do
61
68
  before do
62
69
  allow(ApiClient).to receive(:get).with(Dovico::Project::URL_PATH).and_return(projects_api_hash)
63
- allow(ApiClient).to receive(:get).with("#{Dovico::Project::URL_PATH}T456").and_return(tasks_api_hash)
70
+ allow(ApiClient).to receive(:get).with("#{Dovico::Project::URL_PATH}/T456").and_return(tasks_api_hash)
64
71
  end
65
72
 
66
73
  it 'returns projects with formatted text' do
67
- expect(Dovico::Project.format_all).to eq(" Project | Task | Description 123 | 789 | Project Dovico API Client: Task write specs")
74
+ expected_strings = [
75
+ ' Project | Task | Description',
76
+ ' 123 | 789 | Project Dovico API Client: Task write specs',
77
+ ' 123 | 995 | Project Dovico API Client: Task write specs, second part',
78
+ ]
79
+ expect(Dovico::Project.format_all).to eq(expected_strings.join("\n"))
68
80
  end
69
81
  end
70
82
 
@@ -182,6 +182,18 @@ module Dovico
182
182
  end
183
183
  end
184
184
 
185
+ describe ".delete!" do
186
+ before do
187
+ allow(ApiClient).to receive(:delete)
188
+ end
189
+
190
+ it 'calls the API and delete TimeEntries objects' do
191
+ subject.delete!
192
+
193
+ expect(ApiClient).to have_received(:delete).with("#{Dovico::TimeEntry::URL_PATH}/#{subject.id}")
194
+ end
195
+ end
196
+
185
197
  describe ".to_api" do
186
198
  it 'serializes the object' do
187
199
  expect(subject.to_api).to eq(
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dovico
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Théophile Helleboid
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-02-09 00:00:00.000000000 Z
12
+ date: 2017-10-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: easy_app_helper
@@ -53,6 +53,20 @@ dependencies:
53
53
  - - ">="
54
54
  - !ruby/object:Gem::Version
55
55
  version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: highline
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
56
70
  - !ruby/object:Gem::Dependency
57
71
  name: pry
58
72
  requirement: !ruby/object:Gem::Requirement
@@ -332,7 +346,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
332
346
  version: '0'
333
347
  requirements: []
334
348
  rubyforge_project:
335
- rubygems_version: 2.6.8
349
+ rubygems_version: 2.6.13
336
350
  signing_key:
337
351
  specification_version: 4
338
352
  summary: Simple client & tools for http://www.dovico.com/.