diff --git a/app/Livewire/CompanyManagement.php b/app/Livewire/CompanyManagement.php new file mode 100644 index 0000000..3b47d23 --- /dev/null +++ b/app/Livewire/CompanyManagement.php @@ -0,0 +1,236 @@ + '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() + { + $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() + { + $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() + { + $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) + { + $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'); + } +} \ No newline at end of file diff --git a/app/Models/Company.php b/app/Models/Company.php index 0d8ed7a..0b4c943 100644 --- a/app/Models/Company.php +++ b/app/Models/Company.php @@ -10,6 +10,9 @@ class Company extends Model use HasFactory; protected $fillable = [ + 'apodo', + 'estado', + 'logo_path', 'name', 'tax_id', 'address', diff --git a/database/migrations/2026_05_26_115830_add_logo_path_to_companies_table.php b/database/migrations/2026_05_26_115830_add_logo_path_to_companies_table.php new file mode 100644 index 0000000..d3b6455 --- /dev/null +++ b/database/migrations/2026_05_26_115830_add_logo_path_to_companies_table.php @@ -0,0 +1,28 @@ +string('logo_path')->nullable()->after('notes'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('companies', function (Blueprint $table) { + $table->dropColumn('logo_path'); + }); + } +}; \ No newline at end of file diff --git a/database/migrations/2026_05_26_135412_add_apodo_and_estado_to_companies_table.php b/database/migrations/2026_05_26_135412_add_apodo_and_estado_to_companies_table.php new file mode 100644 index 0000000..a73ff95 --- /dev/null +++ b/database/migrations/2026_05_26_135412_add_apodo_and_estado_to_companies_table.php @@ -0,0 +1,29 @@ +string('apodo')->nullable()->after('name'); + $table->enum('estado', ['activo', 'inactivo', 'suspendido'])->default('activo')->after('apodo'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('companies', function (Blueprint $table) { + $table->dropColumn(['apodo', 'estado']); + }); + } +}; \ No newline at end of file diff --git a/resources/views/livewire/company-management.blade.php b/resources/views/livewire/company-management.blade.php new file mode 100644 index 0000000..a06ec8d --- /dev/null +++ b/resources/views/livewire/company-management.blade.php @@ -0,0 +1,327 @@ +
Gestione las empresas que participan en los proyectos
++ Complete la información de la empresa. Los campos marcados con * son obligatorios. +
+No hay empresas registradas. Cree su primera empresa usando el botón de arriba.
++ @if($company->tax_id) + {{ $company->tax_id }} + @else + Sin NIF/CIF + @endif +
+ @if($company->type) + + {{ ucfirst($company->type) }} + + @endif +