PDF-Auftragsvorlagen-System, Objekttyp/Lage-Felder, Eigentümer-Fallback bei Bankverbindung
- PDF-Template-Editor in Einstellungen: Vorlagen hochladen, Formularfelder automatisch auslesen, CRM-Felder zuordnen - PDF-Vorschau mit annotierten Feldnamen, seitenweise Sortierung der Felder - Auftrag generieren aus Vertragsdaten (Button im Vertrags-Detail) - Dynamische Rufnummern-Felder mit Vorwahl-Extraktion und konfigurierbarer Maximalanzahl - Nicht zugeordnete Felder bleiben editierbar im generierten PDF - Eigentümer-Felder mit Namens-Kombinationen (Firma+Name etc.) und Fallback auf Kundendaten - Stressfrei-E-Mail als Feld-Option im Template-Editor - Objekttyp, Lage und Lage des Anschlusses als neue Felder bei Festnetz-Verträgen (DSL, Glasfaser, Kabel) - Bankverbindung-Fallback: wenn keine am Vertrag verknüpft, wird automatisch die neueste aktive des Kunden genommen Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -717,6 +717,14 @@ function AddressesTab({
|
||||
</p>
|
||||
<p className="text-gray-500">{addr.country}</p>
|
||||
</CopyableBlock>
|
||||
{(addr.ownerFirstName || addr.ownerLastName || addr.ownerCompany) && (
|
||||
<div className="mt-2 pt-2 border-t text-xs text-gray-500">
|
||||
<span className="font-medium">Eigentümer: </span>
|
||||
{addr.ownerCompany && <span>{addr.ownerCompany} – </span>}
|
||||
{addr.ownerFirstName} {addr.ownerLastName}
|
||||
{addr.ownerPhone && <span> · {addr.ownerPhone}</span>}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
@@ -2097,6 +2105,16 @@ function AddressModal({
|
||||
city: address?.city || '',
|
||||
country: address?.country || 'Deutschland',
|
||||
isDefault: address?.isDefault || false,
|
||||
ownerCompany: address?.ownerCompany || '',
|
||||
ownerFirstName: address?.ownerFirstName || '',
|
||||
ownerLastName: address?.ownerLastName || '',
|
||||
ownerStreet: address?.ownerStreet || '',
|
||||
ownerHouseNumber: address?.ownerHouseNumber || '',
|
||||
ownerPostalCode: address?.ownerPostalCode || '',
|
||||
ownerCity: address?.ownerCity || '',
|
||||
ownerPhone: address?.ownerPhone || '',
|
||||
ownerMobile: address?.ownerMobile || '',
|
||||
ownerEmail: address?.ownerEmail || '',
|
||||
});
|
||||
|
||||
const [formData, setFormData] = useState(getInitialFormData);
|
||||
@@ -2106,15 +2124,7 @@ function AddressModal({
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['customer', customerId] });
|
||||
onClose();
|
||||
setFormData({
|
||||
type: 'DELIVERY_RESIDENCE',
|
||||
street: '',
|
||||
houseNumber: '',
|
||||
postalCode: '',
|
||||
city: '',
|
||||
country: 'Deutschland',
|
||||
isDefault: false,
|
||||
});
|
||||
setFormData(getInitialFormData());
|
||||
},
|
||||
});
|
||||
|
||||
@@ -2205,6 +2215,82 @@ function AddressModal({
|
||||
Als Standard setzen
|
||||
</label>
|
||||
|
||||
{/* Eigentümer (optional, nur bei Liefer-/Meldeadresse) */}
|
||||
{formData.type === 'DELIVERY_RESIDENCE' && (
|
||||
<div className="pt-4 border-t">
|
||||
<h4 className="text-sm font-medium text-gray-700 mb-1">Eigentümer</h4>
|
||||
<p className="text-xs text-gray-500 mb-3">
|
||||
Nur ausfüllen wenn der Kunde nicht selbst Eigentümer ist (z.B. Mietwohnung).
|
||||
</p>
|
||||
<div className="space-y-3">
|
||||
<Input
|
||||
label="Firma (optional)"
|
||||
value={formData.ownerCompany}
|
||||
onChange={(e) => setFormData({ ...formData, ownerCompany: e.target.value })}
|
||||
placeholder="z.B. Wohnungsbaugesellschaft"
|
||||
/>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<Input
|
||||
label="Vorname"
|
||||
value={formData.ownerFirstName}
|
||||
onChange={(e) => setFormData({ ...formData, ownerFirstName: e.target.value })}
|
||||
/>
|
||||
<Input
|
||||
label="Nachname"
|
||||
value={formData.ownerLastName}
|
||||
onChange={(e) => setFormData({ ...formData, ownerLastName: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 gap-3">
|
||||
<div className="col-span-2">
|
||||
<Input
|
||||
label="Straße"
|
||||
value={formData.ownerStreet}
|
||||
onChange={(e) => setFormData({ ...formData, ownerStreet: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
<Input
|
||||
label="Hausnr."
|
||||
value={formData.ownerHouseNumber}
|
||||
onChange={(e) => setFormData({ ...formData, ownerHouseNumber: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 gap-3">
|
||||
<Input
|
||||
label="PLZ"
|
||||
value={formData.ownerPostalCode}
|
||||
onChange={(e) => setFormData({ ...formData, ownerPostalCode: e.target.value })}
|
||||
/>
|
||||
<div className="col-span-2">
|
||||
<Input
|
||||
label="Ort"
|
||||
value={formData.ownerCity}
|
||||
onChange={(e) => setFormData({ ...formData, ownerCity: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 gap-3">
|
||||
<Input
|
||||
label="Telefon"
|
||||
value={formData.ownerPhone}
|
||||
onChange={(e) => setFormData({ ...formData, ownerPhone: e.target.value })}
|
||||
/>
|
||||
<Input
|
||||
label="Mobil"
|
||||
value={formData.ownerMobile}
|
||||
onChange={(e) => setFormData({ ...formData, ownerMobile: e.target.value })}
|
||||
/>
|
||||
<Input
|
||||
label="E-Mail"
|
||||
value={formData.ownerEmail}
|
||||
onChange={(e) => setFormData({ ...formData, ownerEmail: e.target.value })}
|
||||
type="email"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex justify-end gap-2">
|
||||
<Button type="button" variant="secondary" onClick={onClose}>
|
||||
Abbrechen
|
||||
|
||||
Reference in New Issue
Block a user