85 lines
3.9 KiB
JavaScript
85 lines
3.9 KiB
JavaScript
/* Abschnitt „Aufträge“ im Reiter Rechnungen des Kundenportals (geladen von app.js, loadCustomerOrders; request ist api aus app.js).
|
|
Kundentext kommt nur über textContent in die Seite. Alle Texte stehen in auftrag-ansicht.js; das Portal spricht in der Du-Form. */
|
|
import {
|
|
ANREDE_DU, agbPfad, darfBestaetigen, kartenMeta, sortiereAuftraege, statusAnzeige, texte,
|
|
} from './auftrag-ansicht.js'
|
|
import {
|
|
h, renderBestaetigtBlock, renderBestaetigung, renderDokumente, renderZusammenfassung,
|
|
} from './auftrag-dom.js'
|
|
|
|
export async function initAuftraege({ section, body, invoicesTitle, request, viewAs = false } = {}) {
|
|
if (!section || !body || typeof request !== 'function') return { sichtbar: false }
|
|
const t = texte(ANREDE_DU)
|
|
let eintraege = []
|
|
|
|
/** Bestätigen darf, wer der Server dafür freigibt; in der Kundenansicht zeigt die Oberfläche die offene AB mit gesperrtem Formular. */
|
|
const wirksam = (e) => darfBestaetigen(e) && (viewAs || e.kannBestaetigen === true)
|
|
|
|
async function ladeListe() {
|
|
const daten = await request('/api/auftraege')
|
|
if (daten?.aktiv !== true || !Array.isArray(daten.auftraege)) return []
|
|
return daten.auftraege.filter((e) => e && typeof e.id === 'string' && e.id !== '')
|
|
}
|
|
|
|
function karte(auftrag, offeneId) {
|
|
const kann = wirksam(auftrag)
|
|
const status = statusAnzeige({ ...auftrag, kannBestaetigen: kann })
|
|
const pfad = `/api/auftraege/${encodeURIComponent(auftrag.id)}`
|
|
|
|
async function senden(koerper) {
|
|
try {
|
|
const antwort = await request(`${pfad}/bestaetigen`, { method: 'POST', body: JSON.stringify(koerper) })
|
|
return antwort?.auftrag ? { ok: true, auftrag: antwort.auftrag } : { ok: false, status: 0, body: {} }
|
|
} catch (err) {
|
|
return { ok: false, status: Number(err?.status) || 0, body: { error: String(err?.message ?? '') } }
|
|
}
|
|
}
|
|
function nachErfolg(neu) {
|
|
eintraege = eintraege.map((alt) => (alt.id === auftrag.id ? { ...alt, ...neu, id: alt.id, kannBestaetigen: false } : alt))
|
|
zeichne(auftrag.id)
|
|
body.querySelector(`[data-auftrag="${CSS.escape(auftrag.id)}"] [data-bestaetigt]`)?.focus()
|
|
}
|
|
async function nachEnde() {
|
|
try {
|
|
eintraege = await ladeListe()
|
|
zeichne('')
|
|
} catch {
|
|
/* die Anzeige bleibt stehen */
|
|
}
|
|
}
|
|
|
|
return h('article', { class: 'ab-karte', 'data-auftrag': auftrag.id, 'data-status': auftrag.status || '' },
|
|
h('div', { class: 'ab-karte-kopf' },
|
|
h('div', null,
|
|
h('p', { class: 'ab-karte-nummer' }, h('strong', null, auftrag.nummer || '')),
|
|
auftrag.titel ? h('p', { class: 'ab-karte-titel' }, auftrag.titel) : null,
|
|
h('p', { class: 'ab-karte-meta' }, kartenMeta(auftrag))),
|
|
h('span', { class: `ab-pille ab-pille-${status.ton}` }, status.text)),
|
|
h('div', { class: 'ab-karte-aktionen' },
|
|
h('a', { class: 'ab-link', 'data-link': 'pdf', href: `${pfad}/pdf`, target: '_blank', rel: 'noopener noreferrer' }, t.kartePdf)),
|
|
h('details', { class: 'ab-details', open: kann || auftrag.id === offeneId },
|
|
h('summary', null, kann ? t.karteDetailsBestaetigen : t.karteDetails),
|
|
renderZusammenfassung(auftrag, { ebene: 4 }),
|
|
renderDokumente({ agbHref: agbPfad(auftrag.agbUrl) }),
|
|
renderBestaetigtBlock(auftrag, { anrede: ANREDE_DU }),
|
|
kann
|
|
? renderBestaetigung(auftrag, { senden, nachErfolg, nachEnde, gesperrt: viewAs ? t.ansichtsmodus : '', anrede: ANREDE_DU })
|
|
: null))
|
|
}
|
|
|
|
function zeichne(offeneId) {
|
|
body.replaceChildren(...sortiereAuftraege(eintraege.map((e) => ({ ...e, kannBestaetigen: wirksam(e) }))).map((e) => karte(eintraege.find((x) => x.id === e.id), offeneId)))
|
|
}
|
|
|
|
try {
|
|
eintraege = await ladeListe()
|
|
} catch {
|
|
return { sichtbar: false }
|
|
}
|
|
if (!eintraege.length) return { sichtbar: false }
|
|
zeichne('')
|
|
section.classList.remove('hidden')
|
|
invoicesTitle?.classList.remove('hidden')
|
|
return { sichtbar: true }
|
|
}
|