@extends('layouts.app') @section('title', __('Billing')) @section('content') @php use Illuminate\Support\Carbon; use App\Models\FileAnalysis; use App\Models\TenantMonthlyInvoice; $tenantId = $tenant?->id ?? 0; // --- Period filter --------------------------------------------------- $monthParam = request('month'); try { $period = $monthParam ? Carbon::createFromFormat('Y-m', $monthParam)->startOfMonth() : Carbon::now()->startOfMonth(); } catch (\Throwable $e) { $period = Carbon::now()->startOfMonth(); } $periodStart = $period->copy()->startOfMonth(); $periodEnd = $period->copy()->endOfMonth(); // --- Approved analyses for this period (admin-reviewed, sent to client) $hasBillable = \Illuminate\Support\Facades\Schema::hasColumn('file_analyses', 'billable_amount'); $hasReviewed = \Illuminate\Support\Facades\Schema::hasColumn('file_analyses', 'reviewed_at'); $approvedCol = $hasReviewed ? 'reviewed_at' : 'finished_at'; $analyses = FileAnalysis::query() ->with(['submission.uploader', 'reviewer']) ->where('tenant_id', $tenantId) ->where('status', FileAnalysis::STATUS_DONE) ->whereBetween($approvedCol, [$periodStart, $periodEnd]) ->orderByDesc($approvedCol) ->paginate(25) ->withQueryString(); // --- Period stats ---------------------------------------------------- $totalApproved = FileAnalysis::query() ->where('tenant_id', $tenantId) ->where('status', FileAnalysis::STATUS_DONE) ->whereBetween($approvedCol, [$periodStart, $periodEnd]) ->count(); $billable = $hasBillable ? (float) FileAnalysis::query() ->where('tenant_id', $tenantId) ->where('status', FileAnalysis::STATUS_DONE) ->whereBetween($approvedCol, [$periodStart, $periodEnd]) ->sum('billable_amount') : 0.0; $billedCount = $hasBillable ? FileAnalysis::query() ->where('tenant_id', $tenantId) ->where('status', FileAnalysis::STATUS_DONE) ->whereBetween($approvedCol, [$periodStart, $periodEnd]) ->whereNotNull('billed_invoice_id') ->count() : 0; $unbilledCount = max(0, $totalApproved - $billedCount); $freeAllowance = \Illuminate\Support\Facades\Schema::hasColumn('tenants', 'free_analyses_per_month') ? (int) ($tenant?->free_analyses_per_month ?? config('subscriptions.usage.free_analyses_per_month', 0)) : (int) config('subscriptions.usage.free_analyses_per_month', 0); $freeRemaining = max(0, $freeAllowance - $totalApproved); // --- Month picker options -------------------------------------------- $monthOptions = []; $cursor = Carbon::now()->startOfMonth(); for ($i = 0; $i < 12; $i++) { $monthOptions[$cursor->format('Y-m')] = $cursor->translatedFormat('F Y'); $cursor->subMonthNoOverflow(); } // --- Invoice for this period (if any) -------------------------------- $invoice = TenantMonthlyInvoice::query() ->where('tenant_id', $tenantId) ->whereDate('period_start', $periodStart->toDateString()) ->first(); @endphp {{-- Header --}}
{{ __('Every approved analysis adds a line to the monthly invoice.') }}
{{ $period->translatedFormat('F Y') }} — {{ __('reviewed and sent to clients.') }}
{{ __('No approved analyses in this period.') }}
| {{ __('File') }} | {{ __('Approved at') }} | {{ __('Amount') }} | {{ __('Status') }} | |
|---|---|---|---|---|
|
{{ $a->submission?->original_name ?? '—' }}
{{ optional($a->submission?->uploader)->name ?? '—' }}
|
{{ $approvedAt?->format('Y-m-d H:i') ?? '—' }} | @if(! is_null($amount)) {{ number_format($amount, 2, ',', ' ') }} {{ $currency }} @else — @endif | @if($billed) {{ __('Billed') }} @else {{ __('Pending') }} @endif | @if($a->submission) {{ __('View') }} → @endif |
{{ __('Only approved analyses sent to clients are billable. Failed runs and re-runs are excluded.') }}
@endsection