*/ public array $fornitoriOptions = []; // Main view navigation: 'elenco' or 'scheda' public string $mainTab = 'elenco'; // Sub-tab inside the Scheda detail view (reproducing TecnoRepair desktop tabs) public string $schedaSubTab = 'entrata'; public ?int $selectedRowId = null; public ?string $selectedRowType = null; // 'tecnorepair' or 'ticket' /** @var array|null */ public ?array $activeScheda = null; /** @var array Editable form fields for active scheda */ public array $schedaForm = []; /** @var array 3x3 pattern unlock grid nodes */ public array $unlockPattern = [0, 0, 0, 0, 0, 0, 0, 0, 0]; // Quick workflow inputs public string $workflowNote = ''; public string $workflowRmaCode = ''; // Filter properties public string $scope = 'tutte'; public string $search = ''; public string $filterStato = ''; public string $filterOrigine = ''; public string $dataDa = ''; public string $dataA = ''; /** @var array> */ public array $rows = []; /** @var array */ public array $totals = [ 'tutte' => 0, 'aperte' => 0, 'chiuse' => 0, 'ticket_amministratore' => 0, 'interne' => 0, ]; // Legacy modal compatibility public ?array $detailModal = null; public static function canAccess(): bool { $user = Auth::user(); return $user instanceof User && $user->hasAnyRole(['super-admin', 'admin', 'amministratore', 'collaboratore', 'fornitore']); } public function mount(): void { $this->scope = (string) request()->query('scope', 'tutte'); [$fornitore] = $this->resolveOperatoreContext(allowAdminWithoutSupplier: true); if (! $fornitore instanceof Fornitore) { $fornitore = Fornitore::query()->where('partita_iva', '10055221005')->first() ?? Fornitore::query()->orderBy('id')->first(); } if (! $fornitore instanceof Fornitore) { $this->missingAdminContext = true; return; } $this->fornitoreId = (int) $fornitore->id; $this->fornitoreLabel = $this->getFornitoreLabel($fornitore); $user = Auth::user(); if ($this->isInternalOperator($user)) { $this->fornitoriOptions = Fornitore::query() ->where(function ($q) { $q->whereHas('ticketInterventi') ->orWhere('partita_iva', '10055221005') ->orWhere('partita_iva', '14001151001') ->orWhereIn('id', [236, 359, 392]); }) ->orderBy('ragione_sociale') ->get() ->mapWithKeys(fn(Fornitore $f): array => [ (int) $f->id => trim((string) ($f->ragione_sociale ?: ('Fornitore #' . $f->id))) . ($f->partita_iva ? ' (' . $f->partita_iva . ')' : ''), ]) ->all(); } $this->refreshData(); } public function updatedFornitoreId(): void { $fornitore = Fornitore::query()->find((int) $this->fornitoreId); if ($fornitore instanceof Fornitore) { $this->fornitoreLabel = $this->getFornitoreLabel($fornitore); $this->closeScheda(); $this->refreshData(); } } public function updatedScope(): void { $this->refreshData(); } public function setScope(string $scope): void { $this->scope = $scope; $this->mainTab = 'elenco'; $this->refreshData(); } public function setMainTab(string $tab): void { $this->mainTab = in_array($tab, ['elenco', 'scheda'], true) ? $tab : 'elenco'; } public function setSchedaSubTab(string $subTab): void { $this->schedaSubTab = $subTab; } public function resetFiltri(): void { $this->search = ''; $this->filterStato = ''; $this->filterOrigine = ''; $this->dataDa = ''; $this->dataA = ''; $this->scope = 'tutte'; $this->refreshData(); } public function refreshData(): void { if (! $this->fornitoreId) { $this->rows = []; return; } [$fornitore, $dipendente] = $this->resolveOperatoreContext($this->fornitoreId); if (! $fornitore instanceof Fornitore) { $fornitore = Fornitore::query()->find($this->fornitoreId); } if (! $fornitore instanceof Fornitore) { $this->rows = []; return; } $baseQuery = $this->buildBaseQuery($fornitore, $dipendente); $ticketCount = (clone $baseQuery)->count(); $tecnorepairCount = $this->buildTecnorepairQuery($fornitore)->count(); $this->totals = [ 'tutte' => $ticketCount + $tecnorepairCount, 'aperte' => 0, 'chiuse' => 0, 'ticket_amministratore' => $ticketCount, 'interne' => 0, ]; if ($this->scope === 'interne') { $this->rows = []; return; } $ticketRows = $baseQuery ->limit(150) ->get() ->map(function (TicketIntervento $intervento): array { $base = $this->buildInterventoRow($intervento); $isClosed = $this->isClosedStatus((string) $intervento->stato); return array_merge($base, [ 'row_type' => 'ticket', 'row_class' => $this->resolveTicketRowClass((string) $intervento->stato), 'badge_class' => $this->resolveTicketBadgeClass((string) $intervento->stato), 'row_color' => $isClosed ? 'green' : 'blue', 'is_closed' => $isClosed, 'numero' => (string) $intervento->ticket_id, 'numero_scheda'=> (string) $intervento->ticket_id, 'cliente' => $base['contatto'], 'difetto' => $base['problema'], 'brand' => $this->extractDeviceBrand($base['apparato']), 'modello' => $base['apparato'], 'seriale' => '-', 'cod_prodotto' => '-', 'id' => (int) $intervento->id, 'ticket_id' => (int) $intervento->ticket_id, 'titolo' => (string) ($intervento->ticket->titolo ?? '-'), 'stato' => (string) $intervento->stato, 'status_code' => (string) $intervento->stato, 'stabile' => (string) ($intervento->ticket->stabile->denominazione ?? '-'), 'operatore' => (string) $intervento->operatore_assegnato_label, 'tempo_minuti' => (int) ($intervento->tempo_minuti ?? 0), 'updated_at' => optional($intervento->updated_at)->format('d/m/Y H:i') ?: '-', 'sort_at' => optional($intervento->created_at)->format('Y-m-d H:i:s') ?: '1970-01-01 00:00:00', 'origine' => 'Ticket amministratore', 'url' => TicketInterventoScheda::getUrl(['record' => (int) $intervento->id], panel: 'admin-filament'), ]); }) ->all(); $rows = array_merge($ticketRows, $this->buildTecnorepairRows($fornitore)); usort($rows, function (array $left, array $right): int { return strcmp((string) ($right['sort_at'] ?? ''), (string) ($left['sort_at'] ?? '')); }); $this->totals['aperte'] = count(array_filter($rows, fn(array $row): bool => ! (bool) ($row['is_closed'] ?? false))); $this->totals['chiuse'] = count(array_filter($rows, fn(array $row): bool => (bool) ($row['is_closed'] ?? false))); // Scope filter if ($this->scope === 'aperte') { $rows = array_values(array_filter($rows, fn(array $row): bool => ! (bool) ($row['is_closed'] ?? false))); } elseif ($this->scope === 'chiuse') { $rows = array_values(array_filter($rows, fn(array $row): bool => (bool) ($row['is_closed'] ?? false))); } elseif ($this->scope === 'ticket_amministratore') { $rows = array_values(array_filter($rows, fn(array $row): bool => ($row['row_type'] ?? '') === 'ticket')); } // Additional filters if (trim($this->search) !== '') { $term = strtolower(trim($this->search)); $rows = array_values(array_filter($rows, function (array $row) use ($term): bool { return str_contains(strtolower((string) ($row['numero'] ?? '')), $term) || str_contains(strtolower((string) ($row['cliente'] ?? '')), $term) || str_contains(strtolower((string) ($row['telefono'] ?? '')), $term) || str_contains(strtolower((string) ($row['modello'] ?? '')), $term) || str_contains(strtolower((string) ($row['seriale'] ?? '')), $term) || str_contains(strtolower((string) ($row['difetto'] ?? '')), $term) || str_contains(strtolower((string) ($row['brand'] ?? '')), $term) || str_contains(strtolower((string) ($row['cod_prodotto'] ?? '')), $term); })); } if (trim($this->filterStato) !== '' && $this->filterStato !== '0') { $rows = array_values(array_filter($rows, fn(array $r): bool => (string) ($r['status_code'] ?? '') === (string) $this->filterStato || str_contains(strtolower((string) ($r['stato'] ?? '')), strtolower($this->filterStato)))); } if (trim($this->filterOrigine) !== '') { $rows = array_values(array_filter($rows, fn(array $r): bool => ($r['row_type'] ?? '') === $this->filterOrigine)); } $this->rows = array_slice($rows, 0, 160); } public function openRowDetail(string $rowType, int $rowId): void { $this->selectedRowType = $rowType; $this->selectedRowId = $rowId; if ($rowType === 'tecnorepair') { $scheda = AssistenzaTecnorepairScheda::query()->find($rowId); if (! $scheda instanceof AssistenzaTecnorepairScheda) { return; } $metadata = is_array($scheda->metadata ?? null) ? $scheda->metadata : []; $raw = is_array($metadata['raw'] ?? null) ? $metadata['raw'] : []; $cliente = is_array($metadata['cliente'] ?? null) ? $metadata['cliente'] : []; // Segno di sblocco (pattern grid 3x3) $segnoStr = trim((string) ($raw['SegnoDiSblocco'] ?? '')); $segnoParts = preg_split('/\s+/', $segnoStr); $pattern = [0, 0, 0, 0, 0, 0, 0, 0, 0]; if (is_array($segnoParts) && count($segnoParts) >= 9) { for ($i = 0; $i < 9; $i++) { $pattern[$i] = (int) ($segnoParts[$i] ?? 0); } } $this->unlockPattern = $pattern; $this->activeScheda = [ 'type' => 'tecnorepair', 'id' => (int) $scheda->id, 'legacy_id' => (int) ($scheda->legacy_id ?? 0), 'numero_scheda' => (string) ($scheda->legacy_numero_scheda ?: $scheda->legacy_id ?: '-'), 'title' => (string) $scheda->display_title, 'status' => (string) ($scheda->status_label ?: $scheda->status_bucket ?: '-'), 'status_code' => (string) ($scheda->status_code ?: '21'), 'customer_name' => (string) ($scheda->customer_name ?: ($cliente['NomeCognome'] ?? 'Cliente TecnoRepair')), 'customer_phone' => (string) ($scheda->customer_phone ?: ($cliente['NumeroTelefono'] ?? '')), 'customer_phone_alt' => (string) ($scheda->customer_phone_alt ?: ($cliente['TelFisso'] ?? '')), 'customer_email' => (string) ($scheda->customer_email ?: ($cliente['Email'] ?? '')), 'customer_address' => (string) ($cliente['Indirizzo'] ?? ''), 'customer_city' => (string) ($cliente['Citta'] ?? ''), 'product_type' => (string) ($raw['Cod_TipoApparecchio'] ?? 'Apparecchio Elettronico'), 'brand' => (string) ($this->extractDeviceBrand((string) ($scheda->product_model ?: ''))), 'product_model' => (string) ($scheda->product_model ?: ($raw['Modello'] ?? '-')), 'product_code' => (string) ($scheda->product_code ?: ($raw['CodiceProdotto'] ?? '-')), 'serial_number' => (string) ($scheda->serial_number ?: ($raw['SerialNumber'] ?? '-')), 'serial_number_2' => (string) ($scheda->serial_number_2 ?: ($raw['SerialNumber2'] ?? '-')), 'serial_number_3' => (string) ($raw['SerialNumber3'] ?? '-'), 'tag' => (string) ($raw['Tag'] ?? '-'), 'accessories' => (string) ($raw['AccessoriConsegnati'] ?? 'NESSUNO'), 'location' => (string) ($raw['Locazione'] ?? ($raw['Cod_Ubicazione'] ?? 'Laboratorio')), 'technician' => (string) ($scheda->technician_name ?: ($raw['NomeTecnicoRiparatore'] ?? 'Tecnico')), 'operator' => (string) ($scheda->operator_name ?: ($raw['NomeOperatore'] ?? 'Operatore')), 'defect_reported' => (string) ($scheda->defect_reported ?: ($raw['DifettoSegnalato'] ?? '-')), 'customer_requests' => (string) ($raw['RiparazioneRichiesta'] ?? '-'), 'general_state' => (string) ($raw['StatoGenerale'] ?? '-'), 'pin_code' => (string) ($scheda->pin_code ?: ($raw['CodicePIN'] ?? '-')), 'unlock_code' => (string) ($scheda->unlock_code ?: ($raw['CodiceSblocco'] ?? '-')), 'repair_description' => (string) ($scheda->repair_description ?: ($raw['DescrizioneRiparazione'] ?? '')), 'note_interne' => (string) ($raw['NoteInterne'] ?? ''), 'note_stampa' => (string) ($raw['NoteStampa'] ?? ''), 'communications' => (string) ($scheda->communications ?: ($raw['Comunicazioni'] ?? '')), 'date_received' => optional($scheda->date_received)->format('d/m/Y') ?: '-', 'time_received' => (string) ($raw['OrarioIngresso'] ?? '10:00'), 'date_delivery_prev' => ! empty($raw['DataPrevRip']) ? Carbon::parse($raw['DataPrevRip'])->format('d/m/Y') : '-', 'date_repaired' => ! empty($raw['DataRiparazione']) ? Carbon::parse($raw['DataRiparazione'])->format('d/m/Y') : '-', 'date_returned' => ! empty($raw['DataRiconsegna']) ? Carbon::parse($raw['DataRiconsegna'])->format('d/m/Y') : '-', 'is_fare_preventivo' => (bool) ($raw['isFarePreventivo'] ?? false), 'is_riparazione_sede' => (bool) ($raw['isRiparazioneInSede'] ?? false), 'is_riconsegnato' => (bool) ($raw['isRiconsegnato'] ?? false), 'is_rientro' => (bool) ($raw['Rientro'] ?? false), 'is_esame_tecnico' => (bool) ($raw['isEsameTecnico'] ?? false), 'consegnato_no_doc' => (bool) ($raw['ConsegnatoSenzaDoc'] ?? false), 'costo_preventivo' => (string) ($raw['CostoPreventivo'] ?? '0.00'), 'costo_subito' => (string) ($raw['CostoSubito'] ?? '0.00'), 'costo_addebitato' => (string) ($raw['CostoAddebitato'] ?? '0.00'), 'acconto' => (string) ($raw['AccontoRiparazione'] ?? '0.00'), 'rif_ddt_entrata' => (string) ($raw['RifDDTEntrata'] ?? '-'), 'rif_ddt_uscita' => (string) ($raw['RifDDTUscita'] ?? '-'), 'sost_marca_modello' => (string) ($raw['Sost_MarcaModello'] ?? '-'), 'sost_seriale' => (string) ($raw['Sost_SerialNumber'] ?? '-'), 'sost_stato' => (string) ($raw['Sost_StatoGenerale'] ?? '-'), 'updated_at' => optional($scheda->updated_at)->format('d/m/Y H:i') ?: '-', 'metadata' => $metadata, ]; $this->schedaForm = [ 'status_code' => (string) ($scheda->status_code ?: '21'), 'status_label' => (string) ($scheda->status_label ?: 'IN RIPARAZIONE'), 'is_fare_preventivo' => (bool) ($raw['isFarePreventivo'] ?? false), 'is_riparazione_sede'=> (bool) ($raw['isRiparazioneInSede'] ?? false), 'is_riconsegnato' => (bool) ($raw['isRiconsegnato'] ?? false), 'is_rientro' => (bool) ($raw['Rientro'] ?? false), 'is_esame_tecnico' => (bool) ($raw['isEsameTecnico'] ?? false), 'consegnato_no_doc' => (bool) ($raw['ConsegnatoSenzaDoc'] ?? false), 'cliente_nome' => (string) ($scheda->customer_name ?: ($cliente['NomeCognome'] ?? '')), 'cliente_telefono' => (string) ($scheda->customer_phone ?: ($cliente['NumeroTelefono'] ?? '')), 'cliente_tel_fisso' => (string) ($scheda->customer_phone_alt ?: ($cliente['TelFisso'] ?? '')), 'cliente_email' => (string) ($scheda->customer_email ?: ($cliente['Email'] ?? '')), 'cliente_indirizzo' => (string) ($cliente['Indirizzo'] ?? ''), 'cliente_citta' => (string) ($cliente['Citta'] ?? ''), 'difetto_segnalato' => (string) ($scheda->defect_reported ?: ($raw['DifettoSegnalato'] ?? '')), 'richieste_cliente' => (string) ($raw['RiparazioneRichiesta'] ?? ''), 'stato_generale' => (string) ($raw['StatoGenerale'] ?? ''), 'pin_code' => (string) ($scheda->pin_code ?: ($raw['CodicePIN'] ?? '')), 'unlock_code' => (string) ($scheda->unlock_code ?: ($raw['CodiceSblocco'] ?? '')), 'repair_description' => (string) ($scheda->repair_description ?: ($raw['DescrizioneRiparazione'] ?? '')), 'note_interne' => (string) ($raw['NoteInterne'] ?? ''), 'note_stampa' => (string) ($raw['NoteStampa'] ?? ''), 'communications' => (string) ($scheda->communications ?: ($raw['Comunicazioni'] ?? '')), 'tecnico' => (string) ($scheda->technician_name ?: ($raw['NomeTecnicoRiparatore'] ?? '')), 'costo_preventivo' => (string) ($raw['CostoPreventivo'] ?? '0.00'), 'costo_subito' => (string) ($raw['CostoSubito'] ?? '0.00'), 'costo_addebitato' => (string) ($raw['CostoAddebitato'] ?? '0.00'), 'acconto' => (string) ($raw['AccontoRiparazione'] ?? '0.00'), ]; $this->schedaSubTab = 'entrata'; $this->mainTab = 'scheda'; $this->detailModal = null; return; } // TICKET AMMINISTRATORE [$fornitore, $dipendente] = $this->resolveOperatoreContext((int) $this->fornitoreId); $intervento = $this->buildBaseQuery($fornitore, $dipendente)->find($rowId); if (! $intervento instanceof TicketIntervento) { return; } $base = $this->buildInterventoRow($intervento); $this->activeScheda = [ 'type' => 'ticket', 'id' => (int) $intervento->id, 'numero_scheda' => 'TK-' . (int) $intervento->ticket_id, 'title' => 'Ticket #' . (int) $intervento->ticket_id . ' ยท ' . (string) ($intervento->ticket->titolo ?? '-'), 'status' => (string) $intervento->stato, 'status_code' => (string) $intervento->stato, 'customer_name' => $base['contatto'], 'customer_phone' => $base['telefono'], 'customer_email' => '', 'customer_address' => (string) ($intervento->ticket->stabile->indirizzo ?? ''), 'customer_city' => (string) ($intervento->ticket->stabile->citta ?? ''), 'brand' => $this->extractDeviceBrand($base['apparato']), 'product_model' => $base['apparato'], 'product_code' => '-', 'serial_number' => '-', 'stabile' => (string) ($intervento->ticket->stabile->denominazione ?? '-'), 'unita' => (string) ($intervento->ticket->unitaImmobiliare->denominazione ?? '-'), 'operator' => (string) $intervento->operatore_assegnato_label, 'defect_reported' => $base['problema'], 'repair_description' => (string) ($intervento->rapporto_fornitore ?? ''), 'note_interne' => (string) ($intervento->rapporto_fornitore ?? ''), 'note_stampa' => (string) ($intervento->ticket->descrizione ?? ''), 'communications' => '', 'updated_at' => optional($intervento->updated_at)->format('d/m/Y H:i') ?: '-', 'url' => TicketInterventoScheda::getUrl(['record' => (int) $intervento->id], panel: 'admin-filament'), 'metadata' => [], ]; $this->schedaForm = [ 'status_code' => (string) $intervento->stato, 'repair_description' => (string) ($intervento->rapporto_fornitore ?? ''), 'note_interne' => (string) ($intervento->rapporto_fornitore ?? ''), ]; $this->schedaSubTab = 'entrata'; $this->mainTab = 'scheda'; $this->detailModal = null; } public function togglePatternDot(int $index): void { if (isset($this->unlockPattern[$index])) { $this->unlockPattern[$index] = $this->unlockPattern[$index] === 1 ? 0 : 1; } } public function saveActiveScheda(): void { if (! $this->selectedRowId) { return; } if ($this->selectedRowType === 'tecnorepair') { $scheda = AssistenzaTecnorepairScheda::query()->find($this->selectedRowId); if (! $scheda instanceof AssistenzaTecnorepairScheda) { return; } $scheda->defect_reported = $this->schedaForm['difetto_segnalato'] ?? $scheda->defect_reported; $scheda->repair_description = $this->schedaForm['repair_description'] ?? $scheda->repair_description; $scheda->communications = $this->schedaForm['communications'] ?? $scheda->communications; $scheda->pin_code = $this->schedaForm['pin_code'] ?? $scheda->pin_code; $scheda->unlock_code = $this->schedaForm['unlock_code'] ?? $scheda->unlock_code; $scheda->technician_name = $this->schedaForm['tecnico'] ?? $scheda->technician_name; $scheda->status_code = (string) ($this->schedaForm['status_code'] ?? $scheda->status_code); $scheda->status_label = $this->resolveStatusLabel((string) $scheda->status_code); $scheda->status_bucket = AssistenzaTecnorepairScheda::normalizeStatusBucket($scheda->status_label); $metadata = is_array($scheda->metadata ?? null) ? $scheda->metadata : []; $raw = is_array($metadata['raw'] ?? null) ? $metadata['raw'] : []; $cliente = is_array($metadata['cliente'] ?? null) ? $metadata['cliente'] : []; $raw['isFarePreventivo'] = ! empty($this->schedaForm['is_fare_preventivo']) ? '1' : '0'; $raw['isRiparazioneInSede'] = ! empty($this->schedaForm['is_riparazione_sede']) ? '1' : '0'; $raw['isRiconsegnato'] = ! empty($this->schedaForm['is_riconsegnato']) ? '1' : '0'; $raw['Rientro'] = ! empty($this->schedaForm['is_rientro']) ? '1' : '0'; $raw['isEsameTecnico'] = ! empty($this->schedaForm['is_esame_tecnico']) ? '1' : '0'; $raw['ConsegnatoSenzaDoc'] = ! empty($this->schedaForm['consegnato_no_doc']) ? '1' : '0'; $raw['StatoGenerale'] = (string) ($this->schedaForm['stato_generale'] ?? ''); $raw['RiparazioneRichiesta'] = (string) ($this->schedaForm['richieste_cliente'] ?? ''); $raw['NoteInterne'] = (string) ($this->schedaForm['note_interne'] ?? ''); $raw['NoteStampa'] = (string) ($this->schedaForm['note_stampa'] ?? ''); $raw['SegnoDiSblocco'] = implode(' ', $this->unlockPattern); $cliente['NomeCognome'] = (string) ($this->schedaForm['cliente_nome'] ?? ($cliente['NomeCognome'] ?? '')); $cliente['NumeroTelefono'] = (string) ($this->schedaForm['cliente_telefono'] ?? ($cliente['NumeroTelefono'] ?? '')); $cliente['TelFisso'] = (string) ($this->schedaForm['cliente_tel_fisso'] ?? ($cliente['TelFisso'] ?? '')); $cliente['Email'] = (string) ($this->schedaForm['cliente_email'] ?? ($cliente['Email'] ?? '')); $cliente['Indirizzo'] = (string) ($this->schedaForm['cliente_indirizzo'] ?? ($cliente['Indirizzo'] ?? '')); $cliente['Citta'] = (string) ($this->schedaForm['cliente_citta'] ?? ($cliente['Citta'] ?? '')); $metadata['raw'] = $raw; $metadata['cliente'] = $cliente; $scheda->metadata = $metadata; $scheda->save(); Notification::make() ->title('Scheda #' . ($scheda->legacy_numero_scheda ?: $scheda->legacy_id) . ' salvata con successo') ->success() ->send(); $this->openRowDetail('tecnorepair', (int) $scheda->id); $this->refreshData(); return; } if ($this->selectedRowType === 'ticket') { $intervento = TicketIntervento::query()->find($this->selectedRowId); if ($intervento instanceof TicketIntervento) { $intervento->rapporto_fornitore = (string) ($this->schedaForm['repair_description'] ?? $intervento->rapporto_fornitore); if (! empty($this->schedaForm['status_code'])) { $intervento->stato = $this->schedaForm['status_code']; } $intervento->save(); Notification::make() ->title('Ticket intervento salvato con successo') ->success() ->send(); $this->openRowDetail('ticket', (int) $intervento->id); $this->refreshData(); } } } public function cambiaStatoRapido(string $code): void { $this->schedaForm['status_code'] = $code; if ($code === '4') { // Riparato $this->schedaForm['is_riconsegnato'] = false; } elseif ($code === '23') { // Rottamazione $this->schedaForm['is_riconsegnato'] = false; } $this->saveActiveScheda(); } public function closeScheda(): void { $this->mainTab = 'elenco'; $this->detailModal = null; } public function closeDetailModal(): void { $this->closeScheda(); } public function getTicketsUrl(): string { if ($this->fornitoreId) { return TicketOperativi::getUrl(['fornitore' => $this->fornitoreId], panel: 'admin-filament'); } return TicketOperativi::getUrl(panel: 'admin-filament'); } public function getCollaboratoriUrl(): string { if ($this->fornitoreId) { return Collaboratori::getUrl(['fornitore' => $this->fornitoreId], panel: 'admin-filament'); } return Collaboratori::getUrl(panel: 'admin-filament'); } public function getRubricaUrl(): string { if ($this->fornitoreId) { return RubricaClienti::getUrl(['fornitore' => $this->fornitoreId], panel: 'admin-filament'); } return RubricaClienti::getUrl(panel: 'admin-filament'); } public function getProdottiUrl(): string { if ($this->fornitoreId) { return ProdottiCatalogo::getUrl(['fornitore' => $this->fornitoreId], panel: 'admin-filament'); } return ProdottiCatalogo::getUrl(panel: 'admin-filament'); } public function getImpostazioniUrl(): string { if ($this->fornitoreId) { return ImpostazioniArchivio::getUrl(['fornitore' => $this->fornitoreId], panel: 'admin-filament'); } return ImpostazioniArchivio::getUrl(panel: 'admin-filament'); } protected function buildBaseQuery(Fornitore $fornitore, ?FornitoreDipendente $dipendente): Builder { $query = TicketIntervento::query() ->with(['ticket.stabile', 'ticket.unitaImmobiliare', 'ticket.soggettoRichiedente', 'eseguitoDaDipendente']) ->where('fornitore_id', (int) $fornitore->id) ->orderByDesc('created_at'); if ($dipendente instanceof FornitoreDipendente) { $query->where(function (Builder $builder) use ($dipendente): void { $builder->whereNull('eseguito_da_dipendente_id') ->orWhere('eseguito_da_dipendente_id', (int) $dipendente->id); }); } return $query; } protected function buildTecnorepairQuery(Fornitore $fornitore): Builder { $fornitoreIds = [(int) $fornitore->id]; if (in_array((int) $fornitore->id, [236, 359], true) || str_contains(strtoupper($fornitore->ragione_sociale), 'NETHOME')) { $fornitoreIds = [236, 359]; } return AssistenzaTecnorepairScheda::query() ->whereIn('fornitore_id', $fornitoreIds) ->orderByDesc('date_received') ->orderByDesc('id'); } /** * @return array> */ protected function buildTecnorepairRows(Fornitore $fornitore): array { return $this->buildTecnorepairQuery($fornitore) ->limit(200) ->get() ->map(function (AssistenzaTecnorepairScheda $scheda): array { $raw = data_get($scheda->metadata, 'raw', []); $isRiconsegnato = (bool) ($raw['isRiconsegnato'] ?? false); $isRiparato = ((string) $scheda->status_code === '4') || (bool) ($raw['isRiparato'] ?? false); $isClosed = (bool) ($scheda->is_closed ?? false) || $isRiconsegnato || $isRiparato || in_array((string) $scheda->status_code, ['4', '10', '23', '31', '37'], true); $rowColor = match ((string) $scheda->status_code) { '4' => 'green', '10', '23' => 'red', '2', '21' => 'blue', '5', '6', '33' => 'amber', default => $isClosed ? 'green' : 'blue', }; return [ 'row_type' => 'tecnorepair', 'row_class' => (string) $scheda->row_classes, 'badge_class' => (string) $scheda->status_badge_classes, 'row_color' => $rowColor, 'is_closed' => $isClosed, 'numero' => (string) ($scheda->legacy_numero_scheda ?: $scheda->legacy_id), 'numero_scheda'=> (string) ($scheda->legacy_numero_scheda ?: $scheda->legacy_id), 'ingresso' => optional($scheda->date_received)->format('d/m/Y') ?: '-', 'cliente' => (string) ($scheda->customer_name ?: 'Cliente TecnoRepair'), 'contatto' => (string) ($scheda->customer_name ?: 'Cliente TecnoRepair'), 'telefono' => (string) ($scheda->customer_phone ?: $scheda->customer_phone_alt ?: ''), 'difetto' => (string) ($scheda->defect_reported ?: '-'), 'problema' => (string) ($scheda->defect_reported ?: '-'), 'brand' => $this->extractDeviceBrand((string) ($scheda->product_model ?: '')), 'apparato' => (string) ($scheda->product_model ?: '-'), 'modello' => (string) ($scheda->product_model ?: '-'), 'seriale' => (string) $scheda->serial_label, 'cod_prodotto' => (string) ($scheda->product_code ?: '-'), 'id' => (int) $scheda->id, 'ticket_id' => null, 'titolo' => (string) $scheda->display_title, 'stato' => (string) ($scheda->status_label ?: $scheda->status_bucket ?: '-'), 'status_code' => (string) ($scheda->status_code ?: ''), 'stabile' => 'Archivio TecnoRepair', 'operatore' => (string) ($scheda->technician_name ?: $scheda->operator_name ?: '-'), 'tempo_minuti' => 0, 'updated_at' => optional($scheda->updated_at)->format('d/m/Y H:i') ?: '-', 'sort_at' => optional($scheda->date_received ?? $scheda->updated_at)->format('Y-m-d H:i:s') ?: '1970-01-01 00:00:00', 'origine' => 'TecnoRepair MDB', 'url' => null, ]; }) ->all(); } protected function resolveTicketRowClass(string $status): string { $status = strtolower(trim($status)); return match (true) { in_array($status, ['chiuso', 'fatturato'], true) => 'bg-emerald-50/70 hover:bg-emerald-50', in_array($status, ['fatturabile', 'verifica'], true) => 'bg-amber-50/70 hover:bg-amber-50', default => 'bg-sky-50/60 hover:bg-sky-50', }; } protected function resolveTicketBadgeClass(string $status): string { $status = strtolower(trim($status)); return match (true) { in_array($status, ['chiuso', 'fatturato'], true) => 'border-emerald-200 bg-emerald-50 text-emerald-800', in_array($status, ['fatturabile', 'verifica'], true) => 'border-amber-200 bg-amber-50 text-amber-800', default => 'border-sky-200 bg-sky-50 text-sky-800', }; } protected function isClosedStatus(string $status): bool { $status = strtolower(trim($status)); return str_contains($status, 'chius') || str_contains($status, 'fatturat') || str_contains($status, 'riconsegn') || str_contains($status, 'riparato') || str_contains($status, 'acquisto'); } protected function extractDeviceBrand(string $label): string { $label = trim($label); if ($label === '' || $label === '-') { return '-'; } $parts = preg_split('/\s+/', $label) ?: []; $first = trim((string) ($parts[0] ?? '')); return $first !== '' ? strtoupper($first) : '-'; } protected function resolveStatusLabel(string $code): string { return match ($code) { '0' => 'TUTTI', '4' => 'RIPARATO', '21' => 'INGRESSO ACCETTAZIONE', '2' => 'DISPOSITIVO IN RIPARAZIONE', '5' => 'ATTESA RICAMBIO', '6' => 'INVIATO NUOVO PREVENTIVO', '10' => 'DISPOSITIVO IRRIPARABILE', '23' => 'PC DA UTILIZZARE COME RICAMBI', '33' => 'MANDATO IN GARANZIA AL PRODUTTORE', '31' => 'ACQUISTO RICONDIZIONATO', '37' => 'SMALTITO PER ABBANDONO', default => 'IN LAVORAZIONE (' . $code . ')', }; } }