dovico 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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/.