Files
Webklar-Kundenbereich/public/neu/ansicht-stunden.js
T

71 lines
4.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* Kundenansicht neu (P2): Reiter Stunden in Verträge. Stundenkonto des Wartungs-Abos mit Verlauf; ein Vorschuss für die Einrichtung
(ab P6 in ledger.vorschussMinutes) wird nie als Mehraufwand gezeigt. */
import { h, leeren } from './dom.js'
import { K, ersetze, fmtStd, fmtDatum, ladeAbo, ABO_NICHT_GELADEN } from './ansicht-hilfen.js'
import { aboWarnungen } from './vertraege-abo.js'
const laeufe = new WeakMap() // Reiter-Inhalt → Nummer des jüngsten Aufrufs
const stat = (wert, beschriftung) => h('div', { class: 'kn-stat' }, h('strong', { class: 'kn-num' }, wert), h('span', null, beschriftung))
/** Zeile zum Vorschuss für die Einrichtung; bei 0 oder weniger leer. gekuendigt: der Rest verfällt. */
export function vorschussZeile(minuten, gekuendigt) {
if (!(Number(minuten) > 0)) return ''
return `Vorschuss für Einrichtung: ${fmtStd(minuten)}, ${gekuendigt ? 'verfällt, wird nicht berechnet' : 'wird mit den nächsten Monaten verrechnet'}`
}
function verlaufZeile(u) {
const vorschuss = Number(u.vorschussMinutes) || 0
const mehr = Number(u.overageMinutes) || 0
const pille = vorschuss > 0
? h('span', { class: K.pille.violett }, `Vorschuss ${fmtStd(vorschuss)}`)
: mehr > 0 ? h('span', { class: K.pille.orange, title: 'Über das Kontingent hinaus' }, `+${fmtStd(mehr)} extra`) : null
return h('tr', null,
h('td', { 'data-label': 'Datum' }, fmtDatum(u.date)),
h('td', { 'data-label': 'Vorgang' }, u.topic || u.details || 'Arbeitszeit', u.woid ? h('span', { class: 'kn-zeile-sub' }, ` #${u.woid}`) : null),
h('td', { 'data-label': 'Zeit', class: 'kn-num' }, `−${fmtStd(u.minutes)}`, u.supportMinutes ? h('span', { class: 'kn-zeile-sub' }, ` inkl. ${fmtStd(u.supportMinutes)} Unterstützung`) : null, pille ? ' ' : null, pille))
}
function gutschriftZeile(c) {
return h('tr', null,
h('td', { 'data-label': 'Datum' }, fmtDatum(c.grantedAt)),
h('td', { 'data-label': 'Vorgang' }, 'Monatskontingent'),
h('td', { 'data-label': 'Zeit', class: 'kn-num' }, `+${fmtStd(c.minutes)}`, h('span', { class: 'kn-zeile-sub' }, ` ${c.expired ? 'abgelaufen' : `nutzbar bis ${fmtDatum(c.expiresAt)}`}`)))
}
/** Reiter-Inhalt Stunden. daten (GET /api/abo) ist optional; ohne sie lädt die Funktion selbst. */
export async function zeigeStunden(wurzel, { route, me, nav, daten } = {}) {
const nr = (laeufe.get(wurzel) ?? 0) + 1
laeufe.set(wurzel, nr)
const aktuell = () => laeufe.get(wurzel) === nr
leeren(wurzel).append(h('p', { class: K.leer }, 'Wird geladen …'))
const abo = daten ?? await ladeAbo()
if (!aktuell()) return
if (!abo) { leeren(wurzel).append(h('p', { class: K.fehler }, ABO_NICHT_GELADEN)); return }
const sub = abo.subscription
const l = abo.ledger
if (!sub?.active || sub.productKey !== 'wartung' || !l) {
leeren(wurzel).append(h('p', { class: K.leer }, 'Ein Stundenkonto gibt es im Wartungs-Abo.'))
return
}
const gekuendigt = Boolean(sub.cancelAtPeriodEnd || sub.cancelAt)
const vorschuss = vorschussZeile(l.vorschussMinutes, gekuendigt)
const zeilen = [...(l.usage || []).map(verlaufZeile), ...(l.credits || []).slice().reverse().map(gutschriftZeile)]
ersetze(wurzel,
...aboWarnungen(sub),
h('div', { class: 'kn-statistik' },
stat(fmtStd(l.balanceMinutes), 'verfügbare Zeit'),
stat(fmtStd(l.usedMinutes), 'bisher genutzt'),
l.nextExpiry ? stat(fmtStd(l.nextExpiry.minutes), `verfallen am ${fmtDatum(l.nextExpiry.at)}`) : null),
vorschuss ? h('p', { class: 'kn-hinweis kn-vorschuss' }, vorschuss) : null,
h('p', { class: 'kn-hinweis' }, '1 Stunde pro bezahltem Monat. Angerechnet wird in 15-Minuten-Schritten, die ältesten Stunden zuerst.'),
h('p', { class: 'kn-links' }, h('a', { href: sub.termsUrl || '/abo-bedingungen.html', target: '_blank', rel: 'noopener noreferrer' }, 'Leistungen & Bedingungen')),
h('section', { class: 'kn-sektion' },
h('h2', { class: K.abschnitt }, 'Verlauf'),
zeilen.length
? h('div', { class: 'kn-tabelle' }, h('table', null, h('thead', null, h('tr', null, h('th', null, 'Datum'), h('th', null, 'Vorgang'), h('th', null, 'Zeit'))), h('tbody', null, zeilen)))
: h('p', { class: 'kn-hinweis' }, 'Noch keine Buchungen.')))
}