-
Notifications
You must be signed in to change notification settings - Fork 0
/
invox
executable file
·185 lines (153 loc) · 4.6 KB
/
invox
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#!/usr/bin/env bash
# Invox: simple invoice formatter
# See usage message for more details
set -eu
set -o pipefail
usage() {
echo "
invox
Simple invoice formatter
USAGE: invox [OPTIONS]
NB: Requires bash v4.x or higher
Requires time period and hours worked to be passed in a pipeline (see example below)
OPTIONS
-i <string> (required) invoice_id, the identifer for this invoice
-d <string> issue date of the invoice
-e <string> custom due date of the invoice
-c <string> custom config file
-t <string> custom html template
-n no pdf (html only)
-h help (this message)
EXAMPLES
With defaults:
$ watson report -G | invox -i 97
The invoice will be saved as invoice_97.pdf in the current directory.
With custom config, template, date, and filename:
$ watson report -G | ./invox -i MC81 -d \"1 August 2020\" -t ./invox_template.html -c ./.invoxrc -f \"Invoice\"
The invoice will be saved as Invoice.pdf in the current directory.
SETUP
1. Config file located in ~/.config/invox/.invoxrc
- includes all the variables to be replaced in the template file
- can be overriden with the -c flag (see above)
2. Template located in ~/.config/invox/invox_template.html
- can be overriden with the -t flag (see above)
You can have whatever variables in the config and template, as long as they are the same. Variables are wrapped in double brackets in the template file, e.g. {{recipient_name}}.
"
}
config=~/.config/invox/.invoxrc
template=~/.config/invox/invox_template.html
date_issued=$(gdate "+%d %B %Y")
due_date=$(gdate -d "+13 days" "+%d %B %Y")
no_pdf=false
while getopts "i:d:e:t:c:f:nh" opt; do
case "$opt" in
i )
invoice_id="$OPTARG"
;;
d )
date_issued="$OPTARG"
;;
e )
due_date="$OPTARG"
;;
c )
config="$OPTARG"
;;
t )
template="$OPTARG"
;;
f )
filename="$OPTARG"
;;
n )
no_pdf=true
;;
h )
usage
exit 0
;;
\? )
usage
exit 1
;;
esac
done
shift $((OPTIND -1))
if [[ ! ${invoice_id+x} ]]
then echo "-i required: set the invoice id" && usage && exit 1
fi
if test -t 0; then
echo "Time sheet required in pipeline. Currently only supports watson."
usage
exit 1
fi
# read time period and hours worked from stdin (piped from `watson report -G`)
read -r time_period
read -r _
read -r details
# format start and end dates in time_period to dd.mm.yy
format_date() {
echo $(gdate -d "$1" +%Y.%m.%d)
}
start_date=$(echo "$time_period" | grep -o '^[^-]*')
end_date=$(echo "$time_period" | grep -o '[^>]*$')
time_period="$(format_date "$start_date") - $(format_date "$end_date")"
hours=$(perl -ne 'print "$&\n" if /\d+(?=h)/' <<< "$details")
minutes=$(perl -ne 'print "$&\n" if /\d+(?=m)/' <<< "$details")
hours=${hours#0}
minutes=${minutes#0}
# Round up the hour count at a half hour
if [[ $minutes -gt 30 ]]
then
((hours=hours+1))
fi
# get values for report from config file
declare -A report
while IFS='=' read -d $'\n' -r key value; do
# Skip empty lines & lines starting with sharp (comments)
[[ "$key" =~ ^([[:space:]]*|[[:space:]]*#.*)$ ]] && continue
report[$key]="$value"
done < "$config"
# calculate & cost to nearest integer
cost=$(bc <<< "((${hours} * ${report[hourly_rate]}) + 0.5)/1")
# add date, invoice id, time period, hours, and cost to report
report[time_period]="$time_period"
report[hours]="$hours"
report[cost]="$cost"
report[date_issued]="$date_issued"
report[due_date]="$due_date"
report[invoice_id]="$invoice_id"
# get all variable names in template file
vars=$(grep -oE '\{\{([A-Za-z0-9_]+)\}\}' "$template" |
gsed -rn 's/.*\{\{([A-Za-z0-9_]+)\}\}.*/\1/p' |
sort |
uniq)
# default filename if no -f flag is set
if [[ ! ${filename+x} ]]
then filename="Invoice ${invoice_id} - ${date_issued} - ${report[sender_name]}"
fi
cp "$template" "$filename.html"
for var in $vars; do
if [ "${report[$var]}" ]; then
value="${report[$var]}"
gsed -i "s/{{$var}}/${report[$var]}/" "$filename.html"
fi
done
if [[ $no_pdf == false ]]
then
echo "Creating PDF invoice, saving to $(pwd)/$filename.pdf"
wkhtmltopdf \
--page-size "Letter" \
--margin-top "0mm" \
--margin-right "0mm" \
--margin-bottom "0mm" \
--margin-left "0mm" \
--quiet \
"$filename.html" "$filename.pdf" && \
open "$filename.pdf" || \
echo "Failed to create invoice PDF. Check filename for formatting errors."
echo "Removing HTML file"
rm "$filename.html"
else
echo "Creating HTML invoice, saving to $(pwd)/$filename.html"
fi