diff --git a/src/lib/server/db/schema.ts b/src/lib/server/db/schema.ts index 86e54ae..47a4198 100644 --- a/src/lib/server/db/schema.ts +++ b/src/lib/server/db/schema.ts @@ -893,6 +893,8 @@ export const companyAccounts = pgTable( creditLimit: numeric('credit_limit', { precision: 15, scale: 2 }), statementCloseDay: integer('statement_close_day'), paymentDueDay: integer('payment_due_day'), + // FX conversion to company base currency (e.g. 34.5 for USD→THB) + fxRateToBase: numeric('fx_rate_to_base', { precision: 18, scale: 8 }).notNull().default('1'), // Banking integration link externalAccountId: uuid('external_account_id').references(() => externalAccounts.id, { onDelete: 'set null' diff --git a/src/routes/(app)/companies/[companyId]/+layout.server.ts b/src/routes/(app)/companies/[companyId]/+layout.server.ts index a3da916..2c90fde 100644 --- a/src/routes/(app)/companies/[companyId]/+layout.server.ts +++ b/src/routes/(app)/companies/[companyId]/+layout.server.ts @@ -27,10 +27,10 @@ export const load: LayoutServerLoad = async ({ locals, params }) => { error(403, 'Not a member of this company'); } - // Total budget = sum of all non-deleted account balances + // Total budget = sum of all non-deleted account balances, converted to base currency const [balanceRow] = await db .select({ - total: sql`coalesce(sum(${companyAccountTransactions.amount}), '0')::text` + total: sql`coalesce(sum(${companyAccountTransactions.amount} * ${companyAccounts.fxRateToBase}), '0')::text` }) .from(companyAccountTransactions) .innerJoin(companyAccounts, eq(companyAccountTransactions.accountId, companyAccounts.id)) diff --git a/src/routes/(app)/companies/[companyId]/accounts/+page.server.ts b/src/routes/(app)/companies/[companyId]/accounts/+page.server.ts index 2be3760..d0a162b 100644 --- a/src/routes/(app)/companies/[companyId]/accounts/+page.server.ts +++ b/src/routes/(app)/companies/[companyId]/accounts/+page.server.ts @@ -112,6 +112,7 @@ type AccountFields = { creditLimit: string | null; statementCloseDay: number | null; paymentDueDay: number | null; + fxRateToBase: string; externalAccountId: string | null; }; @@ -171,6 +172,7 @@ function extractAccountFields(fd: FormData): creditLimit: parseDecimalOrNull(fd.get('creditLimit')), statementCloseDay, paymentDueDay, + fxRateToBase: parseDecimalOrNull(fd.get('fxRateToBase')) ?? '1', externalAccountId: trimOrNull(fd.get('externalAccountId')) } }; @@ -304,6 +306,7 @@ export const actions: Actions = { creditLimit: f.creditLimit, statementCloseDay: f.statementCloseDay, paymentDueDay: f.paymentDueDay, + fxRateToBase: f.fxRateToBase, externalAccountId: f.externalAccountId }) .returning({ id: companyAccounts.id }); @@ -383,6 +386,7 @@ export const actions: Actions = { creditLimit: f.creditLimit, statementCloseDay: f.statementCloseDay, paymentDueDay: f.paymentDueDay, + fxRateToBase: f.fxRateToBase, externalAccountId: f.externalAccountId, updatedAt: new Date() }) diff --git a/src/routes/(app)/companies/[companyId]/accounts/+page.svelte b/src/routes/(app)/companies/[companyId]/accounts/+page.svelte index 51b413c..7b5c5ce 100644 --- a/src/routes/(app)/companies/[companyId]/accounts/+page.svelte +++ b/src/routes/(app)/companies/[companyId]/accounts/+page.svelte @@ -143,6 +143,7 @@ creditLimit?: string | null; statementCloseDay?: number | null; paymentDueDay?: number | null; + fxRateToBase?: string | null; externalAccountId?: string | null; } = {} )} @@ -176,7 +177,20 @@ class={inputCls} /> -
+
+ + +

1.0 if same as company currency

+
{#if type === 'bank'}
@@ -891,6 +905,7 @@ creditLimit: acct.creditLimit, statementCloseDay: acct.statementCloseDay, paymentDueDay: acct.paymentDueDay, + fxRateToBase: acct.fxRateToBase, externalAccountId: acct.externalAccountId })}