add statistics
This commit is contained in:
@ -0,0 +1,54 @@
|
||||
import type { printJobs } from "@/server/db/schema";
|
||||
import type { InferResultType } from "@/utils/drizzle";
|
||||
import type { InferSelectModel } from "drizzle-orm";
|
||||
|
||||
export interface PrinterErrorRate {
|
||||
printerId: string;
|
||||
name: string;
|
||||
errorRate: number; // Error rate as a percentage (0-100)
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the error rate for print jobs aggregated by printer as a percentage.
|
||||
*
|
||||
* @param pJobs - Array of print job objects.
|
||||
* @returns An array of PrinterErrorRate objects, each containing the printer ID and its error rate.
|
||||
*/
|
||||
export function calculatePrinterErrorRate(
|
||||
pJobs: InferResultType<"printJobs", { printer: true }>[],
|
||||
): PrinterErrorRate[] {
|
||||
if (pJobs.length === 0) {
|
||||
return []; // No jobs, no data.
|
||||
}
|
||||
const printers = pJobs.map((job) => job.printer);
|
||||
|
||||
// Group jobs by printer ID
|
||||
const jobsByPrinter: Record<string, InferSelectModel<typeof printJobs>[]> = pJobs.reduce(
|
||||
(acc, job) => {
|
||||
if (!acc[job.printerId]) {
|
||||
acc[job.printerId] = [];
|
||||
}
|
||||
acc[job.printerId].push(job);
|
||||
return acc;
|
||||
},
|
||||
{} as Record<string, InferSelectModel<typeof printJobs>[]>,
|
||||
);
|
||||
|
||||
// Calculate the error rate for each printer
|
||||
const printerErrorRates: PrinterErrorRate[] = Object.entries(jobsByPrinter).map(([printerId, jobs]) => {
|
||||
const totalJobs = jobs.length;
|
||||
const abortedJobsCount = jobs.filter((job) => job.aborted).length;
|
||||
const errorRate = (abortedJobsCount / totalJobs) * 100;
|
||||
|
||||
const printer = printers.find((printer) => printer.id === printerId);
|
||||
const printerName = printer ? printer.name : "Unbekannter Drucker";
|
||||
|
||||
return {
|
||||
printerId,
|
||||
name: printerName,
|
||||
errorRate: Number.parseFloat(errorRate.toFixed(2)), // Rounded to two decimal places
|
||||
};
|
||||
});
|
||||
|
||||
return printerErrorRates;
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
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 = (endOfThisMonth.getTime() - startOfThisMonth.getTime()) / (1000 * 60);
|
||||
|
||||
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,
|
||||
};
|
||||
});
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
import type { InferResultType } from "@/utils/drizzle";
|
||||
|
||||
export function calculatePrinterUtilization(jobs: InferResultType<"printJobs", { printer: true }>[]) {
|
||||
const printers = jobs.reduce<Record<string, string>>((acc, job) => {
|
||||
acc[job.printerId] = job.printer.name;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const usedTimePerPrinter: Record<string, number> = jobs.reduce(
|
||||
(acc, job) => {
|
||||
acc[job.printer.id] = (acc[job.printer.id] || 0) + job.durationInMinutes;
|
||||
|
||||
return acc;
|
||||
},
|
||||
{} as Record<string, number>,
|
||||
);
|
||||
|
||||
const totalTimeInMinutes = 60 * 70 * 4; // 60 Minutes * 70h * 4 Weeks
|
||||
|
||||
const printerUtilizationPercentage = Object.keys(usedTimePerPrinter).map((printerId) => {
|
||||
const usedTime = usedTimePerPrinter[printerId];
|
||||
return {
|
||||
printerId,
|
||||
name: printers[printerId],
|
||||
utilizationPercentage: usedTime / totalTimeInMinutes,
|
||||
};
|
||||
});
|
||||
|
||||
return printerUtilizationPercentage;
|
||||
}
|
49
packages/reservation-platform/src/utils/analytics/volume.ts
Normal file
49
packages/reservation-platform/src/utils/analytics/volume.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import type { printJobs } from "@/server/db/schema";
|
||||
import { endOfDay, endOfMonth, endOfWeek, startOfDay, startOfMonth, startOfWeek } from "date-fns";
|
||||
import type { InferSelectModel } from "drizzle-orm";
|
||||
|
||||
interface PrintVolumes {
|
||||
today: number;
|
||||
thisWeek: number;
|
||||
thisMonth: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the number of print jobs for today, this week, and this month.
|
||||
*
|
||||
* @param printJobs - Array of print job objects.
|
||||
* @returns An object with counts of print jobs for today, this week, and this month.
|
||||
*/
|
||||
export function calculatePrintVolumes(pJobs: InferSelectModel<typeof printJobs>[]): PrintVolumes {
|
||||
const now = new Date();
|
||||
|
||||
// Define time ranges
|
||||
const timeRanges = {
|
||||
today: { start: startOfDay(now), end: endOfDay(now) },
|
||||
thisWeek: { start: startOfWeek(now), end: endOfWeek(now) },
|
||||
thisMonth: { start: startOfMonth(now), end: endOfMonth(now) },
|
||||
};
|
||||
|
||||
// Initialize counts
|
||||
const volumes: PrintVolumes = {
|
||||
today: 0,
|
||||
thisWeek: 0,
|
||||
thisMonth: 0,
|
||||
};
|
||||
|
||||
// Iterate over print jobs and count based on time ranges
|
||||
for (const job of pJobs) {
|
||||
const jobStart = new Date(job.startAt);
|
||||
if (jobStart >= timeRanges.today.start && jobStart <= timeRanges.today.end) {
|
||||
volumes.today += 1;
|
||||
}
|
||||
if (jobStart >= timeRanges.thisWeek.start && jobStart <= timeRanges.thisWeek.end) {
|
||||
volumes.thisWeek += 1;
|
||||
}
|
||||
if (jobStart >= timeRanges.thisMonth.start && jobStart <= timeRanges.thisMonth.end) {
|
||||
volumes.thisMonth += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return volumes;
|
||||
}
|
Reference in New Issue
Block a user