diff --git a/server/src/lib/projects.js b/server/src/lib/projects.js index da4170e..d056b28 100644 --- a/server/src/lib/projects.js +++ b/server/src/lib/projects.js @@ -175,6 +175,7 @@ export function isBillable(project, task) { export async function loadProjects(settings, { where = '1=1', params = [] } = {}) { const [projects] = await pool.query( `SELECT p.*, c.name AS customer_name, c.short_name AS customer_short, c.color AS customer_color, + c.is_active AS customer_active, u.name AS owner_name FROM pulse_projects p JOIN pulse_customers c ON c.id = p.customer_id @@ -270,7 +271,7 @@ export async function loadProjects(settings, { where = '1=1', params = [] } = {} return { ...project, display_name: displayName(settings, project, customer), - customer: { id: p.customer_id, name: p.customer_name, short_name: p.customer_short, color: p.customer_color }, + customer: { id: p.customer_id, name: p.customer_name, short_name: p.customer_short, color: p.customer_color, is_active: Boolean(p.customer_active) }, pots: projectPots, tasks: tasks .filter((t) => t.project_id === p.id) diff --git a/src/components/booking/ExportDialog.tsx b/src/components/booking/ExportDialog.tsx index 0a8ab40..fb23c6c 100644 --- a/src/components/booking/ExportDialog.tsx +++ b/src/components/booking/ExportDialog.tsx @@ -33,12 +33,20 @@ export const ExportDialog: React.FC<{ const [busy, setBusy] = useState(false); const isLead = atLeast(user, 'lead'); + /* + * Zur Auswahl stehen nur laufende Projekte aktiver Kunden. Archivierte + * Projekte und stillgelegte Kunden wuerden die Liste mit Aufträgen fuellen, + * fuer die niemand mehr einen Nachweis schreibt. Ihre Zeiten sind dadurch + * nicht verloren: ohne Filter exportiert der Nachweis alles, was die Person + * im Monat gebucht hat - und der Projektreport hat einen eigenen Export. + */ + const waehlbar = useMemo(() => projects.filter((p) => p.is_active && p.customer.is_active !== false), [projects]); const customers = useMemo(() => { const map = new Map(); - projects.forEach((p) => map.set(p.customer.id, p.customer.name)); + waehlbar.forEach((p) => map.set(p.customer.id, p.customer.name)); return [...map.entries()].sort((a, b) => a[1].localeCompare(b[1], 'de')); - }, [projects]); - const projectOptions = projects.filter((p) => !customerId || p.customer_id === customerId); + }, [waehlbar]); + const projectOptions = waehlbar.filter((p) => !customerId || p.customer_id === customerId); // Monate: 18 zurueck, 2 voraus. const months = useMemo(() => { diff --git a/src/types.ts b/src/types.ts index 32fe208..cfa8088 100644 --- a/src/types.ts +++ b/src/types.ts @@ -178,7 +178,7 @@ export interface Project { owner_id: number | null; owner_name: string | null; is_active: boolean; - customer: { id: number; name: string; short_name: string; color: string | null }; + customer: { id: number; name: string; short_name: string; color: string | null; is_active: boolean }; pots: BudgetPot[]; tasks: Task[]; members: MemberRef[];