From: Paul Hänsch Date: Thu, 3 Apr 2025 10:44:58 +0000 (+0200) Subject: Invoices per day X-Git-Url: https://git.plutz.net/?a=commitdiff_plain;h=fd3dd820e643eebe626f7335daf361a60cfbc5cf;p=invoices Invoices per day --- diff --git a/tmpl_byday/form.css b/tmpl_byday/form.css new file mode 120000 index 0000000..f26ee0d --- /dev/null +++ b/tmpl_byday/form.css @@ -0,0 +1 @@ +../tmpl_byhour/form.css \ No newline at end of file diff --git a/tmpl_byday/form.sh b/tmpl_byday/form.sh new file mode 100755 index 0000000..b5d8add --- /dev/null +++ b/tmpl_byday/form.sh @@ -0,0 +1,175 @@ +#!/bin/sh + +. "$_EXEC/datetime.sh" + +sumtotal(){ + local taxrate="$(DB3 get taxrate || printf 19)" + local rate="$(DB3 get rate || printf 0)" + local n=0 time seq=1 total=0 + + [ $n -lt "$(DB3 count tb_time )" ] && n="$(DB3 count tb_time)" + + while [ $seq -le $n ]; do + time="$(DB3 get tb_time $seq |grep -m1 -xEe '-?[0-9]+(.00?|.25|.50?|.75)?' || printf 0)" + + total=$(awk "BEGIN { printf \"%.2f\", ${total} + ${time} * ${rate}; }") + seq=$((seq + 1)) + done + + case $(DB3 get taxtype) in + net) awk " + BEGIN { printf \"%.2f %.2f %.2f\", + $total, int($total * $taxrate + .5) / 100, + $total + int($total * $taxrate + .5) / 100 + }" + ;; + gross) awk " + BEGIN { printf \"%.2f %.2f %.2f\", + $total - int($total / (100 + $taxrate) * $taxrate * 100 + .5) / 100, + int($total / (100 + $taxrate) * $taxrate * 100 + .5) / 100, $total + }" + ;; + free|*) awk " + BEGIN { printf \"%.2f %.2f %.2f\", + $total, 0, $total + }" + ;; + esac +} + +DB3 get taxtype |grep -qxE 'free|net|gross' || DB3 set taxtype gross +DB3 get taxrate |grep -qxE '[-+]?[0-9]+(\.[0-9]+)?' || DB3 set taxrate 19 +isdate "$(DB3 get date)" >/dev/null || DB3 set date "$(date +%d.%m.%Y)" + +if ! DB3 get invnum |grep -qxE '.+'; then + invnum="$(date +%s) " + DB3 set invnum "$invnum" +fi + +DB3 get rate |grep -m1 -qxEe '-?(\.[0-9]+|[0-9]+\.?[0-9]*)' || DB3 set rate 0 +rate="$(printf '%.2f' "$(DB3 get rate)")" + +read -r net tax gross x <<-EOF +$(sumtotal) +EOF + +yield_form(){ + printf '%s\r\n' "Content-Type: text/html; charset=utf-8" "" + + "$_EXEC/cgilite/html-sh.sed" <<-EOF +[html [head + [meta name="viewport" content="width=device-width"] + [link rel="stylesheet" type="text/css" href="$_BASE/cgilite/common.css"] + [link rel="stylesheet" type="text/css" href="$_BASE/tmpl_byhour/form.css"] + [title $(_ Invoices)] +] [body + [datalist #senders + $(grep -hE '^sender ' "$_DATA"/*.kvd \ + | sort -u \ + | while read junk sender; do + printf '[option . %s]' "$(UNSTRING $sender |HTML)" + done) + ] + [datalist #clients + $(grep -hE '^rcpt ' "$_DATA"/*.kvd \ + | sort -u \ + | while read junk rcpt; do + printf '[option . %s]' "$(UNSTRING $rcpt |HTML)" + done) + ] + [datalist #taxfreetext + [option . Der Rechnungsbetrag ist nach §4 Abs. 21 UStG. umsatzsteuerfrei] + [option . Der Rechnungsbetrag ist nach §4 Abs. 25 UStG. umsatzsteuerfrei] + [option . Gemäß Kleinunternehmerregelung (§19 UStG.) wird keine Umsatzsteuer berechnet.] + ] + [form method="POST" + [label for=sender Absender:] + [input #sender list=senders name=sender value="$(DB3 get sender |HTML)" placeholder="Name; Straße; PLZ Ort"] + + [label for=rcpt Empfänger:] + [input #rcpt list=clients name=rcpt value="$(DB3 get rcpt |HTML)" placeholder="Name; Straße; PLZ Ort"] + + [label for=invnum Rechnungsnummer:] + [input #invnum name=invnum value="$(DB3 get invnum |HTML)"] + + [label for=date Datum:] + [input #date name=date value="$(DB3 get date)" placeholder="TT.MM.YYYY"] + + $([ "$(grep -xF "invnum $(DB3 get invnum |STRING)" "$_DATA"/*.kvd |wc -l)" -gt 1 ] \ + && printf '[span .warning Warnung: Rechnungsnummer doppelt vergeben]' + ) + + [label for=rate Tagessatz:] + [input type=number id=rate name=rate value="$rate" step=".01"] + + [table + [tr [th Datum] [th Leistung] [th Tage] [th Betrag] ] + $(n=0; seq=0; + [ $n -lt "$(DB3 count tb_date)" ] && n="$(DB3 count tb_date)" + [ $n -lt "$(DB3 count tb_desc)" ] && n="$(DB3 count tb_desc)" + [ $n -lt "$(DB3 count tb_time)" ] && n="$(DB3 count tb_time)" + + while [ $seq -le $n ]; do + seq=$((seq + 1)) + date="$(DB3 get tb_date $seq |HTML)" + desc="$(DB3 get tb_desc $seq |HTML)" + time="$(DB3 get tb_time $seq |grep -m1 -xEe '-?[0-9]+(.00?|.25|.50?|.75)?' || printf 0)" + time="$(printf %.2f "$time")" + time="${time%0}" time="${time%.0}" + [ "$date" = "" -a "$desc" = "" -a "$time" = 0 ] && continue + + printf '[tr + [td [textarea name=tb_date . %s]] + [td [textarea name=tb_desc . %s]] + [td [input type=number name=tb_time value="%s" step=.25] ] + [td %s] + ]' "$date" "$desc" "${time}"\ + "$(awk "BEGIN { printf \"%.2f €\", ${time} * ${rate}; }")" + done + ) + [tr + [td [textarea name=tb_date]] + [td [textarea name=tb_desc]] + [td [input type=number name=tb_time value="0" step=.25] ] + [td] + ] + $(case $(DB3 get taxtype) in + (net) printf '[tr [th colspan=3 . Summe:][td . %7.2f €]] + [tr [th colspan=3 . + USt.:][td . %7.2f €]] + [tr [th colspan=3 . Gesamt:][td . %7.2f €]] + ' $net $tax $gross ;; + (gross) printf '[tr [th colspan=3 . Gesamt:][td . %7.2f €]] + [tr [th colspan=3 . incl. Netto:][td . %7.2f €]] + [tr [th colspan=3 . + USt.:][td . %7.2f €]] + ' $gross $net $tax ;; + (free|*) printf '[tr [th colspan=3 . Gesamt:][td . %7.2f €]]' "$net" + ;; + esac) + ] + + [radio "taxtype" "free" #taxfree $([ "$(DB3 get taxtype)" = free ] && printf checked)] + [label for=taxfree Umsatzsteuerfrei] + [radio "taxtype" "net" #taxnet $([ "$(DB3 get taxtype)" = net ] && printf checked)] + [label for=taxnet Netto] + [radio "taxtype" "gross" #taxgross $([ "$(DB3 get taxtype)" = gross ] && printf checked)] + [label for=taxgross Brutto] + [input list="taxfreetext" name="taxfreetext" value="$(DB3 get taxfreetext |HTML)" placeholder="Kommentar zur Umsatzsteuerbefreiung"] + [label for=taxrate USt. %:][input type=number #taxrate name="taxrate" value="$(DB3 get taxrate)"] + + [label for=status . $(_ Status):] + [select #status name=status + [option value=open $([ "$status" = open ] && printf selected=selected) . $(_ Offen)] + [option value=sent $([ "$status" = sent ] && printf selected=selected) . $(_ Versendet)] + [option value=resent $([ "$status" = resent ] && printf selected=selected) . $(_ Erinnert)] + [option value=paid $([ "$status" = paid ] && printf selected=selected) . $(_ Bezahlt)] + [option value=cancelled $([ "$status" = cancelled ] && printf selected=selected) . $(_ Storniert)] + ] + [input type=hidden name=id value="$id"] + [input type=hidden name=tid value="$tid"] + [input type=hidden name=session_key value="$SESSION_KEY"] + [button type=submit name=action value=update_invoice . $(_ Update)] + [button type=submit name=action value=update_invoice_return . ← Übersicht] + ] +] ] +EOF +} diff --git a/tmpl_byday/print.sh b/tmpl_byday/print.sh new file mode 100755 index 0000000..1f1fecf --- /dev/null +++ b/tmpl_byday/print.sh @@ -0,0 +1,168 @@ +#!/bin/zsh + +filenamestring="Rechnung $(DB3 get sender |sed -E 's/ *;.*$//g') an $(DB3 get rcpt |sed -E 's/ *;.*$//g') $(isdate "$(DB3 get date)")" + +yield_html(){ + local sender rcpt date seq time desc taxtype hourly + + local net tax gross + read -r net tax gross <<-EOF + $(sumtotal) + EOF + taxtype="$(DB3 get taxtype)" + + date="$(isdate "$(DB3 get date)" || date +%F)" + date="$(date -d "$date" +%s)" + hourly="$(DB3 get rate |grep -m1 -xEe '-?(\.[0-9]+|[0-9]+\.?[0-9]*)' || printf 0)" + hourly="$(printf %.2f "$hourly")" + + sender="$(DB3 get sender |sed -E 's/ *; */\r\n/g' |HTML)" + rcpt="$(DB3 get rcpt |sed -E 's/ *; */\r\n/g' |HTML |sed -E ':A; /(.* ){6}/!{ s/$/\ \ /g; bA; }')" + [ ! "$rcpt" ] && rcpt=" " + + freeformtop="$(DB3 get freeformtop |sed -E 's/ *; */\r\n/g' |HTML)" + + cat <<-EOF + + + + + + + + + + + + +

