528 lines
22 KiB
PHP
528 lines
22 KiB
PHP
<?php
|
|
namespace App\Filament\Pages\Fornitore;
|
|
|
|
use App\Filament\Pages\Fornitore\Concerns\ResolvesOperatoreContext;
|
|
use App\Models\AssistenzaTecnorepairAllegato;
|
|
use App\Models\AssistenzaTecnorepairScheda;
|
|
use App\Models\Fornitore;
|
|
use App\Models\User;
|
|
use App\Services\Catalog\ContabilitaMysqlSerialImportService;
|
|
use App\Services\Tecnorepair\TecnoRepairArchiveService;
|
|
use BackedEnum;
|
|
use Carbon\Carbon;
|
|
use Filament\Notifications\Notification;
|
|
use Filament\Pages\Page;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use UnitEnum;
|
|
|
|
class PraticheTecnorepair extends Page
|
|
{
|
|
use ResolvesOperatoreContext;
|
|
|
|
protected static ?string $navigationLabel = 'Pratiche TecnoRepair';
|
|
|
|
protected static ?string $title = 'Pratiche & Riparazioni TecnoRepair';
|
|
|
|
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-computer-desktop';
|
|
|
|
protected static UnitEnum|string|null $navigationGroup = 'Fornitore';
|
|
|
|
protected static ?int $navigationSort = 2;
|
|
|
|
protected static ?string $slug = 'fornitore/pratiche';
|
|
|
|
protected string $view = 'filament.pages.fornitore.pratiche-tecnorepair';
|
|
|
|
public ?int $fornitoreId = null;
|
|
|
|
public ?string $fornitoreLabel = null;
|
|
|
|
public bool $missingAdminContext = false;
|
|
|
|
/** @var array<int, string> */
|
|
public array $fornitoriOptions = [];
|
|
|
|
// Filter properties
|
|
public string $searchMatricola = '';
|
|
|
|
public string $searchNumScheda = '';
|
|
|
|
public string $searchCliente = '';
|
|
|
|
public bool $searchClienteParziale = true;
|
|
|
|
public string $searchNumOrdine = '';
|
|
|
|
public string $filterStato = '0';
|
|
|
|
public bool $escludiRiconsegnati = true;
|
|
|
|
public bool $soloRiconsegnati = false;
|
|
|
|
public ?int $nonLavorateDaGiorni = null;
|
|
|
|
public string $dataIngressoDal = '';
|
|
|
|
public string $dataIngressoAl = '';
|
|
|
|
// Active Scheda modal state
|
|
public ?int $selectedSchedaId = null;
|
|
|
|
public string $schedaTab = 'entrata';
|
|
|
|
/** @var array<string, mixed>|null */
|
|
public ?array $activeScheda = null;
|
|
|
|
// Workflow inputs for active scheda
|
|
public string $workflowNote = '';
|
|
|
|
public string $workflowMotivoRottamazione = '';
|
|
|
|
public bool $workflowComeRicambi = false;
|
|
|
|
public string $workflowRmaCode = '';
|
|
|
|
public ?int $workflowFornitoreResoId = null;
|
|
|
|
/** @var array<int, array<string, mixed>> */
|
|
public array $rows = [];
|
|
|
|
/** @var array<string, int> */
|
|
public array $totals = [
|
|
'totale' => 0,
|
|
'aperte' => 0,
|
|
'riparate' => 0,
|
|
'rottamate' => 0,
|
|
'rma_garanzia' => 0,
|
|
];
|
|
|
|
public static function canAccess(): bool
|
|
{
|
|
$user = Auth::user();
|
|
|
|
return $user instanceof User
|
|
&& $user->hasAnyRole(['super-admin', 'admin', 'amministratore', 'collaboratore', 'fornitore']);
|
|
}
|
|
|
|
public function mount(): void
|
|
{
|
|
[$fornitore] = $this->resolveOperatoreContext(allowAdminWithoutSupplier: true);
|
|
|
|
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('productSerials')
|
|
->orWhere('partita_iva', '10055221005')
|
|
->orWhere('partita_iva', '14001151001')
|
|
->orWhereIn('id', [236, 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();
|
|
}
|
|
|
|
// Optional date range
|
|
$this->dataIngressoDal = trim((string) request()->query('dal', ''));
|
|
$this->dataIngressoAl = trim((string) request()->query('al', ''));
|
|
|
|
// Optional query params
|
|
if (request()->has('scheda')) {
|
|
$this->searchNumScheda = trim((string) request()->query('scheda'));
|
|
}
|
|
if (request()->has('q')) {
|
|
$this->searchMatricola = trim((string) request()->query('q'));
|
|
}
|
|
|
|
$this->refreshData();
|
|
|
|
if (request()->has('open')) {
|
|
$openId = (int) request()->query('open');
|
|
if ($openId > 0) {
|
|
$this->openScheda($openId);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function updatedFornitoreId(): void
|
|
{
|
|
$fornitore = Fornitore::query()->find((int) $this->fornitoreId);
|
|
if ($fornitore instanceof Fornitore) {
|
|
$this->fornitoreLabel = $this->getFornitoreLabel($fornitore);
|
|
$this->selectedSchedaId = null;
|
|
$this->activeScheda = null;
|
|
$this->refreshData();
|
|
}
|
|
}
|
|
|
|
public function updatedSearchMatricola(): void { $this->refreshData(); }
|
|
public function updatedSearchNumScheda(): void { $this->refreshData(); }
|
|
public function updatedSearchCliente(): void { $this->refreshData(); }
|
|
public function updatedFilterStato(): void { $this->refreshData(); }
|
|
public function updatedEscludiRiconsegnati(): void { $this->refreshData(); }
|
|
public function updatedSoloRiconsegnati(): void { $this->refreshData(); }
|
|
|
|
public function resetFiltri(): void
|
|
{
|
|
$this->searchMatricola = '';
|
|
$this->searchNumScheda = '';
|
|
$this->searchCliente = '';
|
|
$this->searchNumOrdine = '';
|
|
$this->filterStato = '0';
|
|
$this->escludiRiconsegnati = true;
|
|
$this->soloRiconsegnati = false;
|
|
$this->nonLavorateDaGiorni = null;
|
|
$this->dataIngressoDal = now()->subYears(2)->startOfYear()->format('Y-m-d');
|
|
$this->dataIngressoAl = now()->addYear()->endOfYear()->format('Y-m-d');
|
|
$this->refreshData();
|
|
}
|
|
|
|
public function refreshData(): void
|
|
{
|
|
if (! $this->fornitoreId) {
|
|
$this->rows = [];
|
|
return;
|
|
}
|
|
|
|
$query = AssistenzaTecnorepairScheda::query()
|
|
->where(function (Builder $builder) {
|
|
$builder->where('fornitore_id', (int) $this->fornitoreId);
|
|
// Also include merged suppliers (e.g. NCOMSRL if Nethome)
|
|
if ((int) $this->fornitoreId === 236) {
|
|
$builder->orWhere('fornitore_id', 392);
|
|
}
|
|
});
|
|
|
|
// Search filters
|
|
if (trim($this->searchMatricola) !== '') {
|
|
$val = trim($this->searchMatricola);
|
|
$query->where(function (Builder $b) use ($val) {
|
|
$b->where('serial_number', 'like', "%{$val}%")
|
|
->orWhere('serial_number_2', 'like', "%{$val}%")
|
|
->orWhere('product_code', 'like', "%{$val}%");
|
|
});
|
|
}
|
|
|
|
if (trim($this->searchNumScheda) !== '') {
|
|
$val = trim($this->searchNumScheda);
|
|
$query->where(function (Builder $b) use ($val) {
|
|
$b->where('legacy_numero_scheda', 'like', "%{$val}%")
|
|
->orWhere('legacy_id', $val);
|
|
});
|
|
}
|
|
|
|
if (trim($this->searchCliente) !== '') {
|
|
$val = trim($this->searchCliente);
|
|
$query->where('customer_name', 'like', "%{$val}%");
|
|
}
|
|
|
|
if (trim($this->searchNumOrdine) !== '') {
|
|
$val = trim($this->searchNumOrdine);
|
|
$query->where('order_number', 'like', "%{$val}%");
|
|
}
|
|
|
|
if ($this->filterStato !== '0' && trim($this->filterStato) !== '') {
|
|
$st = trim($this->filterStato);
|
|
$query->where(function (Builder $b) use ($st) {
|
|
$b->where('status_code', $st)
|
|
->orWhere('status_label', 'like', "%{$st}%");
|
|
});
|
|
}
|
|
|
|
if ($this->escludiRiconsegnati) {
|
|
$query->where(function (Builder $b) {
|
|
$b->whereNull('metadata->raw->isRiconsegnato')
|
|
->orWhere('metadata->raw->isRiconsegnato', 0)
|
|
->orWhere('metadata->raw->isRiconsegnato', '0')
|
|
->orWhere('metadata->raw->isRiconsegnato', false);
|
|
});
|
|
} elseif ($this->soloRiconsegnati) {
|
|
$query->where(function (Builder $b) {
|
|
$b->where('metadata->raw->isRiconsegnato', 1)
|
|
->orWhere('metadata->raw->isRiconsegnato', '1')
|
|
->orWhere('metadata->raw->isRiconsegnato', true);
|
|
});
|
|
}
|
|
|
|
if ($this->dataIngressoDal !== '') {
|
|
$query->where('date_received', '>=', Carbon::parse($this->dataIngressoDal)->startOfDay());
|
|
}
|
|
if ($this->dataIngressoAl !== '') {
|
|
$query->where('date_received', '<=', Carbon::parse($this->dataIngressoAl)->endOfDay());
|
|
}
|
|
|
|
// Count totals across dataset
|
|
$baseTotalQuery = AssistenzaTecnorepairScheda::query()
|
|
->where(function (Builder $builder) {
|
|
$builder->where('fornitore_id', (int) $this->fornitoreId);
|
|
if ((int) $this->fornitoreId === 236) {
|
|
$builder->orWhere('fornitore_id', 392);
|
|
}
|
|
});
|
|
|
|
$this->totals = [
|
|
'totale' => (clone $baseTotalQuery)->count(),
|
|
'riparate' => (clone $baseTotalQuery)->where('status_code', '4')->count(),
|
|
'rottamate' => (clone $baseTotalQuery)->whereIn('status_code', ['10', '23', '37'])->count(),
|
|
'rma_garanzia' => (clone $baseTotalQuery)->where('status_code', '33')->count(),
|
|
'aperte' => (clone $baseTotalQuery)->whereNotIn('status_code', ['4', '10', '23', '37'])->count(),
|
|
];
|
|
|
|
$records = $query->orderByDesc('legacy_id')->limit(120)->get();
|
|
|
|
$this->rows = $records->map(function (AssistenzaTecnorepairScheda $s): array {
|
|
$raw = (array) data_get($s->metadata, 'raw', []);
|
|
$isRiconsegnato = (bool) ($raw['isRiconsegnato'] ?? false);
|
|
$statusCode = (string) ($s->status_code ?: '');
|
|
$statusLabel = strtoupper((string) ($s->status_label ?: 'IN LAVORAZIONE'));
|
|
|
|
// Row style logic matching TecnoRepair screenshots:
|
|
// Green: RIPARATO (4) / ACQUISTO RICONDIZIONATO (31)
|
|
// Red: DISPOSITIVO IRRIPARABILE (10) / PZ-RICAM (23) / SMALTITO (37)
|
|
// Blue: INGRESSO ACCETTAZIONE (21)
|
|
// Amber: ATTESA RICAMBIO (5) / LABORATORIO ESTERNO (27)
|
|
$rowColor = 'white';
|
|
if (in_array($statusCode, ['4', '31'], true) || str_contains($statusLabel, 'RIPARATO') || str_contains($statusLabel, 'ACQUISTO RICONDIZIONATO')) {
|
|
$rowColor = 'green';
|
|
} elseif (in_array($statusCode, ['10', '23', '37'], true) || str_contains($statusLabel, 'IRRIPARABILE') || str_contains($statusLabel, 'RICAMBI') || str_contains($statusLabel, 'SMALTITO')) {
|
|
$rowColor = 'red';
|
|
} elseif ($statusCode === '21' || str_contains($statusLabel, 'INGRESSO') || str_contains($statusLabel, 'ACCETTAZIONE')) {
|
|
$rowColor = 'blue';
|
|
} elseif (in_array($statusCode, ['5', '27', '30'], true) || str_contains($statusLabel, 'ATTESA') || str_contains($statusLabel, 'URGENTE')) {
|
|
$rowColor = 'amber';
|
|
}
|
|
|
|
return [
|
|
'id' => (int) $s->id,
|
|
'legacy_id' => (int) ($s->legacy_id ?: $s->id),
|
|
'numero_scheda' => (string) ($s->legacy_numero_scheda ?: $s->legacy_id ?: $s->id),
|
|
'ingresso' => optional($s->date_received)->format('d/m/Y') ?: '-',
|
|
'cliente' => (string) ($s->customer_name ?: '-'),
|
|
'telefono' => (string) ($s->customer_phone ?: $s->customer_phone_alt ?: '-'),
|
|
'difetto' => (string) ($s->defect_reported ?: '-'),
|
|
'marca' => (string) ($raw['Cod_Marca'] ?? $this->extractBrand($s->product_model)),
|
|
'modello' => (string) ($s->product_model ?: '-'),
|
|
'seriale' => (string) ($s->serial_number ?: '-'),
|
|
'cod_prodotto' => (string) ($s->product_code ?: '-'),
|
|
'riconsegnato' => $isRiconsegnato,
|
|
'data_ricons' => ! empty($raw['DataRiconsegna']) ? Carbon::parse($raw['DataRiconsegna'])->format('d/m/Y') : '-',
|
|
'num_ordine' => (string) ($s->order_number ?: '0'),
|
|
'stato_rip' => $statusLabel,
|
|
'status_code' => $statusCode,
|
|
'operatore' => (string) ($s->operator_name ?: $s->technician_name ?: 'MICHELE BARONE'),
|
|
'row_color' => $rowColor,
|
|
];
|
|
})->all();
|
|
}
|
|
|
|
public function openScheda(int $schedaId): void
|
|
{
|
|
$scheda = AssistenzaTecnorepairScheda::query()
|
|
->with(['allegati'])
|
|
->find($schedaId);
|
|
|
|
if (! $scheda instanceof AssistenzaTecnorepairScheda) {
|
|
return;
|
|
}
|
|
|
|
$raw = (array) data_get($scheda->metadata, 'raw', []);
|
|
$cliente = (array) data_get($scheda->metadata, 'cliente', []);
|
|
$ricambi = (array) data_get($scheda->metadata, 'ricambi_scheda', []);
|
|
|
|
$this->selectedSchedaId = (int) $scheda->id;
|
|
$this->schedaTab = 'entrata';
|
|
$this->workflowNote = '';
|
|
$this->workflowRmaCode = (string) ($scheda->rma_code ?: ('RMA-' . date('Ymd') . '-' . ($scheda->legacy_numero_scheda ?: $scheda->id)));
|
|
|
|
$this->activeScheda = [
|
|
'id' => (int) $scheda->id,
|
|
'numero_scheda' => (string) ($scheda->legacy_numero_scheda ?: $scheda->legacy_id ?: $scheda->id),
|
|
'data_ingresso' => optional($scheda->date_received)->format('d/m/Y H:i') ?: '-',
|
|
'data_riparazione' => ! empty($raw['DataRiparazione']) ? Carbon::parse($raw['DataRiparazione'])->format('d/m/Y H:i') : '-',
|
|
'data_riconsegna' => ! empty($raw['DataRiconsegna']) ? Carbon::parse($raw['DataRiconsegna'])->format('d/m/Y') : '-',
|
|
'stato_rip' => (string) ($scheda->status_label ?: 'INGRESSO ACCETTAZIONE'),
|
|
'status_code' => (string) ($scheda->status_code ?: '21'),
|
|
'rma_code' => (string) ($scheda->rma_code ?: ''),
|
|
'num_ordine' => (string) ($scheda->order_number ?: '0'),
|
|
// Cliente
|
|
'cliente_nome' => (string) ($scheda->customer_name ?: '-'),
|
|
'cliente_email' => (string) ($scheda->customer_email ?: '-'),
|
|
'cliente_telefono' => (string) ($scheda->customer_phone ?: '-'),
|
|
'cliente_fisso' => (string) ($scheda->customer_phone_alt ?: '-'),
|
|
'cliente_indirizzo' => (string) ($cliente['Indirizzo'] ?? '-'),
|
|
'cliente_citta' => (string) ($cliente['Citta'] ?? '-'),
|
|
// Apparecchio
|
|
'tipo_apparecchio' => (string) ($raw['Cod_TipoApparecchio'] ?? 'AIO / PC / Dispositivo'),
|
|
'marca' => (string) ($raw['Cod_Marca'] ?? $this->extractBrand($scheda->product_model)),
|
|
'modello' => (string) ($scheda->product_model ?: '-'),
|
|
'codice_prodotto' => (string) ($scheda->product_code ?: '-'),
|
|
'seriale' => (string) ($scheda->serial_number ?: '-'),
|
|
'seriale_2' => (string) ($scheda->serial_number_2 ?: '-'),
|
|
'accessori' => (string) ($raw['AccessoriConsegnati'] ?? 'NESSUNO'),
|
|
'difetto' => (string) ($scheda->defect_reported ?: '-'),
|
|
'richieste_cliente' => (string) ($raw['RiparazioneRichiesta'] ?? '-'),
|
|
'stato_generale' => (string) ($raw['StatoGenerale'] ?? '-'),
|
|
'codice_pin' => (string) ($scheda->pin_code ?: '-'),
|
|
'codice_sblocco' => (string) ($scheda->unlock_code ?: '-'),
|
|
'tecnico' => (string) ($scheda->technician_name ?: $scheda->operator_name ?: 'MICHELE BARONE'),
|
|
// Riparazione
|
|
'descrizione_lavorazione'=> (string) ($scheda->repair_description ?: '-'),
|
|
'comunicazioni' => (string) ($scheda->communications ?: '-'),
|
|
// Economico
|
|
'costo_subito' => (float) str_replace(',', '.', (string) ($raw['CostoSubito'] ?? 0)),
|
|
'costo_addebitato' => (float) str_replace(',', '.', (string) ($raw['CostoAddebitato'] ?? 0)),
|
|
'acconto' => (float) str_replace(',', '.', (string) ($raw['AccontoRiparazione'] ?? 0)),
|
|
'preventivo' => (float) str_replace(',', '.', (string) ($raw['CostoPreventivo'] ?? 0)),
|
|
// Ricambi
|
|
'ricambi' => $ricambi,
|
|
'allegati' => $scheda->allegati->map(fn(AssistenzaTecnorepairAllegato $a) => [
|
|
'nome' => $a->file_name,
|
|
'path' => $a->file_path,
|
|
])->all(),
|
|
];
|
|
}
|
|
|
|
public function closeScheda(): void
|
|
{
|
|
$this->selectedSchedaId = null;
|
|
$this->activeScheda = null;
|
|
}
|
|
|
|
public function setSchedaTab(string $tab): void
|
|
{
|
|
$this->schedaTab = $tab;
|
|
}
|
|
|
|
// Automated Workflow Actions
|
|
public function eseguiChiusuraRiparato(): void
|
|
{
|
|
if (! $this->selectedSchedaId) {
|
|
return;
|
|
}
|
|
|
|
$scheda = AssistenzaTecnorepairScheda::query()->find($this->selectedSchedaId);
|
|
if (! $scheda instanceof AssistenzaTecnorepairScheda) {
|
|
return;
|
|
}
|
|
|
|
$service = app(TecnoRepairArchiveService::class);
|
|
$service->chiudiComeRiparato($scheda, $this->workflowNote ?: 'Intervento concluso e collaudato con successo.');
|
|
|
|
Notification::make()->title('Pratica segnata come RIPARATO con successo')->success()->send();
|
|
$this->openScheda($this->selectedSchedaId);
|
|
$this->refreshData();
|
|
}
|
|
|
|
public function eseguiChiusuraRottamazione(): void
|
|
{
|
|
if (! $this->selectedSchedaId) {
|
|
return;
|
|
}
|
|
|
|
$scheda = AssistenzaTecnorepairScheda::query()->find($this->selectedSchedaId);
|
|
if (! $scheda instanceof AssistenzaTecnorepairScheda) {
|
|
return;
|
|
}
|
|
|
|
$service = app(TecnoRepairArchiveService::class);
|
|
$service->chiudiComeRottamato(
|
|
$scheda,
|
|
$this->workflowMotivoRottamazione ?: 'Apparato non riparabile convenientemente',
|
|
$this->workflowComeRicambi
|
|
);
|
|
|
|
$label = $this->workflowComeRicambi ? 'destinato a recupero ricambi' : 'contrassegnato per rottamazione';
|
|
Notification::make()->title("Apparato {$label}")->warning()->send();
|
|
$this->openScheda($this->selectedSchedaId);
|
|
$this->refreshData();
|
|
}
|
|
|
|
public function eseguiResoFornitoreRma(): void
|
|
{
|
|
if (! $this->selectedSchedaId) {
|
|
return;
|
|
}
|
|
|
|
$scheda = AssistenzaTecnorepairScheda::query()->find($this->selectedSchedaId);
|
|
if (! $scheda instanceof AssistenzaTecnorepairScheda) {
|
|
return;
|
|
}
|
|
|
|
$service = app(TecnoRepairArchiveService::class);
|
|
$service->rendiAFornitoreRma(
|
|
$scheda,
|
|
$this->workflowRmaCode,
|
|
$this->workflowFornitoreResoId ?: 392,
|
|
$this->workflowNote ?: 'Reso in garanzia al produttore / fornitore'
|
|
);
|
|
|
|
Notification::make()->title("Pratica inviata in RMA/Garanzia (RMA: {$scheda->rma_code})")->info()->send();
|
|
$this->openScheda($this->selectedSchedaId);
|
|
$this->refreshData();
|
|
}
|
|
|
|
public function sincronizzaMdb(): void
|
|
{
|
|
try {
|
|
$service = app(TecnoRepairArchiveService::class);
|
|
$stats = $service->importArchive(13, (int) $this->fornitoreId);
|
|
$msg = sprintf(
|
|
'Archivio MDB TecnoRepair sincronizzato: %d schede (%d create, %d agg.), %d ricambi, %d seriali.',
|
|
$stats['schede_lette'],
|
|
$stats['schede_create'],
|
|
$stats['schede_aggiornate'],
|
|
$stats['ricambi_catalogati'],
|
|
$stats['seriali_allineati']
|
|
);
|
|
Notification::make()->title($msg)->success()->send();
|
|
$this->refreshData();
|
|
} catch (\Throwable $e) {
|
|
Notification::make()->title('Errore sincronizzazione TecnoRepair: ' . $e->getMessage())->danger()->send();
|
|
}
|
|
}
|
|
|
|
public function sincronizzaContabilita(): void
|
|
{
|
|
try {
|
|
$service = app(ContabilitaMysqlSerialImportService::class);
|
|
$stats = $service->importForSupplier('NCOMSRL');
|
|
$msg = sprintf(
|
|
'Contabilità MySQL sincronizzata: %d fatture lette, %d seriali aggiornati.',
|
|
$stats['invoices_count'],
|
|
$stats['serials_created'] + $stats['serials_updated']
|
|
);
|
|
Notification::make()->title($msg)->success()->send();
|
|
$this->refreshData();
|
|
} catch (\Throwable $e) {
|
|
Notification::make()->title('Errore sincronizzazione Contabilità: ' . $e->getMessage())->danger()->send();
|
|
}
|
|
}
|
|
|
|
private function extractBrand(?string $model): string
|
|
{
|
|
$model = trim((string) $model);
|
|
if ($model === '') {
|
|
return '-';
|
|
}
|
|
|
|
$firstWord = strtoupper(explode(' ', $model)[0] ?? '');
|
|
if (in_array($firstWord, ['HP', 'LENOVO', 'DELL', 'ASUS', 'ACER', 'APPLE', 'TOSHIBA', 'MSI', 'SAMSUNG', 'HANSUNG'], true)) {
|
|
return $firstWord;
|
|
}
|
|
|
|
return $firstWord ?: '-';
|
|
}
|
|
}
|