harvestime 0.0.2 → 0.0.3
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/README.md +8 -2
- data/bin/harvestime.rb +113 -0
- data/lib/harvestime/interface.rb +2 -1
- data/lib/harvestime/time_filter.rb +25 -12
- data/lib/harvestime/version.rb +1 -1
- data/spec/harvestime/time_filter_spec.rb +1 -1
- metadata +5 -4
- data/.DS_Store +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f617962a7dc85f1afdf1f4652025c24be54d71c
|
4
|
+
data.tar.gz: 9f5875f24089c193ff9c505c6433d7c8b9b44faf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a84ea57ef99bf77dc5808108cf234d58d3c9a23162375a158d4c6612487a7ff2b14e4ee404326a5880b4dd14c0daff9bc5ee44b2cb8740baa60dd8d9b550b00
|
7
|
+
data.tar.gz: 9e968419b8586bb2c11ed5f1dc23a5ce70bef06e7ff940d0a29ed3723482b2e19f0232ba158c20a57b66952b2243fb7415ad683148db1bc56132cadf02b625e3
|
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# Harvestime
|
2
|
+
Utility library for streamlining and automating time and invoice management in Harvest
|
3
|
+
|
4
|
+
Forks and pulls welcome, will be using github for issue tracking as well.
|
2
5
|
|
3
|
-
TODO: Write a gem description
|
4
6
|
|
5
7
|
## Installation
|
6
8
|
|
@@ -18,7 +20,11 @@ Or install it yourself as:
|
|
18
20
|
|
19
21
|
## Usage
|
20
22
|
|
21
|
-
|
23
|
+
Create a Harvest interface with:
|
24
|
+
|
25
|
+
Harvestime.interface('subdomain','username','password')
|
26
|
+
|
27
|
+
|
22
28
|
|
23
29
|
## Contributing
|
24
30
|
|
data/bin/harvestime.rb
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'harvested'
|
3
|
+
require 'harvestime'
|
4
|
+
require 'thor'
|
5
|
+
require 'yaml'
|
6
|
+
require 'pp'
|
7
|
+
|
8
|
+
class HarvestimeCLI < Thor
|
9
|
+
include Thor::Actions
|
10
|
+
# Invoices
|
11
|
+
desc 'all_invoices <STATUS> <ACCOUNT_INDEX>',
|
12
|
+
'Find all invoices with optional status and account index'
|
13
|
+
method_option :status, aliases: '-s', default: 'all', type: :string, banner: 'status of the invoice'
|
14
|
+
method_option :account_index, aliases: '-a', default: 0, type: :numeric, banner: 'Account index according to %HOME%/.harvestime_client.yml'
|
15
|
+
def all_invoices
|
16
|
+
puts "Account index given #{options[:account_index]}"
|
17
|
+
credentials = YAML.load(File.open(File.join(Dir.home, '.harvestime_client.yml')))
|
18
|
+
client = Harvest.hardy_client(credentials[options[:account_index]][:subdomain],
|
19
|
+
credentials[options[:account_index]][:username],
|
20
|
+
credentials[options[:account_index]][:password])
|
21
|
+
pp Harvestime::InvoiceFilter.new(client).all_with_status(options[:status])
|
22
|
+
end
|
23
|
+
|
24
|
+
# Time
|
25
|
+
desc 'all_times <ACCOUNT_INDEX> <DATE>',
|
26
|
+
"Find all of a date's time entries, defaulting to today and the first account"
|
27
|
+
method_option :account_index, aliases: '-a', default: 0, type: :numeric, banner: 'Account index according to %HOME%/.harvestime_client.yml'
|
28
|
+
method_option :date, aliases: '-d', default: Date.today.to_s, type: :string, banner: 'Entry date'
|
29
|
+
def all_times
|
30
|
+
credentials = YAML.load(File.open(File.join(Dir.home, '.harvestime_client.yml')))
|
31
|
+
client = Harvest.hardy_client(credentials[options[:account_index]][:subdomain],
|
32
|
+
credentials[options[:account_index]][:username],
|
33
|
+
credentials[options[:account_index]][:password])
|
34
|
+
pp Harvestime::TimeFilter.new(client).all_times_in_date(Date.parse(options[:date]))
|
35
|
+
end
|
36
|
+
|
37
|
+
desc 'create_time_entry [PROJECT_ID] [TASK_ID] <ACCOUNT_INDEX> <NOTES> <HOURS> <SPENT_AT>',
|
38
|
+
'Create a time entry with a given project and task id, with optional account index, notes, hours spent, and date spent at.'
|
39
|
+
method_option :project_id, required: true, aliases: '-p', type: :numeric, banner: 'project id'
|
40
|
+
method_option :task_id, required: true, aliases: '-t', type: :numeric, banner: 'task id'
|
41
|
+
method_option :account_index, aliases: '-a', default: 0, type: :numeric, banner: 'Account index according to %HOME%/.harvestime_client.yml'
|
42
|
+
method_option :notes, aliases: '-n', default: '', type: :string, banner: 'Project Notes'
|
43
|
+
method_option :hours, aliases: '-h', default: 0, type: :numeric, banner: 'Time in hours spent on project'
|
44
|
+
method_option :spent_at, aliases: '-d', default: Date.today.to_s, type: :string, banner: 'Date for time entry'
|
45
|
+
def create_time_entry
|
46
|
+
credentials = YAML.load(File.open(File.join(Dir.home, '.harvestime_client.yml')))
|
47
|
+
client = Harvest.hardy_client(credentials[options[:account_index]][:subdomain],
|
48
|
+
credentials[options[:account_index]][:username],
|
49
|
+
credentials[options[:account_index]][:password])
|
50
|
+
time_filter = Harvestime::TimeFilter.new(client)
|
51
|
+
time_filter.create_entry(time_filter.build_entry( notes: options[:notes],
|
52
|
+
hours: options[:hours],
|
53
|
+
project_id: options[:project_id],
|
54
|
+
task_id: options[:task_id],
|
55
|
+
spent_at: options[:spent_at]))
|
56
|
+
puts "Entry created"
|
57
|
+
end
|
58
|
+
|
59
|
+
desc 'move_entry [FROM_ACCOUNT_INDEX] [TO_ACCOUNT_INDEX] [ENTRY_ID] <DATE>',
|
60
|
+
'Copy a time entry from one account to another, given the indexes for both accounts as well as the time entry id'
|
61
|
+
method_option :from_account, required: true, aliases: '-f', type: :numeric, banner: 'Time entry origin account index according to %HOME%/.harvestime_client.yml'
|
62
|
+
method_option :to_account, required: true, aliases: '-t', type: :numeric, banner: 'Time entry destination account index according to %HOME%/.harvestime_client.yml'
|
63
|
+
method_option :entry_id, required: true, aliases: '-e', type: :numeric, banner: 'Time entry ID'
|
64
|
+
method_option :date, aliases: '-d', default: Date.today.to_s, type: :string, banner: 'Date of time entry (default today)'
|
65
|
+
def move_entry
|
66
|
+
credentials = YAML.load(File.open(File.join(Dir.home, '.harvestime_client.yml')))
|
67
|
+
to_client = Harvest.hardy_client(credentials[options[:to_account]][:subdomain],
|
68
|
+
credentials[options[:to_account]][:username],
|
69
|
+
credentials[options[:to_account]][:password])
|
70
|
+
entry = to_client.time.all(options[:date]).detect {|ent| ent.id == options[:entry_id]}
|
71
|
+
if entry
|
72
|
+
pp Harvestime::TimeFilter.new(to_client)
|
73
|
+
.copy_entry_from(Harvest.hardy_client(credentials[options[:from_account]][:subdomain],
|
74
|
+
credentials[options[:from_account]][:username],
|
75
|
+
credentials[options[:from_account]][:password]), entry)
|
76
|
+
else
|
77
|
+
puts 'ERROR: Entry not found'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
desc 'move_date_range [FROM_ACCOUNT_INDEX] [TO_ACCOUNT_INDEX] [START_DATE] [END_DATE]',
|
82
|
+
'Copy several time entries from one account to another, given the indexes for both accounts as well as a start and an end date for the ragne of entries to move'
|
83
|
+
method_option :from_account, required: true, aliases: '-f', type: :numeric, banner: 'Time entry origin account index according to %HOME%/.harvestime_client.yml'
|
84
|
+
method_option :to_account, required: true, aliases: '-t', type: :numeric, banner: 'Time entry destination account index according to %HOME%/.harvestime_client.yml'
|
85
|
+
method_option :start_date, required: true, aliases: '-s', type: :string, banner: 'Start date (YYYY-MM-DD)'
|
86
|
+
method_option :end_date, required: true, aliases: '-e', type: :string, banner: 'End date (YYYY-MM-DD)'
|
87
|
+
def move_date_range
|
88
|
+
credentials = YAML.load(File.open(File.join(Dir.home, '.harvestime_client.yml')))
|
89
|
+
pp Harvestime::TimeFilter.new(Harvest.hardy_client(credentials[options[:to_account]][:subdomain],
|
90
|
+
credentials[options[:to_account]][:username],
|
91
|
+
credentials[options[:to_account]][:password]))
|
92
|
+
.copy_date_range(Harvest.hardy_client(credentials[options[:from_account]][:subdomain],
|
93
|
+
credentials[options[:from_account]][:username],
|
94
|
+
credentials[options[:from_account]][:password]),
|
95
|
+
options[:start_date], options[:end_date])
|
96
|
+
end
|
97
|
+
|
98
|
+
desc 'purge_times [ACCOUNT_INDEX] <FORCE> <START_DATE> <END_DATE>',
|
99
|
+
'Delete all time entries from today or a given date range'
|
100
|
+
method_option :account_index, required: true, aliases: '-a', type: :numeric, banner: 'Account index to clear time entries of'
|
101
|
+
method_option :force, default: false, aliases: '-f', type: :boolean, banner: 'Go through with the purge'
|
102
|
+
method_option :start_date, default: Date.today.to_s, type: :string, banner: 'Start date for range clearing'
|
103
|
+
method_option :end_date, default: Date.today.to_s, type: :string, banner: 'End date for range clearing'
|
104
|
+
def purge_times
|
105
|
+
credentials = YAML.load(File.open(File.join(Dir.home, '.harvestime_client.yml')))
|
106
|
+
pp Harvestime::TimeFilter.new(Harvest.hardy_client(credentials[options[:account_index]][:subdomain],
|
107
|
+
credentials[options[:account_index]][:username],
|
108
|
+
credentials[options[:account_index]][:password]))
|
109
|
+
.delete_date_range(options[:start_date], options[:end_date])
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
HarvestimeCLI.start
|
data/lib/harvestime/interface.rb
CHANGED
@@ -2,11 +2,9 @@ require 'harvested'
|
|
2
2
|
|
3
3
|
module Harvestime
|
4
4
|
class TimeFilter
|
5
|
-
|
6
5
|
def initialize(client)
|
7
6
|
@client = client
|
8
7
|
end
|
9
|
-
|
10
8
|
def scale_entry(time_entry, modifier)
|
11
9
|
time_entry.hours = time_entry.hours * modifier
|
12
10
|
@client.time.update(time_entry)
|
@@ -15,29 +13,47 @@ module Harvestime
|
|
15
13
|
# Current date only
|
16
14
|
def all_times
|
17
15
|
@client.time.all
|
18
|
-
end
|
19
|
-
|
16
|
+
end
|
20
17
|
def all_times_in_date(time)
|
21
18
|
@client.time.all(time)
|
22
|
-
end
|
23
|
-
|
19
|
+
end
|
24
20
|
def move_entry_from(other_account, entry)
|
25
21
|
create_entry(build_entry_from_existing(entry))
|
26
22
|
other_account.time.delete(entry)
|
27
23
|
:success
|
28
24
|
end
|
29
|
-
|
25
|
+
def copy_entry_from(other_account, entry)
|
26
|
+
create_entry(build_entry_from_existing(entry))
|
27
|
+
end
|
28
|
+
def copy_date_range(other_account, start_date, end_date)
|
29
|
+
date_range = (Date.parse(start_date.to_s)..Date.parse(end_date.to_s))
|
30
|
+
.map { |day| day }
|
31
|
+
date_range.each do |date|
|
32
|
+
other_account.time.all(date).each do |entry|
|
33
|
+
copy_entry_from(other_account, entry)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
def delete_date_range(start_date, end_date)
|
38
|
+
date_range = (Date.parse(start_date.to_s)..Date.parse(end_date.to_s))
|
39
|
+
.map { |day| day }
|
40
|
+
date_range.each do |date|
|
41
|
+
all_times_in_date(date).each do |entry|
|
42
|
+
delete_entry(entry)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
# Ensure client exists.
|
30
47
|
def build_entry(args = {})
|
31
48
|
Harvest::TimeEntry.new(
|
32
49
|
{ notes: '',
|
33
50
|
hours: '0',
|
34
51
|
project_id: 0,
|
35
52
|
task_id: 0,
|
36
|
-
spent_at:
|
53
|
+
spent_at: Date.today.strftime('%a, %e %b %Y')
|
37
54
|
}.merge(args)
|
38
55
|
)
|
39
56
|
end
|
40
|
-
|
41
57
|
def build_entry_from_existing(entry)
|
42
58
|
Harvest::TimeEntry.new(
|
43
59
|
notes: entry.notes,
|
@@ -47,19 +63,16 @@ module Harvestime
|
|
47
63
|
spent_at: entry.spent_at
|
48
64
|
)
|
49
65
|
end
|
50
|
-
|
51
66
|
def clear_daily_entries
|
52
67
|
@client.time.all.each do |entry|
|
53
68
|
delete_entry(entry)
|
54
69
|
end
|
55
70
|
:success
|
56
71
|
end
|
57
|
-
|
58
72
|
def delete_entry(entry)
|
59
73
|
@client.time.delete(entry)
|
60
74
|
:success
|
61
75
|
end
|
62
|
-
|
63
76
|
def create_entry (entry)
|
64
77
|
@client.time.create(entry)
|
65
78
|
:success
|
data/lib/harvestime/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: harvestime
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Fausnight
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-07-
|
12
|
+
date: 2013-07-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: harvested
|
@@ -113,11 +113,11 @@ description: For streamlining and automating time and invoice management in Harv
|
|
113
113
|
email:
|
114
114
|
- nick.s.fausnight@gmail.com
|
115
115
|
- wes@databasically.com
|
116
|
-
executables:
|
116
|
+
executables:
|
117
|
+
- harvestime.rb
|
117
118
|
extensions: []
|
118
119
|
extra_rdoc_files: []
|
119
120
|
files:
|
120
|
-
- .DS_Store
|
121
121
|
- .gitignore
|
122
122
|
- .rspec
|
123
123
|
- .ruby-gemset
|
@@ -127,6 +127,7 @@ files:
|
|
127
127
|
- LICENSE.txt
|
128
128
|
- README.md
|
129
129
|
- Rakefile
|
130
|
+
- bin/harvestime.rb
|
130
131
|
- harvestime.gemspec
|
131
132
|
- lib/harvestime.rb
|
132
133
|
- lib/harvestime/client_filter.rb
|
data/.DS_Store
DELETED
Binary file
|