From 06ae314b3c95f339a463b715ae042ac10db152c7 Mon Sep 17 00:00:00 2001 From: grabowski Date: Tue, 21 Apr 2026 14:03:08 +0700 Subject: [PATCH] Convert project list and detail spent to base currency via FX rate Both the projects list and the project detail stats (totalApproved, totalPending) now left-join companyAccounts and multiply expense amounts by fxRateToBase before summing, matching the overview and budget page fix. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../(app)/companies/[companyId]/projects/+page.server.ts | 5 +++-- .../[companyId]/projects/[projectId]/+page.server.ts | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/routes/(app)/companies/[companyId]/projects/+page.server.ts b/src/routes/(app)/companies/[companyId]/projects/+page.server.ts index 804d6b4..a0b19cb 100644 --- a/src/routes/(app)/companies/[companyId]/projects/+page.server.ts +++ b/src/routes/(app)/companies/[companyId]/projects/+page.server.ts @@ -1,6 +1,6 @@ import type { PageServerLoad } from './$types'; import { db } from '$lib/server/db/index.js'; -import { projects, expenses } from '$lib/server/db/schema.js'; +import { projects, expenses, companyAccounts } from '$lib/server/db/schema.js'; import { eq, sql } from 'drizzle-orm'; export const load: PageServerLoad = async ({ parent }) => { @@ -13,12 +13,13 @@ export const load: PageServerLoad = async ({ parent }) => { description: projects.description, allocatedBudget: projects.allocatedBudget, isActive: projects.isActive, - spent: sql`coalesce(sum(case when ${expenses.status} = 'approved' then ${expenses.amount} else 0 end), 0)`, + spent: sql`coalesce(sum(case when ${expenses.status} = 'approved' then ${expenses.amount} * coalesce(${companyAccounts.fxRateToBase}, 1) else 0 end), 0)::text`, expenseCount: sql`count(${expenses.id})::int`, pendingCount: sql`count(case when ${expenses.status} = 'pending' then 1 end)::int` }) .from(projects) .leftJoin(expenses, eq(expenses.projectId, projects.id)) + .leftJoin(companyAccounts, eq(expenses.accountId, companyAccounts.id)) .where(eq(projects.companyId, company.id)) .groupBy(projects.id) .orderBy(projects.name); diff --git a/src/routes/(app)/companies/[companyId]/projects/[projectId]/+page.server.ts b/src/routes/(app)/companies/[companyId]/projects/[projectId]/+page.server.ts index 05a057a..3e81fa7 100644 --- a/src/routes/(app)/companies/[companyId]/projects/[projectId]/+page.server.ts +++ b/src/routes/(app)/companies/[companyId]/projects/[projectId]/+page.server.ts @@ -1,7 +1,7 @@ import { error, fail } from '@sveltejs/kit'; import type { Actions, PageServerLoad } from './$types'; import { db } from '$lib/server/db/index.js'; -import { projects, expenses, users, categories } from '$lib/server/db/schema.js'; +import { projects, expenses, users, categories, companyAccounts } from '$lib/server/db/schema.js'; import { eq, and, sql } from 'drizzle-orm'; import { requireCompanyRole } from '$lib/server/authorization.js'; import { logCompanyEvent } from '$lib/server/audit.js'; @@ -41,11 +41,12 @@ export const load: PageServerLoad = async ({ params, parent }) => { const [stats] = await db .select({ - totalApproved: sql`coalesce(sum(case when ${expenses.status} = 'approved' then ${expenses.amount} else 0 end), 0)`, - totalPending: sql`coalesce(sum(case when ${expenses.status} = 'pending' then ${expenses.amount} else 0 end), 0)`, + totalApproved: sql`coalesce(sum(case when ${expenses.status} = 'approved' then ${expenses.amount} * coalesce(${companyAccounts.fxRateToBase}, 1) else 0 end), 0)::text`, + totalPending: sql`coalesce(sum(case when ${expenses.status} = 'pending' then ${expenses.amount} * coalesce(${companyAccounts.fxRateToBase}, 1) else 0 end), 0)::text`, count: sql`count(*)::int` }) .from(expenses) + .leftJoin(companyAccounts, eq(expenses.accountId, companyAccounts.id)) .where(eq(expenses.projectId, params.projectId)); return { project, expenses: expenseList, stats };