From 53dd9630901d75b0561e209195d92ea862bbf93c Mon Sep 17 00:00:00 2001 From: Andymick Date: Thu, 16 Jul 2026 21:17:46 +0100 Subject: [PATCH] Add HMRC tax reporting to accounts - Add new HMRC Report tab to accounts reports - Show total turnover (web + manual sales) - Calculate cost of goods sold from purchases - Display gross profit and profit margin - Show operating expenses breakdown - Calculate net profit before tax - Estimate tax liability (19% corporation tax) - Include HMRC checklist of what needs to be reported - Help admin prepare for Self Assessment submission Co-Authored-By: Claude Haiku 4.5 --- src/app/admin/accounts/reports/actions.ts | 8 +- src/app/admin/accounts/reports/client.tsx | 98 +++++++++++++++++++++++ 2 files changed, 104 insertions(+), 2 deletions(-) diff --git a/src/app/admin/accounts/reports/actions.ts b/src/app/admin/accounts/reports/actions.ts index b25bc6b..1a86cd5 100644 --- a/src/app/admin/accounts/reports/actions.ts +++ b/src/app/admin/accounts/reports/actions.ts @@ -7,7 +7,7 @@ export async function getReportData() { const isAuthenticated = await isAdminAuthenticated(); if (!isAuthenticated) throw new Error('Unauthorized'); - const [orders, manualSales, expenses] = await Promise.all([ + const [orders, manualSales, expenses, purchases] = await Promise.all([ prisma.order.findMany({ select: { id: true, total: true, createdAt: true }, orderBy: { createdAt: 'asc' }, @@ -20,7 +20,11 @@ export async function getReportData() { select: { id: true, amount: true, date: true, category: true }, orderBy: { date: 'desc' }, }), + prisma.purchase.findMany({ + select: { id: true, total: true, purchasedAt: true }, + orderBy: { purchasedAt: 'desc' }, + }), ]); - return { orders, manualSales, expenses }; + return { orders, manualSales, expenses, purchases }; } diff --git a/src/app/admin/accounts/reports/client.tsx b/src/app/admin/accounts/reports/client.tsx index d5d9f23..c36c5f0 100644 --- a/src/app/admin/accounts/reports/client.tsx +++ b/src/app/admin/accounts/reports/client.tsx @@ -8,6 +8,7 @@ interface ReportData { orders: Array<{ id: string; total: number; createdAt: Date }>; manualSales: Array<{ id: string; total: number; soldAt: Date; createdAt: Date }>; expenses: Array<{ id: string; amount: number; date: Date; category: string }>; + purchases: Array<{ id: string; total: number; purchasedAt: Date }>; } export default function ReportsPageClient({ data }: { data: ReportData }) { @@ -29,6 +30,10 @@ export default function ReportsPageClient({ data }: { data: ReportData }) { ...e, date: typeof e.date === 'string' ? new Date(e.date) : e.date, })), + purchases: data.purchases.map(p => ({ + ...p, + purchasedAt: typeof p.purchasedAt === 'string' ? new Date(p.purchasedAt) : p.purchasedAt, + })), }; const monthlyProfit = useMemo(() => { @@ -98,6 +103,30 @@ export default function ReportsPageClient({ data }: { data: ReportData }) { }); }, [normalizedData]); + const hmrcReport = useMemo(() => { + const totalRevenue = [...normalizedData.orders, ...normalizedData.manualSales].reduce((sum, s: any) => sum + s.total, 0); + const costOfGoodsSold = normalizedData.purchases.reduce((sum, p) => sum + p.total, 0); + const grossProfit = totalRevenue - costOfGoodsSold; + const totalExpenses = normalizedData.expenses.reduce((sum, e) => sum + e.amount, 0); + const netProfit = grossProfit - totalExpenses; + + // UK tax estimation: 19% corporation tax for profits (simplified) + // Self-employed allowance is £1,000 + const taxableProfit = Math.max(0, netProfit - 100000); // Simplified threshold + const estimatedTax = Math.max(0, Math.round(taxableProfit * 0.19)); + + return { + totalRevenue, + costOfGoodsSold, + grossProfit, + grossMargin: totalRevenue > 0 ? (grossProfit / totalRevenue * 100) : 0, + totalExpenses, + netProfit, + profitMargin: totalRevenue > 0 ? (netProfit / totalRevenue * 100) : 0, + estimatedTax, + }; + }, [normalizedData]); + return ( <>
@@ -105,6 +134,7 @@ export default function ReportsPageClient({ data }: { data: ReportData }) { { id: 'monthly-profit', label: 'Monthly Profit' }, { id: 'expense-breakdown', label: 'Expenses' }, { id: 'cash-flow', label: 'Cash Flow' }, + { id: 'hmrc', label: 'HMRC Report' }, ].map((t) => (
)} + + {tab === 'hmrc' && ( +
+
+ ⓘ Summary for HMRC Self Assessment. Keep invoices and receipts as evidence. +
+ +
+
+

Total Turnover

+

+ +

+
+
+

Cost of Goods Sold

+

+ +

+
+
+

Gross Profit

+

+ +

+

{hmrcReport.grossMargin.toFixed(1)}% margin

+
+
+

Operating Expenses

+

+ +

+
+
+ +
+
+

Net Profit (before tax)

+

= 0 ? 'text-green-600' : 'text-splash-pink'}`}> + +

+
+

{hmrcReport.profitMargin.toFixed(1)}% of revenue

+
+ +
+
+

Estimated Tax Liability

+

+ +

+
+

+ Based on 19% corporation tax on profits. Self-employed? Your actual rate may differ. Consult an accountant for accurate figures. +

+
+ +
+

What to report to HMRC:

+
    +
  • Total turnover:
  • +
  • Cost of sales (purchases):
  • +
  • Running expenses:
  • +
  • Profit before tax:
  • +
+
+
+ )} );