AB-Kern: Projekt nachträglich einer Auftragsbestätigung zuordnen

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-07 14:15:37 +00:00
1 parent c791146af4
commit 66ec8e0a44
2 files changed
+158 -1

No files matched your search

+32 -1
View File
@@ -15,7 +15,7 @@ import { entfernePdf, lesePdf, speicherePdf } from './ablage.js'
import { createAuftrag, deleteAuftrag, getAuftrag, listAuftraege, updateAuftrag } from './auftragStore.js'
import { AuftragError } from './fehler.js'
import { vergibNummer } from './nummern.js'
import { umhaengen } from './projektRechnungenStore.js'
import { listProjektRechnungen, umhaengen, updateProjektRechnung } from './projektRechnungenStore.js'
import { TEXTE_FASSUNG } from './texte.js'
import {
AGB_FASSUNG, AUFTRAG_ARTEN, AUFTRAG_WEGE, KUNDENARTEN, LIMITS, SPERRE_NUMMER, sperreAuftrag, STUNDENSATZ_STANDARD_CENTS, VEREINBARTE_STATUS, VIERTELSTUNDE, ZAHLUNGSPLAN_ARTEN,
@@ -544,3 +544,34 @@ export async function storniereAuftrag(id) {
return updateAuftrag(id, { status: 'storniert', storniertAm: new Date().toISOString() })
})
}
// ---------------------------------------------------------------------------------------------------------------------
// Projekt nachträglich zuordnen
// ---------------------------------------------------------------------------------------------------------------------
/**
* Ordnet einer AB ohne Projekt nachträglich ein Projekt des Kunden zu: setzt projektId, bei leerer Zeitquelle das Ticket des
* Projekts, und hängt die Projektrechnungen der AB mit leerer projektId um (Stripe bleibt unverändert). PDF, Nummer, Status
* und Token bleiben. Zuerst die Projektrechnungen, zuletzt die AB: scheitert etwas dazwischen, bleibt die AB ohne Projekt
* und die Wiederholung führt alles zu Ende.
*/
export async function ordneProjektZu(id, projektId) {
if (!hatText(projektId)) throw new AuftragError(400, 'Projekt: Bitte ein Projekt angeben.')
if (!istDokumentId(projektId)) throw new AuftragError(400, 'Projekt: Ungültige Projekt-Kennung.')
return withLocks(sperreAuftrag(id), async () => {
const auftrag = await ladeAuftrag(id)
if (['storniert', 'ersetzt', 'widerrufen'].includes(auftrag.status)) {
throw new AuftragError(409, 'Einer stornierten, ersetzten oder widerrufenen Auftragsbestätigung lässt sich kein Projekt mehr zuordnen.')
}
if (hatText(auftrag.projektId)) throw new AuftragError(409, 'Diese Auftragsbestätigung gehört schon zu einem Projekt.')
const projekt = await ladeProjekt(projektId)
if (!projekt || projekt.customerId !== auftrag.kundenId) throw new AuftragError(400, 'Projekt: Das Projekt gehört nicht zu diesem Kunden.')
const rechnungen = await listProjektRechnungen({ auftragId: id, nurAktiv: false })
for (const rechnung of rechnungen) {
if (rechnung.projektId === '') await updateProjektRechnung(rechnung.invoiceId, { projektId })
}
const patch = { projektId }
if (auftrag.zeitquelle.length === 0) patch.zeitquelle = ticketsDesProjekts(projekt)
return updateAuftrag(id, patch)
})
}