]> git.plutz.net Git - invoices/blobdiff - invoices.sh
sort invoice list, newest to oldest
[invoices] / invoices.sh
index 93292cbee74a31f0b69613940c8a4bc72b215712..d53ace75b41d3452e5224fb75d43222435ac6323 100755 (executable)
@@ -23,59 +23,92 @@ client_list(){
 }
 
 list_invoices(){
+  [ -d invoices/ ] || return 0
+
+  printf '[h1 Open]'
+  for i in invoices/*; do case "$(sed 1q <$i)" in
+    *status=open*) list_invoice "$i";;
+    *status=*) :;;
+    *) list_invoice "$i";;
+  esac; done
+
+  for n in resent:Resent sent:Sent paid:Paid cancelled:Cancelled; do
+    printf '[h1 %s]' "${n#*:}"
+    printf "%s\n" invoices/* \
+    | sort -r \
+    | while read i; do case "$(sed 1q <$i)" in
+      *status=${n%:*}*) list_invoice "$i";;
+    esac; done
+  done
+}
+
+list_invoice(){
+  local i="$1"
   local sender client date number vat vatrate iban bic hourly \
-        taxtype nett tax gross total
+        taxtype nett tax gross total status
 
-  [ -d invoices/ ] && for i in invoices/*; do
-    read -r sender client date number vat vatrate hourly x<<-EOF
+  read -r sender client date number vat vatrate hourly status x<<-EOF
        $(sed q "$i")
        EOF
 
-    [ ! -f "senders/${sender#sender=}" ] \
-    && sender="(unset)" \
-    || read -r sender iban bic x<"senders/${sender#sender=}"
+  [ ! -f "senders/${sender#sender=}" ] \
+  && sender="(unset)" \
+  || read -r sender iban bic x<"senders/${sender#sender=}"
 
-    [ ! -f "clients/${client#client=}" ] \
-    && client="(unset)" \
-    || read -r client hourly x<"clients/${client#client=}"
+  [ ! -f "clients/${client#client=}" ] \
+  && client="(unset)" \
+  || read -r client hourly x<"clients/${client#client=}"
 
-    [ "${date#date=}" -ge 0 ] 2>&- \
-    && date="$(date -d "@${date#date=}" +%x)" \
-    || date="(unset)"
+  [ "${date#date=}" -ge 0 ] 2>&- \
+  && date="$(date -d "@${date#date=}" +%x)" \
+  || date="(unset)"
 
-    read -r taxtype nett tax gross x<<-EOF
+  read -r taxtype nett tax gross x<<-EOF
        $(invoice_total "${i#invoices/}")
        EOF
-    case $taxtype in
-      nett)  total="${nett} € + VAT";;
-      gross) total="${gross} € incl. VAT";;
-      *) total="${gross} €";;
-    esac
-
-    printf '[div .invoice
-      [h2
-          %s]
-      [label From:] %s [label To:] %s [label on] %s
-      [label Amount:] %s
-      [a href="/invoices/%s" Edit]
-    ]' "$(UNSTRING "${number#number=}" |HTML)" \
-       "$(UNSTRING "${sender#address=}" |sed q |HTML)" \
-       "$(UNSTRING "${client#address=}" |sed q |HTML)" "$(HTML "$date")" \
-       "$total" \
-       "$(HTML ${i#invoices/})"
-  done
+  case $taxtype in
+    nett)  total="${nett} € + VAT";;
+    gross) total="${gross} € incl. VAT";;
+    *) total="${gross} €";;
+  esac
+
+  case $status in
+    status=sent|status=resent|status=paid|status=cancelled)
+      status="${status#status=}"
+    ;;
+    *) status=open;;
+  esac
+
+  printf '[div .invoice
+    [h2
+        %s]
+    [label From:] %s [label To:] %s [label on] %s
+    [label Amount:] %s
+    [a href="/invoices/%s" Edit]
+  ]' "$(UNSTRING "${number#number=}" |HTML)" \
+     "$(UNSTRING "${sender#address=}" |sed q |HTML)" \
+     "$(UNSTRING "${client#address=}" |sed q |HTML)" "$(HTML "$date")" \
+     "$total" \
+     "$(HTML ${i#invoices/})"
 }
 
 edit_invoice(){
   local id="$1" sender client date number vat vatrate caddress hourly \
-        taxtype nett tax gross
+        taxtype nett tax gross status
 
   if [ -f "invoices/$id" ]; then
-    read -r sender client date number vat vatrate hourly x<<-EOF
+    read -r sender client date number vat vatrate hourly status x<<-EOF
        $(sed q "invoices/$id")
        EOF
   fi
 
+  case $status in
+    status=sent|status=resent|status=paid|status=cancelled)
+      status="${status#status=}"
+    ;;
+    *) status=open;;
+  esac
+
   [ "${date#date=}" -ge 0 ] 2>&- \
   && date="$(date -d "@${date#date=}" +%F)" \
   || date="$(date +%F)"
@@ -95,7 +128,7 @@ edit_invoice(){
   && hourly="${hourly#hourly=}" \
   || hourly="${chourly}"
 
-  tid="$(tid "invoices/$id")"
+  tid="$(transid "invoices/$id")"
 
   read -r taxtype nett tax gross x<<-EOF
        $(invoice_total "$id")
@@ -136,17 +169,19 @@ edit_invoice(){
            [tr [th Date] [th Work] [th Hours] [th Price] ]
 $({ sed 1d "invoices/$id"; printf 'time= work= hours=\n'; } \
   | while read -r time work hours x; do
-    hours="$(UNSTRING "${hours#hours=}" |grep -m1 -xE '[0-9]+' || printf 0)"
+    hours="$(UNSTRING "${hours#hours=}" \
+             |grep -m1 -xE '\.[0-9]+|[0-9]+\.?[0-9]*' || printf 0)"
     printf '[tr
             [td [textarea name=time
 %s] ]
             [td [textarea name=work
 %s] ]
-            [td [input type=number name=hours value="%s"] ]
+            [td [input type=number name=hours value="%g" step=any] ]
             [td %s]
    ]' "$(UNSTRING "${time#time=}" |HTML)" \
       "$(UNSTRING "${work#work=}" |HTML)" \
-      "$hours" "$((hours * hourly)) €"
+      "$hours" \
+      "$(awk "BEGIN { printf \"%.2f €\", ${hours} * ${hourly}; }")"
   done
 )
             [tr [td colspan=4 
@@ -159,6 +194,13 @@ $({ sed 1d "invoices/$id"; printf 'time= work= hours=\n'; } \
             esac)
             ]]
          ]
+          [select name=status
+             [option value=open      $( [ $status = open      ] && printf selected=selected ) Open]
+             [option value=sent      $( [ $status = sent      ] && printf selected=selected ) Sent]
+             [option value=resent    $( [ $status = resent    ] && printf selected=selected ) Resent]
+             [option value=paid      $( [ $status = paid      ] && printf selected=selected ) Paid]
+             [option value=cancelled $( [ $status = cancelled ] && printf selected=selected ) Cancelled]
+          ]
          [submit "genpdf" "$tid" Export PDF]
          [submit "update" "$tid" Update]
        ]
@@ -183,10 +225,10 @@ invoice_total(){
 
     sed 1d "invoices/$id" \
     | { while read -r time work hours; do
-        [ "${hours#hours=}" -gt 0 ] 2>&- \
+        [ "${hours#hours=}" ] 2>&- \
         && hours="${hours#hours=}" \
         || hours=0
-        total=$((total + hours * hourly))
+        total=$(awk "BEGIN { printf \"%.2f\", ${total} + ${hours} * ${hourly}; }")
       done
       case $vat in
         vat=nett)
@@ -215,7 +257,7 @@ invoice_total(){
 
 update_invoice(){
   local id="$(POST id |checkid)" extra=0 tid
-  tid="$(tid invoices/$id)"
+  tid="$(transid invoices/$id)"
 
   if [ "$(POST update)" = "$tid" ] || [ "$(POST genpdf)" = "$tid" ]; then
     mkdir -p invoices
@@ -224,20 +266,26 @@ update_invoice(){
       [ "$n" -gt "$extra" ] && extra="$n"
     done
 
-    { printf 'sender=%s        client=%s       date=%s number=%s       vat=%s  vatrate=%s      hourly=%s\n' \
+    { printf 'sender=%s        client=%s       date=%s number=%s       vat=%s  vatrate=%s      hourly=%s       status=%s\n' \
         "$(POST sender)" "$(POST client)" \
         "$(date -d "$(POST date)" +%s)" \
         "$(POST number |STRING)" \
         "$(POST vat |grep -m1 -xE 'smallbusiness|gross|nett')" \
         "$(POST vatrate |grep -m1 -xE '[0-9]+')" \
-        "$(POST hourly |grep -m1 -xE '[0-9]+')"
+        "$(POST hourly |grep -m1 -xE '[0-9]+')" \
+        "$(POST status |grep -m1 -xE 'open|sent|resent|paid|cancelled')"
       for n in $(seq 1 $extra); do
         printf 'time=%s        work=%s hours=%s\n' \
           "$(POST time $n |STRING)" "$(POST work $n |STRING)" \
           "$(POST hours $n |STRING)" \
-        | grep -xvF 'time=     work=   hours=0'
+        | grep -xvF 'time=\    work=\  hours=0'
       done
     } >"invoices/$id"
+
+    [ -d .git ] && {
+      git add "invoices/$id"
+      git commit -m 'Update invoice info for "'"$(POST number)"'"' -- "invoices/$id"
+    } >/dev/null
   fi
   if [ "$(POST genpdf)" ]; then
     read -r sender client date x<"invoices/$id"