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; cancellationPeriodId: number | null;
contractDurationId: number | null; contractDurationId: number | null;
previousContractId: number | null; previousContractId: number | null;
previousProviderId: number | null;
previousCustomerNumber: string | null;
previousContractNumber: string | null;
providerId: number | null; providerId: number | null;
tariffId: number | null; tariffId: number | null;
contractNumberAtProvider: string | null;
priceFirst12Months: string | null; priceFirst12Months: string | null;
priceFrom13Months: string | null; priceFrom13Months: string | null;
priceAfter24Months: string | null; priceAfter24Months: string | null;
@ -256,6 +260,7 @@ export declare function getContractById(id: number, decryptPassword?: boolean):
} & { } & {
id: number; id: number;
meterId: number | null; meterId: number | null;
previousCustomerNumber: string | null;
contractId: number; contractId: number;
maloId: string | null; maloId: string | null;
annualConsumption: number | null; annualConsumption: number | null;
@ -264,7 +269,6 @@ export declare function getContractById(id: number, decryptPassword?: boolean):
unitPrice: number | null; unitPrice: number | null;
bonus: number | null; bonus: number | null;
previousProviderName: string | null; previousProviderName: string | null;
previousCustomerNumber: string | null;
}) | null; }) | null;
stressfreiEmail: { stressfreiEmail: {
id: number; id: number;
@ -445,6 +449,7 @@ export declare function getContractById(id: number, decryptPassword?: boolean):
} & { } & {
id: number; id: number;
meterId: number | null; meterId: number | null;
previousCustomerNumber: string | null;
contractId: number; contractId: number;
maloId: string | null; maloId: string | null;
annualConsumption: number | null; annualConsumption: number | null;
@ -453,7 +458,6 @@ export declare function getContractById(id: number, decryptPassword?: boolean):
unitPrice: number | null; unitPrice: number | null;
bonus: number | null; bonus: number | null;
previousProviderName: string | null; previousProviderName: string | null;
previousCustomerNumber: string | null;
}) | null; }) | null;
carInsuranceDetails: { carInsuranceDetails: {
id: number; id: number;
@ -549,8 +553,12 @@ export declare function getContractById(id: number, decryptPassword?: boolean):
cancellationPeriodId: number | null; cancellationPeriodId: number | null;
contractDurationId: number | null; contractDurationId: number | null;
previousContractId: number | null; previousContractId: number | null;
previousProviderId: number | null;
previousCustomerNumber: string | null;
previousContractNumber: string | null;
providerId: number | null; providerId: number | null;
tariffId: number | null; tariffId: number | null;
contractNumberAtProvider: string | null;
priceFirst12Months: string | null; priceFirst12Months: string | null;
priceFrom13Months: string | null; priceFrom13Months: string | null;
priceAfter24Months: string | null; priceAfter24Months: string | null;
@ -572,6 +580,16 @@ export declare function getContractById(id: number, decryptPassword?: boolean):
status: import(".prisma/client").$Enums.ContractStatus; status: import(".prisma/client").$Enums.ContractStatus;
contractNumber: string; contractNumber: string;
} | null; } | null;
previousProvider: {
id: number;
isActive: boolean;
createdAt: Date;
updatedAt: Date;
name: string;
portalUrl: string | null;
usernameFieldName: string | null;
passwordFieldName: string | null;
} | null;
} & { } & {
id: number; id: number;
customerId: number; customerId: number;
@ -595,8 +613,12 @@ export declare function getContractById(id: number, decryptPassword?: boolean):
cancellationPeriodId: number | null; cancellationPeriodId: number | null;
contractDurationId: number | null; contractDurationId: number | null;
previousContractId: number | null; previousContractId: number | null;
previousProviderId: number | null;
previousCustomerNumber: string | null;
previousContractNumber: string | null;
providerId: number | null; providerId: number | null;
tariffId: number | null; tariffId: number | null;
contractNumberAtProvider: string | null;
priceFirst12Months: string | null; priceFirst12Months: string | null;
priceFrom13Months: string | null; priceFrom13Months: string | null;
priceAfter24Months: string | null; priceAfter24Months: string | null;
@ -764,6 +786,7 @@ export declare function createContract(data: ContractCreateData): Promise<{
energyDetails: { energyDetails: {
id: number; id: number;
meterId: number | null; meterId: number | null;
previousCustomerNumber: string | null;
contractId: number; contractId: number;
maloId: string | null; maloId: string | null;
annualConsumption: number | null; annualConsumption: number | null;
@ -772,7 +795,6 @@ export declare function createContract(data: ContractCreateData): Promise<{
unitPrice: number | null; unitPrice: number | null;
bonus: number | null; bonus: number | null;
previousProviderName: string | null; previousProviderName: string | null;
previousCustomerNumber: string | null;
} | null; } | null;
carInsuranceDetails: { carInsuranceDetails: {
id: number; id: number;
@ -881,8 +903,12 @@ export declare function createContract(data: ContractCreateData): Promise<{
cancellationPeriodId: number | null; cancellationPeriodId: number | null;
contractDurationId: number | null; contractDurationId: number | null;
previousContractId: number | null; previousContractId: number | null;
previousProviderId: number | null;
previousCustomerNumber: string | null;
previousContractNumber: string | null;
providerId: number | null; providerId: number | null;
tariffId: number | null; tariffId: number | null;
contractNumberAtProvider: string | null;
priceFirst12Months: string | null; priceFirst12Months: string | null;
priceFrom13Months: string | null; priceFrom13Months: string | null;
priceAfter24Months: string | null; priceAfter24Months: string | null;
@ -1011,6 +1037,7 @@ export declare function updateContract(id: number, data: Partial<ContractCreateD
} & { } & {
id: number; id: number;
meterId: number | null; meterId: number | null;
previousCustomerNumber: string | null;
contractId: number; contractId: number;
maloId: string | null; maloId: string | null;
annualConsumption: number | null; annualConsumption: number | null;
@ -1019,7 +1046,6 @@ export declare function updateContract(id: number, data: Partial<ContractCreateD
unitPrice: number | null; unitPrice: number | null;
bonus: number | null; bonus: number | null;
previousProviderName: string | null; previousProviderName: string | null;
previousCustomerNumber: string | null;
}) | null; }) | null;
stressfreiEmail: { stressfreiEmail: {
id: number; id: number;
@ -1200,6 +1226,7 @@ export declare function updateContract(id: number, data: Partial<ContractCreateD
} & { } & {
id: number; id: number;
meterId: number | null; meterId: number | null;
previousCustomerNumber: string | null;
contractId: number; contractId: number;
maloId: string | null; maloId: string | null;
annualConsumption: number | null; annualConsumption: number | null;
@ -1208,7 +1235,6 @@ export declare function updateContract(id: number, data: Partial<ContractCreateD
unitPrice: number | null; unitPrice: number | null;
bonus: number | null; bonus: number | null;
previousProviderName: string | null; previousProviderName: string | null;
previousCustomerNumber: string | null;
}) | null; }) | null;
carInsuranceDetails: { carInsuranceDetails: {
id: number; id: number;
@ -1304,8 +1330,12 @@ export declare function updateContract(id: number, data: Partial<ContractCreateD
cancellationPeriodId: number | null; cancellationPeriodId: number | null;
contractDurationId: number | null; contractDurationId: number | null;
previousContractId: number | null; previousContractId: number | null;
previousProviderId: number | null;
previousCustomerNumber: string | null;
previousContractNumber: string | null;
providerId: number | null; providerId: number | null;
tariffId: number | null; tariffId: number | null;
contractNumberAtProvider: string | null;
priceFirst12Months: string | null; priceFirst12Months: string | null;
priceFrom13Months: string | null; priceFrom13Months: string | null;
priceAfter24Months: string | null; priceAfter24Months: string | null;
@ -1327,6 +1357,16 @@ export declare function updateContract(id: number, data: Partial<ContractCreateD
status: import(".prisma/client").$Enums.ContractStatus; status: import(".prisma/client").$Enums.ContractStatus;
contractNumber: string; contractNumber: string;
} | null; } | null;
previousProvider: {
id: number;
isActive: boolean;
createdAt: Date;
updatedAt: Date;
name: string;
portalUrl: string | null;
usernameFieldName: string | null;
passwordFieldName: string | null;
} | null;
} & { } & {
id: number; id: number;
customerId: number; customerId: number;
@ -1350,8 +1390,12 @@ export declare function updateContract(id: number, data: Partial<ContractCreateD
cancellationPeriodId: number | null; cancellationPeriodId: number | null;
contractDurationId: number | null; contractDurationId: number | null;
previousContractId: number | null; previousContractId: number | null;
previousProviderId: number | null;
previousCustomerNumber: string | null;
previousContractNumber: string | null;
providerId: number | null; providerId: number | null;
tariffId: number | null; tariffId: number | null;
contractNumberAtProvider: string | null;
priceFirst12Months: string | null; priceFirst12Months: string | null;
priceFrom13Months: string | null; priceFrom13Months: string | null;
priceAfter24Months: string | null; priceAfter24Months: string | null;
@ -1391,8 +1435,12 @@ export declare function deleteContract(id: number): Promise<{
cancellationPeriodId: number | null; cancellationPeriodId: number | null;
contractDurationId: number | null; contractDurationId: number | null;
previousContractId: number | null; previousContractId: number | null;
previousProviderId: number | null;
previousCustomerNumber: string | null;
previousContractNumber: string | null;
providerId: number | null; providerId: number | null;
tariffId: number | null; tariffId: number | null;
contractNumberAtProvider: string | null;
priceFirst12Months: string | null; priceFirst12Months: string | null;
priceFrom13Months: string | null; priceFrom13Months: string | null;
priceAfter24Months: string | null; priceAfter24Months: string | null;
@ -1462,6 +1510,7 @@ export declare function createFollowUpContract(previousContractId: number): Prom
energyDetails: { energyDetails: {
id: number; id: number;
meterId: number | null; meterId: number | null;
previousCustomerNumber: string | null;
contractId: number; contractId: number;
maloId: string | null; maloId: string | null;
annualConsumption: number | null; annualConsumption: number | null;
@ -1470,7 +1519,6 @@ export declare function createFollowUpContract(previousContractId: number): Prom
unitPrice: number | null; unitPrice: number | null;
bonus: number | null; bonus: number | null;
previousProviderName: string | null; previousProviderName: string | null;
previousCustomerNumber: string | null;
} | null; } | null;
carInsuranceDetails: { carInsuranceDetails: {
id: number; id: number;
@ -1579,8 +1627,12 @@ export declare function createFollowUpContract(previousContractId: number): Prom
cancellationPeriodId: number | null; cancellationPeriodId: number | null;
contractDurationId: number | null; contractDurationId: number | null;
previousContractId: number | null; previousContractId: number | null;
previousProviderId: number | null;
previousCustomerNumber: string | null;
previousContractNumber: string | null;
providerId: number | null; providerId: number | null;
tariffId: number | null; tariffId: number | null;
contractNumberAtProvider: string | null;
priceFirst12Months: string | null; priceFirst12Months: string | null;
priceFrom13Months: string | null; priceFrom13Months: string | null;
priceAfter24Months: 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, provider: true,
tariff: true, tariff: true,
contractCategory: true, contractCategory: true,
previousProvider: true,
previousContract: { previousContract: {
include: { include: {
energyDetails: { include: { meter: { include: { readings: true } }, invoices: true } }, 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++; 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 // 5. KEIN ANBIETER/TARIF
if (!contract.providerId && !contract.providerName) { if (!contract.providerId && !contract.providerName) {
issues.push({ 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; cancellationPeriodId: number | null;
contractDurationId: number | null; contractDurationId: number | null;
previousContractId: number | null; previousContractId: number | null;
previousProviderId: number | null;
previousCustomerNumber: string | null;
previousContractNumber: string | null;
providerId: number | null; providerId: number | null;
tariffId: number | null; tariffId: number | null;
contractNumberAtProvider: string | null;
priceFirst12Months: string | null; priceFirst12Months: string | null;
priceFrom13Months: string | null; priceFrom13Months: string | null;
priceAfter24Months: 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', cancellationPeriodId: 'cancellationPeriodId',
contractDurationId: 'contractDurationId', contractDurationId: 'contractDurationId',
previousContractId: 'previousContractId', previousContractId: 'previousContractId',
previousProviderId: 'previousProviderId',
previousCustomerNumber: 'previousCustomerNumber',
previousContractNumber: 'previousContractNumber',
providerId: 'providerId', providerId: 'providerId',
tariffId: 'tariffId', tariffId: 'tariffId',
providerName: 'providerName', providerName: 'providerName',
tariffName: 'tariffName', tariffName: 'tariffName',
customerNumberAtProvider: 'customerNumberAtProvider', customerNumberAtProvider: 'customerNumberAtProvider',
contractNumberAtProvider: 'contractNumberAtProvider',
priceFirst12Months: 'priceFirst12Months', priceFirst12Months: 'priceFirst12Months',
priceFrom13Months: 'priceFrom13Months', priceFrom13Months: 'priceFrom13Months',
priceAfter24Months: 'priceAfter24Months', 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", "main": "index.js",
"types": "index.d.ts", "types": "index.d.ts",
"browser": "index-browser.js", "browser": "index-browser.js",

View File

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

View File

@ -412,11 +412,15 @@ exports.Prisma.ContractScalarFieldEnum = {
cancellationPeriodId: 'cancellationPeriodId', cancellationPeriodId: 'cancellationPeriodId',
contractDurationId: 'contractDurationId', contractDurationId: 'contractDurationId',
previousContractId: 'previousContractId', previousContractId: 'previousContractId',
previousProviderId: 'previousProviderId',
previousCustomerNumber: 'previousCustomerNumber',
previousContractNumber: 'previousContractNumber',
providerId: 'providerId', providerId: 'providerId',
tariffId: 'tariffId', tariffId: 'tariffId',
providerName: 'providerName', providerName: 'providerName',
tariffName: 'tariffName', tariffName: 'tariffName',
customerNumberAtProvider: 'customerNumberAtProvider', customerNumberAtProvider: 'customerNumberAtProvider',
contractNumberAtProvider: 'contractNumberAtProvider',
priceFirst12Months: 'priceFirst12Months', priceFirst12Months: 'priceFirst12Months',
priceFrom13Months: 'priceFrom13Months', priceFrom13Months: 'priceFrom13Months',
priceAfter24Months: 'priceAfter24Months', 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) isActive Boolean @default(true)
tariffs Tariff[] tariffs Tariff[]
contracts Contract[] contracts Contract[]
previousContracts Contract[] @relation("PreviousProvider") // Verträge wo dieser Provider Altanbieter ist
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt
} }
@ -509,6 +510,12 @@ model Contract {
previousContract Contract? @relation("ContractHistory", fields: [previousContractId], references: [id]) previousContract Contract? @relation("ContractHistory", fields: [previousContractId], references: [id])
followUpContract Contract? @relation("ContractHistory") 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) // Anbieter & Tarif (neue Verknüpfung)
providerId Int? providerId Int?
provider Provider? @relation(fields: [providerId], references: [id]) provider Provider? @relation(fields: [providerId], references: [id])
@ -519,6 +526,7 @@ model Contract {
providerName String? providerName String?
tariffName String? tariffName String?
customerNumberAtProvider String? customerNumberAtProvider String?
contractNumberAtProvider String? // Vertragsnummer beim Anbieter
priceFirst12Months String? // Preis erste 12 Monate priceFirst12Months String? // Preis erste 12 Monate
priceFrom13Months String? // Preis ab 13. Monat priceFrom13Months String? // Preis ab 13. Monat
priceAfter24Months String? // Preis nach 24 Monaten priceAfter24Months String? // Preis nach 24 Monaten

View File

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

View File

@ -361,6 +361,17 @@ export async function getCockpitData(): Promise<CockpitResult> {
summary.byCategory.missingData++; 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 // 5. KEIN ANBIETER/TARIF
if (!contract.providerId && !contract.providerName) { if (!contract.providerId && !contract.providerName) {
issues.push({ 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" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OpenCRM</title> <title>OpenCRM</title>
<script type="module" crossorigin src="/assets/index-BUCLPhDH.js"></script> <script type="module" crossorigin src="/assets/index-OTeAOPxR.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-BTfzRMgT.css"> <link rel="stylesheet" crossorigin href="/assets/index-B06MVODt.css">
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>

View File

@ -105,6 +105,39 @@ export default function ContractDetailModal({ contractId, isOpen, onClose }: Con
</dd> </dd>
</div> </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> </div>
</Card> </Card>
)} )}

View File

@ -1569,6 +1569,12 @@ export default function ContractDetail() {
<dd className="font-mono">{c.previousContract.customerNumberAtProvider}</dd> <dd className="font-mono">{c.previousContract.customerNumberAtProvider}</dd>
</div> </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 && ( {c.previousContract.portalUsername && (
<div> <div>
<dt className="text-sm text-gray-500">Zugangsdaten</dt> <dt className="text-sm text-gray-500">Zugangsdaten</dt>
@ -1579,6 +1585,38 @@ export default function ContractDetail() {
</Card> </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 */} {/* Cancellation Confirmation Warning */}
{c.cancellationConfirmationDate && ( {c.cancellationConfirmationDate && (
<div className="mb-6 p-4 bg-red-50 border-2 border-red-400 rounded-lg flex items-start gap-3"> <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> </dd>
</div> </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 && ( {c.salesPlatform && (
<div> <div>
<dt className="text-sm text-gray-500">Vertriebsplattform</dt> <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 contractType = watch('type') as ContractType;
const customerId = watch('customerId'); const customerId = watch('customerId');
const previousContractId = watch('previousContractId');
// Fetch existing contract for edit // Fetch existing contract for edit
const { data: contract } = useQuery({ const { data: contract } = useQuery({
@ -255,6 +256,7 @@ export default function ContractForm() {
providerName: c.providerName || '', providerName: c.providerName || '',
tariffName: c.tariffName || '', tariffName: c.tariffName || '',
customerNumberAtProvider: c.customerNumberAtProvider || '', customerNumberAtProvider: c.customerNumberAtProvider || '',
contractNumberAtProvider: c.contractNumberAtProvider || '',
priceFirst12Months: c.priceFirst12Months || '', priceFirst12Months: c.priceFirst12Months || '',
priceFrom13Months: c.priceFrom13Months || '', priceFrom13Months: c.priceFrom13Months || '',
priceAfter24Months: c.priceAfter24Months || '', priceAfter24Months: c.priceAfter24Months || '',
@ -273,8 +275,6 @@ export default function ContractForm() {
basePrice: c.energyDetails?.basePrice || '', basePrice: c.energyDetails?.basePrice || '',
unitPrice: c.energyDetails?.unitPrice || '', unitPrice: c.energyDetails?.unitPrice || '',
bonus: c.energyDetails?.bonus || '', bonus: c.energyDetails?.bonus || '',
previousProviderName: c.energyDetails?.previousProviderName || '',
previousCustomerNumber: c.energyDetails?.previousCustomerNumber || '',
// Internet details // Internet details
downloadSpeed: c.internetDetails?.downloadSpeed || '', downloadSpeed: c.internetDetails?.downloadSpeed || '',
uploadSpeed: c.internetDetails?.uploadSpeed || '', uploadSpeed: c.internetDetails?.uploadSpeed || '',
@ -317,6 +317,10 @@ export default function ContractForm() {
wasSpecialCancellation: c.wasSpecialCancellation || false, wasSpecialCancellation: c.wasSpecialCancellation || false,
// Vorgänger-Vertrag // Vorgänger-Vertrag
previousContractId: c.previousContractId?.toString() || '', previousContractId: c.previousContractId?.toString() || '',
// Altanbieter (nur wenn kein Vorgängervertrag)
previousProviderId: c.previousProviderId?.toString() || '',
previousCustomerNumber: c.previousCustomerNumber || '',
previousContractNumber: c.previousContractNumber || '',
}); });
// Load simCards if available // Load simCards if available
@ -473,6 +477,7 @@ export default function ContractForm() {
providerName: emptyToNull(data.providerName), providerName: emptyToNull(data.providerName),
tariffName: emptyToNull(data.tariffName), tariffName: emptyToNull(data.tariffName),
customerNumberAtProvider: emptyToNull(data.customerNumberAtProvider), customerNumberAtProvider: emptyToNull(data.customerNumberAtProvider),
contractNumberAtProvider: emptyToNull(data.contractNumberAtProvider),
priceFirst12Months: emptyToNull(data.priceFirst12Months), priceFirst12Months: emptyToNull(data.priceFirst12Months),
priceFrom13Months: emptyToNull(data.priceFrom13Months), priceFrom13Months: emptyToNull(data.priceFrom13Months),
priceAfter24Months: emptyToNull(data.priceAfter24Months), priceAfter24Months: emptyToNull(data.priceAfter24Months),
@ -490,6 +495,10 @@ export default function ContractForm() {
cancellationConfirmationOptionsDate: data.cancellationConfirmationOptionsDate ? new Date(data.cancellationConfirmationOptionsDate) : null, cancellationConfirmationOptionsDate: data.cancellationConfirmationOptionsDate ? new Date(data.cancellationConfirmationOptionsDate) : null,
wasSpecialCancellation: data.wasSpecialCancellation || false, wasSpecialCancellation: data.wasSpecialCancellation || false,
previousContractId: safeParseInt(data.previousContractId) ?? null, 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 // Add type-specific details
@ -502,8 +511,6 @@ export default function ContractForm() {
basePrice: data.basePrice ? parseFloat(data.basePrice) : null, basePrice: data.basePrice ? parseFloat(data.basePrice) : null,
unitPrice: data.unitPrice ? parseFloat(data.unitPrice) : null, unitPrice: data.unitPrice ? parseFloat(data.unitPrice) : null,
bonus: data.bonus ? parseFloat(data.bonus) : 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" 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> </div>
</Card> </Card>
@ -775,6 +805,7 @@ export default function ContractForm() {
disabled={!selectedProviderId} disabled={!selectedProviderId}
/> />
<Input label="Kundennummer beim Anbieter" {...register('customerNumberAtProvider')} /> <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="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 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" /> <Input label="Preis ab 13. Monat" {...register('priceFrom13Months')} placeholder="z.B. 39,99 €/Monat" />
@ -943,8 +974,6 @@ export default function ContractForm() {
{...register('unitPrice')} {...register('unitPrice')}
/> />
<Input label="Bonus (€)" type="number" step="0.01" {...register('bonus')} /> <Input label="Bonus (€)" type="number" step="0.01" {...register('bonus')} />
<Input label="Vorversorger" {...register('previousProviderName')} />
<Input label="Kundennr. beim Vorversorger" {...register('previousCustomerNumber')} />
</div> </div>
{/* Hinweis für Zählerstände und Rechnungen */} {/* Hinweis für Zählerstände und Rechnungen */}

View File

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