g
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\Product;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class ImportarProductosCsv extends Command
|
||||
{
|
||||
// Este es el comando que escribirás en la terminal
|
||||
protected $signature = 'importar:productos';
|
||||
protected $description = 'Importa bicicletas, accesorios e indumentaria desde archivos CSV';
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$this->info("Iniciando importación masiva de Lauck...");
|
||||
|
||||
// Definimos los archivos, el tipo de producto, y cuántas filas saltar (los encabezados)
|
||||
$archivos = [
|
||||
[
|
||||
'ruta' => 'imports/LISTA DE PRECIOS.xlsx - LISTA.csv',
|
||||
'tipo' => 'accessory',
|
||||
'saltar' => 1 // Asumimos 1 fila de encabezado
|
||||
],
|
||||
[
|
||||
'ruta' => 'imports/LISTA DE PRECIOS.xlsx - BICICLETAS.csv',
|
||||
'tipo' => 'bike',
|
||||
'saltar' => 11 // Metadatos dicen que hay ~10 filas arriba del encabezado
|
||||
],
|
||||
[
|
||||
'ruta' => 'imports/LISTA DE PRECIOS.xlsx - INDUMENTARIA.csv',
|
||||
'tipo' => 'clothing',
|
||||
'saltar' => 8 // Metadatos dicen que hay ~7 filas arriba
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($archivos as $archivo) {
|
||||
$this->procesarCsv($archivo['ruta'], $archivo['tipo'], $archivo['saltar']);
|
||||
}
|
||||
|
||||
$this->info("¡Importación finalizada con éxito!");
|
||||
}
|
||||
|
||||
private function procesarCsv($rutaArchivo, $tipoProducto, $filasASaltar)
|
||||
{
|
||||
// Verificamos si el archivo existe en storage/app/imports/
|
||||
if (!Storage::exists($rutaArchivo)) {
|
||||
$this->error("No se encontró el archivo: {$rutaArchivo}");
|
||||
return;
|
||||
}
|
||||
|
||||
$this->line("Procesando: {$rutaArchivo}...");
|
||||
|
||||
// Abrimos el archivo
|
||||
$rutaCompleta = storage_path('app/' . $rutaArchivo);
|
||||
$file = fopen($rutaCompleta, 'r');
|
||||
|
||||
// 1. Saltamos las filas "basura" del principio
|
||||
for ($i = 0; $i < $filasASaltar; $i++) {
|
||||
fgetcsv($file);
|
||||
}
|
||||
|
||||
$contador = 0;
|
||||
|
||||
// 2. Leemos fila por fila (para no saturar la memoria RAM)
|
||||
while (($fila = fgetcsv($file, 1000, ',')) !== false) {
|
||||
// Ignorar filas completamente vacías
|
||||
if (empty(array_filter($fila))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// ¡ATENCIÓN ACÁ! Tenés que mapear las columnas de tu Excel.
|
||||
// En programación, la primera columna (A) es la 0, la (B) es 1, etc.
|
||||
// =========================================================
|
||||
|
||||
$sku = $fila[0] ?? null; // Ajustar número de columna
|
||||
$name = $fila[1] ?? 'Sin Nombre'; // Ajustar número
|
||||
|
||||
// Limpiamos los precios (sacar el signo $ y separar miles si es necesario)
|
||||
$precioRaw = $fila[2] ?? 0; // Ajustar número
|
||||
$precioLimpio = (float) filter_var($precioRaw, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
|
||||
|
||||
$stock = $fila[3] ?? 0; // Ajustar número
|
||||
|
||||
// 3. Guardar en la Base de Datos
|
||||
// Usamos updateOrCreate para que si corrés el comando 2 veces, no duplique cosas
|
||||
Product::updateOrCreate(
|
||||
['sku' => $sku], // Busca por SKU. Si existe, actualiza. Si no, crea.
|
||||
[
|
||||
'name' => $name,
|
||||
'price' => $precioLimpio,
|
||||
'stock_quantity' => (int) $stock,
|
||||
'type' => $tipoProducto,
|
||||
'min_stock_alert' => 5, // Valor por defecto
|
||||
'suppliers_id' => 1, // Valor por defecto
|
||||
]
|
||||
);
|
||||
|
||||
$contador++;
|
||||
}
|
||||
|
||||
fclose($file);
|
||||
$this->info("✔ {$contador} productos importados de tipo {$tipoProducto}.");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user