contracts: VVL (Vertragsverlängerung) als Split-Button neben Folgevertrag

VVL = Vertragsverlängerung beim selben Anbieter (vs. Folgevertrag = i.d.R.
Anbieterwechsel).

Im Gegensatz zu createFollowUpContract wird ALLES kopiert:
- Provider, Tarif, Portal-Username/Passwort (verschlüsselt)
- Preise (basePrice/unitPrice/bonus etc.)
- Notes, Commission, Internet-Zugangsdaten, SIP-Daten, SIM-PINs
- ContractDocuments (1:1, gleiche Datei-Referenz)
- Detail-Tabellen (Energy/Internet/Mobile/TV/CarInsurance) komplett

Berechnet:
- newStartDate = oldStartDate + Vertragslaufzeit (Monate aus
  ContractDuration.code/description geparsed: "24M" / "24 Monate" / "2J")
- newEndDate = newStartDate + Laufzeit
- status = DRAFT (User bestätigt manuell)

NICHT kopiert:
- documentType "Auftragsformular" (das wird neu unterschrieben)
- cancellation*-Felder (alter Cancel-Flow nicht relevant)

Frontend:
- Split-Button: Hauptaktion "Folgevertrag anlegen" + ChevronDown-Pfeil
- Dropdown: "VVL anlegen" mit Bestätigungs-Modal
- Modal zeigt Vorhersage des neuen Startdatums (alter Start +
  Vertragslaufzeit als Hinweis)

History-Einträge wie bei Folgevertrag, mit eigenem VVL-Wording.
Doppel-Schutz: maximal 1 Folge-/VVL-Vertrag pro Vorgänger.

Live-verifiziert:
- Contract #17 (FIBER, 2026-05-01, 24M) → VVL mit Start 2028-05-01 ✓
- Provider/Tarif/Preise/Credentials 1:1 übernommen
- 2 Dokumente kopiert (außer Auftragsformular)
- History-Einträge in beiden Verträgen vorhanden

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-03 09:12:39 +02:00
parent e763952a84
commit 77602bb4ac
6 changed files with 447 additions and 8 deletions
@@ -129,3 +129,35 @@ export async function createNewContractFromPredecessorEntry(
createdBy,
});
}
/**
* Automatischen Historie-Eintrag für VVL (Vertragsverlängerung) im Vorgängervertrag.
*/
export async function createRenewalHistoryEntry(
previousContractId: number,
newContractNumber: string,
createdBy: string
) {
return createHistoryEntry(previousContractId, {
title: `Vertragsverlängerung erstellt: ${newContractNumber}`,
description: `Eine Vertragsverlängerung (VVL) als ${newContractNumber} wurde aus diesem Vertrag erstellt alle Daten wurden 1:1 übernommen, das Auftragsdokument muss neu hochgeladen werden.`,
isAutomatic: true,
createdBy,
});
}
/**
* Automatischen Historie-Eintrag im neuen VVL-Vertrag.
*/
export async function createNewRenewalFromPredecessorEntry(
newContractId: number,
previousContractNumber: string,
createdBy: string
) {
return createHistoryEntry(newContractId, {
title: `VVL zu ${previousContractNumber}`,
description: `Dieser Vertrag wurde als Vertragsverlängerung (VVL) zu ${previousContractNumber} erstellt.`,
isAutomatic: true,
createdBy,
});
}