37 lines
1.6 KiB
JavaScript
37 lines
1.6 KiB
JavaScript
/* Kundenansicht neu (P2): Zeile "Rechnung offen" für Website und Funktionen. Offen heißt wie überall Number(balance) > 0 (V3).
|
|
Fällt der Abruf aus, fehlt nur diese Zeile. */
|
|
|
|
import { api } from './api.js'
|
|
import { h } from './dom.js'
|
|
import { fmtEuro, safeUrl, zuAnsicht } from './ansicht-hilfen.js'
|
|
|
|
/** Rechnungen mit offenem Betrag, in der Reihenfolge der Antwort von GET /api/invoices. */
|
|
export function offeneRechnungen(antwort) {
|
|
const liste = Array.isArray(antwort?.invoices) ? antwort.invoices : []
|
|
return liste.filter((r) => Number(r?.balance) > 0)
|
|
}
|
|
|
|
/** Lädt GET /api/invoices und liefert die offenen Rechnungen; jeder Fehler ergibt eine leere Liste. */
|
|
export async function ladeOffeneRechnungen(apiFn = api) {
|
|
try {
|
|
return offeneRechnungen(await apiFn('/api/invoices'))
|
|
} catch {
|
|
return []
|
|
}
|
|
}
|
|
|
|
/** Die Zeile für die offenen Rechnungen; ohne offene Rechnung null. Eine Rechnung mit sicherem Link führt dorthin, sonst zu den Rechnungen. */
|
|
export function rechnungOffenZeile(offen) {
|
|
if (!Array.isArray(offen) || !offen.length) return null
|
|
const summe = Math.round(offen.reduce((s, r) => s + (Number(r.balance) || 0), 0) * 100) / 100
|
|
const einzel = offen.length === 1 ? offen[0] : null
|
|
const url = einzel ? safeUrl(einzel.portalUrl) : ''
|
|
const link = url
|
|
? h('a', { href: url, target: '_blank', rel: 'noopener noreferrer' }, 'Zahlen')
|
|
: h('a', zuAnsicht('invoices'), 'Zahlen')
|
|
const teile = einzel
|
|
? ['Rechnung offen', einzel.number, fmtEuro(summe)]
|
|
: [`${offen.length} Rechnungen offen`, fmtEuro(summe)]
|
|
return h('p', { class: 'kn-rechnung-offen' }, `${teile.filter(Boolean).join(' · ')} · `, link)
|
|
}
|