adjust statistics
This commit is contained in:
39
packages/reservation-platform/src/utils/analytics/errors.ts
Normal file
39
packages/reservation-platform/src/utils/analytics/errors.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import type { InferResultType } from "@/utils/drizzle";
|
||||
|
||||
export interface AbortReasonCount {
|
||||
abortReason: string;
|
||||
count: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the count of each unique abort reason for print jobs.
|
||||
*
|
||||
* @param pJobs - Array of print job objects.
|
||||
* @returns An array of AbortReasonCount objects, each containing the abort reason and its count.
|
||||
*/
|
||||
export function calculateAbortReasonsCount(pJobs: InferResultType<"printJobs">[]): AbortReasonCount[] {
|
||||
if (pJobs.length === 0) {
|
||||
return []; // No jobs, no data.
|
||||
}
|
||||
|
||||
// Filter aborted jobs and count each abort reason
|
||||
const abortReasonsCount = pJobs
|
||||
.filter((job) => job.aborted && job.abortReason) // Consider only aborted jobs with a reason
|
||||
.reduce(
|
||||
(acc, job) => {
|
||||
const reason = job.abortReason || "Unbekannter Grund";
|
||||
if (!acc[reason]) {
|
||||
acc[reason] = 0;
|
||||
}
|
||||
acc[reason]++;
|
||||
return acc;
|
||||
},
|
||||
{} as Record<string, number>,
|
||||
);
|
||||
|
||||
// Convert the result to an array of AbortReasonCount objects
|
||||
return Object.entries(abortReasonsCount).map(([abortReason, count]) => ({
|
||||
abortReason,
|
||||
count,
|
||||
}));
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import type { InferResultType } from "@/utils/drizzle";
|
||||
|
||||
type UsagePerDay = {
|
||||
day: number; // 0 (Sunday) to 6 (Saturday)
|
||||
usageMinutes: number;
|
||||
dataPoints: number;
|
||||
};
|
||||
|
||||
function aggregateUsageByDay(jobs: InferResultType<"printJobs">[]): UsagePerDay[] {
|
||||
const usagePerDayMap = new Map<number, number>();
|
||||
const usagePerDayDatapointsMap = new Map<number, number>();
|
||||
|
||||
for (const job of jobs) {
|
||||
let remainingDuration = job.durationInMinutes;
|
||||
const currentStart = new Date(job.startAt);
|
||||
|
||||
while (remainingDuration > 0) {
|
||||
const day = currentStart.getDay();
|
||||
const dataPoints = usagePerDayDatapointsMap.get(day) || 0;
|
||||
usagePerDayDatapointsMap.set(day, dataPoints + 1);
|
||||
|
||||
// Calculate minutes remaining in the current day
|
||||
const minutesRemainingInDay = (24 - currentStart.getHours()) * 60 - currentStart.getMinutes();
|
||||
const minutesToAdd = Math.min(remainingDuration, minutesRemainingInDay);
|
||||
|
||||
// Update the usage for the current day
|
||||
const usageMinutes = usagePerDayMap.get(day) || 0;
|
||||
usagePerDayMap.set(day, usageMinutes + minutesToAdd);
|
||||
|
||||
// Update remaining duration and move to the next day
|
||||
remainingDuration -= minutesToAdd;
|
||||
currentStart.setDate(currentStart.getDate() + 1);
|
||||
currentStart.setHours(0, 0, 0, 0); // Start at the beginning of the next day
|
||||
}
|
||||
}
|
||||
|
||||
const usageData: UsagePerDay[] = Array.from({ length: 7 }, (_, day) => ({
|
||||
day,
|
||||
usageMinutes: usagePerDayMap.get(day) || 0,
|
||||
dataPoints: usagePerDayDatapointsMap.get(day) || 0,
|
||||
}));
|
||||
|
||||
return usageData;
|
||||
}
|
||||
|
||||
export function forecastPrinterUsage(jobs: InferResultType<"printJobs">[]): number[] {
|
||||
const usageData = aggregateUsageByDay(jobs);
|
||||
console.log(usageData);
|
||||
const forecasts: number[] = [];
|
||||
for (const data of usageData) {
|
||||
let usagePrediction = data.usageMinutes / data.dataPoints;
|
||||
if (Number.isNaN(usagePrediction)) {
|
||||
usagePrediction = 0;
|
||||
}
|
||||
forecasts.push(Math.round(usagePrediction));
|
||||
}
|
||||
|
||||
return forecasts;
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
import type { printJobs, printers } from "@/server/db/schema";
|
||||
import { endOfMonth, startOfMonth } from "date-fns";
|
||||
import type { InferSelectModel } from "drizzle-orm";
|
||||
|
||||
interface PrinterIdleTime {
|
||||
printerId: string;
|
||||
printerName: string;
|
||||
averageIdleTime: number; // in minutes
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the average idle time for each printer within the current month.
|
||||
*
|
||||
* @param printJobs - Array of print job objects.
|
||||
* @param printers - Array of printer objects.
|
||||
* @returns An array of PrinterIdleTime objects with average idle times.
|
||||
*/
|
||||
export function calculatePrinterIdleTime(
|
||||
pJobs: InferSelectModel<typeof printJobs>[],
|
||||
p: InferSelectModel<typeof printers>[],
|
||||
): PrinterIdleTime[] {
|
||||
const now = new Date();
|
||||
const startOfThisMonth = startOfMonth(now);
|
||||
const endOfThisMonth = endOfMonth(now);
|
||||
const totalMinutesInMonth = 60 * 70 * 4; // 60min * 70h (35*2) * 4 Weeks
|
||||
|
||||
const usedTimePerPrinter: Record<string, number> = pJobs.reduce(
|
||||
(acc, job) => {
|
||||
const jobStart = new Date(job.startAt);
|
||||
if (jobStart >= startOfThisMonth && jobStart <= endOfThisMonth) {
|
||||
acc[job.printerId] = (acc[job.printerId] || 0) + job.durationInMinutes;
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{} as Record<string, number>,
|
||||
);
|
||||
|
||||
return p.map((printer) => {
|
||||
const usedTime = usedTimePerPrinter[printer.id] || 0;
|
||||
const idleTime = totalMinutesInMonth - usedTime;
|
||||
const averageIdleTime = idleTime < 0 ? 0 : idleTime; // Ensure no negative idle time
|
||||
|
||||
return {
|
||||
printerId: printer.id,
|
||||
printerName: printer.name,
|
||||
averageIdleTime,
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -15,10 +15,12 @@ export function calculatePrinterUtilization(jobs: InferResultType<"printJobs", {
|
||||
{} as Record<string, number>,
|
||||
);
|
||||
|
||||
const totalTimeInMinutes = 60 * 70 * 4; // 60 Minutes * 70h * 4 Weeks
|
||||
const totalTimeInMinutes = 60 * 35 * 3; // 60 Minutes * 35h * 3 Weeks
|
||||
// 35h Woche, 3 mal in der Woche in TBA
|
||||
|
||||
const printerUtilizationPercentage = Object.keys(usedTimePerPrinter).map((printerId) => {
|
||||
const usedTime = usedTimePerPrinter[printerId];
|
||||
|
||||
return {
|
||||
printerId,
|
||||
name: printers[printerId],
|
||||
|
||||
Reference in New Issue
Block a user