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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: be8bf87ed48cab202cfd06a2e29ea7c54b2cfcfe
4
- data.tar.gz: ddf20e2a3e40ba96527a7ba1f09f4f4f25ddc50c
3
+ metadata.gz: 3f617962a7dc85f1afdf1f4652025c24be54d71c
4
+ data.tar.gz: 9f5875f24089c193ff9c505c6433d7c8b9b44faf
5
5
  SHA512:
6
- metadata.gz: e94d4a8e2604a264326b052179158f73af1eb7f4470848c4c1015f9c1ac7fc6b3f6d81fee0bdf8422a42e9e0cbf732065040a3ab5a4f22bb23fd0b3c19b5ec45
7
- data.tar.gz: bd578a3bb68ae8288356ccf9fd29e926e51af0a1cc8b30903daf7624fc7090531d7d9d6671ef49f90946ab177b0075fea31912a24fd8bf22e6693d78f006a89f
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
- TODO: Write usage instructions here
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
@@ -9,4 +9,5 @@ module Harvestime
9
9
  @time_filter = Harvestime::TimeFilter.new(@interface)
10
10
  end
11
11
  end
12
- end
12
+ end
13
+
@@ -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
- # build / create delivers ER404 (sometimes)
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: Time.now.strftime('%a, %e %b %Y')
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
@@ -1,3 +1,3 @@
1
1
  module Harvestime
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
@@ -34,7 +34,7 @@ describe 'Harvestime::TimeFilter' do
34
34
  hours = 12
35
35
  project_id = client.projects.all[0].id
36
36
  task_id = client.tasks.all[0].id
37
- spent_at = Time.now
37
+ spent_at = Date.today
38
38
 
39
39
  entry = time_filter.build_entry(notes: notes,
40
40
  hours: hours,
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.2
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-08 00:00:00.000000000 Z
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