+ ${rcpt}

+ +

+ $(date -d @${date} +%d.%m.%Y)

+ +

+ Rechnung $(DB3 get invnum |HTML)

+ +

+ ${freeformtop}

+ +

+ Tagessatz: ${hourly} €

+ + + + + + + + + + + + + + + + + $(n=0; seq=0; + [ $n -lt "$(DB3 count tb_date)" ] && n="$(DB3 count tb_date)" + [ $n -lt "$(DB3 count tb_time)" ] && n="$(DB3 count tb_time)" + [ $n -lt "$(DB3 count tb_desc)" ] && n="$(DB3 count tb_desc)" + + while [ $seq -le $n ]; do + seq=$((seq + 1)) + date="$(DB3 get tb_date $seq |HTML)" + desc="$(DB3 get tb_desc $seq |HTML)" + time="$(DB3 get tb_time $seq |grep -m1 -xEe '-?[0-9]+(.00?|.25|.50?|.75)?' || printf 0)" + time="$(printf %.2f "$time")" + time="${time%0}" time="${time%.0}" + + [ "$date" = "" -a "$desc" = "" -a "$time" = 0 ] && continue + + cat <<-ROW + + + + + + + ROW + done + ) + $([ $taxtype != free ] && cat <<-ROW + + + + + + + ROW + ) + + + + + + + +

+ Datum

+

+

+

+ Leistung

+

+ Betrag

+

+ ${date}

+

+

+

+ $(HTML "$desc")

+

+ + $(awk "BEGIN { printf \"%.2f €\", ${time} * ${hourly}; }" |num)

+

+

+

+

+

+ + $([ $taxtype = gross ] && printf "incl."; [ $taxtype = net ] && printf "zzgl."; ) + $(DB3 get taxrate)% MwSt.: + $([ $taxtype = gross ] && printf '%.2f €' $tax |num) +

+

+ + $([ $taxtype = net ] && printf '%.2f €' $tax |num) +

+

+

+

+

+

+ Gesamtsumme:

+

+ + $(printf '%.2f €' $gross |num)

+
+ + $([ $taxtype = free ] && cat <<-EOF +

+ $(DB3 get taxfreetext |HTML)

+ EOF + ) + +

+ $(DB3 get freeformbottom |HTML)

+ + + + EOF +}