diff --git a/src/data/mockStore.jsx b/src/data/mockStore.jsx index 0382e58..f10e536 100644 --- a/src/data/mockStore.jsx +++ b/src/data/mockStore.jsx @@ -2011,6 +2011,8 @@ const MOCK_PROJECTS = [ spent: 22500, variancePercent: -50.0, margin: 0.40, + commission: 4500, + additionalExpenses: 1200, startDate: '2026-01-20', endDate: '2026-03-05', completionPercentage: 55, @@ -2084,6 +2086,8 @@ const MOCK_PROJECTS = [ spent: 8500, variancePercent: 0, margin: 0.35, + commission: 850, + additionalExpenses: 350, startDate: '2025-11-15', endDate: '2025-12-10', completionPercentage: 100, @@ -2130,6 +2134,8 @@ const MOCK_PROJECTS = [ spent: 18400, variancePercent: -42.5, margin: 0.30, + commission: 3200, + additionalExpenses: 900, startDate: '2026-01-06', endDate: '2026-02-28', completionPercentage: 42, @@ -2202,6 +2208,8 @@ const MOCK_PROJECTS = [ spent: 62300, variancePercent: 13.3, margin: -0.13, + commission: 5500, + additionalExpenses: 3800, startDate: '2025-12-01', endDate: '2026-02-28', completionPercentage: 78, @@ -2285,6 +2293,8 @@ const MOCK_PROJECTS = [ spent: 14200, variancePercent: -49.3, margin: 0.25, + commission: 2800, + additionalExpenses: 600, startDate: '2026-01-06', endDate: '2026-02-20', completionPercentage: 38, @@ -2355,6 +2365,8 @@ const MOCK_PROJECTS = [ spent: 5600, variancePercent: -69.7, margin: 0.38, + commission: 1850, + additionalExpenses: 450, startDate: '2026-02-03', endDate: '2026-03-15', completionPercentage: 22, @@ -2404,6 +2416,8 @@ const MOCK_PROJECTS = [ spent: 48000, variancePercent: -61.6, margin: 0.35, + commission: 12500, + additionalExpenses: 2800, startDate: '2026-01-27', endDate: '2026-04-15', completionPercentage: 32, @@ -2495,6 +2509,8 @@ const MOCK_PROJECTS = [ spent: 91500, variancePercent: 22.0, margin: -0.22, + commission: 7500, + additionalExpenses: 4200, startDate: '2025-11-18', endDate: '2026-02-28', completionPercentage: 88, @@ -2542,6 +2558,8 @@ const MOCK_PROJECTS = [ budget: 42000, spent: 25800, margin: 0.28, + commission: 4200, + additionalExpenses: 1100, startDate: '2026-01-13', endDate: '2026-03-10', completionPercentage: 50, @@ -2587,6 +2605,8 @@ const MOCK_PROJECTS = [ budget: 35000, spent: 35000, margin: 0.30, + commission: 3500, + additionalExpenses: 800, startDate: '2025-09-15', endDate: '2025-10-28', completionPercentage: 100, @@ -2632,6 +2652,8 @@ const MOCK_PROJECTS = [ budget: 95000, spent: 68400, margin: 0.20, + commission: 9500, + additionalExpenses: 5200, startDate: '2025-12-08', endDate: '2026-03-20', completionPercentage: 62, @@ -2685,6 +2707,8 @@ const MOCK_PROJECTS = [ budget: 58000, spent: 22600, margin: 0.32, + commission: 5800, + additionalExpenses: 1500, startDate: '2026-01-13', endDate: '2026-04-01', completionPercentage: 28, diff --git a/src/pages/owner/OwnerProjectDetail.jsx b/src/pages/owner/OwnerProjectDetail.jsx index 1a61d7d..2f52522 100644 --- a/src/pages/owner/OwnerProjectDetail.jsx +++ b/src/pages/owner/OwnerProjectDetail.jsx @@ -12,7 +12,7 @@ import { ArrowLeft, CheckCircle, Clock, AlertTriangle, PauseCircle, ShieldAlert, FileText, DollarSign, GitPullRequest, AlertCircle, Activity, Milestone, Shield, ChevronRight, Phone, MessageSquare, Mail, AlertOctagon, TrendingUp, Key, Zap, Camera, Plus, Map, User, Crosshair, Image as ImageIcon, MapPin, - Upload, Trash2, Eye, Pencil, X as XIcon, FolderOpen, Download, File, StickyNote, Banknote, ChevronLeft, ChevronDown as ChevronDownIcon + Upload, Trash2, Eye, Pencil, X as XIcon, FolderOpen, Download, File, StickyNote, Banknote, ChevronLeft, ChevronDown as ChevronDownIcon, Info } from 'lucide-react'; import ChangeOrderDrawer from '../../components/owner/ChangeOrderDrawer'; import InvoiceDetailModal from '../../components/owner/InvoiceDetailModal'; @@ -220,6 +220,18 @@ const OwnerProjectDetail = () => { projects.find(p => p.id === projectId && p.ownerId === user?.id) , [projects, projectId, user]); + const profitMetrics = useMemo(() => { + if (!project) return { totalCosts: 0, commission: 0, additionalExp: 0, grossProfit: 0, netProfit: 0, grossMargin: 0, netMargin: 0 }; + const totalCosts = Number(project.actualCost ?? project.spent) || 0; + const commission = Number(project.commission) || 0; + const additionalExp = Number(project.additionalExpenses) || 0; + const gross = totalReceived - totalCosts; + const net = gross - commission - additionalExp; + const grossMargin = totalReceived > 0 ? (gross / totalReceived) * 100 : 0; + const netMargin = totalReceived > 0 ? (net / totalReceived) * 100 : 0; + return { totalCosts, commission, additionalExp, grossProfit: gross, netProfit: net, grossMargin, netMargin }; + }, [project, totalReceived]); + if (!project) { return (
Gross Profit Formula
+Total Received − Total Actual Costs
+{formatCurrency(totalReceived)} − {formatCurrency(profitMetrics.totalCosts)}
+= {formatCurrency(profitMetrics.grossProfit)}
+Net Profit Formula
+Gross Profit − Commission − Addl. Expenses
+{formatCurrency(profitMetrics.grossProfit)} − {formatCurrency(profitMetrics.commission)} − {formatCurrency(profitMetrics.additionalExp)}
+= {formatCurrency(profitMetrics.netProfit)}
+