@extends('layouts.app') @section('title', 'Profit & Loss - ' . setting('system_name')) @section('content') @php $money = fn ($v, $d = 0) => $currency . ' ' . number_format((float) $v, $d); $netProfitStatus = $netProfit < 0 ? 'danger' : ($netMargin >= 15 ? 'success' : ($netMargin >= 5 ? 'warning' : 'danger')); $grossMarginStatus = $grossMargin >= 30 ? 'success' : ($grossMargin >= 20 ? 'warning' : 'danger'); $canRecordExpenses = auth()->user()->hasPermission('add_expense') || auth()->user()->hasPermission('access_all_expenses'); $expensesUrl = route('expenses.index', ['from' => $fromDateDisplay, 'to' => $toDateDisplay]); @endphp {{-- Change against the previous period; null means there is nothing to compare with --}} @php $delta = function ($value, $onDark = false) use ($comparisonLabel) { if ($value === null) { return 'No earlier data to compare'; } $up = $value >= 0; $cls = $onDark ? 'bg-white text-dark' : ($up ? 'bg-success-subtle text-success' : 'bg-danger-subtle text-danger'); return ' ' . abs($value) . '% ' . e($comparisonLabel) . ''; }; @endphp
{{ $fromDateLabel }} – {{ $toDateLabel }} · {{ setting('system_name') }}
| Sales revenue ({{ number_format($totalTransactions) }} sales) | {{ $money($totalSales, 2) }} |
| Less: cost of goods sold | − {{ $money($costOfGoodsSold, 2) }} |
| Gross profit ({{ $grossMargin }}%) | {{ $money($grossProfit, 2) }} |
| Less: stock written off | − {{ $money($stockWrittenOff, 2) }} |
| {{ $reason }} | {{ $money($amount, 2) }} |
| Less: running costs | − {{ $money($operatingExpenses, 2) }} |
| {{ $category }} | {{ $money($amount, 2) }} |
| Net profit ({{ $netMargin }}%) | {{ $money($netProfit, 2) }} |
Cost of goods uses the purchase price recorded at the time of each sale. Written-off stock is valued at its purchase price.
| Product | Sold | Sales | Profit | Margin |
|---|---|---|---|---|
| {{ $product['name'] }} | {{ number_format($product['qty']) }} | {{ $money($product['revenue']) }} | {{ $money($product['profit']) }} | {{ $product['margin'] }}% |
| No sales in this period. | ||||
Split payments are counted per method; change given back is excluded.
@if(count($paymentBreakdown))| {{ $row['method'] }} | {{ $row['count'] }} {{ $row['count'] == 1 ? 'payment' : 'payments' }} | {{ $money($row['total']) }} |
No payments in this period.
@endifNo sales in this period.
@endforelse| At start ({{ \Carbon\Carbon::parse($fromDateDisplay)->format('d M') }}) | {{ $money($openingStockCost) }} |
| + Received | {{ $money($stockReceived) }} |
| − Sold (at cost) | {{ $money($costOfGoodsSold) }} |
| − Written off | {{ $money($stockWrittenOff) }} |
| {{ $otherStockChanges > 0 ? '+' : '−' }} Other changes | {{ $money(abs($otherStockChanges)) }} |
| At end ({{ \Carbon\Carbon::parse($toDateDisplay)->format('d M') }}) | {{ $money($closingStockCost) }} |
{{ $money($slowMovingValue) }} of cash is tied up in stock that has not sold in 30 days.
| {{ $item->name }} | {{ number_format($item->current_stock) }} units | {{ $money($item->current_stock * $item->purchase_price) }} |
| Everything in stock has sold in the last 30 days. |