Files
autocrm/app/Filament/Tenant/Pages/ExcelImportWizard.php
T
Vasyka 29e5481fc3 refactor(nav): collapse single-item groups + fix ungrouped CRM resources
Previously nav had 12 groups, several with just 1 item. Now 8 clean
groups, no orphans:

- Anvelope (1 item) → merged into Service (Seturi anvelope)
- Stoc & Finanțe (1 item) → merged into Depozit (Import factură Excel)
- Tinichigerie (1 item) → merged into Service (Tinichigerie / Detailing)
- Subcontractare (2 items) → merged into Service (Lucrări terți,
  Subcontractori)
- Integrări moved from Marketing → Admin (it's a config concern, not
  a marketing feature)
- ClientResource + VehicleResource were ungrouped → added to CRM

Final groups:
  Admin(8) · Analiză(4) · CRM(5) · Depozit(10) · Finanțe(6) ·
  Magazin(2) · Marketing(3) · Service(11)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-08-10 19:29:03 +00:00

155 lines
4.8 KiB
PHP

<?php
namespace App\Filament\Tenant\Pages;
use App\Models\Tenant\Supplier;
use App\Services\ExcelInvoiceImportService;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Illuminate\Support\Facades\Storage;
use Livewire\WithFileUploads;
class ExcelImportWizard extends Page
{
use WithFileUploads;
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-arrow-up-tray';
public static function getNavigationLabel(): string
{
return __('nav.label.Import factură Excel');
}
public static function getNavigationGroup(): ?string
{
return __('nav.group.Depozit');
}
protected static ?int $navigationSort = 65;
protected static ?string $title = null;
public function getTitle(): string
{
return __('Import factură Excel/CSV');
}
protected string $view = 'filament.tenant.pages.excel-import-wizard';
public int $step = 1;
public ?int $supplierId = null;
public $upload = null;
public ?string $storedPath = null;
public array $headersPreview = ['columns' => [], 'rows' => []];
public array $mapping = [
'article_col' => 'B',
'name_col' => 'C',
'qty_col' => 'E',
'price_col' => 'F',
'brand_col' => null,
'header_row' => 1,
];
public bool $rememberMapping = true;
public array $previewRows = [];
public array $previewSummary = ['total' => 0, 'found' => 0, 'new' => 0, 'no_article' => 0];
public bool $createNew = true;
public function getMaxContentWidth(): \Filament\Support\Enums\Width
{
return \Filament\Support\Enums\Width::Full;
}
public function getSupplierOptions(): array
{
return Supplier::orderBy('name')->pluck('name', 'id')->toArray();
}
public function goToStep2(): void
{
if (! $this->supplierId) {
Notification::make()->title(__('Selectează furnizorul'))->danger()->send();
return;
}
if (! $this->upload) {
Notification::make()->title(__('Încarcă fișierul Excel sau CSV'))->danger()->send();
return;
}
// Persist the uploaded file so Livewire reuses can resolve it
$this->storedPath = $this->upload->store('imports', 'local');
// Try to load remembered mapping for this supplier
$svc = app(ExcelInvoiceImportService::class);
$supplier = Supplier::find($this->supplierId);
$remembered = $svc->rememberedMappingFor($supplier);
if ($remembered) {
$this->mapping = array_merge($this->mapping, $remembered);
}
$absPath = Storage::disk('local')->path($this->storedPath);
$this->headersPreview = $svc->headersPreview($absPath);
$this->step = 2;
}
public function goToStep3(): void
{
$absPath = Storage::disk('local')->path($this->storedPath);
$svc = app(ExcelInvoiceImportService::class);
$result = $svc->preview($absPath, $this->mapping);
$this->previewRows = $result['rows'];
$this->previewSummary = $result['summary'];
if (empty($this->previewRows)) {
Notification::make()->title(__('Nu am găsit linii valide — verifică maparea coloanelor'))->warning()->send();
return;
}
$this->step = 3;
}
public function confirmImport(): void
{
$svc = app(ExcelInvoiceImportService::class);
$supplier = Supplier::find($this->supplierId);
if ($this->rememberMapping) {
$svc->rememberMapping($supplier, $this->mapping, basename($this->storedPath ?? ''));
}
$purchase = $svc->import($supplier, $this->previewRows, $this->createNew);
Notification::make()
->title("Import reușit — Purchase {$purchase->number}")
->body("{$this->previewSummary['total']} linii importate")
->success()
->send();
// Cleanup uploaded file
if ($this->storedPath) {
Storage::disk('local')->delete($this->storedPath);
}
$this->step = 4;
$this->dispatch('purchase-created', purchaseId: $purchase->id);
// Set the redirect URL on the page so the blade can show a CTA
session()->flash('purchase_id', $purchase->id);
}
public function reset_(): void
{
$this->step = 1;
$this->supplierId = null;
$this->upload = null;
$this->storedPath = null;
$this->headersPreview = ['columns' => [], 'rows' => []];
$this->mapping = [
'article_col' => 'B', 'name_col' => 'C', 'qty_col' => 'E',
'price_col' => 'F', 'brand_col' => null, 'header_row' => 1,
];
$this->previewRows = [];
$this->previewSummary = ['total' => 0, 'found' => 0, 'new' => 0, 'no_article' => 0];
}
}