Vertragsauswahl: Kundennr./Zählernr./Telefonnr. in allen Pickern
Zentraler Helper contractLabel.ts liefert je nach Vertragstyp die sinnvollen Zusatzinfos (nur wenn Daten vorhanden): - Kdnr. <customer.customerNumber> (immer) - Anbieter-Vtr. <contractNumberAtProvider> - Zähler <meterNumber> (Strom/Gas) - Mobil <main-SIM-Nummer> (Mobilfunk) - Festnetz <main-phone> (Internet) Backend contractApi.getAll include um energyDetails.meter und internetDetails.phoneNumbers erweitert – vorher fehlten die im Response. Angewendet auf 5 Call-Sites: - AssignToContractModal (Email-zu-Vertrag zuordnen) - TaskList (Mitarbeiter- und Kundenportal-"Neue Aufgabe/Anfrage") - Dashboard (Support-Anfrage-Modal) - PdfTemplates (Test-Vorlage-Kontext-Auswahl) - ContractForm (Vorgänger-Vertrag-Select) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@ import { useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { useAuth } from '../context/AuthContext';
|
||||
import { customerApi, contractApi, contractTaskApi, appSettingsApi } from '../services/api';
|
||||
import { buildContractLabelParts } from '../utils/contractLabel';
|
||||
import Card from '../components/ui/Card';
|
||||
import Button from '../components/ui/Button';
|
||||
import Input from '../components/ui/Input';
|
||||
@@ -572,6 +573,14 @@ function CreateSupportTicketModal({
|
||||
{contract.providerName || 'Kein Anbieter'}
|
||||
{contract.tariffName && ` - ${contract.tariffName}`}
|
||||
</div>
|
||||
{(() => {
|
||||
const parts = buildContractLabelParts(contract);
|
||||
return parts.extras.length > 0 ? (
|
||||
<div className="text-xs text-gray-400 truncate">
|
||||
{parts.extras.join(' · ')}
|
||||
</div>
|
||||
) : null;
|
||||
})()}
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
|
||||
@@ -11,6 +11,7 @@ import Input from '../../components/ui/Input';
|
||||
import Select from '../../components/ui/Select';
|
||||
import CopyButton from '../../components/ui/CopyButton';
|
||||
import CustomerInfoModal from '../../components/contracts/CustomerInfoModal';
|
||||
import { buildContractLabelParts } from '../../utils/contractLabel';
|
||||
import type { ContractType } from '../../types';
|
||||
import { formatDate } from '../../utils/dateFormat';
|
||||
import { useProviderSettings } from '../../hooks/useProviderSettings';
|
||||
@@ -878,10 +879,15 @@ export default function ContractForm() {
|
||||
<Select
|
||||
label="Vorgänger-Vertrag"
|
||||
{...register('previousContractId')}
|
||||
options={predecessorContracts.map((c) => ({
|
||||
value: c.id,
|
||||
label: `${c.contractNumber} (${c.type}${c.startDate ? ` - ${formatDate(c.startDate)}` : ''})`,
|
||||
}))}
|
||||
options={predecessorContracts.map((c) => {
|
||||
const parts = buildContractLabelParts(c);
|
||||
const dateHint = c.startDate ? ` – ${formatDate(c.startDate)}` : '';
|
||||
const suffix = parts.extras.length > 0 ? ` · ${parts.extras.join(' · ')}` : '';
|
||||
return {
|
||||
value: c.id,
|
||||
label: `${c.contractNumber} (${c.type}${dateHint})${suffix}`,
|
||||
};
|
||||
})}
|
||||
placeholder="Keinen Vorgänger auswählen"
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { pdfTemplateApi, contractApi, authApi } from '../../services/api';
|
||||
import type { PdfTemplate, CrmField, Contract } from '../../types';
|
||||
import { buildContractLabelParts } from '../../utils/contractLabel';
|
||||
import Card from '../../components/ui/Card';
|
||||
import Button from '../../components/ui/Button';
|
||||
import Input from '../../components/ui/Input';
|
||||
@@ -475,13 +476,23 @@ function TestPreviewModal({ template, onClose }: { template: PdfTemplate; onClos
|
||||
selectedContractId === c.id ? 'bg-blue-50 border-blue-200' : ''
|
||||
}`}
|
||||
>
|
||||
<div>
|
||||
<span className="font-mono font-medium">{c.contractNumber}</span>
|
||||
{c.customer && (
|
||||
<span className="text-gray-500 ml-2">
|
||||
{c.customer.companyName || `${c.customer.firstName} ${c.customer.lastName}`}
|
||||
</span>
|
||||
)}
|
||||
<div className="flex-1 min-w-0">
|
||||
<div>
|
||||
<span className="font-mono font-medium">{c.contractNumber}</span>
|
||||
{c.customer && (
|
||||
<span className="text-gray-500 ml-2">
|
||||
{c.customer.companyName || `${c.customer.firstName} ${c.customer.lastName}`}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{(() => {
|
||||
const parts = buildContractLabelParts(c);
|
||||
return parts.extras.length > 0 ? (
|
||||
<div className="text-xs text-gray-400 truncate">
|
||||
{parts.extras.join(' · ')}
|
||||
</div>
|
||||
) : null;
|
||||
})()}
|
||||
</div>
|
||||
<Badge variant="default">{c.type}</Badge>
|
||||
</button>
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
Trash2,
|
||||
} from 'lucide-react';
|
||||
import type { ContractTask, ContractTaskStatus, Contract, Customer, ContractTaskSubtask } from '../../types';
|
||||
import { buildContractLabelParts } from '../../utils/contractLabel';
|
||||
|
||||
const statusLabels: Record<ContractTaskStatus, string> = {
|
||||
OPEN: 'Offen',
|
||||
@@ -687,6 +688,14 @@ function CreateSupportTicketModal({
|
||||
{contract.providerName || 'Kein Anbieter'}
|
||||
{contract.tariffName && ` - ${contract.tariffName}`}
|
||||
</div>
|
||||
{(() => {
|
||||
const parts = buildContractLabelParts(contract);
|
||||
return parts.extras.length > 0 ? (
|
||||
<div className="text-xs text-gray-400 truncate">
|
||||
{parts.extras.join(' · ')}
|
||||
</div>
|
||||
) : null;
|
||||
})()}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -915,6 +924,14 @@ function CreateTaskModal({
|
||||
{contract.providerName || 'Kein Anbieter'}
|
||||
{contract.tariffName && ` - ${contract.tariffName}`}
|
||||
</div>
|
||||
{(() => {
|
||||
const parts = buildContractLabelParts(contract);
|
||||
return parts.extras.length > 0 ? (
|
||||
<div className="text-xs text-gray-400 truncate">
|
||||
{parts.extras.join(' · ')}
|
||||
</div>
|
||||
) : null;
|
||||
})()}
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
|
||||
Reference in New Issue
Block a user