Doc clean-up, and restore the wayward inv script.
Removed temp script
Adds an invoice number based on a client.id and the current YEARMONTH
Generates a PDF invoice from TimeWarrior logs.
Both dependencies are probably in your package manager. vim comes with a Lout syntax.
This software does not require any non-core Go libraries to build, so
there's no go.mod
file.
Build the executable:
go build -o invoice .
Copy invoice
and inv
to your extensions directory:
chmod u+x inv
cp invoice inv ~/.timewarrior/extensions
Configure it first. It needs to know your information, your client's information, and other stuff, and it'll be unhappy if you don't configure it first.
The template requires some configuration that uses TimeWarrior's
configuration utility. Rates and addresses are pulled from the
timew config, and this requires configuration before running the
tool. Configurations can be set with the timew config
command, e.g.
timew config rate 60.0
With the default template, the following are expected:
rate
: float, the hourly rate used to calculate subtotals and totals
myname
: string, your name formatted for display
address1
: string, the first line of your address
address2
: string, the second line of your address
phone
: string, your phone number
: string, your email address
For example:
timew config myname "Sean E. Russell"
Set your client's contact info with the following configurations:
.company
: string, the name of your client formatted for display
.contact
: string, the name of a contact at your client, e.g. "Bill Manager"
.address1
: string, the first line of your client's address
.address2
: string, the second line of your client's address
.id
: string, an ID used in generating a unique invoice number
E.g.
timew config megacorp.company "MegaCorp, Inc"
You may enter as many clients as you wish.
Note: TimeWarrior uses #
as a comment character, and don't
document how to escape it. I haven't yet figured it out, so you can't
have it in any of the configuration fields.
Next, you have to tag all of your records for that client with client:, e.g.
timew tag @1 client:megacorp
Run your reports with the client:megacorp
tag; the program uses that
to determine which client configuration information to use, which allows
you to have multiple clients.
In the normal course of things, you'd run this with timew
, e.g.
timew report inv 2019-12-01 - 2019-12-31 client:megacorp
The inv
script does some set-up, calls invoice
to generate the
Lout source, runs lout
to create the PDF, and then cleans up. It's
a pretty simple script, and isn't necessary if you want to run some
commands yourself.
You can get the raw Lout source by using the invoice
report:
timew report invoice 2019-12-01 - 2019-12-31 client:megacorp
The invoice command itself reads from STDIN and expects output in the
format of timew report
.
invoice [args]
One way to do that is to have an echo
report in the extensions
directory:
cat > ~/.timewarrior/extensions/echo <<EOL
#!/bin/bash
while read x; do
echo $x
done
EOL
and then:
timew report echo 2019-12-01 - 2019-12-31 client:megacorp | ./invoice
There is limited ability to override the template. To do so, have a
file invoice.tmpl
in the current directory. You can use the one in
the source repository as a starting point. These are Go templates;
Go replaces the stuff in double-braces ({{
... }}
), and if you
hard-code those you don't need the addresses in the configuration,
or the client tags on your TimeWarrior records. You do still
need the rate
configuration, and the {{range .}}
... {{end}}
markup. However, you can mess around with the table formats, fonts,
and etcetera. Change the $
to €
. Move the columns around. Weighing
in at 78 lines long, it's not too complex. One thing to keep in mind:
double-braces are Go, single-braces are Lout. Make sure there are
spaces between Lout braces to prevent Go from trying to mess with them.
IMPORTANT: Any time you change invoice.tmpl, you must run go generate
before compiling the tool. This requires the bundling tool
esc, which you can get with go get github.com/mjibson/esc
.
Why not LaTeX?
: Lout is a more simple syntax, with a much smaller learning curve. I can (and do) go for years between using Lout and it's easy to pick up each time; I can't say the same for TeX.
Lout is a single 727KB executable. LaTeX (tetex-live) is 445MB, distributed as a bunch of packages (on Arch), and that's considered a small implementation of LaTex. As I use these infrequently, I'd rather clutter up my hard drive with a smaller tool.
Why not Markdown?
: It's not the right tool. An invoice is tabular data on (usually) letterhead; Markdown has never claimed to be, and is not particularly good at, desktop publishing, and it discourages tabular data. The original Markdown format required escaping into HTML to do tables.
Why not X?
: I don't know X. I'm sure it's great, and I'd be thrilled if any part of this project helps you implement a solution based around X. If you do, please do let me know; I'd love to hear about it.
Lout sounds awesome! Where can I learn more?
: Right here.
Why esc
, and not Y?
: It was installed from an earlier project, and I haven't yet taken the time to see if any of the other asset bundling tools are any better.