2023-05-03 10:46:25 +00:00
|
|
|
{{ define "title" -}}
|
|
|
|
{{- /*gotype: dev.tandem.ws/tandem/numerus/pkg.expensesIndexPage*/ -}}
|
|
|
|
{{( pgettext "Expenses" "title" )}}
|
|
|
|
{{- end }}
|
|
|
|
|
|
|
|
{{ define "breadcrumbs" -}}
|
|
|
|
{{- /*gotype: dev.tandem.ws/tandem/numerus/pkg.expensesIndexPage*/ -}}
|
Remove almost all data-hx-boost attributes
Since 16e80b5ae, <body> no longer has overflow, thus no scroll. As a
consequence, htmx no longer is able to scroll up <main> when it changes
due to the default, implicit `show:true` applied to the request: is
calls <main>’s scrollIntoView, however there is nothing to scroll to.
I probably could fix it by changing the target of `show`, or even add
a `scroll` directive to all boosted links, but at this point i think it
is better no not boost links at all, as they do what i want—show the new
page from the top—with less markup, plus the browser now show a loading
animation, and it is not that slower, too.
2024-09-07 23:29:30 +00:00
|
|
|
<nav>
|
|
|
|
<p>
|
2023-05-03 10:46:25 +00:00
|
|
|
<a href="{{ companyURI "/" }}">{{( pgettext "Home" "title" )}}</a> /
|
|
|
|
<a>{{( pgettext "Expenses" "title" )}}</a>
|
|
|
|
</p>
|
Add option to export the list of quotes, invoices, and expenses to ODS
This was requested by a potential user, as they want to be able to do
whatever they want to do to these lists with a spreadsheet.
In fact, they requested to be able to export to CSV, but, as always,
using CSV is a minefield because of Microsoft: since their Excel product
is fucking unable to write and read CSV from different locales, even if
using the same exact Excel product, i can not also create a CSV file
that is guaranteed to work on all locales. If i used the non-standard
sep=; thing to tell Excel that it is a fucking stupid application, then
proper applications would show that line as a row, which is the correct
albeit undesirable behaviour.
The solution is to use a spreadsheet file format that does not have this
issue. As far as I know, by default Excel is able to read XLSX and ODS
files, but i refuse to use the artificially complex, not the actually
used in Excel, and lobbied standard that Microsoft somehow convinced ISO
to publish, as i am using a different format because of the mess they
made, and i do not want to bend over in front of them, so ODS it is.
ODS is neither an elegant or good format by any means, but at least i
can write them using simple strings, because there is no ODS library
in Debian and i am not going to write yet another DEB package for an
overengineered package to write a simple table—all i want is to say
“here are these n columns, and these m columns; have a good day!”.
Part of #51.
2023-07-18 11:29:36 +00:00
|
|
|
|
|
|
|
<form id="batch-form" action="{{ companyURI "/expenses/batch" }}" method="post">
|
|
|
|
{{ csrfToken }}
|
|
|
|
{{ with .Filters }}
|
|
|
|
{{ template "hidden-select-field" .Contact }}
|
|
|
|
{{ template "hidden-select-field" .ExpenseStatus }}
|
|
|
|
{{ template "hidden-field" .FromDate }}
|
|
|
|
{{ template "hidden-field" .ToDate }}
|
|
|
|
{{ template "hidden-field" .InvoiceNumber }}
|
|
|
|
{{ template "hidden-field" .Tags }}
|
|
|
|
{{ template "hidden-field" .TagsCondition }}
|
|
|
|
{{ end }}
|
|
|
|
<p>
|
|
|
|
{{ template "filters-toggle" }}
|
|
|
|
<button type="submit"
|
|
|
|
name="action" value="export"
|
|
|
|
>{{( pgettext "Export list" "action" )}}</button>
|
|
|
|
<a class="primary button"
|
|
|
|
href="{{ companyURI "/expenses/new" }}">{{( pgettext "New expense" "action" )}}</a>
|
|
|
|
</p>
|
|
|
|
</form>
|
2023-05-03 10:46:25 +00:00
|
|
|
</nav>
|
|
|
|
{{- end }}
|
|
|
|
|
|
|
|
{{ define "content" }}
|
|
|
|
{{- /*gotype: dev.tandem.ws/tandem/numerus/pkg.expensesIndexPage*/ -}}
|
2023-05-24 10:13:09 +00:00
|
|
|
<form class="filters" method="GET" action="{{ companyURI "/expenses"}}"
|
|
|
|
data-hx-target="main" data-hx-boost="true" data-hx-trigger="change,search,submit"
|
|
|
|
aria-labelledby="filters-toggle"
|
|
|
|
>
|
2023-07-16 18:56:11 +00:00
|
|
|
<fieldset>
|
|
|
|
{{ with .Filters }}
|
|
|
|
{{ template "select-field" .Contact }}
|
|
|
|
{{ template "select-field" .ExpenseStatus }}
|
|
|
|
{{ template "input-field" .FromDate }}
|
|
|
|
{{ template "input-field" .ToDate }}
|
|
|
|
{{ template "input-field" .InvoiceNumber }}
|
|
|
|
{{ template "tags-field" .Tags | addTagsAttr (print `data-conditions="` .TagsCondition.Name `-field"`) }}
|
|
|
|
{{ template "toggle-field" .TagsCondition }}
|
|
|
|
{{ end }}
|
|
|
|
</fieldset>
|
2023-05-24 10:13:09 +00:00
|
|
|
<noscript>
|
|
|
|
<button type="submit">{{( pgettext "Filter" "action" )}}</button>
|
|
|
|
</noscript>
|
2023-07-16 18:56:11 +00:00
|
|
|
{{ if .Filters.HasValue }}
|
|
|
|
<a href="{{ companyURI "/expenses" }}" class="button">{{( pgettext "Reset" "action" )}}</a>
|
|
|
|
{{ end }}
|
2023-05-24 10:13:09 +00:00
|
|
|
</form>
|
2023-05-03 10:46:25 +00:00
|
|
|
<table>
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th>{{( pgettext "Contact" "title" )}}</th>
|
|
|
|
<th>{{( pgettext "Invoice Date" "title" )}}</th>
|
|
|
|
<th>{{( pgettext "Invoice Number" "title" )}}</th>
|
2023-07-11 13:33:26 +00:00
|
|
|
<th>{{( pgettext "Status" "title" )}}</th>
|
2023-05-06 09:08:21 +00:00
|
|
|
<th>{{( pgettext "Tags" "title" )}}</th>
|
2023-10-02 10:16:50 +00:00
|
|
|
<th class="numeric">{{( pgettext "Amount" "title" )}}</th>
|
|
|
|
{{ range $class := .TaxClasses -}}
|
|
|
|
<th class="numeric">{{ . }}</th>
|
|
|
|
{{ end -}}
|
|
|
|
<th class="numeric">{{( pgettext "Total" "title" )}}</th>
|
2024-08-26 12:47:22 +00:00
|
|
|
<th>{{( pgettext "Payments" "title" )}}</th>
|
2023-05-06 09:08:21 +00:00
|
|
|
<th>{{( pgettext "Actions" "title" )}}</th>
|
2023-05-03 10:46:25 +00:00
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
{{ with .Expenses }}
|
2024-09-08 22:08:02 +00:00
|
|
|
{{ $confirm := (gettext "Are you sure you wish to delete this expense?") }}
|
2023-07-11 13:33:26 +00:00
|
|
|
{{- range $expense := . }}
|
2023-05-03 10:46:25 +00:00
|
|
|
<tr>
|
2023-05-06 09:08:21 +00:00
|
|
|
<td>{{ .InvoicerName }}</td>
|
2023-05-03 10:46:25 +00:00
|
|
|
<td>{{ .InvoiceDate|formatDate }}</td>
|
2024-08-15 23:44:20 +00:00
|
|
|
<td>
|
|
|
|
{{- if .InvoiceNumber -}}
|
|
|
|
<a href="{{ companyURI "/expenses/"}}{{ .Slug }}">{{ .InvoiceNumber }}</a>
|
|
|
|
{{- end -}}
|
|
|
|
</td>
|
2024-08-13 00:34:21 +00:00
|
|
|
<td class="expense-status-{{ .Status }}">{{ .StatusLabel }}</td>
|
2023-05-08 10:58:54 +00:00
|
|
|
<td
|
|
|
|
data-hx-get="{{companyURI "/expenses/"}}{{ .Slug }}/tags/edit"
|
|
|
|
data-hx-target="this"
|
|
|
|
data-hx-swap="outerHTML"
|
|
|
|
>
|
2023-05-03 10:46:25 +00:00
|
|
|
{{- range $index, $tag := .Tags }}
|
|
|
|
{{- if gt $index 0 }}, {{ end -}}
|
|
|
|
{{ . }}
|
|
|
|
{{- end }}
|
|
|
|
</td>
|
|
|
|
<td class="numeric">{{ .Amount | formatPrice }}</td>
|
2023-10-02 10:16:50 +00:00
|
|
|
{{ range $class := $.TaxClasses -}}
|
|
|
|
{{ $tax := index $expense.Taxes $class }}
|
|
|
|
<td class="numeric">{{ if $tax }}{{ $tax | formatPrice }}{{ end }}</td>
|
|
|
|
{{- end }}
|
|
|
|
<td class="numeric">{{ .Total | formatPrice }}</td>
|
2023-05-14 16:46:16 +00:00
|
|
|
<td class="invoice-download">
|
2024-08-26 12:47:22 +00:00
|
|
|
<a role="menuitem" href="{{ companyURI "/expenses"}}/{{ .Slug }}/payments"
|
|
|
|
title="{{( gettext "Expense payments" )}}"
|
|
|
|
aria-label="{{( gettext "Expense payments" )}}"
|
|
|
|
>
|
|
|
|
<i class="ri-bank-card-2-line"></i>
|
|
|
|
</a>
|
2023-05-14 16:46:16 +00:00
|
|
|
</td>
|
2023-05-06 09:08:21 +00:00
|
|
|
<td class="actions">
|
|
|
|
<details class="menu">
|
2023-07-06 09:49:36 +00:00
|
|
|
{{- $label := .InvoiceNumber | printf (gettext "Actions for expense %s") -}}
|
|
|
|
<summary aria-label="{{ $label }}"><i class="ri-more-line"></i></summary>
|
Remove almost all data-hx-boost attributes
Since 16e80b5ae, <body> no longer has overflow, thus no scroll. As a
consequence, htmx no longer is able to scroll up <main> when it changes
due to the default, implicit `show:true` applied to the request: is
calls <main>’s scrollIntoView, however there is nothing to scroll to.
I probably could fix it by changing the target of `show`, or even add
a `scroll` directive to all boosted links, but at this point i think it
is better no not boost links at all, as they do what i want—show the new
page from the top—with less markup, plus the browser now show a loading
animation, and it is not that slower, too.
2024-09-07 23:29:30 +00:00
|
|
|
<ul role="menu" class="action-menu">
|
2023-05-06 09:08:21 +00:00
|
|
|
<li role="presentation">
|
2024-08-17 03:31:01 +00:00
|
|
|
<a role="menuitem" href="{{ companyURI "/expenses"}}/{{ .Slug }}">
|
2023-05-06 09:08:21 +00:00
|
|
|
<i class="ri-edit-line"></i>
|
|
|
|
{{( pgettext "Edit" "action" )}}
|
|
|
|
</a>
|
|
|
|
</li>
|
2024-08-26 12:47:22 +00:00
|
|
|
{{ if .OriginalFileName }}
|
|
|
|
<li role="presentation">
|
|
|
|
<a role="menuitem"
|
|
|
|
href="{{ companyURI "/expenses/"}}{{ .Slug }}/download/{{.OriginalFileName}}"
|
|
|
|
><i class="ri-download-line"></i>
|
|
|
|
{{ ( pgettext "Download expense attachment" "action" ) }}
|
|
|
|
</a>
|
|
|
|
</li>
|
|
|
|
{{ end }}
|
2024-09-08 22:08:02 +00:00
|
|
|
<li role="presentation">
|
|
|
|
<form method="POST" action="{{ companyURI "/expenses/"}}{{ .Slug }}"
|
|
|
|
data-hx-boost="true"
|
|
|
|
data-hx-target="main"
|
|
|
|
data-hx-confirm="{{ $confirm }}"
|
|
|
|
>
|
|
|
|
{{ csrfToken }}
|
|
|
|
{{ deleteMethod }}
|
2024-09-09 09:26:28 +00:00
|
|
|
<button class="icon" role="menuitem">
|
2024-09-08 22:08:02 +00:00
|
|
|
<i class="ri-delete-back-2-line"></i>
|
|
|
|
{{( pgettext "Remove" "action" )}}
|
|
|
|
</button>
|
|
|
|
</form>
|
|
|
|
</li>
|
2023-05-06 09:08:21 +00:00
|
|
|
</ul>
|
|
|
|
</details>
|
|
|
|
</td>
|
2023-05-03 10:46:25 +00:00
|
|
|
</tr>
|
|
|
|
{{- end }}
|
|
|
|
{{ else }}
|
|
|
|
<tr>
|
2023-10-02 10:16:50 +00:00
|
|
|
<td colspan="{{ add 9 (len .TaxClasses) }}">{{( gettext "No expenses added yet." )}}</td>
|
2023-05-03 10:46:25 +00:00
|
|
|
</tr>
|
|
|
|
{{ end }}
|
|
|
|
</tbody>
|
2023-06-20 09:33:28 +00:00
|
|
|
{{ if .Expenses }}
|
|
|
|
<tfoot>
|
|
|
|
<tr>
|
2023-10-02 14:36:42 +00:00
|
|
|
<th scope="row" colspan="5">{{( gettext "Total" )}}</th>
|
|
|
|
<td class="numeric">{{ .SumAmount | formatPrice }}</td>
|
|
|
|
{{ range $class := $.TaxClasses -}}
|
|
|
|
{{ $tax := index $.SumTaxes $class }}
|
|
|
|
<td class="numeric">{{ if $tax }}{{ $tax | formatPrice }}{{ else }}{{ "0.0" | formatPrice }}{{ end }}</td>
|
|
|
|
{{- end }}
|
|
|
|
<td class="numeric">{{ .SumTotal | formatPrice }}</td>
|
2023-06-20 09:33:28 +00:00
|
|
|
<td colspan="2"></td>
|
|
|
|
</tr>
|
|
|
|
</tfoot>
|
|
|
|
{{ end }}
|
2023-05-03 10:46:25 +00:00
|
|
|
</table>
|
|
|
|
{{- end }}
|