'required|string|max:255', 'apodo' => 'nullable|string|max:100', 'tax_id' => 'nullable|string|max:50|unique:companies,tax_id,', 'estado' => 'required|in:activo,inactivo,suspendido', 'address' => 'nullable|string', 'phone' => 'nullable|string|max:20', 'email' => 'nullable|email|max:255', 'website' => 'nullable|url|max:255', 'type' => 'required|in:owner,constructor,subcontractor,consultant,supplier,other', 'notes' => 'nullable|string', 'logo' => 'nullable|image|max:2048', // 2MB max ]; public function mount() { if (!Auth::user()->hasRole('Admin')) abort(403); $this->resetForm(); } public function resetForm() { $this->name = ''; $this->tax_id = ''; $this->address = ''; $this->phone = ''; $this->email = ''; $this->website = ''; $this->type = 'other'; $this->notes = ''; $this->apodo = ''; $this->estado = 'activo'; $this->logo = null; $this->editingCompanyId = null; $this->showCreateForm = false; $this->showEditForm = false; $this->resetErrorBag(); $this->resetValidation(); } public function resetFilters() { $this->search = ''; $this->filterType = ''; $this->filterEstado = ''; } public function toggleCreateForm() { $this->showCreateForm = !$this->showCreateForm; if ($this->showCreateForm) { $this->showEditForm = false; $this->resetForm(); } } public function editCompany(Company $company) { $this->editingCompanyId = $company->id; $this->name = $company->name; $this->tax_id = $company->tax_id; $this->address = $company->address; $this->phone = $company->phone; $this->email = $company->email; $this->website = $company->website; $this->type = $company->type; $this->notes = $company->notes; $this->apodo = $company->apodo; $this->estado = $company->estado; // Note: logo is not populated for security reasons $this->showEditForm = true; $this->showCreateForm = false; } public function updateCompany() { if (!Auth::user()->hasRole('Admin')) abort(403); $this->validate(); $company = Company::findOrFail($this->editingCompanyId); $data = [ 'name' => $this->name, 'tax_id' => $this->tax_id, 'address' => $this->address, 'phone' => $this->phone, 'email' => $this->email, 'website' => $this->website, 'type' => $this->type, 'notes' => $this->notes, ]; if ($this->logo) { $logoPath = $this->logo->store('company-logos', 'public'); $data['logo_path'] = $logoPath; } $company->update($data); session()->flash('message', 'Empresa actualizada correctamente.'); $this->resetForm(); } public function createCompany() { if (!Auth::user()->hasRole('Admin')) abort(403); $this->validate(); $data = [ 'name' => $this->name, 'tax_id' => $this->tax_id, 'address' => $this->address, 'phone' => $this->phone, 'email' => $this->email, 'website' => $this->website, 'type' => $this->type, 'notes' => $this->notes, ]; if ($this->logo) { $logoPath = $this->logo->store('company-logos', 'public'); $data['logo_path'] = $logoPath; } Company::create($data); session()->flash('message', 'Empresa creada correctamente.'); $this->resetForm(); } public function deleteCompany(Company $company) { if (!Auth::user()->hasRole('Admin')) abort(403); $company->delete(); // Soft delete session()->flash('message', 'Empresa eliminada correctamente.'); } public function getCompaniesProperty() { return Company::when($this->search, function ($query) { $query->where('name', 'like', '%' . $this->search . '%') ->orWhere('apodo', 'like', '%' . $this->search . '%') ->orWhere('tax_id', 'like', '%' . $this->search . '%'); }) ->when($this->filterType, function ($query) { $query->where('type', $this->filterType); }) ->when($this->filterEstado, function ($query) { $query->where('estado', $this->filterEstado); }) ->withCount('projects') // Eager load project count ->orderBy('name') ->get(); } public function exportCsv() { $companies = $this->getCompaniesProperty(); // Create CSV content $headers = [ "Content-type: text/csv", "Content-Disposition: attachment; filename=empresas.csv", "Pragma: no-cache", "Cache-Control: must-revalidate, post-check=0, pre-check=0", "Expires: 0" ]; $callback = function() use ($companies) { $handle = fopen('php://output', 'w'); // Add BOM for UTF-8 in Excel fprintf($handle, chr(0xEF).chr(0xBB).chr(0xBF)); // Header row fputcsv($handle, ['Nombre', 'Apodo', 'NIF/Tax ID', 'Tipo', 'Estado', 'Dirección', 'Teléfono', 'Email', 'Website', 'Proyectos Asociados', 'Fecha Creación']); foreach ($companies as $company) { fputcsv($handle, [ $company->name, $company->apodo ?? '', $company->tax_id ?? '', $company->type, $company->estado, $company->address ?? '', $company->phone ?? '', $company->email ?? '', $company->website ?? '', $company->projects_count ?? 0, $company->created_at ? $company->created_at->format('d/m/Y H:i') : '' ]); } fclose($handle); }; return response()->stream($callback, 200, $headers); } public function render() { return view('livewire.company-management'); } }