snooze vor expired, contracts, display snoozed contracts if an item is missing, un snooze implemented, fixed invoice upload bug

This commit is contained in:
2026-02-08 13:08:58 +01:00
parent 839bb40f5e
commit 2ab2bb7562
39 changed files with 1369 additions and 800 deletions
+1
View File
@@ -11,4 +11,5 @@ export declare function getSimCardCredentials(req: Request, res: Response): Prom
export declare function getInternetCredentials(req: Request, res: Response): Promise<void>;
export declare function getSipCredentials(req: Request, res: Response): Promise<void>;
export declare function getCockpit(req: AuthRequest, res: Response): Promise<void>;
export declare function snoozeContract(req: Request, res: Response): Promise<void>;
//# sourceMappingURL=contract.controller.d.ts.map
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"contract.controller.d.ts","sourceRoot":"","sources":["../../src/controllers/contract.controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,EAAe,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE7D,wBAAsB,YAAY,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAwCjF;AAED,wBAAsB,WAAW,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BhF;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAU/E;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAU/E;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAU/E;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAU/E;AAED,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBpF;AAED,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAUtF;AAED,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAUvF;AAED,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAUlF;AAID,wBAAsB,UAAU,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAW/E"}
{"version":3,"file":"contract.controller.d.ts","sourceRoot":"","sources":["../../src/controllers/contract.controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAI5C,OAAO,EAAe,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAI7D,wBAAsB,YAAY,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAwCjF;AAED,wBAAsB,WAAW,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BhF;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAU/E;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAU/E;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAU/E;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAU/E;AAED,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBpF;AAED,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAUtF;AAED,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAUvF;AAED,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAUlF;AAID,wBAAsB,UAAU,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAW/E;AAID,wBAAsB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAyC/E"}
+44
View File
@@ -44,8 +44,11 @@ exports.getSimCardCredentials = getSimCardCredentials;
exports.getInternetCredentials = getInternetCredentials;
exports.getSipCredentials = getSipCredentials;
exports.getCockpit = getCockpit;
exports.snoozeContract = snoozeContract;
const client_1 = require("@prisma/client");
const contractService = __importStar(require("../services/contract.service.js"));
const contractCockpitService = __importStar(require("../services/contractCockpit.service.js"));
const prisma = new client_1.PrismaClient();
async function getContracts(req, res) {
try {
const { customerId, type, status, search, page, limit, tree } = req.query;
@@ -230,4 +233,45 @@ async function getCockpit(req, res) {
});
}
}
// ==================== SNOOZE (VERTRAG ZURÜCKSTELLEN) ====================
async function snoozeContract(req, res) {
try {
const id = parseInt(req.params.id);
const { nextReviewDate, months } = req.body;
let reviewDate = null;
if (nextReviewDate) {
// Explizites Datum angegeben
reviewDate = new Date(nextReviewDate);
}
else if (months) {
// Monate angegeben → berechne Datum
reviewDate = new Date();
reviewDate.setMonth(reviewDate.getMonth() + months);
}
// Wenn beides leer → nextReviewDate wird auf null gesetzt (Snooze aufheben)
const updated = await prisma.contract.update({
where: { id },
data: { nextReviewDate: reviewDate },
select: {
id: true,
contractNumber: true,
nextReviewDate: true,
},
});
res.json({
success: true,
data: updated,
message: reviewDate
? `Vertrag zurückgestellt bis ${reviewDate.toLocaleDateString('de-DE')}`
: 'Zurückstellung aufgehoben',
});
}
catch (error) {
console.error('Snooze error:', error);
res.status(500).json({
success: false,
error: 'Fehler beim Zurückstellen des Vertrags',
});
}
}
//# sourceMappingURL=contract.controller.js.map
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"contract.routes.d.ts","sourceRoot":"","sources":["../../src/routes/contract.routes.ts"],"names":[],"mappings":"AAIA,QAAA,MAAM,MAAM,4CAAW,CAAC;AA2BxB,eAAe,MAAM,CAAC"}
{"version":3,"file":"contract.routes.d.ts","sourceRoot":"","sources":["../../src/routes/contract.routes.ts"],"names":[],"mappings":"AAIA,QAAA,MAAM,MAAM,4CAAW,CAAC;AA8BxB,eAAe,MAAM,CAAC"}
+2
View File
@@ -46,6 +46,8 @@ router.put('/:id', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('con
router.delete('/:id', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('contracts:delete'), contractController.deleteContract);
// Follow-up contract
router.post('/:id/follow-up', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('contracts:create'), contractController.createFollowUp);
// Snooze (Vertrag zurückstellen)
router.patch('/:id/snooze', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('contracts:update'), contractController.snoozeContract);
// Get decrypted password
router.get('/:id/password', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('contracts:read'), contractController.getContractPassword);
// Get decrypted SimCard PIN/PUK
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"contract.routes.js","sourceRoot":"","sources":["../../src/routes/contract.routes.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qCAAiC;AACjC,0FAA4E;AAC5E,mDAAwE;AAExE,MAAM,MAAM,GAAG,IAAA,gBAAM,GAAE,CAAC;AAExB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,YAAY,CAAC,CAAC;AACpG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;AAEzG,2CAA2C;AAC3C,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,UAAU,CAAC,CAAC;AAEzG,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC;AACtG,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;AAC3G,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;AAE9G,qBAAqB;AACrB,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;AAEtH,yBAAyB;AACzB,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,mBAAmB,CAAC,CAAC;AAEvH,gCAAgC;AAChC,MAAM,CAAC,GAAG,CAAC,iCAAiC,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;AAE3I,kCAAkC;AAClC,MAAM,CAAC,GAAG,CAAC,2BAA2B,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,sBAAsB,CAAC,CAAC;AAEtI,6BAA6B;AAC7B,MAAM,CAAC,GAAG,CAAC,6CAA6C,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;AAEnJ,kBAAe,MAAM,CAAC"}
{"version":3,"file":"contract.routes.js","sourceRoot":"","sources":["../../src/routes/contract.routes.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qCAAiC;AACjC,0FAA4E;AAC5E,mDAAwE;AAExE,MAAM,MAAM,GAAG,IAAA,gBAAM,GAAE,CAAC;AAExB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,YAAY,CAAC,CAAC;AACpG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;AAEzG,2CAA2C;AAC3C,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,UAAU,CAAC,CAAC;AAEzG,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC;AACtG,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;AAC3G,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;AAE9G,qBAAqB;AACrB,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;AAEtH,iCAAiC;AACjC,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;AAEpH,yBAAyB;AACzB,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,mBAAmB,CAAC,CAAC;AAEvH,gCAAgC;AAChC,MAAM,CAAC,GAAG,CAAC,iCAAiC,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;AAE3I,kCAAkC;AAClC,MAAM,CAAC,GAAG,CAAC,2BAA2B,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,sBAAsB,CAAC,CAAC;AAEtI,6BAA6B;AAC7B,MAAM,CAAC,GAAG,CAAC,6CAA6C,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;AAEnJ,kBAAe,MAAM,CAAC"}
+8
View File
@@ -135,6 +135,7 @@ export declare function getAllContracts(filters: ContractFilters): Promise<{
wasSpecialCancellation: boolean;
portalUsername: string | null;
stressfreiEmailId: number | null;
nextReviewDate: Date | null;
})[];
pagination: {
page: number;
@@ -564,6 +565,7 @@ export declare function getContractById(id: number, decryptPassword?: boolean):
wasSpecialCancellation: boolean;
portalUsername: string | null;
stressfreiEmailId: number | null;
nextReviewDate: Date | null;
}) | null;
followUpContract: {
id: number;
@@ -609,6 +611,7 @@ export declare function getContractById(id: number, decryptPassword?: boolean):
wasSpecialCancellation: boolean;
portalUsername: string | null;
stressfreiEmailId: number | null;
nextReviewDate: Date | null;
}) | null>;
interface ContractCreateData {
customerId: number;
@@ -894,6 +897,7 @@ export declare function createContract(data: ContractCreateData): Promise<{
wasSpecialCancellation: boolean;
portalUsername: string | null;
stressfreiEmailId: number | null;
nextReviewDate: Date | null;
}>;
export declare function updateContract(id: number, data: Partial<ContractCreateData>): Promise<({
customer: {
@@ -1316,6 +1320,7 @@ export declare function updateContract(id: number, data: Partial<ContractCreateD
wasSpecialCancellation: boolean;
portalUsername: string | null;
stressfreiEmailId: number | null;
nextReviewDate: Date | null;
}) | null;
followUpContract: {
id: number;
@@ -1361,6 +1366,7 @@ export declare function updateContract(id: number, data: Partial<ContractCreateD
wasSpecialCancellation: boolean;
portalUsername: string | null;
stressfreiEmailId: number | null;
nextReviewDate: Date | null;
}) | null>;
export declare function deleteContract(id: number): Promise<{
id: number;
@@ -1401,6 +1407,7 @@ export declare function deleteContract(id: number): Promise<{
wasSpecialCancellation: boolean;
portalUsername: string | null;
stressfreiEmailId: number | null;
nextReviewDate: Date | null;
}>;
export declare function createFollowUpContract(previousContractId: number): Promise<{
customer: {
@@ -1588,6 +1595,7 @@ export declare function createFollowUpContract(previousContractId: number): Prom
wasSpecialCancellation: boolean;
portalUsername: string | null;
stressfreiEmailId: number | null;
nextReviewDate: Date | null;
}>;
export declare function getContractPassword(id: number): Promise<string | null>;
export declare function getSimCardCredentials(simCardId: number): Promise<{
File diff suppressed because one or more lines are too long
+1
View File
@@ -43,6 +43,7 @@ export interface CockpitSummary {
missingInvoices: number;
openTasks: number;
pendingContracts: number;
reviewDue: number;
};
}
export interface CockpitResult {
+1 -1
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;KAC1B,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,CAya7D"}
{"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"}
+48 -17
View File
@@ -190,14 +190,42 @@ async function getCockpitData() {
missingInvoices: 0,
openTasks: 0,
pendingContracts: 0,
reviewDue: 0,
},
};
for (const contract of contracts) {
const issues = [];
// SNOOZE-LOGIK: Prüfen ob Snooze aktiv ist (für Fristen-Unterdrückung)
let snoozeActive = false;
if (contract.nextReviewDate) {
const reviewDate = new Date(contract.nextReviewDate);
const now = new Date();
now.setHours(0, 0, 0, 0);
reviewDate.setHours(0, 0, 0, 0);
if (reviewDate > now) {
// Snooze aktiv → NUR Fristen-Warnungen unterdrücken, andere Prüfungen laufen weiter
snoozeActive = true;
}
else {
// Snooze abgelaufen → "Erneute Prüfung fällig" Warnung
const daysSince = Math.floor((now.getTime() - reviewDate.getTime()) / (1000 * 60 * 60 * 24));
issues.push({
type: 'review_due',
label: 'Erneute Prüfung fällig',
urgency: daysSince > 30 ? 'critical' : 'warning',
daysRemaining: -daysSince,
details: daysSince === 0
? 'Heute zur Prüfung fällig'
: `Zur Prüfung seit ${daysSince} Tagen fällig`,
});
summary.byCategory.reviewDue++;
}
}
// Prüfen ob aktiver Folgevertrag existiert - dann keine Kündigungswarnungen nötig
const hasActiveFollowUp = contract.followUpContract?.status === 'ACTIVE';
// 1. KÜNDIGUNGSFRIST (nur wenn kein aktiver Folgevertrag)
if (!hasActiveFollowUp) {
// 1. KÜNDIGUNGSFRIST (nur wenn kein aktiver Folgevertrag UND Snooze nicht aktiv)
// Snooze unterdrückt NUR Fristen-bezogene Warnungen!
if (!hasActiveFollowUp && !snoozeActive) {
const cancellationDeadline = calculateCancellationDeadline(contract.endDate, contract.cancellationPeriod?.code);
const daysToCancellation = daysUntil(cancellationDeadline);
if (daysToCancellation !== null && daysToCancellation <= okDays) {
@@ -236,21 +264,24 @@ async function getCockpitData() {
}
}
}
// 2. VERTRAGSENDE
const daysToEnd = daysUntil(contract.endDate);
if (daysToEnd !== null && daysToEnd <= okDays) {
const urgency = getUrgencyByDays(daysToEnd, criticalDays, warningDays, okDays);
if (urgency !== 'none') {
issues.push({
type: 'contract_ending',
label: 'Vertragsende',
urgency,
daysRemaining: daysToEnd,
details: daysToEnd < 0
? `Vertrag seit ${Math.abs(daysToEnd)} Tagen abgelaufen!`
: `Noch ${daysToEnd} Tage bis Vertragsende`,
});
summary.byCategory.contractEnding++;
// 2. VERTRAGSENDE (nur wenn Snooze nicht aktiv)
// Snooze unterdrückt NUR Fristen-bezogene Warnungen!
if (!snoozeActive) {
const daysToEnd = daysUntil(contract.endDate);
if (daysToEnd !== null && daysToEnd <= okDays) {
const urgency = getUrgencyByDays(daysToEnd, criticalDays, warningDays, okDays);
if (urgency !== 'none') {
issues.push({
type: 'contract_ending',
label: 'Vertragsende',
urgency,
daysRemaining: daysToEnd,
details: daysToEnd < 0
? `Vertrag seit ${Math.abs(daysToEnd)} Tagen abgelaufen!`
: `Noch ${daysToEnd} Tage bis Vertragsende`,
});
summary.byCategory.contractEnding++;
}
}
}
// 3. FEHLENDE PORTAL-ZUGANGSDATEN
File diff suppressed because one or more lines are too long
+1
View File
@@ -196,6 +196,7 @@ export declare function getCustomerById(id: number): Promise<({
wasSpecialCancellation: boolean;
portalUsername: string | null;
stressfreiEmailId: number | null;
nextReviewDate: Date | null;
})[];
} & {
id: number;
File diff suppressed because one or more lines are too long
+5 -3
View File
File diff suppressed because one or more lines are too long
+1
View File
@@ -433,6 +433,7 @@ exports.Prisma.ContractScalarFieldEnum = {
portalUsername: 'portalUsername',
portalPasswordEncrypted: 'portalPasswordEncrypted',
stressfreiEmailId: 'stressfreiEmailId',
nextReviewDate: 'nextReviewDate',
notes: 'notes',
createdAt: 'createdAt',
updatedAt: 'updatedAt'
+136
View File
@@ -26320,6 +26320,7 @@ export namespace Prisma {
portalUsername: string | null
portalPasswordEncrypted: string | null
stressfreiEmailId: number | null
nextReviewDate: Date | null
notes: string | null
createdAt: Date | null
updatedAt: Date | null
@@ -26361,6 +26362,7 @@ export namespace Prisma {
portalUsername: string | null
portalPasswordEncrypted: string | null
stressfreiEmailId: number | null
nextReviewDate: Date | null
notes: string | null
createdAt: Date | null
updatedAt: Date | null
@@ -26402,6 +26404,7 @@ export namespace Prisma {
portalUsername: number
portalPasswordEncrypted: number
stressfreiEmailId: number
nextReviewDate: number
notes: number
createdAt: number
updatedAt: number
@@ -26481,6 +26484,7 @@ export namespace Prisma {
portalUsername?: true
portalPasswordEncrypted?: true
stressfreiEmailId?: true
nextReviewDate?: true
notes?: true
createdAt?: true
updatedAt?: true
@@ -26522,6 +26526,7 @@ export namespace Prisma {
portalUsername?: true
portalPasswordEncrypted?: true
stressfreiEmailId?: true
nextReviewDate?: true
notes?: true
createdAt?: true
updatedAt?: true
@@ -26563,6 +26568,7 @@ export namespace Prisma {
portalUsername?: true
portalPasswordEncrypted?: true
stressfreiEmailId?: true
nextReviewDate?: true
notes?: true
createdAt?: true
updatedAt?: true
@@ -26691,6 +26697,7 @@ export namespace Prisma {
portalUsername: string | null
portalPasswordEncrypted: string | null
stressfreiEmailId: number | null
nextReviewDate: Date | null
notes: string | null
createdAt: Date
updatedAt: Date
@@ -26751,6 +26758,7 @@ export namespace Prisma {
portalUsername?: boolean
portalPasswordEncrypted?: boolean
stressfreiEmailId?: boolean
nextReviewDate?: boolean
notes?: boolean
createdAt?: boolean
updatedAt?: boolean
@@ -26815,6 +26823,7 @@ export namespace Prisma {
portalUsername?: boolean
portalPasswordEncrypted?: boolean
stressfreiEmailId?: boolean
nextReviewDate?: boolean
notes?: boolean
createdAt?: boolean
updatedAt?: boolean
@@ -26906,6 +26915,7 @@ export namespace Prisma {
portalUsername: string | null
portalPasswordEncrypted: string | null
stressfreiEmailId: number | null
nextReviewDate: Date | null
notes: string | null
createdAt: Date
updatedAt: Date
@@ -27334,6 +27344,7 @@ export namespace Prisma {
readonly portalUsername: FieldRef<"Contract", 'String'>
readonly portalPasswordEncrypted: FieldRef<"Contract", 'String'>
readonly stressfreiEmailId: FieldRef<"Contract", 'Int'>
readonly nextReviewDate: FieldRef<"Contract", 'DateTime'>
readonly notes: FieldRef<"Contract", 'String'>
readonly createdAt: FieldRef<"Contract", 'DateTime'>
readonly updatedAt: FieldRef<"Contract", 'DateTime'>
@@ -38180,6 +38191,7 @@ export namespace Prisma {
portalUsername: 'portalUsername',
portalPasswordEncrypted: 'portalPasswordEncrypted',
stressfreiEmailId: 'stressfreiEmailId',
nextReviewDate: 'nextReviewDate',
notes: 'notes',
createdAt: 'createdAt',
updatedAt: 'updatedAt'
@@ -40345,6 +40357,7 @@ export namespace Prisma {
portalUsername?: StringNullableFilter<"Contract"> | string | null
portalPasswordEncrypted?: StringNullableFilter<"Contract"> | string | null
stressfreiEmailId?: IntNullableFilter<"Contract"> | number | null
nextReviewDate?: DateTimeNullableFilter<"Contract"> | Date | string | null
notes?: StringNullableFilter<"Contract"> | string | null
createdAt?: DateTimeFilter<"Contract"> | Date | string
updatedAt?: DateTimeFilter<"Contract"> | Date | string
@@ -40407,6 +40420,7 @@ export namespace Prisma {
portalUsername?: SortOrderInput | SortOrder
portalPasswordEncrypted?: SortOrderInput | SortOrder
stressfreiEmailId?: SortOrderInput | SortOrder
nextReviewDate?: SortOrderInput | SortOrder
notes?: SortOrderInput | SortOrder
createdAt?: SortOrder
updatedAt?: SortOrder
@@ -40472,6 +40486,7 @@ export namespace Prisma {
portalUsername?: StringNullableFilter<"Contract"> | string | null
portalPasswordEncrypted?: StringNullableFilter<"Contract"> | string | null
stressfreiEmailId?: IntNullableFilter<"Contract"> | number | null
nextReviewDate?: DateTimeNullableFilter<"Contract"> | Date | string | null
notes?: StringNullableFilter<"Contract"> | string | null
createdAt?: DateTimeFilter<"Contract"> | Date | string
updatedAt?: DateTimeFilter<"Contract"> | Date | string
@@ -40534,6 +40549,7 @@ export namespace Prisma {
portalUsername?: SortOrderInput | SortOrder
portalPasswordEncrypted?: SortOrderInput | SortOrder
stressfreiEmailId?: SortOrderInput | SortOrder
nextReviewDate?: SortOrderInput | SortOrder
notes?: SortOrderInput | SortOrder
createdAt?: SortOrder
updatedAt?: SortOrder
@@ -40583,6 +40599,7 @@ export namespace Prisma {
portalUsername?: StringNullableWithAggregatesFilter<"Contract"> | string | null
portalPasswordEncrypted?: StringNullableWithAggregatesFilter<"Contract"> | string | null
stressfreiEmailId?: IntNullableWithAggregatesFilter<"Contract"> | number | null
nextReviewDate?: DateTimeNullableWithAggregatesFilter<"Contract"> | Date | string | null
notes?: StringNullableWithAggregatesFilter<"Contract"> | string | null
createdAt?: DateTimeWithAggregatesFilter<"Contract"> | Date | string
updatedAt?: DateTimeWithAggregatesFilter<"Contract"> | Date | string
@@ -43378,6 +43395,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -43440,6 +43458,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -43475,6 +43494,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -43537,6 +43557,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -43586,6 +43607,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -43613,6 +43635,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -43654,6 +43677,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -46230,6 +46254,7 @@ export namespace Prisma {
portalUsername?: SortOrder
portalPasswordEncrypted?: SortOrder
stressfreiEmailId?: SortOrder
nextReviewDate?: SortOrder
notes?: SortOrder
createdAt?: SortOrder
updatedAt?: SortOrder
@@ -46289,6 +46314,7 @@ export namespace Prisma {
portalUsername?: SortOrder
portalPasswordEncrypted?: SortOrder
stressfreiEmailId?: SortOrder
nextReviewDate?: SortOrder
notes?: SortOrder
createdAt?: SortOrder
updatedAt?: SortOrder
@@ -46330,6 +46356,7 @@ export namespace Prisma {
portalUsername?: SortOrder
portalPasswordEncrypted?: SortOrder
stressfreiEmailId?: SortOrder
nextReviewDate?: SortOrder
notes?: SortOrder
createdAt?: SortOrder
updatedAt?: SortOrder
@@ -50508,6 +50535,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -50568,6 +50596,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -50902,6 +50931,7 @@ export namespace Prisma {
portalUsername?: StringNullableFilter<"Contract"> | string | null
portalPasswordEncrypted?: StringNullableFilter<"Contract"> | string | null
stressfreiEmailId?: IntNullableFilter<"Contract"> | number | null
nextReviewDate?: DateTimeNullableFilter<"Contract"> | Date | string | null
notes?: StringNullableFilter<"Contract"> | string | null
createdAt?: DateTimeFilter<"Contract"> | Date | string
updatedAt?: DateTimeFilter<"Contract"> | Date | string
@@ -51376,6 +51406,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -51436,6 +51467,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -51481,6 +51513,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -51541,6 +51574,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -51780,6 +51814,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -51840,6 +51875,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -52063,6 +52099,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -52123,6 +52160,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -52346,6 +52384,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -52406,6 +52445,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -52699,6 +52739,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -52760,6 +52801,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -52854,6 +52896,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -52915,6 +52958,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -53299,6 +53343,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -53359,6 +53404,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -53420,6 +53466,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -53480,6 +53527,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -53541,6 +53589,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -53601,6 +53650,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -53689,6 +53739,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -53749,6 +53800,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -53866,6 +53918,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -53926,6 +53979,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -54021,6 +54075,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -54081,6 +54136,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -54450,6 +54506,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -54511,6 +54568,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -54550,6 +54608,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -54610,6 +54669,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -55357,6 +55417,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -55418,6 +55479,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -55463,6 +55525,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -55523,6 +55586,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -55890,6 +55954,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -55951,6 +56016,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -56030,6 +56096,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -56091,6 +56158,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -56221,6 +56289,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -56282,6 +56351,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -56389,6 +56459,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -56450,6 +56521,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -56618,6 +56690,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -56679,6 +56752,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -56756,6 +56830,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -56817,6 +56892,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -56950,6 +57026,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -57011,6 +57088,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -57094,6 +57172,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -57155,6 +57234,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -57287,6 +57367,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -57348,6 +57429,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -57398,6 +57480,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -57459,6 +57542,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -57493,6 +57577,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -57554,6 +57639,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -57604,6 +57690,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -57665,6 +57752,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -57842,6 +57930,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -58096,6 +58185,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -58156,6 +58246,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -58204,6 +58295,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -58296,6 +58388,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -58336,6 +58429,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -58363,6 +58457,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -58423,6 +58518,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -58471,6 +58567,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -58498,6 +58595,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -58558,6 +58656,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -58606,6 +58705,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -58646,6 +58746,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -58673,6 +58774,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -58733,6 +58835,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -58781,6 +58884,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -58821,6 +58925,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -58848,6 +58953,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -58908,6 +59014,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -58956,6 +59063,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -58996,6 +59104,7 @@ export namespace Prisma {
wasSpecialCancellation?: boolean
portalUsername?: string | null
portalPasswordEncrypted?: string | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -59050,6 +59159,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -59110,6 +59220,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -59158,6 +59269,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -59366,6 +59478,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -59393,6 +59506,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -59453,6 +59567,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -59501,6 +59616,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -59541,6 +59657,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -59568,6 +59685,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -59628,6 +59746,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -59676,6 +59795,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -59716,6 +59836,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -59743,6 +59864,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -59803,6 +59925,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -59851,6 +59974,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -59899,6 +60023,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -59951,6 +60076,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -60011,6 +60137,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -60059,6 +60186,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -60099,6 +60227,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -60126,6 +60255,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -60186,6 +60316,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -60234,6 +60365,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -60274,6 +60406,7 @@ export namespace Prisma {
portalUsername?: string | null
portalPasswordEncrypted?: string | null
stressfreiEmailId?: number | null
nextReviewDate?: Date | string | null
notes?: string | null
createdAt?: Date | string
updatedAt?: Date | string
@@ -60301,6 +60434,7 @@ export namespace Prisma {
wasSpecialCancellation?: BoolFieldUpdateOperationsInput | boolean
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -60361,6 +60495,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
@@ -60409,6 +60544,7 @@ export namespace Prisma {
portalUsername?: NullableStringFieldUpdateOperationsInput | string | null
portalPasswordEncrypted?: NullableStringFieldUpdateOperationsInput | string | null
stressfreiEmailId?: NullableIntFieldUpdateOperationsInput | number | null
nextReviewDate?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
notes?: NullableStringFieldUpdateOperationsInput | string | null
createdAt?: DateTimeFieldUpdateOperationsInput | Date | string
updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string
+5 -3
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,5 +1,5 @@
{
"name": "prisma-client-a41de88ab23bcfe6707e2a70a25cdd4736b5f2e024b64f8f8760b0e23260313f",
"name": "prisma-client-05071f627540060c098bd6f9ad2705f280d372ae8cdaf0576ff7e91f8d0f9863",
"main": "index.js",
"types": "index.d.ts",
"browser": "index-browser.js",
+3
View File
@@ -545,6 +545,9 @@ model Contract {
stressfreiEmailId Int?
stressfreiEmail StressfreiEmail? @relation(fields: [stressfreiEmailId], references: [id])
// Snooze: Vertrag zurückstellen bis Datum (für Cockpit)
nextReviewDate DateTime? // Erneute Prüfung am
notes String? @db.Text
energyDetails EnergyContractDetails?
+1
View File
@@ -433,6 +433,7 @@ exports.Prisma.ContractScalarFieldEnum = {
portalUsername: 'portalUsername',
portalPasswordEncrypted: 'portalPasswordEncrypted',
stressfreiEmailId: 'stressfreiEmailId',
nextReviewDate: 'nextReviewDate',
notes: 'notes',
createdAt: 'createdAt',
updatedAt: 'updatedAt'
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE `Contract` ADD COLUMN `nextReviewDate` DATETIME(3) NULL;
+3
View File
@@ -545,6 +545,9 @@ model Contract {
stressfreiEmailId Int?
stressfreiEmail StressfreiEmail? @relation(fields: [stressfreiEmailId], references: [id])
// Snooze: Vertrag zurückstellen bis Datum (für Cockpit)
nextReviewDate DateTime? // Erneute Prüfung am
notes String? @db.Text
energyDetails EnergyContractDetails?
@@ -1,8 +1,11 @@
import { Request, Response } from 'express';
import { PrismaClient } from '@prisma/client';
import * as contractService from '../services/contract.service.js';
import * as contractCockpitService from '../services/contractCockpit.service.js';
import { ApiResponse, AuthRequest } from '../types/index.js';
const prisma = new PrismaClient();
export async function getContracts(req: AuthRequest, res: Response): Promise<void> {
try {
const { customerId, type, status, search, page, limit, tree } = req.query;
@@ -194,3 +197,48 @@ export async function getCockpit(req: AuthRequest, res: Response): Promise<void>
} as ApiResponse);
}
}
// ==================== SNOOZE (VERTRAG ZURÜCKSTELLEN) ====================
export async function snoozeContract(req: Request, res: Response): Promise<void> {
try {
const id = parseInt(req.params.id);
const { nextReviewDate, months } = req.body;
let reviewDate: Date | null = null;
if (nextReviewDate) {
// Explizites Datum angegeben
reviewDate = new Date(nextReviewDate);
} else if (months) {
// Monate angegeben → berechne Datum
reviewDate = new Date();
reviewDate.setMonth(reviewDate.getMonth() + months);
}
// Wenn beides leer → nextReviewDate wird auf null gesetzt (Snooze aufheben)
const updated = await prisma.contract.update({
where: { id },
data: { nextReviewDate: reviewDate },
select: {
id: true,
contractNumber: true,
nextReviewDate: true,
},
});
res.json({
success: true,
data: updated,
message: reviewDate
? `Vertrag zurückgestellt bis ${reviewDate.toLocaleDateString('de-DE')}`
: 'Zurückstellung aufgehoben',
} as ApiResponse);
} catch (error) {
console.error('Snooze error:', error);
res.status(500).json({
success: false,
error: 'Fehler beim Zurückstellen des Vertrags',
} as ApiResponse);
}
}
+3
View File
@@ -17,6 +17,9 @@ router.delete('/:id', authenticate, requirePermission('contracts:delete'), contr
// Follow-up contract
router.post('/:id/follow-up', authenticate, requirePermission('contracts:create'), contractController.createFollowUp);
// Snooze (Vertrag zurückstellen)
router.patch('/:id/snooze', authenticate, requirePermission('contracts:update'), contractController.snoozeContract);
// Get decrypted password
router.get('/:id/password', authenticate, requirePermission('contracts:read'), contractController.getContractPassword);
+50 -17
View File
@@ -52,6 +52,7 @@ export interface CockpitSummary {
missingInvoices: number;
openTasks: number;
pendingContracts: number;
reviewDue: number; // Erneute Prüfung fällig (Snooze abgelaufen)
};
}
@@ -229,17 +230,46 @@ export async function getCockpitData(): Promise<CockpitResult> {
missingInvoices: 0,
openTasks: 0,
pendingContracts: 0,
reviewDue: 0,
},
};
for (const contract of contracts) {
const issues: CockpitIssue[] = [];
// SNOOZE-LOGIK: Prüfen ob Snooze aktiv ist (für Fristen-Unterdrückung)
let snoozeActive = false;
if (contract.nextReviewDate) {
const reviewDate = new Date(contract.nextReviewDate);
const now = new Date();
now.setHours(0, 0, 0, 0);
reviewDate.setHours(0, 0, 0, 0);
if (reviewDate > now) {
// Snooze aktiv → NUR Fristen-Warnungen unterdrücken, andere Prüfungen laufen weiter
snoozeActive = true;
} else {
// Snooze abgelaufen → "Erneute Prüfung fällig" Warnung
const daysSince = Math.floor((now.getTime() - reviewDate.getTime()) / (1000 * 60 * 60 * 24));
issues.push({
type: 'review_due',
label: 'Erneute Prüfung fällig',
urgency: daysSince > 30 ? 'critical' : 'warning',
daysRemaining: -daysSince,
details: daysSince === 0
? 'Heute zur Prüfung fällig'
: `Zur Prüfung seit ${daysSince} Tagen fällig`,
});
summary.byCategory.reviewDue++;
}
}
// Prüfen ob aktiver Folgevertrag existiert - dann keine Kündigungswarnungen nötig
const hasActiveFollowUp = contract.followUpContract?.status === 'ACTIVE';
// 1. KÜNDIGUNGSFRIST (nur wenn kein aktiver Folgevertrag)
if (!hasActiveFollowUp) {
// 1. KÜNDIGUNGSFRIST (nur wenn kein aktiver Folgevertrag UND Snooze nicht aktiv)
// Snooze unterdrückt NUR Fristen-bezogene Warnungen!
if (!hasActiveFollowUp && !snoozeActive) {
const cancellationDeadline = calculateCancellationDeadline(
contract.endDate,
contract.cancellationPeriod?.code
@@ -284,21 +314,24 @@ export async function getCockpitData(): Promise<CockpitResult> {
}
}
// 2. VERTRAGSENDE
const daysToEnd = daysUntil(contract.endDate);
if (daysToEnd !== null && daysToEnd <= okDays) {
const urgency = getUrgencyByDays(daysToEnd, criticalDays, warningDays, okDays);
if (urgency !== 'none') {
issues.push({
type: 'contract_ending',
label: 'Vertragsende',
urgency,
daysRemaining: daysToEnd,
details: daysToEnd < 0
? `Vertrag seit ${Math.abs(daysToEnd)} Tagen abgelaufen!`
: `Noch ${daysToEnd} Tage bis Vertragsende`,
});
summary.byCategory.contractEnding++;
// 2. VERTRAGSENDE (nur wenn Snooze nicht aktiv)
// Snooze unterdrückt NUR Fristen-bezogene Warnungen!
if (!snoozeActive) {
const daysToEnd = daysUntil(contract.endDate);
if (daysToEnd !== null && daysToEnd <= okDays) {
const urgency = getUrgencyByDays(daysToEnd, criticalDays, warningDays, okDays);
if (urgency !== 'none') {
issues.push({
type: 'contract_ending',
label: 'Vertragsende',
urgency,
daysRemaining: daysToEnd,
details: daysToEnd < 0
? `Vertrag seit ${Math.abs(daysToEnd)} Tagen abgelaufen!`
: `Noch ${daysToEnd} Tage bis Vertragsende`,
});
summary.byCategory.contractEnding++;
}
}
}
+7 -5
View File
@@ -39,13 +39,15 @@ export async function getInvoice(energyContractDetailsId: number, invoiceId: num
/**
* Neue Rechnung hinzufügen
*
* Hinweis: Die Validierung ob ein Dokument vorhanden ist, erfolgt NICHT hier,
* da der typische Flow so aussieht:
* 1. Invoice erstellen (ohne Dokument) → Invoice-ID zurückbekommen
* 2. Dokument hochladen mit der Invoice-ID
*
* Die Validierung ob alle Rechnungen Dokumente haben, erfolgt im Cockpit.
*/
export async function addInvoice(energyContractDetailsId: number, data: CreateInvoiceData) {
// Validierung: documentPath ist Pflicht, außer bei NOT_AVAILABLE
if (data.invoiceType !== 'NOT_AVAILABLE' && !data.documentPath) {
throw new Error('Dokument ist Pflicht (außer bei Typ "Nicht verfügbar")');
}
// Prüfen ob EnergyContractDetails existiert
const energyDetails = await prisma.energyContractDetails.findUnique({
where: { id: energyContractDetailsId },