Finanzen: Bankbuchungen Rechnungen, Auszahlungen, Fixkosten und Kategorien zuordnen

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-01 15:42:06 +00:00
1 parent f14a6b7b57
commit 2bf67cb48d
3 files changed
+767 -3

No files matched your search

+44 -3
View File
@@ -4,9 +4,10 @@ import { withLocks } from '../../services/keyedLock.js'
import { EnableBankingError } from '../../services/finance/enableBanking.js'
import { completeBankAuth, startBankAuth, syncBank } from '../../services/finance/bankSync.js'
import { getConnection, listTransactions, saveConnection } from '../../services/finance/bankStore.js'
import { AssignError, assignTransaction, unassignTransaction, withSuggestions } from '../../services/finance/assign.js'
/**
* Finanzen im WOMS (nur Admins): Bankstatus, Abruf, Neuverbindung und Buchungen. Die Handler sind klein und rufen
* Finanzen im WOMS (nur Admins): Bankstatus, Abruf, Neuverbindung, Buchungen und deren Zuordnung. Die Handler sind klein und rufen
* die Dienste in server/services/finance auf; weitere Finanz-Routen kommen in dieselbe Datei.
*/
const router = Router()
@@ -113,12 +114,52 @@ router.post('/bank/rueckkehr', async (req, res) => {
router.get('/buchungen', async (_req, res) => {
try {
const buchungen = (await listTransactions()).map(publicTransaction)
return res.json({ buchungen })
// Vorschlaege kommen von Stripe: ein Ausfall dort (stripeFehler) macht die Liste nie kaputt
return res.json(await withSuggestions((await listTransactions()).map(publicTransaction)))
} catch (err) {
logFailure('Buchungen laden', err)
return res.status(500).json({ error: 'Buchungen konnten nicht geladen werden.' })
}
})
const STRIPE_REJECTED_MESSAGE = 'Stripe hat die Änderung abgelehnt.'
const STRIPE_UNAVAILABLE_MESSAGE = 'Stripe ist gerade nicht erreichbar.'
// Fehler des Stripe-Pakets (StripeInvalidRequestError, StripeConnectionError, ...) tragen type "Stripe..."
const isStripeError = (err) => typeof err?.type === 'string' && err.type.startsWith('Stripe')
/**
* Antwort auf einen Fehler beim Zuordnen: AssignError (eigene, anzeigbare Meldung) mit seinem Status; Stripe lehnt
* ab (4xx, ausser 429) -> 409; Stripe sonst nicht erreichbar -> 502; alles andere 500. Meldungen von Stripe, Appwrite
* und Netzfehlern (Adressen, Schluessel) gehen nie an die Seite.
*/
function sendAssignError(res, what, err) {
if (err instanceof AssignError) return res.status(err.status).json({ error: err.message })
logFailure(what, err)
if (isStripeError(err)) {
const status = err.statusCode
if (status >= 400 && status < 500 && status !== 429) return res.status(409).json({ error: STRIPE_REJECTED_MESSAGE })
return res.status(502).json({ error: STRIPE_UNAVAILABLE_MESSAGE })
}
return res.status(500).json({ error: 'Interner Fehler.' })
}
router.post('/buchungen/:id/zuordnen', async (req, res) => {
const { invoiceId, payoutId, fixedCostId, category, note } = req.body || {}
try {
const buchung = await assignTransaction(req.params.id, { invoiceId, payoutId, fixedCostId, category, note })
return res.json({ buchung: publicTransaction(buchung) })
} catch (err) {
return sendAssignError(res, 'Buchung zuordnen', err)
}
})
router.delete('/buchungen/:id/zuordnung', async (req, res) => {
try {
return res.json({ buchung: publicTransaction(await unassignTransaction(req.params.id)) })
} catch (err) {
return sendAssignError(res, 'Zuordnung lösen', err)
}
})
export default router