Module: Freshtrack

Defined in:
lib/freshtrack/version.rb,
lib/freshtrack.rb,
lib/freshtrack/time_collectors/punch.rb,
lib/freshtrack/time_collectors/one_inch_punch.rb,
lib/freshtrack/time_collectors/punchy_template.rb

Overview

:nodoc:

Defined Under Namespace

Modules: TimeCollector, VERSION

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.configObject (readonly)

Returns the value of attribute config.



8
9
10
# File 'lib/freshtrack.rb', line 8

def config
  @config
end

.projectObject (readonly)

Returns the value of attribute project.



8
9
10
# File 'lib/freshtrack.rb', line 8

def project
  @project
end

.project_nameObject (readonly)

Returns the value of attribute project_name.



8
9
10
# File 'lib/freshtrack.rb', line 8

def project_name
  @project_name
end

.taskObject (readonly)

Returns the value of attribute task.



8
9
10
# File 'lib/freshtrack.rb', line 8

def task
  @task
end

Class Method Details

.collector(options = {}) ⇒ Object



88
89
90
91
92
93
94
# File 'lib/freshtrack.rb', line 88

def collector(options = {})
  collector_name = config['collector']
  class_name = collector_name.capitalize.gsub(/([a-z])_([a-z])/) { "#{$1}#{$2.upcase}" }
  require "freshtrack/time_collectors/#{collector_name}"
  klass = Freshtrack::TimeCollector.const_get(class_name)
  klass.new(options)
end

.companyObject



20
21
22
# File 'lib/freshtrack.rb', line 20

def company
  project_info_value('company')
end

.create_entry(entry_data, time_entry = FreshBooks::TimeEntry.new) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/freshtrack.rb', line 68

def create_entry(entry_data, time_entry = FreshBooks::TimeEntry.new)
  time_entry ||= FreshBooks::TimeEntry.new

  time_entry.project_id = project.project_id
  time_entry.task_id    = task.task_id
  time_entry.date       = entry_data['date']
  time_entry.hours      = entry_data['hours']
  time_entry.notes      = entry_data['notes']

  method = time_entry.time_entry_id ? :update : :create
  result = time_entry.send(method)

  if result
    true
  else
    STDERR.puts "warning: unsuccessful time entry creation for date #{entry_data['date']}"
    nil
  end
end

.get_data(project_name, options = {}) ⇒ Object



48
49
50
51
# File 'lib/freshtrack.rb', line 48

def get_data(project_name, options = {})
  get_project_data(project_name)
  collector(options).get_time_data(project_name)
end

.get_project_data(project_name) ⇒ Object



40
41
42
43
44
45
46
# File 'lib/freshtrack.rb', line 40

def get_project_data(project_name)
  raise unless mapping = project_task_mapping[project_name]
  @project = FreshBooks::Project.find_by_name(mapping[:project])
  raise unless @project
  @task = FreshBooks::Task.find_by_name(mapping[:task])
  raise unless @task
end

.get_tracked_data(data) ⇒ Object



62
63
64
65
66
# File 'lib/freshtrack.rb', line 62

def get_tracked_data(data)
  return [] if data.empty?
  dates = data.collect { |d|  d['date'] }
  FreshBooks::TimeEntry.list('project_id' => project.project_id, 'task_id' => task.task_id, 'date_from' => dates.min, 'date_to' => dates.max)
end

.get_unbilled_time_entries(project_name) ⇒ Object



120
121
122
123
124
# File 'lib/freshtrack.rb', line 120

def get_unbilled_time_entries(project_name)
  get_project_data(project_name)
  time_entries = FreshBooks::TimeEntry.list('project_id' => @project.project_id, 'per_page' => 100)
  time_entries.reject(&:billed)
end

.init(project = nil) ⇒ Object



10
11
12
13
14
# File 'lib/freshtrack.rb', line 10

def init(project = nil)
  load_config
  @project_name = project
  FreshBooks.setup("#{company}.freshbooks.com", token)
end

.invoice_agingObject



101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/freshtrack.rb', line 101

def invoice_aging
  open_invoices.collect do |i|
    {
      :id     => i.invoice_id,
      :number => i.number,
      :client => i.client.organization,
      :age    => Date.today - i.date,
      :status => i.status,
      :amount => i.amount,
      :owed   => i.owed_amount
    }
  end
end

.load_configObject



16
17
18
# File 'lib/freshtrack.rb', line 16

def load_config
  @config = YAML.load(File.read(File.expand_path('~/.freshtrack.yml')))
end

.open_invoicesObject



96
97
98
99
# File 'lib/freshtrack.rb', line 96

def open_invoices
  invoices = FreshBooks::Invoice.list || []
  invoices.select { |i|  i.open? }
end

.project_info_value(key) ⇒ Object



28
29
30
31
32
33
# File 'lib/freshtrack.rb', line 28

def project_info_value(key)
  return config[key.to_s] unless project_name
  info = project_task_mapping[project_name]
  return config[key.to_s] unless info[:company] and info[:token]
  info[key.to_sym]
end

.project_task_mappingObject



36
37
38
# File 'lib/freshtrack.rb', line 36

def project_task_mapping
  config['project_task_mapping']
end

.tokenObject



24
25
26
# File 'lib/freshtrack.rb', line 24

def token
  project_info_value('token')
end

.track(project_name, options = {}) ⇒ Object



53
54
55
56
57
58
59
60
# File 'lib/freshtrack.rb', line 53

def track(project_name, options = {})
  data = get_data(project_name, options)
  tracked = get_tracked_data(data)
  data.each do |entry_data|
    tracked_entry = tracked.detect { |t|  t.date == entry_data['date'] }
    create_entry(entry_data, tracked_entry)
  end
end

.unbilled_time(project_name) ⇒ Object



115
116
117
118
# File 'lib/freshtrack.rb', line 115

def unbilled_time(project_name)
  time_entries = get_unbilled_time_entries(project_name)
  time_entries.collect(&:hours).inject(&:+)
end