billtrap 0.0.2

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.
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