feat: dashboard overhaul, chargeability reports, dispo import enhancements, UI polish
Dashboard: expanded chargeability widget, resource/project table widgets with sorting and filters, stat cards with formatMoney integration. Chargeability: new report client with filtering, chargeability-bookings use case, updated dashboard overview logic. Dispo import: TBD project handling, parse-dispo-matrix improvements, stage-dispo-projects resource value scores, new tests. Estimates: CommercialTermsEditor component, commercial-terms engine module, expanded estimate schemas and types. UI: AppShell navigation updates, timeline filter/toolbar enhancements, role management improvements, signin page redesign, Tailwind/globals polish, SystemSettings SMTP section, anonymization support. Tests: new router tests (anonymization, chargeability, effort-rule, entitlement, estimate, experience-multiplier, notification, resource, staffing, vacation). Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
@@ -10,10 +10,11 @@ import {
|
||||
type AssignmentSlice,
|
||||
} from "@planarchy/engine";
|
||||
import type { SpainScheduleRule } from "@planarchy/shared";
|
||||
import { listAssignmentBookings } from "@planarchy/application";
|
||||
import { isChargeabilityActualBooking, listAssignmentBookings } from "@planarchy/application";
|
||||
import { VacationStatus } from "@planarchy/db";
|
||||
import { z } from "zod";
|
||||
import { createTRPCRouter, controllerProcedure } from "../trpc.js";
|
||||
import { anonymizeResources, getAnonymizationDirectory } from "../lib/anonymization.js";
|
||||
|
||||
export const chargeabilityReportRouter = createTRPCRouter({
|
||||
getReport: controllerProcedure
|
||||
@@ -24,10 +25,11 @@ export const chargeabilityReportRouter = createTRPCRouter({
|
||||
orgUnitId: z.string().optional(),
|
||||
managementLevelGroupId: z.string().optional(),
|
||||
countryId: z.string().optional(),
|
||||
includeProposed: z.boolean().default(false),
|
||||
}),
|
||||
)
|
||||
.query(async ({ ctx, input }) => {
|
||||
const { startMonth, endMonth } = input;
|
||||
const { startMonth, endMonth, includeProposed } = input;
|
||||
|
||||
// Parse month range
|
||||
const [startYear, startMo] = startMonth.split("-").map(Number) as [number, number];
|
||||
@@ -100,7 +102,8 @@ export const chargeabilityReportRouter = createTRPCRouter({
|
||||
|
||||
// Normalize bookings to a common shape
|
||||
const assignments = allBookings
|
||||
.filter((b) => b.resourceId !== null)
|
||||
.filter((booking) => booking.resourceId !== null)
|
||||
.filter((booking) => isChargeabilityActualBooking(booking, includeProposed))
|
||||
.map((b) => ({
|
||||
resourceId: b.resourceId!,
|
||||
startDate: b.startDate,
|
||||
@@ -171,8 +174,6 @@ export const chargeabilityReportRouter = createTRPCRouter({
|
||||
// Build assignment slices for this month
|
||||
const slices: AssignmentSlice[] = [];
|
||||
for (const a of resourceAssignments) {
|
||||
// Skip DRAFT projects
|
||||
if (a.project.status === "DRAFT" || a.project.status === "CANCELLED") continue;
|
||||
const workingDays = countWorkingDaysInOverlap(monthStart, monthEnd, a.startDate, a.endDate);
|
||||
if (workingDays <= 0) continue;
|
||||
|
||||
@@ -236,9 +237,11 @@ export const chargeabilityReportRouter = createTRPCRouter({
|
||||
};
|
||||
});
|
||||
|
||||
const directory = await getAnonymizationDirectory(ctx.db);
|
||||
|
||||
return {
|
||||
monthKeys,
|
||||
resources: resourceRows,
|
||||
resources: anonymizeResources(resourceRows, directory),
|
||||
groupTotals,
|
||||
};
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user