year = (int) now()->year; $this->period = (string) now()->month; } private function trackedFor(Category $category): float { $query = $category->transactions()->whereYear('date_effective', $this->year); if ($this->period !== 'year') { $query->whereMonth('date_effective', (int) $this->period); } return (float) $query->sum('amount'); } public function render() { $household = auth()->user()->currentHousehold; $revenueCategories = $household->categories()->where('type', CategoryType::Revenu)->orderBy('position')->get(); $totalRevenue = $revenueCategories->sum(fn (Category $c) => $this->trackedFor($c)); $outflowCategories = $household->categories() ->whereIn('type', [CategoryType::Depense, CategoryType::Epargne]) ->orderBy('type') ->orderBy('position') ->get() ->map(fn (Category $category) => [ 'category' => $category, 'tracked' => $this->trackedFor($category), ]) ->filter(fn ($row) => $row['tracked'] > 0) ->values(); $totalOutflow = $outflowCategories->sum('tracked'); $unallocated = max(0, $totalRevenue - $totalOutflow); $flows = $outflowCategories->map(fn ($row) => [ 'from' => 'Revenus', 'to' => $row['category']->name, 'flow' => (float) $row['tracked'], 'type' => $row['category']->type->value, ]); if ($unallocated > 0) { $flows->push([ 'from' => 'Revenus', 'to' => 'Non affecté', 'flow' => $unallocated, 'type' => 'unallocated', ]); } return view('livewire.sankey.index', [ 'flows' => $flows->values(), 'totalRevenue' => $totalRevenue, 'totalOutflow' => $totalOutflow, 'unallocated' => $unallocated, 'hasData' => $totalRevenue > 0, ]); } }