pdv.backend/app/Imports/ProductsImport.php
Juan Felipe Zapata Moreno 07ee72e548 add: importar excel
2026-01-02 15:34:57 -06:00

123 lines
3.2 KiB
PHP

<?php
namespace App\Imports;
use App\Models\Inventory;
use App\Models\Price;
use App\Models\Category;
use App\Http\Requests\App\InventoryImportRequest;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithValidation;
use Maatwebsite\Excel\Concerns\Importable;
use Maatwebsite\Excel\Concerns\WithBatchInserts;
use Maatwebsite\Excel\Concerns\WithChunkReading;
/**
* Import de productos desde Excel
*
* Formato esperado del Excel:
* - nombre: Nombre del producto (requerido)
* - sku: Código SKU (opcional, único)
* - categoria: Nombre de la categoría (opcional)
* - stock: Cantidad inicial (requerido, mínimo 0)
* - costo: Precio de costo (requerido, mínimo 0)
* - precio_venta: Precio de venta (requerido, mayor que costo)
* - impuesto: Porcentaje de impuesto (opcional, 0-100)
*/
class ProductsImport implements ToModel, WithHeadingRow, WithValidation, WithBatchInserts, WithChunkReading
{
use Importable;
private $errors = [];
private $imported = 0;
private $skipped = 0;
/**
* Procesa cada fila del Excel
*/
public function model(array $row)
{
try {
// Buscar o crear categoría si se proporciona
$categoryId = null;
if (!empty($row['categoria'])) {
$category = Category::firstOrCreate(
['name' => trim($row['categoria'])],
['is_active' => true]
);
$categoryId = $category->id;
}
// Crear el producto en inventario
$inventory = Inventory::create([
'name' => trim($row['nombre']),
'sku' => !empty($row['sku']) ? trim($row['sku']) : null,
'category_id' => $categoryId,
'stock' => (int) $row['stock'],
'is_active' => true,
]);
// Crear el precio del producto
Price::create([
'inventory_id' => $inventory->id,
'cost' => (float) $row['costo'],
'retail_price' => (float) $row['precio_venta'],
'tax' => !empty($row['impuesto']) ? (float) $row['impuesto'] : 0,
]);
$this->imported++;
return $inventory;
} catch (\Exception $e) {
$this->skipped++;
$this->errors[] = "Error en fila: " . $e->getMessage();
return null;
}
}
/**
* Reglas de validación para cada fila
*/
public function rules(): array
{
return InventoryImportRequest::rowRules();
}
/**
* Mensajes personalizados de validación
*/
public function customValidationMessages()
{
return InventoryImportRequest::rowMessages();
}
/**
* Batch insert size
*/
public function batchSize(): int
{
return 100;
}
/**
* Chunk size for reading
*/
public function chunkSize(): int
{
return 100;
}
/**
* Obtener estadísticas de la importación
*/
public function getStats(): array
{
return [
'imported' => $this->imported,
'skipped' => $this->skipped,
'errors' => $this->errors,
];
}
}