]> git.plutz.net Git - invoices/blob - invoices.sh
a38693298d9c3c235ad9d14c5840dfca7c5f8749
[invoices] / invoices.sh
1 #!/bin/sh
2
3 sender_list(){
4   local select="$1" n name
5   [ -d senders/ ] && for n in '' senders/*; do
6     [ "$n" ] && name="$(sed q "$n" |HTML)"
7     [ "${n#senders/}" = "$select" ] \
8     && printf '<option value="%s" selected=selected>%s</option>' "${n#senders/}" "$name" \
9     || printf '<option value="%s">%s</option>' "${n#senders/}" "$name"
10   done
11 }
12
13 client_list(){
14   local select="$1" n address hourly name
15   [ -d clients/ ] && for n in '' clients/*; do
16     [ "$n" ] && read -r address hourly <"$n"
17     name="$(UNSTRING "${address#address=}" |sed q |HTML)"
18     [ "${n#clients/}" = "$select" ] \
19     && printf '<option value="%s" selected=selected>%s</option>' "${n#clients/}" "$name" \
20     || printf '<option value="%s">%s</option>' "${n#clients/}" "$name"
21   done
22 }
23
24 list_invoices(){
25   [ -d invoices/ ] && for i in invoices/*; do
26     read -r sender client date number vat vatrate<<-EOF
27         $(sed q "$i")
28         EOF
29     [ -f "senders/${sender#sender=}" ] \
30     && sender="$(sed q "senders/${sender#sender=}")" \
31     || sender="(unset)"
32     [ ! -f "clients/${client#client=}" ] \
33     && client="(unset)" \
34     || read -r client hourly <"clients/${client#client=}"
35     [ "${date#date=}" -ge 0 ] 2>&- \
36     && date="$(date -d "@${date#date=}" +%x)" \
37     || date="(unset)"
38
39     printf '[div .invoice
40       [h2
41           %s]
42       [label From:] %s [label To:] %s [label on] %s
43       [a href="/invoices/%s" Edit]
44     ]' "$(UNSTRING "${number#number=}" |HTML)" \
45        "$(HTML "$sender")" \
46        "$(UNSTRING "${client#address=}" |sed q |HTML)" "$(HTML "$date")" \
47        "$(HTML ${i#invoices/})"
48   done
49 }
50
51 edit_invoice(){
52   local id="$1" sender client date number vat vatrate caddress hourly
53   if [ -f "invoices/$id" ]; then
54     read -r sender client date number vat vatrate<<-EOF
55         $(sed q "invoices/$id")
56         EOF
57   fi
58
59   [ "${date#date=}" -ge 0 ] 2>&- \
60   && date="$(date -d "@${date#date=}" +%F)" \
61   || date="$(date +%F)"
62   [ "${number#number=}" ] || number="number=$(date +%s)"
63   [ "${vatrate#vatrate=}" -ge 0 ] 2>&- || vatrate="vatrate=19"
64
65   [ -f "clients/${client#client=}" ] \
66   && read -r caddress hourly <"clients/${client#client=}"
67   hourly="${hourly#hourly=}"
68
69   cat <<-EOF 
70         [form method="POST" action="/update_invoice"
71           [hidden "id" "$(HTML "$id")"]
72         
73           [label Sender:]
74           [select name=sender
75             $(sender_list "${sender#sender=}")
76           ]
77         
78           [label Client:]
79           [select name=client
80             $(client_list "${client#client=}")
81           ]
82         
83           [label for=number Invoice Number:]
84           [input #number name=number value="$(UNSTRING "${number#number=}" |HTML)"]
85         
86           [label for=date Date:]
87           [input #date name=date value="${date}" placeholder="YYYY-MM-TT"]
88         
89           [radio "vat" "smallbusiness" #vatsb $([ "${vat#vat=}" = smallbusiness ] && printf checked) ]
90           [label for=vatsb Small business exemption from VAT]
91           [radio "vat" "nett" #vatnett $([ "${vat#vat=}" = nett ] && printf checked)]
92           [label for=vatnett Nett]
93           [radio "vat" "gross" #vatgross $([ "${vat#vat=}" = gross ] && printf checked)]
94           [label for=vatgross Gross]
95           [label for=vatrate VAT Rate: [input type=number name="vatrate" value="${vatrate#vatrate=}"]% ]
96         
97           [table
98             [tr [th Date] [th Work] [th Hours] [th Price] ]
99 $({ sed 1d "invoices/$id"; printf 'time= work= hours=\n'; } \
100     | while read -r time work hours; do
101       hours="$(UNSTRING "${hours#hours=}" |grep -m1 -xE '[0-9]+' || printf 0)"
102       printf '[tr
103               [td [textarea name=time
104 %s] ]
105               [td [textarea name=work
106 %s] ]
107               [td [input type=number name=hours value="%s"] ]
108               [td %s]
109      ]' "$(UNSTRING "${time#time=}" |HTML)" \
110         "$(UNSTRING "${work#work=}" |HTML)" \
111         "$hours" "$((hours * hourly)) €"
112     done
113 )
114           ]
115           [submit "update" "$(tid "invoices/$id")" Update]
116         ]
117         EOF
118 }
119
120 update_invoice(){
121   local id="$(POST id |checkid)" extra=0
122
123   if [ "$(POST update)" = "$(tid "invoices/$id")" ]; then
124     mkdir -p invoices
125
126     for n in "$(POST_COUNT time)" "$(POST_COUNT work)" "$(POST_COUNT hours)"; do
127       [ "$n" -gt "$extra" ] && extra="$n"
128     done
129
130     { printf 'sender=%s client=%s       date=%s number=%s       vat=%s  vatrate=%s\n' \
131         "$(POST sender)" "$(POST client)" \
132         "$(date -d "$(POST date)" +%s)" \
133         "$(POST number |STRING)" \
134         "$(POST vat |grep -m1 -xE 'smallbusiness|gross|nett')" \
135         "$(POST vatrate |grep -m1 -xE '[0-9]+')"
136       for n in $(seq 1 $extra); do
137         printf 'time=%s work=%s hours=%s\n' \
138           "$(POST time $n |STRING)" "$(POST work $n |STRING)" \
139           "$(POST hours $n |STRING)" \
140         | grep -xvF 'time=      work=   hours=0'
141       done
142     } >"invoices/$id"
143   fi
144   REDIRECT "/invoices/$id"
145 }