feat: Implement price list management and import functionality
- 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.
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// Griglia prezzi del modello: un prezzo per ogni coppia larghezza × altezza.
|
||||
Schema::create('listino_prezzi', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('modello_id')->constrained('modelli')->cascadeOnDelete();
|
||||
$table->decimal('larghezza', 8, 2);
|
||||
$table->decimal('altezza', 8, 2);
|
||||
$table->decimal('prezzo', 10, 2);
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['modello_id', 'larghezza', 'altezza']);
|
||||
});
|
||||
|
||||
Schema::table('modelli', function (Blueprint $table) {
|
||||
$table->timestamp('listino_aggiornato_at')->nullable()->after('moduli');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('modelli', function (Blueprint $table) {
|
||||
$table->dropColumn('listino_aggiornato_at');
|
||||
});
|
||||
|
||||
Schema::dropIfExists('listino_prezzi');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* Le misure passano da centimetri a millimetri: listini dei modelli e misure dei
|
||||
* prodotti già nei preventivi (colonne e payload del configuratore).
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$this->converti(10);
|
||||
|
||||
Schema::table('listino_prezzi', function (Blueprint $table) {
|
||||
$table->unsignedInteger('larghezza')->change();
|
||||
$table->unsignedInteger('altezza')->change();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('listino_prezzi', function (Blueprint $table) {
|
||||
$table->decimal('larghezza', 8, 2)->change();
|
||||
$table->decimal('altezza', 8, 2)->change();
|
||||
});
|
||||
|
||||
$this->converti(0.1);
|
||||
}
|
||||
|
||||
private function converti(float $fattore): void
|
||||
{
|
||||
// In due passaggi (prima negativi, poi positivi): MySQL verifica l'indice univoco
|
||||
// riga per riga, e un valore già convertito (30 → 300) collide con uno non ancora
|
||||
// convertito. I negativi non collidono con nessun valore originale.
|
||||
DB::table('listino_prezzi')->update([
|
||||
'larghezza' => DB::raw("-ROUND(larghezza * {$fattore}, 2)"),
|
||||
'altezza' => DB::raw("-ROUND(altezza * {$fattore}, 2)"),
|
||||
]);
|
||||
DB::table('listino_prezzi')->update([
|
||||
'larghezza' => DB::raw('-larghezza'),
|
||||
'altezza' => DB::raw('-altezza'),
|
||||
]);
|
||||
|
||||
DB::table('preventivo_items')->orderBy('id')->chunkById(200, function ($items) use ($fattore) {
|
||||
foreach ($items as $item) {
|
||||
$payload = json_decode($item->payload ?? 'null', true);
|
||||
foreach (['width', 'height'] as $chiave) {
|
||||
if (is_array($payload) && is_numeric($payload[$chiave] ?? null)) {
|
||||
$payload[$chiave] = (string) round((float) $payload[$chiave] * $fattore, 2);
|
||||
}
|
||||
}
|
||||
|
||||
DB::table('preventivo_items')->where('id', $item->id)->update([
|
||||
'larghezza' => $item->larghezza === null ? null : (int) round($item->larghezza * $fattore),
|
||||
'altezza' => $item->altezza === null ? null : (int) round($item->altezza * $fattore),
|
||||
'payload' => $payload === null ? $item->payload : json_encode($payload),
|
||||
]);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user