- Added ListinoRelationManager for managing price lists associated with models. - Introduced ImportaListiniAction for importing price lists from Excel files. - Created ListinoPrezzo model to represent price entries in the database. - Developed ListinoExcelParser for parsing Excel files containing price lists. - Implemented ListinoImporter to handle the import logic and associations. - Added migration for creating listino_prezzi table and converting measures to mm. - Updated frontend logic to handle new price list features and validations. - Enhanced tests for price list import and conversion functionalities.
87 lines
3.1 KiB
PHP
87 lines
3.1 KiB
PHP
<?php
|
|
|
|
namespace App\Support\Listini;
|
|
|
|
use App\Models\Modello;
|
|
use App\Models\Sistema;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Str;
|
|
|
|
class ListinoImporter
|
|
{
|
|
// Codici del file con refusi noti rispetto al codice interno del modello.
|
|
private const ALIAS = [
|
|
'finestra_wasistas' => 'finestra_vasistas',
|
|
];
|
|
|
|
/**
|
|
* Associazione proposta codice-del-file → modello del sistema (null se nessun
|
|
* modello corrisponde): per codice interno, poi per nome o descrizione.
|
|
*
|
|
* @param list<string> $codici
|
|
* @return array<string, int|null>
|
|
*/
|
|
public static function suggerisciAssociazioni(Sistema $sistema, array $codici): array
|
|
{
|
|
$modelli = $sistema->modelli()->get();
|
|
$associazioni = [];
|
|
|
|
foreach ($codici as $codice) {
|
|
$associazioni[$codice] = self::trovaModello($modelli, $codice)?->id;
|
|
}
|
|
|
|
return $associazioni;
|
|
}
|
|
|
|
private static function trovaModello(Collection $modelli, string $codice): ?Modello
|
|
{
|
|
$slug = Str::slug($codice, '_');
|
|
$slug = self::ALIAS[$slug] ?? $slug;
|
|
|
|
return $modelli->first(fn (Modello $m) => $m->codice === $slug)
|
|
?? $modelli->first(fn (Modello $m) => Str::slug($m->nome, '_') === $slug)
|
|
?? $modelli->first(fn (Modello $m) => $m->descrizione && Str::slug($m->descrizione, '_') === $slug);
|
|
}
|
|
|
|
/**
|
|
* Sostituisce il listino di ogni modello associato con i prezzi del rispettivo blocco.
|
|
*
|
|
* @param list<array{codice: string, prezzi: list<array>}> $blocchi
|
|
* @param array<string, int|null> $associazioni codice del file → id modello
|
|
* @return int numero di modelli aggiornati
|
|
*/
|
|
public static function importa(Sistema $sistema, array $blocchi, array $associazioni): int
|
|
{
|
|
$prezziPerCodice = collect($blocchi)->keyBy('codice')->map(fn (array $b) => $b['prezzi']);
|
|
$modelli = $sistema->modelli()->get()->keyBy('id');
|
|
|
|
return DB::transaction(function () use ($associazioni, $prezziPerCodice, $modelli) {
|
|
$aggiornati = 0;
|
|
$ora = now();
|
|
|
|
foreach ($associazioni as $codice => $modelloId) {
|
|
$modello = $modelloId ? $modelli->get($modelloId) : null;
|
|
if (! $modello || ! $prezziPerCodice->has($codice)) {
|
|
continue;
|
|
}
|
|
|
|
$modello->listino()->delete();
|
|
// Una stessa misura ripetuta nel blocco: vale l'ultima.
|
|
$righe = collect($prezziPerCodice[$codice])
|
|
->keyBy(fn (array $p) => $p['larghezza'].'x'.$p['altezza'])
|
|
->map(fn (array $p) => $p + ['modello_id' => $modello->id, 'created_at' => $ora, 'updated_at' => $ora])
|
|
->values();
|
|
foreach ($righe->chunk(500) as $chunk) {
|
|
$modello->listino()->insert($chunk->all());
|
|
}
|
|
|
|
$modello->update(['listino_aggiornato_at' => $ora]);
|
|
$aggiornati++;
|
|
}
|
|
|
|
return $aggiornati;
|
|
});
|
|
}
|
|
}
|