146 lines
5.3 KiB
JavaScript
146 lines
5.3 KiB
JavaScript
/**
|
|
* Auftragsbestätigungen (Admin), Mount: /api/admin/finanzen/auftraege (vor dem Finanzen-Router, Übersicht V5 „L3“).
|
|
* GET / (?kunde=), POST /, GET|PATCH|DELETE /:id, GET /:id/pdf, POST /:id/projekt, /:id/senden, /:id/erinnern,
|
|
* /:id/neue-fassung, /:id/stornieren. Nur dünne HTTP-Schicht: Kunde laden, Schalter prüfen, Dienst aufrufen, Fehler über
|
|
* sendeFehler. Ist der Schalter für den Kunden aus, antworten alle Routen 404 mit SCHALTER_AUS_MELDUNG.
|
|
*/
|
|
import { Router } from 'express'
|
|
import { requireAppwriteStaff } from '../../middleware/appwriteStaff.js'
|
|
import { auftraegeAktiv } from '../../services/auftraege/schalter.js'
|
|
import { SCHALTER_AUS_MELDUNG } from '../../services/auftraege/konstanten.js'
|
|
import { AuftragError, sendeFehler } from '../../services/auftraege/fehler.js'
|
|
import { auftragFuerTeam } from '../../services/auftraege/auftragSicht.js'
|
|
import { listAuftraege } from '../../services/auftraege/auftragStore.js'
|
|
import {
|
|
aendereEntwurf, erinnereAuftrag, ladeAuftrag, ladeGespeichertesPdf, ladeKunde, legeEntwurfAn, loescheEntwurf, neueFassung,
|
|
ordneProjektZu, sendeAuftrag, storniereAuftrag, vorschauPdf,
|
|
} from '../../services/auftraege/auftraege.js'
|
|
|
|
const router = Router()
|
|
router.use(requireAppwriteStaff)
|
|
|
|
async function ladeKundeMitSchalter(kundenId) {
|
|
const kunde = await ladeKunde(kundenId)
|
|
if (!auftraegeAktiv(kunde)) throw new AuftragError(404, SCHALTER_AUS_MELDUNG)
|
|
return kunde
|
|
}
|
|
|
|
async function ladeMitSchalter(id) {
|
|
const auftrag = await ladeAuftrag(id)
|
|
await ladeKundeMitSchalter(auftrag.kundenId)
|
|
return auftrag
|
|
}
|
|
|
|
const vonAdmin = (req) => req.appwriteUser?.email
|
|
|
|
router.get('/', async (req, res) => {
|
|
try {
|
|
const kundenId = req.query.kunde
|
|
if (typeof kundenId !== 'string' || kundenId === '') return res.status(400).json({ error: 'Kunde fehlt.' })
|
|
await ladeKundeMitSchalter(kundenId)
|
|
return res.json({ auftraege: (await listAuftraege({ kundenId })).map(auftragFuerTeam) })
|
|
} catch (err) {
|
|
return sendeFehler(res, 'Auftragsbestätigungen laden', err)
|
|
}
|
|
})
|
|
|
|
router.post('/', async (req, res) => {
|
|
try {
|
|
const kundenId = req.body?.kundenId
|
|
if (typeof kundenId === 'string' && kundenId !== '') await ladeKundeMitSchalter(kundenId)
|
|
return res.json({ auftrag: auftragFuerTeam(await legeEntwurfAn(req.body, { von: vonAdmin(req) })) })
|
|
} catch (err) {
|
|
return sendeFehler(res, 'Auftragsbestätigung anlegen', err)
|
|
}
|
|
})
|
|
|
|
router.get('/:id', async (req, res) => {
|
|
try {
|
|
return res.json({ auftrag: auftragFuerTeam(await ladeMitSchalter(req.params.id)) })
|
|
} catch (err) {
|
|
return sendeFehler(res, 'Auftragsbestätigung laden', err)
|
|
}
|
|
})
|
|
|
|
router.patch('/:id', async (req, res) => {
|
|
try {
|
|
await ladeMitSchalter(req.params.id)
|
|
return res.json({ auftrag: auftragFuerTeam(await aendereEntwurf(req.params.id, req.body ?? {})) })
|
|
} catch (err) {
|
|
return sendeFehler(res, 'Auftragsbestätigung ändern', err)
|
|
}
|
|
})
|
|
|
|
router.delete('/:id', async (req, res) => {
|
|
try {
|
|
await ladeMitSchalter(req.params.id)
|
|
await loescheEntwurf(req.params.id)
|
|
return res.json({ ok: true })
|
|
} catch (err) {
|
|
return sendeFehler(res, 'Auftragsbestätigung löschen', err)
|
|
}
|
|
})
|
|
|
|
router.get('/:id/pdf', async (req, res) => {
|
|
try {
|
|
const auftrag = await ladeMitSchalter(req.params.id)
|
|
const entwurf = auftrag.status === 'entwurf'
|
|
const buffer = entwurf ? await vorschauPdf(auftrag.id) : await ladeGespeichertesPdf(auftrag)
|
|
const name = entwurf ? 'Auftragsbestaetigung-Entwurf.pdf' : /^AB-\d{4}-\d{4}$/.test(auftrag.nummer) ? `${auftrag.nummer}.pdf` : 'Auftragsbestaetigung.pdf'
|
|
res.set({ 'Content-Type': 'application/pdf', 'Content-Disposition': `inline; filename="${name}"`, 'Cache-Control': 'no-store' })
|
|
return res.send(buffer)
|
|
} catch (err) {
|
|
return sendeFehler(res, 'Auftragsbestätigung-PDF laden', err)
|
|
}
|
|
})
|
|
|
|
/** Antwort der Aktionen, die eine Mail auslösen: { auftrag, mailFehler }. */
|
|
const mitMail = ({ auftrag, mailFehler }) => ({ auftrag: auftragFuerTeam(auftrag), mailFehler })
|
|
|
|
router.post('/:id/senden', async (req, res) => {
|
|
try {
|
|
await ladeMitSchalter(req.params.id)
|
|
return res.json(mitMail(await sendeAuftrag(req.params.id, { von: vonAdmin(req) })))
|
|
} catch (err) {
|
|
return sendeFehler(res, 'Auftragsbestätigung senden', err)
|
|
}
|
|
})
|
|
|
|
router.post('/:id/erinnern', async (req, res) => {
|
|
try {
|
|
await ladeMitSchalter(req.params.id)
|
|
return res.json(mitMail(await erinnereAuftrag(req.params.id)))
|
|
} catch (err) {
|
|
return sendeFehler(res, 'Auftragsbestätigung erinnern', err)
|
|
}
|
|
})
|
|
|
|
router.post('/:id/neue-fassung', async (req, res) => {
|
|
try {
|
|
await ladeMitSchalter(req.params.id)
|
|
return res.json({ auftrag: auftragFuerTeam(await neueFassung(req.params.id, { von: vonAdmin(req) })) })
|
|
} catch (err) {
|
|
return sendeFehler(res, 'Neue Fassung anlegen', err)
|
|
}
|
|
})
|
|
|
|
router.post('/:id/stornieren', async (req, res) => {
|
|
try {
|
|
await ladeMitSchalter(req.params.id)
|
|
return res.json({ auftrag: auftragFuerTeam(await storniereAuftrag(req.params.id)) })
|
|
} catch (err) {
|
|
return sendeFehler(res, 'Auftragsbestätigung stornieren', err)
|
|
}
|
|
})
|
|
|
|
router.post('/:id/projekt', async (req, res) => {
|
|
try {
|
|
await ladeMitSchalter(req.params.id)
|
|
return res.json({ auftrag: auftragFuerTeam(await ordneProjektZu(req.params.id, req.body?.projektId)) })
|
|
} catch (err) {
|
|
return sendeFehler(res, 'Projekt zuordnen', err)
|
|
}
|
|
})
|
|
|
|
export default router
|