billtrap 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ TODOS.md
19
+ *.sw*
20
+ test.db
21
+ testTT.db
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'http://rubygems.org'
2
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Oliver Guenther
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,218 @@
1
+ # Billtrap
2
+
3
+
4
+ Billtrap is a command line invoice management tool in ruby.
5
+ It allows creation and monitoring of invoices and exporting data using template formatters.
6
+
7
+ Billtrap is based on the time tracking tool [Timetrap](https://github.com/samg/timetrap) by Sam Goldstein, and allows importing time entries from Timetrap into invoices.
8
+ However, Billtrap can be used to create invoices manually without data from Timetrap.
9
+
10
+
11
+
12
+ ## Installation
13
+ To install, use rubygems:
14
+
15
+ gem install billtrap
16
+
17
+ This will place the Billtrap executable `bt` in your path.
18
+
19
+ ## Usage
20
+
21
+ If you call Billtrap without any argument (or using --help) will
22
+ display usage information:
23
+
24
+ $ bt --help
25
+
26
+ ### Configuring BillTrap
27
+
28
+ Use `bt configure` to write a config file to `HOME/.billtrap/billtrap.yml` (Override by setting BILLTRAP_HOME in env)
29
+
30
+ The following options are supported
31
+
32
+ - **database**: Sequel Databsae identifier, defaults to `sqlite://<BILLTRAP_HOME>/.billtrap.db`
33
+ - **timetrap_database**: Timetrap database, used to import Entries
34
+ - **round_in_seconds** => 900,
35
+ - **currency**: Currency to use (see [RubyMoney.format](http://rubydoc.info/gems/money/Money/Formatting:format) for options)
36
+ - **default_rate**: Default rate in the above currency
37
+ - **invoice_number_format**: Invoice numbering format. Expands [Date.strftime directives](http://ruby-doc.org/stdlib-2.0/libdoc/date/rdoc/Date.html#method-i-strftime) and `%{invoice_id}`, `%{client_id}` upon export of the invoice (e.g., `%Y%m%d_%{invoice_id}`)
38
+ - **currency_format**: Money formatter, see <http://rubydoc.info/gems/money/Money/Formatting> for output options
39
+ - **date_format**: date format
40
+ - **billtrap_archive**: Output path for exported invoices
41
+ - **serenity_template**: OOffice adapter: Path to invoice template
42
+
43
+ ### Adding invoices
44
+
45
+ Add a **new** invoice with the title *Some important project* to Billtrap and activate it:
46
+
47
+ $ bt new --name 'Some important project'
48
+
49
+ You can also specify a certain date (using [Chronic keywords](https://github.com/mojombo/chronic)) to use with the invoice:
50
+
51
+ # Adds an unnamed invoice, dated yesterday
52
+ $ bt new --date yesterday
53
+
54
+ ### Switching between invoices
55
+
56
+ To display the current set of open invoices, use `bt show`.
57
+
58
+ $ bt show
59
+ Showing open invoices
60
+ ID Name Client Created Payments / Total
61
+ 1 Some important project - 2013-04-12 0,00 EUR / 0,00 EUR
62
+ >>2 - - 2013-04-11 0.00 USD / 0.00 USD
63
+
64
+ Billtrap manages a set of invoices, and allows you to focus on one invoice at a time.
65
+ The "**>>**" marks the current active invoice (ID 2), which we just added with `--date yesterday`.
66
+
67
+ To switch between invoices, use the `in` comand with the ID of the invoice to switch to.
68
+ Now, to switch to the 'Some important project' invoice, enter:
69
+
70
+ $ bt in 1
71
+ Activating invoice #1
72
+
73
+ The active invoice is persisted between calls, i.e., you always
74
+ edit the latest invoice until `bt in` or `bt new` is called.
75
+
76
+ ### Editing the active invoice
77
+ Let's add some entries to the important project by executing
78
+ `bt entry --add`. This will read the entry from STDIN.
79
+
80
+ $ bt entry --add
81
+ Entry title: Programming
82
+ Entry date (YYYY-MM-DD): 2013-04-10
83
+ Displayed unit (Defaults to 'h' for hours):
84
+ Quantity (Numeric): 2.5
85
+ Price in USD per unit (Numeric): 20
86
+ Optional Notes: (Multiline input, type Ctrl-D or insert END and return to exit)
87
+ ^D
88
+
89
+ Added entry (#1) to current invoice (ID 1)
90
+
91
+ Lets check the values we entered with `bt show --detail 1`,
92
+ which displays details for the invoice with ID 1.
93
+
94
+ $ bt show --detail 1
95
+
96
+ Invoice: Some important project (#1)
97
+ Created on: 2013-04-13
98
+ ----------------------
99
+ Invoice entries
100
+ Title Date Quantity Price Notes
101
+ Programming 2013-04-10 2.5h 50.00 USD
102
+
103
+ ### Importing data from Timetrap
104
+ If you manage your time using Timetrap, you can use the `import` command to import entries to the current invoice.
105
+
106
+ Assume you have a sheet called *test* with three entries.
107
+
108
+ $ t display test
109
+ Day Start End Duration Notes
110
+ Sat Oct 29, 2011 22:42:36 - 23:13:02 0:30:26 Foo
111
+ 0:30:26
112
+ Sat Nov 17, 2012 23:13:57 - 23:14:07 24:00:10 Bar
113
+ 24:00:10
114
+ Sun Nov 18, 2012 22:26:00 - 22:31:20 0:05:20 Moo
115
+
116
+ You can import the whole sheet into BillTrap using the following command:
117
+
118
+ $ dbt impoort --sheet test
119
+
120
+ Imported 0.51 hours from sheet test as entry #2
121
+ Imported 0.09 hours from sheet test as entry #3
122
+ Imported 24.0 hours from sheet test as entry #4
123
+
124
+ You could also import single IDs into the current invoice:
125
+
126
+ $ dbt import --entry 1 2
127
+ Imported 0.51 hours from sheet test as entry #5
128
+ Imported 0.09 hours from sheet test as entry #6
129
+
130
+
131
+ If you wish to clear all entries *prior* to the import,
132
+ use the `--clear` flag:
133
+
134
+ $ dbt import --entry 1 2
135
+ Imported 0.51 hours from sheet test as entry #1
136
+ Imported 0.09 hours from sheet test as entry #2
137
+
138
+ **Beware:** Using the `--clear` flag does not ask for confirmation prior to deleting all entries of the current invoice.
139
+
140
+
141
+ ### Setting a client
142
+
143
+ BillTrap allows you to add and manage clients.
144
+ **Note**: This feature is still rudimentary and subject to change.
145
+
146
+ Use `bt client --add` to add a client from STDIN:
147
+
148
+ $ bt client --add
149
+ First name: John
150
+ Surname: Doe
151
+ Company: Doemasters Inc.
152
+ Address: (Multiline input, type Ctrl-D or insert END and return to exit)
153
+ Somestreet 12
154
+ 12345 Sometown^D
155
+ Mail: mail@example.com
156
+ Hourly rate: 25
157
+ Use non-standard Currency? [Leave empty for USD]: EUR
158
+
159
+ Client John Doe was created with id 1
160
+
161
+ Let's set *John Doe* as the client for our important project.
162
+
163
+ # Equivalent to 'bt set client 1'
164
+ $ bt set client Doe
165
+
166
+ SET client to John Doe (#1)
167
+
168
+ **Note**: The client currency setting overrides BillTrap's default setting, thus the currency for all entries of invoice #1
169
+ have changed to EUR.
170
+
171
+ ### Exporting invoices
172
+ Let's review our changes to the Invoice #1:
173
+
174
+ $ bt show
175
+ Showing open invoices
176
+ ID Name Client Created Payments / Total
177
+ >>1 Some important project John Doe 2013-04-13 0,00 EUR / 50,00 EUR
178
+ 2 - - 2013-04-12 0.00 USD / 0.00 USD
179
+
180
+ To export the invoice:
181
+
182
+ $ bt export
183
+
184
+ Generated invoice has been output to: /Users/oliver/Documents/billtrap/invoices/2013/4/13/1.odt
185
+
186
+ Currently, the only working adapter uses the [serenity gem](https://github.com/kremso/serenity) to populate a Open/LibreOffice template of your choosing and renders an ODT.
187
+
188
+ **Note**: Have a look at the config (see *configuring BillTrap*) to change invoice numbering, output paths et cetera.
189
+
190
+ I'm working on creating more adapters. If you want to participate in the discussion, I suggest opening an issue on the [Github tracker](http://github.com/oliverguenther/Billtrap/issues).
191
+
192
+ ### Abbreviating commands
193
+ All commands and their paremeters can be abbreviated.
194
+ For example, instead of `bt new --date yesterday`, you could also enter with same result:
195
+
196
+ $ bt n -d yesterday
197
+
198
+ BillTrap warns you about ambiguous command abbreviations, e.g.,
199
+
200
+ $ bt s
201
+ Error: Ambiguous command 's'
202
+ Matching commands are: set, show
203
+
204
+ ## Special Thanks
205
+
206
+ I'd like to thank Sam Goldstein for his work on Timetrap, which motivated me to improve on my time management and to start this project.
207
+
208
+ Billtrap intentionally borrows heavily from Timetrap, which is available at <https://github.com/samg/timetrap>.
209
+
210
+ --------
211
+
212
+ ## Bugs and Feature Requests
213
+
214
+ Billtrap is still under heavy development.
215
+
216
+ If you have feature requests or found a bug, please file an issue on the Github tracker:
217
+
218
+ <http://github.com/oliverguenther/Billtrap/issues>
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake'
3
+ require 'rdoc/task'
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new
6
+
7
+ desc 'Default: run spec.'
8
+ task :default => :spec
9
+
10
+ lib = File.expand_path('../lib/', __FILE__)
11
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
12
+ require 'billtrap/version'
13
+ Rake::RDocTask.new do |rdoc|
14
+ version = BillTrap::VERSION
15
+
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = "BillTrap #{version}"
18
+ rdoc.rdoc_files.include('README*')
19
+ rdoc.rdoc_files.include('lib/billtrap/**/*.rb')
20
+ rdoc.rdoc_files.include('lib/billtrap.rb')
21
+ end
data/billtrap.gemspec ADDED
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib/', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'billtrap/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "billtrap"
8
+ spec.version = BillTrap::VERSION
9
+ spec.authors = ["Oliver Günther"]
10
+ spec.email = ["mail@oliverguenther.de"]
11
+ spec.summary = "Command line invoice management."
12
+ spec.description = "This gem provides invoice management with imported time slices from the Timetrap gem."
13
+ spec.homepage = "http://github.com/oliverguenther/billtrap/"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.bindir = "bin"
18
+ spec.executables = ['bt']
19
+ spec.test_files = ['spec/']
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_dependency "sequel", ">= 3.9.0"
23
+ spec.add_dependency "sqlite3", ">= 1.3.3"
24
+ spec.add_dependency "chronic", ">= 0.6.4"
25
+ spec.add_dependency "json", ">= 1.4.6"
26
+ spec.add_dependency "trollop", ">= 2.0"
27
+ spec.add_dependency "money", ">= 5.0"
28
+ spec.add_dependency "timetrap", ">= 1.5"
29
+ spec.add_dependency "rubyzip"
30
+
31
+ spec.add_development_dependency "bundler", "~> 1.3"
32
+ spec.add_development_dependency "rake"
33
+ spec.add_development_dependency 'rspec', '~> 2'
34
+ spec.add_development_dependency 'fakefs'
35
+ end
data/bin/bt ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+ begin
3
+ require 'billtrap'
4
+ rescue LoadError
5
+ if File.symlink? __FILE__
6
+ require File.dirname(File.readlink(__FILE__)) + '/../lib/billtrap'
7
+ else
8
+ require File.dirname(__FILE__) + '/../lib/billtrap'
9
+ end
10
+ end
11
+ BillTrap::CLI.args = Array.new(ARGV)
12
+ BillTrap::CLI.invoke
data/bin/dev_b ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # Executable with absolute path to lib for hacking and development
3
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'billtrap')
4
+ # run on argv
5
+ BillTrap::CLI.args = Array.new(ARGV)
6
+ BillTrap::CLI.invoke
data/lib/billtrap.rb ADDED
@@ -0,0 +1,56 @@
1
+ # encoding: utf-8
2
+ require "rubygems"
3
+ require 'sequel'
4
+ # Load migrations
5
+ Sequel.extension :migration, :core_extensions
6
+ # Load inflector (String.classify)
7
+ Sequel.extension :inflector
8
+
9
+ require 'chronic'
10
+ require 'money'
11
+ require 'yaml'
12
+ require 'erb'
13
+ require 'trollop'
14
+ require 'pathname'
15
+
16
+ # require serenity 0.2.2
17
+ require File.join(File.dirname(__FILE__), 'serenity', 'serenity')
18
+
19
+ # Set billtrap home
20
+ BILLTRAP_HOME = ENV['BILLTRAP_HOME'] || File.join(ENV['HOME'], '.billtrap')
21
+
22
+
23
+ BILLTRAP_PATH = Pathname.new(__FILE__).realpath.dirname.to_s
24
+ $:.unshift(BILLTRAP_PATH + '/billtrap')
25
+ require 'version'
26
+ require 'config'
27
+ require 'helpers'
28
+ require 'cli'
29
+ require 'adapters'
30
+ module BillTrap
31
+ # Force encoding to utf-8
32
+ Encoding.default_internal= Encoding::UTF_8
33
+ Sequel::Model.plugin :force_encoding, Encoding::UTF_8
34
+
35
+
36
+ unless File.directory? BILLTRAP_HOME
37
+ FileUtils.mkdir BILLTRAP_HOME
38
+ end
39
+
40
+
41
+ # We need to inclue spec testing here, as RSpec doesn't allow
42
+ # stubs in around blocks, but we need around blocks for Sequel transactions
43
+ DB_NAME = defined?(SPEC_RUNNING) ? "sqlite://test.db" : BillTrap::Config['database']
44
+ DB = Sequel.connect(DB_NAME)
45
+
46
+ # Update to latest migration, if necessary
47
+ unless (Sequel::Migrator.is_current? DB, File.dirname(__FILE__) + '/../migrations/')
48
+ Sequel::Migrator.run(DB, File.dirname(__FILE__) + '/../migrations/')
49
+ end
50
+
51
+ # Open TT timetrap_databasee
52
+ TT_DB_NAME = defined?(SPEC_RUNNING) ? "sqlite://testTT.db" : BillTrap::Config['timetrap_database']
53
+ TT_DB = Sequel.connect(TT_DB_NAME)
54
+
55
+ end
56
+ require 'models'
@@ -0,0 +1,12 @@
1
+ module BillTrap
2
+ module Adapters
3
+ extend self
4
+
5
+ def load_adapter name
6
+ adapter = name.downcase
7
+ require "adapters/#{adapter}"
8
+ # Try to load the adapter
9
+ BillTrap::Adapters.const_get(adapter.classify)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,27 @@
1
+ module BillTrap
2
+ module Adapters
3
+ class Ooffice
4
+ # uses Serenity for ODT output
5
+ include ::Serenity::Generator
6
+ include BillTrap::Helpers
7
+ attr_reader :id
8
+
9
+ def initialize attributes
10
+ attributes.each do |key, val|
11
+ # slurp attributes into instances variables
12
+ instance_variable_set("@#{key}", val)
13
+ end
14
+ end
15
+
16
+ def generate
17
+ date = @invoice[:created]
18
+ output_path = "#{Config['billtrap_archive']}/#{date.year}/#{date.month}/#{date.mday}"
19
+ FileUtils.mkpath(output_path)
20
+
21
+ render_odt Config['serenity_template'], "#{output_path}/#{@invoice.id}.odt"
22
+ puts "Generated invoice has been output to: #{output_path}/#{@invoice.id}.odt"
23
+ end
24
+
25
+ end
26
+ end
27
+ end