@php $logs = $this->logs; @endphp
{{-- Filter bar --}}
{{-- Table with loading overlay --}}
Loading…
{{-- Column shading: calc-col gets the indigo tint; lowest CSS specificity so row/hover backgrounds win --}} {{-- timestamp --}} {{-- product --}} {{-- channel --}} {{-- rule --}} {{-- cost --}} {{-- postage --}} {{-- markup --}} {{-- channel fee --}} {{-- vat --}} {{-- final price --}} {{-- margin --}} {{-- trigger --}} @forelse($logs as $log) @php $zeroCostRow = (float) $log->cost_price === 0.0; $markupPct = $log->markup_percentage !== null ? (float) $log->markup_percentage : ((! $zeroCostRow && $log->markup_applied !== null) ? ($log->markup_applied / $log->cost_price) * 100 : null); $taxRate = (float) ($log->tax_rate_applied ?? 0); $exTax = $taxRate > 0 ? $log->final_price / (1 + $taxRate / 100) : $log->final_price; $taxAmount = $taxRate > 0 ? round($log->final_price - $exTax, 2) : 0.0; // Fees — must be split before margin is computed $feesData = is_string($log->fees_applied) ? json_decode($log->fees_applied, true) : (array) ($log->fees_applied ?? []); $feeLines = $feesData['fee_lines'] ?? []; $platformFeeLines = []; $postageFee = 0.0; foreach ($feeLines as $fl) { $flLabel = $fl['label'] ?? ''; if (str_starts_with($flLabel, 'Postage')) { $postageFee += (float) $fl['amount']; } else { $short = match(true) { str_contains($flLabel, 'Regulatory') => 'Reg', str_contains($flLabel, 'FVF') => 'FVF', str_contains($flLabel, 'Fixed') => 'Fix', str_contains($flLabel, 'Processing') => 'Fee', default => 'Fee', }; $platformFeeLines[] = ['short' => $short, 'amount' => (float) $fl['amount']]; } } $platformFee = array_sum(array_column($platformFeeLines, 'amount')); // Detect Option B (markup on landed cost): when active the engine // sets markup_applied = (cost + postage) × pct, so the implied // base is larger than cost alone. Tolerance of £0.05 covers rounding. $impliedBase = ($markupPct !== null && $markupPct > 0 && $log->markup_applied !== null) ? ((float) $log->markup_applied / $markupPct * 100) : null; $isLandedCostMarkup = $impliedBase !== null && $postageFee > 0 && abs($impliedBase - ((float) $log->cost_price + $postageFee)) < 0.05; // Product margin: markup as a share of the inc-VAT selling price. // Accounts for channel fees and VAT because both inflate the denominator. // For fixed-price rows (markup_applied is null) fall back to a // best-effort formula using the fee breakdown. if (! $zeroCostRow && $log->markup_applied !== null) { $finalPriceVal = (float) $log->final_price; $margin = $finalPriceVal > 0 ? ((float) $log->markup_applied / $finalPriceVal) * 100 : null; } elseif (! $zeroCostRow && $exTax > 0) { $productRevenue = $exTax - $postageFee; $margin = $productRevenue > 0 ? (($productRevenue - (float) $log->cost_price - $platformFee) / $productRevenue) * 100 : null; } else { $margin = null; } $triggerStyles = [ 'cost_change' => 'background:#fffbeb;color:#b45309;', 'rule_change' => 'background:#eff6ff;color:#1d4ed8;', 'fee_profile_change' => 'background:#f0fdf4;color:#15803d;', 'manual' => 'background:#f3f4f6;color:#4b5563;', 'manual_fixed' => 'background:#f5f3ff;color:#7c3aed;', ]; $triggerLabels = [ 'cost_change' => 'Cost change', 'rule_change' => 'Rule change', 'fee_profile_change' => 'Fee change', 'manual' => 'Manual', 'manual_fixed' => 'Fixed price', ]; $triggerStyle = $triggerStyles[$log->triggered_by] ?? 'background:#f3f4f6;color:#4b5563;'; $triggerLabel = $triggerLabels[$log->triggered_by] ?? $log->triggered_by; $ts = \Carbon\Carbon::parse($log->calculated_at); @endphp {{-- Timestamp --}} {{-- Product --}} {{-- Channel --}} {{-- Rule matched --}} {{-- Cost (calc group) --}} {{-- Postage (calc group) --}} {{-- Markup £ + % stacked (calc group) --}} {{-- Channel Fee (calc group) --}} {{-- VAT (calc group) --}} {{-- Final price --}} {{-- Margin % --}} {{-- Trigger --}} @empty @endforelse
Timestamp Product Channel Rule matched Cost Postage Markup Channel Fee VAT Final price (inc tax) Margin %
of sale price, after fees
Trigger
{{ $ts->format('H:i:s') }}
{{ $ts->format('d/m/Y') }}
{{ $log->product_name }}
{{ $log->product_sku }}
{{ $log->channel_name ?? "Channel #{$log->channel_id}" }}
{{ $log->rule_name ?? '—' }}
@if($log->rule_id)
PR-{{ str_pad($log->rule_id, 3, '0', STR_PAD_LEFT) }}
@endif
@if($zeroCostRow) £0.00 @else £{{ number_format($log->cost_price, 2) }} @endif @if($postageFee > 0) +£{{ number_format($postageFee, 2) }} @else — @endif @if($log->markup_applied !== null) @if($markupPct !== null)
{{ number_format($markupPct, 1) }}%
@endif @if($isLandedCostMarkup)
postage included
@endif
+£{{ number_format($log->markup_applied, 2) }}
@elseif($zeroCostRow) n/a @else — @endif
@if(count($platformFeeLines) > 0)
@foreach($platformFeeLines as $feeLine)
{{ $feeLine['short'] }} +£{{ number_format($feeLine['amount'], 2) }}
@endforeach
TTL +£{{ number_format($platformFee, 2) }}
@else — @endif
@if($taxRate > 0)
{{ number_format($taxRate, 0) }}%
+£{{ number_format($taxAmount, 2) }}
@else — @endif
£{{ number_format($log->final_price, 2) }} @if($margin !== null) @php $marginClass = $margin < 0 ? 'text-red-600 font-semibold' : ($margin < 5 ? 'text-red-400' : ($margin < 10 ? 'text-amber-600' : 'text-gray-700 dark:text-gray-300')); @endphp {{ number_format($margin, 1) }}% @elseif($zeroCostRow) n/a @else — @endif {{ $triggerLabel }}
No calculation logs found for the selected filters.
{{-- Pagination footer --}}
Showing {{ $logs->firstItem() ?? 0 }}–{{ $logs->lastItem() ?? 0 }} of {{ number_format($logs->total()) }} entries (page {{ $logs->currentPage() }} of {{ $logs->lastPage() }})
{{-- CSV export --}}