Vertragsstatus-Trigger: Datum beim Upload miterfassen

Beim automatischen Status-Wechsel wird jetzt auch das passende Datum gesetzt,
damit Status und Datumsfeld konsistent sind (Cockpit-Warnung "Datum fehlt"
verschwindet sofort nach Upload).

Backend:
- Upload-Handler für Kündigungsbestätigung(s-Optionen) nimmt optional
  `confirmationDate` aus multipart an, speichert als
  cancellationConfirmationDate / cancellationConfirmationOptionsDate.
  Fallback: heute (nur falls Feld noch leer war).
- maybeActivateOnDeliveryConfirmation nimmt optional deliveryDate, setzt
  Contract.startDate falls leer. Fallback: heute.

Frontend:
- ContractDetail: neues kleines Modal beim Kündigungsbestätigungs-Upload
  fragt das Bestätigungs-Datum ab (Default: heute oder bereits gesetzter
  Wert). Der bestehende inline-Datums-Editor bleibt für spätere Korrekturen.
- ContractDocumentsSection: Datums-Input erscheint conditional im
  Upload-Bereich, sobald Typ "Lieferbestätigung" gewählt ist.
- SaveAttachmentModal (E-Mail-Anhang → Vertragsdokument): gleicher
  Datums-Input conditional für "Lieferbestätigung".
- API-Methoden uploadCancellationConfirmation / uploadDocument /
  saveAttachmentAsContractDocument nehmen optional Datum entgegen.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-24 13:40:04 +02:00
parent 0a757d8e47
commit dea2da0271
8 changed files with 185 additions and 28 deletions
+7 -4
View File
@@ -588,7 +588,7 @@ export const cachedEmailApi = {
saveAttachmentAsContractDocument: async (
emailId: number,
filename: string,
params: { documentType: string; notes?: string },
params: { documentType: string; notes?: string; deliveryDate?: string },
) => {
const encodedFilename = encodeURIComponent(filename);
const res = await api.post<ApiResponse<{ id: number; documentType: string; documentPath: string }>>(
@@ -683,11 +683,12 @@ export const contractApi = {
const res = await api.get<ApiResponse<import('../types').ContractDocument[]>>(`/contracts/${contractId}/documents`);
return res.data;
},
uploadDocument: async (contractId: number, file: File, documentType: string, notes?: string) => {
uploadDocument: async (contractId: number, file: File, documentType: string, notes?: string, deliveryDate?: string) => {
const formData = new FormData();
formData.append('file', file);
formData.append('documentType', documentType);
if (notes) formData.append('notes', notes);
if (deliveryDate) formData.append('deliveryDate', deliveryDate);
const res = await api.post<ApiResponse<import('../types').ContractDocument>>(`/contracts/${contractId}/documents`, formData, {
headers: { 'Content-Type': 'multipart/form-data' },
});
@@ -1087,9 +1088,10 @@ export const uploadApi = {
const res = await api.delete<ApiResponse<void>>(`/upload/contracts/${contractId}/cancellation-letter`);
return res.data;
},
uploadCancellationConfirmation: async (contractId: number, file: File) => {
uploadCancellationConfirmation: async (contractId: number, file: File, confirmationDate?: string) => {
const formData = new FormData();
formData.append('document', file);
if (confirmationDate) formData.append('confirmationDate', confirmationDate);
const res = await api.post<ApiResponse<{ path: string; filename: string }>>(`/upload/contracts/${contractId}/cancellation-confirmation`, formData, {
headers: { 'Content-Type': 'multipart/form-data' },
});
@@ -1111,9 +1113,10 @@ export const uploadApi = {
const res = await api.delete<ApiResponse<void>>(`/upload/contracts/${contractId}/cancellation-letter-options`);
return res.data;
},
uploadCancellationConfirmationOptions: async (contractId: number, file: File) => {
uploadCancellationConfirmationOptions: async (contractId: number, file: File, confirmationDate?: string) => {
const formData = new FormData();
formData.append('document', file);
if (confirmationDate) formData.append('confirmationDate', confirmationDate);
const res = await api.post<ApiResponse<{ path: string; filename: string }>>(`/upload/contracts/${contractId}/cancellation-confirmation-options`, formData, {
headers: { 'Content-Type': 'multipart/form-data' },
});