Compare commits
5 Commits
3a4cd1698c
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| d9fbcc0b98 | |||
| 6a20f179af | |||
| ef80b03029 | |||
| 23d8ce3910 | |||
| 4d1342782d |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
*.bak
|
*.bak
|
||||||
*.pdf
|
*.pdf
|
||||||
last_invoice_number
|
last_invoice_number
|
||||||
|
*.csv
|
||||||
|
|||||||
@@ -7,34 +7,35 @@
|
|||||||
.PH ''''
|
.PH ''''
|
||||||
\# Centered block
|
\# Centered block
|
||||||
.DS C
|
.DS C
|
||||||
.HU "Your Bill"
|
.HU "${COMPANY}'s Bill"
|
||||||
.DE
|
.DE
|
||||||
\# Contact info
|
\# Contact info
|
||||||
.TS
|
.TS
|
||||||
nospaces center tab(;);
|
nospaces center tab(;);
|
||||||
LR.
|
LR.
|
||||||
Cooies Unlimited;(123) 456-7890
|
${COMPANY_NAME};$PHONE
|
||||||
123 Sesame St.;cookie@example.com
|
${ADDR_LN_1};${EMAIL}
|
||||||
Dumpster 1;\*[DT]
|
${ADDR_LN_2};\*[DT]
|
||||||
Nicevile FL;Invoice ID #${INVOICE_NUM}
|
${ADDR_LN_3};Invoice ID #${INVOICE_NUM}
|
||||||
.TE
|
.TE
|
||||||
|
|
||||||
\# Billing info
|
|
||||||
.TS
|
.TS
|
||||||
nospaces center tab(;);
|
nospaces center tab(;);
|
||||||
CbSS
|
CbSS
|
||||||
CiCi|Ci
|
CiCi|Ci
|
||||||
RN|N.
|
RN|N.
|
||||||
${COMPANY}
|
Work Performed
|
||||||
Job;Hours;Cost
|
Job;Hours;Cost
|
||||||
_
|
_
|
||||||
${BODY}
|
${HRS_BODY}
|
||||||
_
|
_
|
||||||
.T&
|
.T&
|
||||||
RbN|Nb.
|
RbN|Nb.
|
||||||
${TOTAL}
|
Total;${HRS_TOTAL}
|
||||||
.TE
|
.TE
|
||||||
|
.DS C
|
||||||
|
.R
|
||||||
|
.DE
|
||||||
.PP
|
.PP
|
||||||
Hours were charged at $${RATE}/hr. If you have any questions please reach out at any of the provided contacts above.
|
Hours were charged at $${RATE}/hr. If you have any questions please reach out at any of the provided contacts above.
|
||||||
Thank you for your business!
|
Thank you for your business!
|
||||||
62
2col.template.mm
Normal file
62
2col.template.mm
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
\# Make headers bold
|
||||||
|
.ds HF 3 3
|
||||||
|
\# Make lvl 1 headers 20pt, lvl 2 18pt
|
||||||
|
.ds HP 20 18
|
||||||
|
.S 12
|
||||||
|
\# Disable page header
|
||||||
|
.PH ''''
|
||||||
|
\# Centered block
|
||||||
|
.DS C
|
||||||
|
.HU "${COMPANY}'s Bill"
|
||||||
|
.DE
|
||||||
|
\# Contact info
|
||||||
|
.TS
|
||||||
|
nospaces center tab(;);
|
||||||
|
LR.
|
||||||
|
${COMPANY_NAME};$PHONE
|
||||||
|
${ADDR_LN_1};${EMAIL}
|
||||||
|
${ADDR_LN_2};\*[DT]
|
||||||
|
${ADDR_LN_3};Invoice ID #${INVOICE_NUM}
|
||||||
|
.TE
|
||||||
|
|
||||||
|
.2C
|
||||||
|
.TS
|
||||||
|
nospaces center tab(;);
|
||||||
|
CbSS
|
||||||
|
CiCi|Ci
|
||||||
|
RN|N.
|
||||||
|
Work Performed
|
||||||
|
Job;Hours;Cost
|
||||||
|
_
|
||||||
|
${HRS_BODY}
|
||||||
|
_
|
||||||
|
.T&
|
||||||
|
RiNi|Ni.
|
||||||
|
Sub-Total;${HRS_TOTAL}
|
||||||
|
.TE
|
||||||
|
.NCOL
|
||||||
|
.TS
|
||||||
|
nospaces center tab(;);
|
||||||
|
CbS
|
||||||
|
Ci|Ci
|
||||||
|
R|N.
|
||||||
|
Other
|
||||||
|
Item;Cost
|
||||||
|
_
|
||||||
|
${ITEM_BODY}
|
||||||
|
_
|
||||||
|
.T&
|
||||||
|
Ri|Ni.
|
||||||
|
Sub-Total;$${ITEM_TOTAL}
|
||||||
|
.TE
|
||||||
|
.1C 1
|
||||||
|
.DS C
|
||||||
|
.PP
|
||||||
|
.B
|
||||||
|
Total: $${TOTAL}
|
||||||
|
.R
|
||||||
|
.DE
|
||||||
|
.PP
|
||||||
|
Hours were charged at $${RATE}/hr. If you have any questions please reach out at any of the provided contacts above.
|
||||||
|
Thank you for your business!
|
||||||
|
|
||||||
18
Makefile
Normal file
18
Makefile
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
support_files := ${XDG_DATA_HOME}/bill-generator/
|
||||||
|
config_files:= ${XDG_CONFIG_HOME}/bill-generator/
|
||||||
|
install_loc := ~/.local/bin/
|
||||||
|
install:
|
||||||
|
mkdir -p $(support_files)
|
||||||
|
mkdir -p $(config_files)
|
||||||
|
mkdir -p $(install_loc)
|
||||||
|
cp *.mm $(support_files)
|
||||||
|
# Copy the ident file but don't overwrite one that is already there.
|
||||||
|
cp --update=none ident $(config_files)
|
||||||
|
cp gen.sh $(install_loc)/bill-gen
|
||||||
|
printf "\nInstalled!\nUpdate your identity at $(config_files)ident\n\n"
|
||||||
|
|
||||||
|
remove:
|
||||||
|
# Remove everything except the config files
|
||||||
|
rm -r $(support_files)
|
||||||
|
rm $(install_loc)bill-gen
|
||||||
|
|
||||||
107
gen.sh
107
gen.sh
@@ -1,45 +1,22 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
DATA_HOME="$XDG_DATA_HOME/bill-generator"
|
||||||
|
source "$XDG_CONFIG_HOME/bill-generator/ident"
|
||||||
|
# Need to be set to the installed location
|
||||||
|
TEMPLATE_1COL="$DATA_HOME/1col.template.mm"
|
||||||
|
TEMPLATE_2COL="$DATA_HOME/2col.template.mm"
|
||||||
|
INV_FILE="$DATA_HOME/last_invoice_number"
|
||||||
|
|
||||||
# What you charge an hour
|
print_help() {
|
||||||
RATE=50
|
echo "$(basename $0) -1 <hrs.csv> <Paying Company Name> [output file]"
|
||||||
|
echo "$(basename $0) -2 <hrs.csv> <items.csv> <Paying Company Name> [output file]"
|
||||||
short_help() {
|
|
||||||
echo "$0 <file.csv> <Paying Company Name> [output file]"
|
|
||||||
echo "--help for help"
|
|
||||||
}
|
|
||||||
long_help() {
|
|
||||||
short_help
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "The csv file should be setup as:"
|
echo "CSV files should be <name>,<value>."
|
||||||
echo ""
|
echo "CSV files should have no empty line at the end."
|
||||||
echo "Job <string>, Hours <number>"
|
|
||||||
echo ""
|
|
||||||
echo "With no empty line at the end."
|
|
||||||
echo "Paying company name is any string"
|
echo "Paying company name is any string"
|
||||||
echo "The output argument is optional and will by default output to invoice-<num>.pdf"
|
echo "The output argument is optional and will by default output to invoice-<num>.pdf"
|
||||||
}
|
}
|
||||||
|
get_invoice_num() {
|
||||||
CSV=""
|
|
||||||
if [[ -z $1 ]]; then
|
|
||||||
short_help
|
|
||||||
exit
|
|
||||||
elif [[ $1 = "--help" ]]; then
|
|
||||||
long_help
|
|
||||||
exit
|
|
||||||
else
|
|
||||||
CSV=$1
|
|
||||||
fi
|
|
||||||
|
|
||||||
COMPANY=""
|
|
||||||
if [[ -z $2 ]]; then
|
|
||||||
short_help
|
|
||||||
exit
|
|
||||||
else
|
|
||||||
COMPANY=$2
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Increment a global invoice number
|
# Increment a global invoice number
|
||||||
INV_FILE="last_invoice_number"
|
|
||||||
INV_NUM=0
|
INV_NUM=0
|
||||||
if [[ -f $INV_FILE ]]; then
|
if [[ -f $INV_FILE ]]; then
|
||||||
INV_NUM=$(expr $(cat $INV_FILE) + 1)
|
INV_NUM=$(expr $(cat $INV_FILE) + 1)
|
||||||
@@ -47,24 +24,52 @@ else
|
|||||||
INV_NUM=1
|
INV_NUM=1
|
||||||
fi
|
fi
|
||||||
echo $INV_NUM > $INV_FILE
|
echo $INV_NUM > $INV_FILE
|
||||||
|
echo $INV_NUM
|
||||||
|
}
|
||||||
|
read_hrs_csv() {
|
||||||
|
TMP=$(mktemp)
|
||||||
|
# Parse the CSV into: Label;Hrs;Cost
|
||||||
|
cat $1 | RATE=$RATE awk -F, '{ sum += $2 }; { print $1 ";" $2 ";" $2 * ENVIRON["RATE"] } END { print sum "; $" sum * ENVIRON["RATE"] }' > $TMP
|
||||||
|
echo $TMP
|
||||||
|
}
|
||||||
|
read_items_csv() {
|
||||||
|
TMP=$(mktemp)
|
||||||
|
cat $1 | awk -F, '{ sum += $2 }; { print $1 ";" $2 } END { print sum }' > $TMP
|
||||||
|
echo $TMP
|
||||||
|
}
|
||||||
|
|
||||||
# 3rd argument is output location (optional)
|
if [[ -z $1 ]]; then
|
||||||
OUTPUT="invoice-${INV_NUM}.pdf"
|
print_help
|
||||||
if [[ ! -z $3 ]]; then
|
exit
|
||||||
OUTPUT=$3
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Parse the CSV into: Label;Hrs;Cost
|
export INVOICE_NUM=$(get_invoice_num)
|
||||||
TMP=$(mktemp)
|
OUTPUT="invoice-${INVOICE_NUM}.pdf"
|
||||||
cat $CSV | RATE=$RATE awk -F, '{ sum += $2 }; { print $1 ";" $2 ";" $2 * ENVIRON["RATE"] } END { print "Total" ";" sum ";" sum * ENVIRON["RATE"]}' > $TMP
|
|
||||||
|
|
||||||
# TOTAL = Last line
|
HRS_TMP=$(read_hrs_csv $2)
|
||||||
# BODY = Everything but the last line
|
export HRS_TOTAL=$(cat $HRS_TMP | tail -n 1)
|
||||||
TOTAL=$(cat $TMP | tail -n 1) \
|
export HRS_BODY=$(cat $HRS_TMP | head -n -1)
|
||||||
BODY=$(cat $TMP | head -n -1) \
|
|
||||||
COMPANY=$COMPANY \
|
|
||||||
INVOICE_NUM=$INV_NUM \
|
|
||||||
RATE=$RATE \
|
|
||||||
envsubst < template.mm | groff -t -mm -T pdf > $OUTPUT
|
|
||||||
|
|
||||||
rm $TMP
|
if [[ $1 = "-1" ]]; then
|
||||||
|
if [[ ! -z $4 ]]; then
|
||||||
|
OUTPUT=$4
|
||||||
|
fi
|
||||||
|
export COMPANY=$3
|
||||||
|
envsubst < $TEMPLATE_1COL | groff -t -mm -T pdf > $OUTPUT
|
||||||
|
elif [[ $1 = "-2" ]]; then
|
||||||
|
if [[ ! -z $5 ]]; then
|
||||||
|
OUTPUT=$5
|
||||||
|
fi
|
||||||
|
HRS_COST=$(cat $HRS_TMP | tail -n 1 | sed s/\\$//g | awk -F";" '{ print $2 }')
|
||||||
|
CONSUME_TMP=$(read_items_csv $3)
|
||||||
|
CONSUME_COST=$(cat $CONSUME_TMP | tail -n 1 | awk -F";" '{ print $2 }')
|
||||||
|
export ITEM_TOTAL=$(cat $CONSUME_TMP | tail -n 1 )
|
||||||
|
echo $ITEM_TOTAL
|
||||||
|
echo $HRS_COST
|
||||||
|
export ITEM_BODY=$(cat $CONSUME_TMP | head -n -1)
|
||||||
|
export TOTAL=$(A=$HRS_COST B=$ITEM_TOTAL awk 'BEGIN{ print ENVIRON["A"] + ENVIRON["B"] }')
|
||||||
|
export COMPANY=$4
|
||||||
|
envsubst < $TEMPLATE_2COL | groff -t -mm -T pdf > $OUTPUT
|
||||||
|
else
|
||||||
|
echo First arg should be either -1 or -2
|
||||||
|
fi
|
||||||
|
|||||||
8
ident
Normal file
8
ident
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
export RATE=50
|
||||||
|
export COMPANY_NAME="Cookies Unlimited, LLC"
|
||||||
|
export ADDR_LN_1="123 Sesasme St"
|
||||||
|
export ADDR_LN_2="Dumpster 1"
|
||||||
|
export ADDR_LN_3="12345, Nicevile, FL"
|
||||||
|
export PHONE="(123) 456-7890"
|
||||||
|
export EMAIL="cookie@exapmle.com"
|
||||||
Reference in New Issue
Block a user