diff --git a/app/Filament/Tenant/Widgets/FinanceOverview.php b/app/Filament/Tenant/Widgets/FinanceOverview.php index cbd1a34..b8655cd 100644 --- a/app/Filament/Tenant/Widgets/FinanceOverview.php +++ b/app/Filament/Tenant/Widgets/FinanceOverview.php @@ -33,19 +33,25 @@ class FinanceOverview extends BaseWidget Stat::make(__('Încasări (luna)'), number_format($income, 2, '.', ' ') . ' MDL') ->icon('heroicon-o-arrow-trending-up') ->color('success') - ->description(now()->translatedFormat('F Y')), + ->description(now()->translatedFormat('F Y')) + ->url(url('/app/payments')), Stat::make(__('Cheltuieli (luna)'), number_format($expenses, 2, '.', ' ') . ' MDL') ->icon('heroicon-o-arrow-trending-down') - ->color('danger'), + ->color('danger') + ->url(url('/app/expenses')), Stat::make(__('Profit (luna)'), number_format($profit, 2, '.', ' ') . ' MDL') ->icon('heroicon-o-banknotes') - ->color($profit >= 0 ? 'success' : 'danger'), + ->color($profit >= 0 ? 'success' : 'danger') + ->description(__('Vezi raportul financiar')) + ->url(url('/app/reports')), Stat::make(__('Datorii clienți'), number_format($debt, 2, '.', ' ') . ' MDL') ->icon('heroicon-o-exclamation-circle') - ->color($debt > 0 ? 'warning' : 'success'), + ->color($debt > 0 ? 'warning' : 'success') + ->description(__('Fișe cu plată în așteptare')) + ->url(url('/app/work-orders') . '?tableFilters[pay_status][value]=unpaid'), ]; } } diff --git a/app/Filament/Tenant/Widgets/LowStockTable.php b/app/Filament/Tenant/Widgets/LowStockTable.php index fd13082..e349c31 100644 --- a/app/Filament/Tenant/Widgets/LowStockTable.php +++ b/app/Filament/Tenant/Widgets/LowStockTable.php @@ -3,6 +3,7 @@ namespace App\Filament\Tenant\Widgets; use App\Models\Tenant\Part; +use Filament\Actions\Action; use Filament\Tables; use Filament\Tables\Table; use Filament\Widgets\TableWidget as BaseWidget; @@ -38,6 +39,13 @@ class LowStockTable extends BaseWidget Tables\Columns\TextColumn::make('min_qty')->label(__('Min.'))->alignRight(), Tables\Columns\TextColumn::make('preferredSupplier.name')->label(__('Furnizor'))->placeholder('—'), ]) + ->recordUrl(fn (Part $r) => url('/app/parts/' . $r->id . '/edit')) + ->actions([ + Action::make('edit') + ->label(__('Editează')) + ->icon('heroicon-m-pencil-square') + ->url(fn (Part $r) => url('/app/parts/' . $r->id . '/edit')), + ]) ->paginated(false) ->defaultSort('qty'); } diff --git a/app/Filament/Tenant/Widgets/StatsOverview.php b/app/Filament/Tenant/Widgets/StatsOverview.php index ec95979..f107b91 100644 --- a/app/Filament/Tenant/Widgets/StatsOverview.php +++ b/app/Filament/Tenant/Widgets/StatsOverview.php @@ -7,6 +7,7 @@ use App\Models\Tenant\Client; use App\Models\Tenant\Deal; use App\Models\Tenant\Lead; use App\Models\Tenant\Vehicle; +use App\Models\Tenant\WorkOrder; use Filament\Widgets\StatsOverviewWidget as BaseWidget; use Filament\Widgets\StatsOverviewWidget\Stat; @@ -19,32 +20,51 @@ class StatsOverview extends BaseWidget $newLeads = Lead::where('status', 'new')->count(); $openDeals = Deal::whereNotIn('stage', ['done', 'lost'])->count(); $todayAppointments = Appointment::whereDate('date', today())->count(); + $activeWos = WorkOrder::whereIn('status', ['in_work', 'awaiting_parts'])->count(); + $readyWos = WorkOrder::where('status', 'ready')->count(); return [ Stat::make(__('Clienți'), Client::count()) ->description(__('Total în baza de date')) ->icon('heroicon-o-users') - ->color('primary'), + ->color('primary') + ->url(url('/app/clients')), Stat::make(__('Mașini'), Vehicle::count()) ->description(__('Total înregistrate')) ->icon('heroicon-o-truck') - ->color('info'), + ->color('info') + ->url(url('/app/vehicles')), Stat::make(__('Cereri noi'), $newLeads) ->description(__('De procesat')) ->icon('heroicon-o-inbox-arrow-down') - ->color($newLeads > 0 ? 'warning' : 'success'), + ->color($newLeads > 0 ? 'warning' : 'success') + ->url(url('/app/leads') . '?tableFilters[status][value]=new'), Stat::make(__('Deal-uri active'), $openDeals) ->description(__('În pipeline')) ->icon('heroicon-o-funnel') - ->color('primary'), + ->color('primary') + ->url(url('/app/deals')), Stat::make(__('Programări azi'), $todayAppointments) ->description(today()->format('d.m.Y')) ->icon('heroicon-o-calendar') - ->color('success'), + ->color('success') + ->url(url('/app/calendar-board')), + + Stat::make(__('Fișe în lucru'), $activeWos) + ->description(__('În serviciu sau așteaptă piese')) + ->icon('heroicon-o-wrench-screwdriver') + ->color($activeWos > 0 ? 'primary' : 'success') + ->url(url('/app/work-orders') . '?tableFilters[status][value]=in_work'), + + Stat::make(__('Fișe gata predare'), $readyWos) + ->description(__('Așteaptă client')) + ->icon('heroicon-o-check-circle') + ->color($readyWos > 0 ? 'success' : 'gray') + ->url(url('/app/work-orders') . '?tableFilters[status][value]=ready'), ]; } } diff --git a/lang/en.json b/lang/en.json index a50aaab..fdbab38 100644 --- a/lang/en.json +++ b/lang/en.json @@ -276,6 +276,7 @@ "Avans achitat": "Advance paid", "Avg zile": "Avg days", "Azi": "Today", + "Așteaptă client": "Awaiting customer", "Așteaptă piese": "Awaiting parts", "Așteaptă piesele": "Awaiting parts", "Aștept aprobare client": "Awaiting client approval", @@ -854,8 +855,11 @@ "Fișa nu are client asociat.": "This work order has no client attached.", "Fișe": "Orders", "Fișe active": "Active orders", + "Fișe cu plată în așteptare": "Work orders with pending payment", "Fișe deschise": "Open orders", + "Fișe gata predare": "Ready for pickup", "Fișe lucru": "Work orders", + "Fișe în lucru": "Active work orders", "Fișe închise": "Closed orders", "Fișier": "File", "Fișier Excel (.xlsx) sau CSV *": "Excel file (.xlsx) or CSV *", @@ -2192,6 +2196,7 @@ "Vezi profit & pierdere (P&L)": "View P&L", "Vezi propriul salariu": "View own salary", "Vezi rapoarte & analitică": "View reports & analytics", + "Vezi raportul financiar": "Open financial report", "Vezi salariile tuturor": "View all salaries", "Vezi stoc (piese)": "View stock (parts)", "Vezi toate fișele": "View all orders", @@ -2525,6 +2530,7 @@ "În lucru": "In progress", "În pipeline": "In pipeline", "În procesare": "Processing", + "În serviciu sau așteaptă piese": "In service or waiting for parts", "În trial": "In trial", "Înainte": "Back", "Înapoi": "Back", diff --git a/lang/ru.json b/lang/ru.json index 260d6e9..76271ab 100644 --- a/lang/ru.json +++ b/lang/ru.json @@ -276,6 +276,7 @@ "Avans achitat": "Аванс оплачен", "Avg zile": "Ср. дней", "Azi": "Сегодня", + "Așteaptă client": "Ожидают клиента", "Așteaptă piese": "Ждёт запчасти", "Așteaptă piesele": "Ждёт запчасти", "Aștept aprobare client": "Ожидание одобрения клиента", @@ -854,8 +855,11 @@ "Fișa nu are client asociat.": "К заказ-наряду не привязан клиент.", "Fișe": "Наряды", "Fișe active": "Активные наряды", + "Fișe cu plată în așteptare": "Заказы с ожидающей оплатой", "Fișe deschise": "Открытые наряды", + "Fișe gata predare": "Готовы к выдаче", "Fișe lucru": "Рабочие листы", + "Fișe în lucru": "Заказы в работе", "Fișe închise": "Закрытые наряды", "Fișier": "Файл", "Fișier Excel (.xlsx) sau CSV *": "Файл Excel (.xlsx) или CSV *", @@ -2192,6 +2196,7 @@ "Vezi profit & pierdere (P&L)": "Просмотр P&L", "Vezi propriul salariu": "Просмотр своей зарплаты", "Vezi rapoarte & analitică": "Просмотр отчётов и аналитики", + "Vezi raportul financiar": "Открыть финансовый отчёт", "Vezi salariile tuturor": "Просмотр зарплат всех", "Vezi stoc (piese)": "Просмотр склада (запчасти)", "Vezi toate fișele": "Просмотр всех нарядов", @@ -2525,6 +2530,7 @@ "În lucru": "В работе", "În pipeline": "В воронке", "În procesare": "В обработке", + "În serviciu sau așteaptă piese": "В работе или ожидание запчастей", "În trial": "В триале", "Înainte": "Назад", "Înapoi": "Назад",