contractnumber provider added, old provider number field only if no previous contact exist

This commit is contained in:
duffyduck 2026-02-08 14:34:56 +01:00
parent 4442ab08b3
commit 06489299d5
30 changed files with 2046 additions and 744 deletions

View File

@ -119,8 +119,12 @@ export declare function getAllContracts(filters: ContractFilters): Promise<{
cancellationPeriodId: number | null;
contractDurationId: number | null;
previousContractId: number | null;
previousProviderId: number | null;
previousCustomerNumber: string | null;
previousContractNumber: string | null;
providerId: number | null;
tariffId: number | null;
contractNumberAtProvider: string | null;
priceFirst12Months: string | null;
priceFrom13Months: string | null;
priceAfter24Months: string | null;
@ -256,6 +260,7 @@ export declare function getContractById(id: number, decryptPassword?: boolean):
} & {
id: number;
meterId: number | null;
previousCustomerNumber: string | null;
contractId: number;
maloId: string | null;
annualConsumption: number | null;
@ -264,7 +269,6 @@ export declare function getContractById(id: number, decryptPassword?: boolean):
unitPrice: number | null;
bonus: number | null;
previousProviderName: string | null;
previousCustomerNumber: string | null;
}) | null;
stressfreiEmail: {
id: number;
@ -445,6 +449,7 @@ export declare function getContractById(id: number, decryptPassword?: boolean):
} & {
id: number;
meterId: number | null;
previousCustomerNumber: string | null;
contractId: number;
maloId: string | null;
annualConsumption: number | null;
@ -453,7 +458,6 @@ export declare function getContractById(id: number, decryptPassword?: boolean):
unitPrice: number | null;
bonus: number | null;
previousProviderName: string | null;
previousCustomerNumber: string | null;
}) | null;
carInsuranceDetails: {
id: number;
@ -549,8 +553,12 @@ export declare function getContractById(id: number, decryptPassword?: boolean):
cancellationPeriodId: number | null;
contractDurationId: number | null;
previousContractId: number | null;
previousProviderId: number | null;
previousCustomerNumber: string | null;
previousContractNumber: string | null;
providerId: number | null;
tariffId: number | null;
contractNumberAtProvider: string | null;
priceFirst12Months: string | null;
priceFrom13Months: string | null;
priceAfter24Months: string | null;
@ -572,6 +580,16 @@ export declare function getContractById(id: number, decryptPassword?: boolean):
status: import(".prisma/client").$Enums.ContractStatus;
contractNumber: string;
} | null;
previousProvider: {
id: number;
isActive: boolean;
createdAt: Date;
updatedAt: Date;
name: string;
portalUrl: string | null;
usernameFieldName: string | null;
passwordFieldName: string | null;
} | null;
} & {
id: number;
customerId: number;
@ -595,8 +613,12 @@ export declare function getContractById(id: number, decryptPassword?: boolean):
cancellationPeriodId: number | null;
contractDurationId: number | null;
previousContractId: number | null;
previousProviderId: number | null;
previousCustomerNumber: string | null;
previousContractNumber: string | null;
providerId: number | null;
tariffId: number | null;
contractNumberAtProvider: string | null;
priceFirst12Months: string | null;
priceFrom13Months: string | null;
priceAfter24Months: string | null;
@ -764,6 +786,7 @@ export declare function createContract(data: ContractCreateData): Promise<{
energyDetails: {
id: number;
meterId: number | null;
previousCustomerNumber: string | null;
contractId: number;
maloId: string | null;
annualConsumption: number | null;
@ -772,7 +795,6 @@ export declare function createContract(data: ContractCreateData): Promise<{
unitPrice: number | null;
bonus: number | null;
previousProviderName: string | null;
previousCustomerNumber: string | null;
} | null;
carInsuranceDetails: {
id: number;
@ -881,8 +903,12 @@ export declare function createContract(data: ContractCreateData): Promise<{
cancellationPeriodId: number | null;
contractDurationId: number | null;
previousContractId: number | null;
previousProviderId: number | null;
previousCustomerNumber: string | null;
previousContractNumber: string | null;
providerId: number | null;
tariffId: number | null;
contractNumberAtProvider: string | null;
priceFirst12Months: string | null;
priceFrom13Months: string | null;
priceAfter24Months: string | null;
@ -1011,6 +1037,7 @@ export declare function updateContract(id: number, data: Partial<ContractCreateD
} & {
id: number;
meterId: number | null;
previousCustomerNumber: string | null;
contractId: number;
maloId: string | null;
annualConsumption: number | null;
@ -1019,7 +1046,6 @@ export declare function updateContract(id: number, data: Partial<ContractCreateD
unitPrice: number | null;
bonus: number | null;
previousProviderName: string | null;
previousCustomerNumber: string | null;
}) | null;
stressfreiEmail: {
id: number;
@ -1200,6 +1226,7 @@ export declare function updateContract(id: number, data: Partial<ContractCreateD
} & {
id: number;
meterId: number | null;
previousCustomerNumber: string | null;
contractId: number;
maloId: string | null;
annualConsumption: number | null;
@ -1208,7 +1235,6 @@ export declare function updateContract(id: number, data: Partial<ContractCreateD
unitPrice: number | null;
bonus: number | null;
previousProviderName: string | null;
previousCustomerNumber: string | null;
}) | null;
carInsuranceDetails: {
id: number;
@ -1304,8 +1330,12 @@ export declare function updateContract(id: number, data: Partial<ContractCreateD
cancellationPeriodId: number | null;
contractDurationId: number | null;
previousContractId: number | null;
previousProviderId: number | null;
previousCustomerNumber: string | null;
previousContractNumber: string | null;
providerId: number | null;
tariffId: number | null;
contractNumberAtProvider: string | null;
priceFirst12Months: string | null;
priceFrom13Months: string | null;
priceAfter24Months: string | null;
@ -1327,6 +1357,16 @@ export declare function updateContract(id: number, data: Partial<ContractCreateD
status: import(".prisma/client").$Enums.ContractStatus;
contractNumber: string;
} | null;
previousProvider: {
id: number;
isActive: boolean;
createdAt: Date;
updatedAt: Date;
name: string;
portalUrl: string | null;
usernameFieldName: string | null;
passwordFieldName: string | null;
} | null;
} & {
id: number;
customerId: number;
@ -1350,8 +1390,12 @@ export declare function updateContract(id: number, data: Partial<ContractCreateD
cancellationPeriodId: number | null;
contractDurationId: number | null;
previousContractId: number | null;
previousProviderId: number | null;
previousCustomerNumber: string | null;
previousContractNumber: string | null;
providerId: number | null;
tariffId: number | null;
contractNumberAtProvider: string | null;
priceFirst12Months: string | null;
priceFrom13Months: string | null;
priceAfter24Months: string | null;
@ -1391,8 +1435,12 @@ export declare function deleteContract(id: number): Promise<{
cancellationPeriodId: number | null;
contractDurationId: number | null;
previousContractId: number | null;
previousProviderId: number | null;
previousCustomerNumber: string | null;
previousContractNumber: string | null;
providerId: number | null;
tariffId: number | null;
contractNumberAtProvider: string | null;
priceFirst12Months: string | null;
priceFrom13Months: string | null;
priceAfter24Months: string | null;
@ -1462,6 +1510,7 @@ export declare function createFollowUpContract(previousContractId: number): Prom
energyDetails: {
id: number;
meterId: number | null;
previousCustomerNumber: string | null;
contractId: number;
maloId: string | null;
annualConsumption: number | null;
@ -1470,7 +1519,6 @@ export declare function createFollowUpContract(previousContractId: number): Prom
unitPrice: number | null;
bonus: number | null;
previousProviderName: string | null;
previousCustomerNumber: string | null;
} | null;
carInsuranceDetails: {
id: number;
@ -1579,8 +1627,12 @@ export declare function createFollowUpContract(previousContractId: number): Prom
cancellationPeriodId: number | null;
contractDurationId: number | null;
previousContractId: number | null;
previousProviderId: number | null;
previousCustomerNumber: string | null;
previousContractNumber: string | null;
providerId: number | null;
tariffId: number | null;
contractNumberAtProvider: string | null;
priceFirst12Months: string | null;
priceFrom13Months: string | null;
priceAfter24Months: string | null;

File diff suppressed because one or more lines are too long

View File

@ -119,6 +119,7 @@ async function getContractById(id, decryptPassword = false) {
provider: true,
tariff: true,
contractCategory: true,
previousProvider: true,
previousContract: {
include: {
energyDetails: { include: { meter: { include: { readings: true } }, invoices: true } },

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"version":3,"file":"contractCockpit.service.d.ts","sourceRoot":"","sources":["../../src/services/contractCockpit.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,cAAc,EACpC,MAAM,gBAAgB,CAAC;AAMxB,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAAC;AAElE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,YAAY,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE;QACR,EAAE,EAAE,MAAM,CAAC;QACX,cAAc,EAAE,MAAM,CAAC;QACvB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,MAAM,CAAC,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,cAAc,EAAE,YAAY,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE;QACV,qBAAqB,EAAE,MAAM,CAAC;QAC9B,cAAc,EAAE,MAAM,CAAC;QACvB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,EAAE,MAAM,CAAC;QACxB,SAAS,EAAE,MAAM,CAAC;QAClB,gBAAgB,EAAE,MAAM,CAAC;QACzB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,EAAE;QACV,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAyED,wBAAsB,cAAc,IAAI,OAAO,CAAC,aAAa,CAAC,CAyc7D"}
{"version":3,"file":"contractCockpit.service.d.ts","sourceRoot":"","sources":["../../src/services/contractCockpit.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,cAAc,EACpC,MAAM,gBAAgB,CAAC;AAMxB,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAAC;AAElE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,YAAY,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE;QACR,EAAE,EAAE,MAAM,CAAC;QACX,cAAc,EAAE,MAAM,CAAC;QACvB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,MAAM,CAAC,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,cAAc,EAAE,YAAY,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE;QACV,qBAAqB,EAAE,MAAM,CAAC;QAC9B,cAAc,EAAE,MAAM,CAAC;QACvB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,EAAE,MAAM,CAAC;QACxB,SAAS,EAAE,MAAM,CAAC;QAClB,gBAAgB,EAAE,MAAM,CAAC;QACzB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,EAAE;QACV,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAyED,wBAAsB,cAAc,IAAI,OAAO,CAAC,aAAa,CAAC,CAod7D"}

View File

@ -307,6 +307,16 @@ async function getCockpitData() {
});
summary.byCategory.missingData++;
}
// 4b. KEINE VERTRAGSNUMMER BEIM ANBIETER
if (!contract.contractNumberAtProvider) {
issues.push({
type: 'missing_contract_number',
label: 'Vertragsnummer fehlt',
urgency: 'warning',
details: 'Vertragsnummer beim Anbieter fehlt',
});
summary.byCategory.missingData++;
}
// 5. KEIN ANBIETER/TARIF
if (!contract.providerId && !contract.providerName) {
issues.push({

File diff suppressed because one or more lines are too long

View File

@ -180,8 +180,12 @@ export declare function getCustomerById(id: number): Promise<({
cancellationPeriodId: number | null;
contractDurationId: number | null;
previousContractId: number | null;
previousProviderId: number | null;
previousCustomerNumber: string | null;
previousContractNumber: string | null;
providerId: number | null;
tariffId: number | null;
contractNumberAtProvider: string | null;
priceFirst12Months: string | null;
priceFrom13Months: string | null;
priceAfter24Months: string | null;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -412,11 +412,15 @@ exports.Prisma.ContractScalarFieldEnum = {
cancellationPeriodId: 'cancellationPeriodId',
contractDurationId: 'contractDurationId',
previousContractId: 'previousContractId',
previousProviderId: 'previousProviderId',
previousCustomerNumber: 'previousCustomerNumber',
previousContractNumber: 'previousContractNumber',
providerId: 'providerId',
tariffId: 'tariffId',
providerName: 'providerName',
tariffName: 'tariffName',
customerNumberAtProvider: 'customerNumberAtProvider',
contractNumberAtProvider: 'contractNumberAtProvider',
priceFirst12Months: 'priceFirst12Months',
priceFrom13Months: 'priceFrom13Months',
priceAfter24Months: 'priceAfter24Months',

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
{
"name": "prisma-client-05071f627540060c098bd6f9ad2705f280d372ae8cdaf0576ff7e91f8d0f9863",
"name": "prisma-client-ab03eeebd49b41f4edbc7df102e0a7779d814508dbccb860745760460e9e271f",
"main": "index.js",
"types": "index.d.ts",
"browser": "index-browser.js",

View File

@ -413,6 +413,7 @@ model Provider {
isActive Boolean @default(true)
tariffs Tariff[]
contracts Contract[]
previousContracts Contract[] @relation("PreviousProvider") // Verträge wo dieser Provider Altanbieter ist
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
@ -509,6 +510,12 @@ model Contract {
previousContract Contract? @relation("ContractHistory", fields: [previousContractId], references: [id])
followUpContract Contract? @relation("ContractHistory")
// Altanbieter-Daten (nur wenn kein Vorgängervertrag existiert)
previousProviderId Int?
previousProvider Provider? @relation("PreviousProvider", fields: [previousProviderId], references: [id])
previousCustomerNumber String? // Kundennummer beim Altanbieter
previousContractNumber String? // Vertragsnummer beim Altanbieter
// Anbieter & Tarif (neue Verknüpfung)
providerId Int?
provider Provider? @relation(fields: [providerId], references: [id])
@ -519,6 +526,7 @@ model Contract {
providerName String?
tariffName String?
customerNumberAtProvider String?
contractNumberAtProvider String? // Vertragsnummer beim Anbieter
priceFirst12Months String? // Preis erste 12 Monate
priceFrom13Months String? // Preis ab 13. Monat
priceAfter24Months String? // Preis nach 24 Monaten

View File

@ -412,11 +412,15 @@ exports.Prisma.ContractScalarFieldEnum = {
cancellationPeriodId: 'cancellationPeriodId',
contractDurationId: 'contractDurationId',
previousContractId: 'previousContractId',
previousProviderId: 'previousProviderId',
previousCustomerNumber: 'previousCustomerNumber',
previousContractNumber: 'previousContractNumber',
providerId: 'providerId',
tariffId: 'tariffId',
providerName: 'providerName',
tariffName: 'tariffName',
customerNumberAtProvider: 'customerNumberAtProvider',
contractNumberAtProvider: 'contractNumberAtProvider',
priceFirst12Months: 'priceFirst12Months',
priceFrom13Months: 'priceFrom13Months',
priceAfter24Months: 'priceAfter24Months',

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE `Contract` ADD COLUMN `contractNumberAtProvider` VARCHAR(191) NULL;

View File

@ -0,0 +1,7 @@
-- AlterTable
ALTER TABLE `Contract` ADD COLUMN `previousContractNumber` VARCHAR(191) NULL,
ADD COLUMN `previousCustomerNumber` VARCHAR(191) NULL,
ADD COLUMN `previousProviderId` INTEGER NULL;
-- AddForeignKey
ALTER TABLE `Contract` ADD CONSTRAINT `Contract_previousProviderId_fkey` FOREIGN KEY (`previousProviderId`) REFERENCES `Provider`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;

View File

@ -413,6 +413,7 @@ model Provider {
isActive Boolean @default(true)
tariffs Tariff[]
contracts Contract[]
previousContracts Contract[] @relation("PreviousProvider") // Verträge wo dieser Provider Altanbieter ist
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
@ -509,6 +510,12 @@ model Contract {
previousContract Contract? @relation("ContractHistory", fields: [previousContractId], references: [id])
followUpContract Contract? @relation("ContractHistory")
// Altanbieter-Daten (nur wenn kein Vorgängervertrag existiert)
previousProviderId Int?
previousProvider Provider? @relation("PreviousProvider", fields: [previousProviderId], references: [id])
previousCustomerNumber String? // Kundennummer beim Altanbieter
previousContractNumber String? // Vertragsnummer beim Altanbieter
// Anbieter & Tarif (neue Verknüpfung)
providerId Int?
provider Provider? @relation(fields: [providerId], references: [id])
@ -519,6 +526,7 @@ model Contract {
providerName String?
tariffName String?
customerNumberAtProvider String?
contractNumberAtProvider String? // Vertragsnummer beim Anbieter
priceFirst12Months String? // Preis erste 12 Monate
priceFrom13Months String? // Preis ab 13. Monat
priceAfter24Months String? // Preis nach 24 Monaten

View File

@ -122,6 +122,7 @@ export async function getContractById(id: number, decryptPassword = false) {
provider: true,
tariff: true,
contractCategory: true,
previousProvider: true,
previousContract: {
include: {
energyDetails: { include: { meter: { include: { readings: true } }, invoices: true } },

View File

@ -361,6 +361,17 @@ export async function getCockpitData(): Promise<CockpitResult> {
summary.byCategory.missingData++;
}
// 4b. KEINE VERTRAGSNUMMER BEIM ANBIETER
if (!contract.contractNumberAtProvider) {
issues.push({
type: 'missing_contract_number',
label: 'Vertragsnummer fehlt',
urgency: 'warning',
details: 'Vertragsnummer beim Anbieter fehlt',
});
summary.byCategory.missingData++;
}
// 5. KEIN ANBIETER/TARIF
if (!contract.providerId && !contract.providerName) {
issues.push({

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

715
frontend/dist/assets/index-OTeAOPxR.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -5,8 +5,8 @@
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OpenCRM</title>
<script type="module" crossorigin src="/assets/index-BUCLPhDH.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-BTfzRMgT.css">
<script type="module" crossorigin src="/assets/index-OTeAOPxR.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-B06MVODt.css">
</head>
<body>
<div id="root"></div>

View File

@ -105,6 +105,39 @@ export default function ContractDetailModal({ contractId, isOpen, onClose }: Con
</dd>
</div>
)}
{c.contractNumberAtProvider && (
<div>
<dt className="text-sm text-gray-500">Vertragsnummer beim Anbieter</dt>
<dd className="font-mono flex items-center gap-1">
{c.contractNumberAtProvider}
<CopyButton value={c.contractNumberAtProvider} />
</dd>
</div>
)}
</div>
</Card>
)}
{/* Zähler (nur bei Strom/Gas) */}
{(c.type === 'ELECTRICITY' || c.type === 'GAS') && c.energyDetails?.meter && (
<Card title="Zähler">
<div className="grid grid-cols-2 gap-4">
<div>
<dt className="text-sm text-gray-500">Zählernummer</dt>
<dd className="font-mono flex items-center gap-1">
{c.energyDetails.meter.meterNumber}
<CopyButton value={c.energyDetails.meter.meterNumber} />
</dd>
</div>
{c.energyDetails.maloId && (
<div>
<dt className="text-sm text-gray-500">MaLo-ID</dt>
<dd className="font-mono flex items-center gap-1">
{c.energyDetails.maloId}
<CopyButton value={c.energyDetails.maloId} />
</dd>
</div>
)}
</div>
</Card>
)}

View File

@ -1569,6 +1569,12 @@ export default function ContractDetail() {
<dd className="font-mono">{c.previousContract.customerNumberAtProvider}</dd>
</div>
)}
{c.previousContract.contractNumberAtProvider && (
<div>
<dt className="text-sm text-gray-500">Vertragsnummer</dt>
<dd className="font-mono">{c.previousContract.contractNumberAtProvider}</dd>
</div>
)}
{c.previousContract.portalUsername && (
<div>
<dt className="text-sm text-gray-500">Zugangsdaten</dt>
@ -1579,6 +1585,38 @@ export default function ContractDetail() {
</Card>
)}
{/* Altanbieter-Info (nur wenn KEIN Vorgängervertrag aber Altanbieter-Daten vorhanden) */}
{!c.previousContract && (c.previousProvider || c.previousCustomerNumber || c.previousContractNumber) && (
<Card className="mb-6 border-l-4 border-l-gray-400" title="Altanbieter">
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
{c.previousProvider && (
<div>
<dt className="text-sm text-gray-500">Anbieter</dt>
<dd>{c.previousProvider.name}</dd>
</div>
)}
{c.previousCustomerNumber && (
<div>
<dt className="text-sm text-gray-500">Kundennummer</dt>
<dd className="font-mono flex items-center gap-1">
{c.previousCustomerNumber}
<CopyButton value={c.previousCustomerNumber} />
</dd>
</div>
)}
{c.previousContractNumber && (
<div>
<dt className="text-sm text-gray-500">Vertragsnummer</dt>
<dd className="font-mono flex items-center gap-1">
{c.previousContractNumber}
<CopyButton value={c.previousContractNumber} />
</dd>
</div>
)}
</div>
</Card>
)}
{/* Cancellation Confirmation Warning */}
{c.cancellationConfirmationDate && (
<div className="mb-6 p-4 bg-red-50 border-2 border-red-400 rounded-lg flex items-start gap-3">
@ -1635,6 +1673,15 @@ export default function ContractDetail() {
</dd>
</div>
)}
{c.contractNumberAtProvider && (
<div>
<dt className="text-sm text-gray-500">Vertragsnummer</dt>
<dd className="font-mono flex items-center gap-1">
{c.contractNumberAtProvider}
<CopyButton value={c.contractNumberAtProvider} />
</dd>
</div>
)}
{c.salesPlatform && (
<div>
<dt className="text-sm text-gray-500">Vertriebsplattform</dt>

View File

@ -77,6 +77,7 @@ export default function ContractForm() {
const contractType = watch('type') as ContractType;
const customerId = watch('customerId');
const previousContractId = watch('previousContractId');
// Fetch existing contract for edit
const { data: contract } = useQuery({
@ -255,6 +256,7 @@ export default function ContractForm() {
providerName: c.providerName || '',
tariffName: c.tariffName || '',
customerNumberAtProvider: c.customerNumberAtProvider || '',
contractNumberAtProvider: c.contractNumberAtProvider || '',
priceFirst12Months: c.priceFirst12Months || '',
priceFrom13Months: c.priceFrom13Months || '',
priceAfter24Months: c.priceAfter24Months || '',
@ -273,8 +275,6 @@ export default function ContractForm() {
basePrice: c.energyDetails?.basePrice || '',
unitPrice: c.energyDetails?.unitPrice || '',
bonus: c.energyDetails?.bonus || '',
previousProviderName: c.energyDetails?.previousProviderName || '',
previousCustomerNumber: c.energyDetails?.previousCustomerNumber || '',
// Internet details
downloadSpeed: c.internetDetails?.downloadSpeed || '',
uploadSpeed: c.internetDetails?.uploadSpeed || '',
@ -317,6 +317,10 @@ export default function ContractForm() {
wasSpecialCancellation: c.wasSpecialCancellation || false,
// Vorgänger-Vertrag
previousContractId: c.previousContractId?.toString() || '',
// Altanbieter (nur wenn kein Vorgängervertrag)
previousProviderId: c.previousProviderId?.toString() || '',
previousCustomerNumber: c.previousCustomerNumber || '',
previousContractNumber: c.previousContractNumber || '',
});
// Load simCards if available
@ -473,6 +477,7 @@ export default function ContractForm() {
providerName: emptyToNull(data.providerName),
tariffName: emptyToNull(data.tariffName),
customerNumberAtProvider: emptyToNull(data.customerNumberAtProvider),
contractNumberAtProvider: emptyToNull(data.contractNumberAtProvider),
priceFirst12Months: emptyToNull(data.priceFirst12Months),
priceFrom13Months: emptyToNull(data.priceFrom13Months),
priceAfter24Months: emptyToNull(data.priceAfter24Months),
@ -490,6 +495,10 @@ export default function ContractForm() {
cancellationConfirmationOptionsDate: data.cancellationConfirmationOptionsDate ? new Date(data.cancellationConfirmationOptionsDate) : null,
wasSpecialCancellation: data.wasSpecialCancellation || false,
previousContractId: safeParseInt(data.previousContractId) ?? null,
// Altanbieter (nur wenn kein Vorgängervertrag)
previousProviderId: data.previousContractId ? null : (safeParseInt(data.previousProviderId) ?? null),
previousCustomerNumber: data.previousContractId ? null : emptyToNull(data.previousCustomerNumber),
previousContractNumber: data.previousContractId ? null : emptyToNull(data.previousContractNumber),
};
// Add type-specific details
@ -502,8 +511,6 @@ export default function ContractForm() {
basePrice: data.basePrice ? parseFloat(data.basePrice) : null,
unitPrice: data.unitPrice ? parseFloat(data.unitPrice) : null,
bonus: data.bonus ? parseFloat(data.bonus) : null,
previousProviderName: emptyToNull(data.previousProviderName),
previousCustomerNumber: emptyToNull(data.previousCustomerNumber),
};
}
@ -710,6 +717,29 @@ export default function ContractForm() {
placeholder="Keinen Vorgänger auswählen"
/>
)}
{/* Altanbieter-Daten (nur wenn KEIN Vorgängervertrag ausgewählt) */}
{customerId && !previousContractId && (
<div className="mt-4 p-4 bg-gray-50 rounded-lg border border-gray-200">
<h4 className="text-sm font-medium text-gray-700 mb-3">Altanbieter-Daten</h4>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<Select
label="Altanbieter"
{...register('previousProviderId')}
options={providers.map((p) => ({ value: p.id, label: p.name }))}
placeholder="Bitte wählen..."
/>
<Input
label="Kundennr. beim Altanbieter"
{...register('previousCustomerNumber')}
/>
<Input
label="Vertragsnr. beim Altanbieter"
{...register('previousContractNumber')}
/>
</div>
</div>
)}
</div>
</Card>
@ -775,6 +805,7 @@ export default function ContractForm() {
disabled={!selectedProviderId}
/>
<Input label="Kundennummer beim Anbieter" {...register('customerNumberAtProvider')} />
<Input label="Vertragsnummer beim Anbieter" {...register('contractNumberAtProvider')} />
<Input label="Provision (€)" type="number" step="0.01" {...register('commission')} />
<Input label="Preis erste 12 Monate" {...register('priceFirst12Months')} placeholder="z.B. 29,99 €/Monat" />
<Input label="Preis ab 13. Monat" {...register('priceFrom13Months')} placeholder="z.B. 39,99 €/Monat" />
@ -943,8 +974,6 @@ export default function ContractForm() {
{...register('unitPrice')}
/>
<Input label="Bonus (€)" type="number" step="0.01" {...register('bonus')} />
<Input label="Vorversorger" {...register('previousProviderName')} />
<Input label="Kundennr. beim Vorversorger" {...register('previousCustomerNumber')} />
</div>
{/* Hinweis für Zählerstände und Rechnungen */}

View File

@ -297,6 +297,11 @@ export interface Contract {
salesPlatform?: SalesPlatform;
previousContractId?: number;
previousContract?: Contract;
// Altanbieter (nur wenn kein Vorgängervertrag)
previousProviderId?: number;
previousProvider?: Provider;
previousCustomerNumber?: string;
previousContractNumber?: string;
providerId?: number;
provider?: Provider;
tariffId?: number;
@ -308,6 +313,7 @@ export interface Contract {
providerName?: string;
tariffName?: string;
customerNumberAtProvider?: string;
contractNumberAtProvider?: string;
priceFirst12Months?: string;
priceFrom13Months?: string;
priceAfter24Months?: string;