147 lines
5.3 KiB
PHP
147 lines
5.3 KiB
PHP
<?php
|
|
namespace App\Filament\Pages\Fornitore;
|
|
|
|
use App\Filament\Pages\Fornitore\Concerns\ResolvesOperatoreContext;
|
|
use App\Models\Fornitore;
|
|
use App\Models\Product;
|
|
use App\Models\ProductIdentifier;
|
|
use App\Models\ProductOffer;
|
|
use App\Models\User;
|
|
use BackedEnum;
|
|
use Filament\Pages\Page;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use UnitEnum;
|
|
|
|
class ProdottiCatalogo extends Page
|
|
{
|
|
use ResolvesOperatoreContext;
|
|
|
|
protected static ?string $navigationLabel = 'Prodotti';
|
|
|
|
protected static ?string $title = 'Catalogo prodotti fornitore';
|
|
|
|
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-archive-box';
|
|
|
|
protected static UnitEnum|string|null $navigationGroup = 'Fornitore';
|
|
|
|
protected static ?int $navigationSort = 4;
|
|
|
|
protected static ?string $slug = 'fornitore/prodotti';
|
|
|
|
protected string $view = 'filament.pages.fornitore.prodotti-catalogo';
|
|
|
|
public ?int $fornitoreId = null;
|
|
|
|
public ?string $fornitoreLabel = null;
|
|
|
|
public bool $missingAdminContext = false;
|
|
|
|
public string $search = '';
|
|
|
|
/** @var array<int, array<string, mixed>> */
|
|
public array $rows = [];
|
|
|
|
public static function canAccess(): bool
|
|
{
|
|
$user = Auth::user();
|
|
|
|
return $user instanceof User
|
|
&& $user->hasAnyRole(['super-admin', 'admin', 'amministratore', '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);
|
|
$this->refreshRows();
|
|
}
|
|
|
|
public function updatedSearch(): void
|
|
{
|
|
$this->refreshRows();
|
|
}
|
|
|
|
public function refreshRows(): void
|
|
{
|
|
if (! $this->fornitoreId) {
|
|
$this->rows = [];
|
|
return;
|
|
}
|
|
|
|
$term = trim($this->search);
|
|
$normalized = preg_replace('/[^A-Za-z0-9]+/', '', strtoupper($term)) ?? '';
|
|
|
|
$products = Product::query()
|
|
->with(['identifiers', 'offers'])
|
|
->where('is_active', true)
|
|
->where(function ($query): void {
|
|
$query->whereNull('default_fornitore_id')
|
|
->orWhere('default_fornitore_id', (int) $this->fornitoreId)
|
|
->orWhereHas('offers', fn($offerQuery) => $offerQuery->where('fornitore_id', (int) $this->fornitoreId));
|
|
})
|
|
->when($term !== '', function ($query) use ($term, $normalized): void {
|
|
$query->where(function ($builder) use ($term, $normalized): void {
|
|
$builder->where('name', 'like', '%' . $term . '%')
|
|
->orWhere('brand', 'like', '%' . $term . '%')
|
|
->orWhere('model', 'like', '%' . $term . '%')
|
|
->orWhere('internal_code', 'like', '%' . $term . '%');
|
|
|
|
if ($normalized !== '') {
|
|
$builder->orWhereHas('identifiers', function ($identifierQuery) use ($normalized): void {
|
|
$identifierQuery->where('normalized_code', $normalized)
|
|
->orWhere('code_value', 'like', '%' . $normalized . '%');
|
|
});
|
|
}
|
|
});
|
|
})
|
|
->limit(120)
|
|
->get();
|
|
|
|
$this->rows = $products->map(function (Product $product): array {
|
|
$identifier = $product->identifiers
|
|
->first(fn(ProductIdentifier $item): bool => (int) ($item->fornitore_id ?? 0) === (int) $this->fornitoreId)
|
|
?? $product->identifiers->first();
|
|
$offer = $product->offers
|
|
->first(fn(ProductOffer $item): bool => (int) ($item->fornitore_id ?? 0) === (int) $this->fornitoreId)
|
|
?? $product->offers->first();
|
|
|
|
return [
|
|
'id' => (int) $product->id,
|
|
'internal_code' => (string) ($product->internal_code ?? ''),
|
|
'label' => trim(implode(' ', array_filter([(string) $product->name, (string) ($product->brand ?? ''), (string) ($product->model ?? '')]))),
|
|
'barcode' => (string) ($identifier->code_value ?? ''),
|
|
'source' => (string) ($offer?->source_name ?: 'Catalogo interno'),
|
|
'price' => $offer?->price_amount !== null ? number_format((float) $offer->price_amount, 2, ',', '.') . ' ' . (string) ($offer->currency ?? 'EUR') : '-',
|
|
'external_url' => (string) ($offer?->referral_url ?: $offer?->external_url ?: $this->buildAmazonSearchUrl((string) $product->name)),
|
|
];
|
|
})->all();
|
|
}
|
|
|
|
public function getLavorazioniUrl(): string
|
|
{
|
|
return LavorazioniOperative::getUrl(['fornitore' => (int) $this->fornitoreId], panel: 'admin-filament');
|
|
}
|
|
|
|
public function getRubricaUrl(): string
|
|
{
|
|
return RubricaClienti::getUrl(['fornitore' => (int) $this->fornitoreId], panel: 'admin-filament');
|
|
}
|
|
|
|
protected function buildAmazonSearchUrl(string $term): string
|
|
{
|
|
$query = ['k' => trim($term)];
|
|
$tag = trim((string) config('services.amazon.referral_tag', ''));
|
|
if ($tag !== '') {
|
|
$query['tag'] = $tag;
|
|
}
|
|
|
|
return 'https://www.amazon.it/s?' . http_build_query($query);
|
|
}
|
|
} |