up
This commit is contained in:
@@ -0,0 +1,295 @@
|
||||
<?php
|
||||
|
||||
namespace App\Imports;
|
||||
|
||||
use App\Models\Producto;
|
||||
use App\Models\ProductVariant;
|
||||
use App\Models\Bodega;
|
||||
use Maatwebsite\Excel\Concerns\ToCollection;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadingRow;
|
||||
use Maatwebsite\Excel\Concerns\WithValidation;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class CompraDetallesImport implements ToCollection, WithHeadingRow, WithValidation
|
||||
{
|
||||
protected $previewData = [];
|
||||
protected $errors = [];
|
||||
|
||||
/**
|
||||
* Procesa la colección y genera vista preliminar
|
||||
*/
|
||||
public function collection(Collection $rows)
|
||||
{
|
||||
$this->previewData = [];
|
||||
$rowNumber = 2; // Comenzar en 2 porque fila 1 son los encabezados
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$detalle = $this->processRow($row->toArray(), $rowNumber);
|
||||
$this->previewData[] = $detalle;
|
||||
$rowNumber++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Procesa una fila individual
|
||||
*/
|
||||
private function processRow(array $row, int $rowNumber): array
|
||||
{
|
||||
$result = [
|
||||
'row_number' => $rowNumber,
|
||||
'valid' => true,
|
||||
'errors' => [],
|
||||
'data' => [],
|
||||
'producto_creado' => false,
|
||||
];
|
||||
|
||||
// Normalizar nombres de columnas
|
||||
$row = $this->normalizeKeys($row);
|
||||
|
||||
// Buscar o crear producto
|
||||
$producto = null;
|
||||
$variante = null;
|
||||
$productoCreado = false;
|
||||
|
||||
// 1. Primero intentar buscar por código de barras
|
||||
if (!empty($row['codigo_barras'])) {
|
||||
// Buscar variante primero
|
||||
$variante = ProductVariant::where('barcode', $row['codigo_barras'])->first();
|
||||
if ($variante) {
|
||||
$producto = $variante->producto;
|
||||
} else {
|
||||
// Buscar producto por código
|
||||
$producto = Producto::where('codigo_barras', $row['codigo_barras'])->first();
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Si no se encontró por código, buscar por nombre
|
||||
if (!$producto && !empty($row['producto'])) {
|
||||
$producto = Producto::where('nombre', 'like', '%' . trim($row['producto']) . '%')->first();
|
||||
}
|
||||
|
||||
// 3. Si no existe, crear el producto
|
||||
if (!$producto) {
|
||||
// Validar que tenga al menos nombre o código
|
||||
if (empty($row['producto']) && empty($row['codigo_barras'])) {
|
||||
$result['valid'] = false;
|
||||
$result['errors'][] = 'Debe proporcionar código de barras o nombre del producto';
|
||||
} else {
|
||||
$nombreProducto = !empty($row['producto']) ? trim($row['producto']) : 'Producto ' . $row['codigo_barras'];
|
||||
$precioUnitario = isset($row['precio_unitario']) ? (float) $row['precio_unitario'] : 0;
|
||||
|
||||
if ($precioUnitario <= 0) {
|
||||
$result['valid'] = false;
|
||||
$result['errors'][] = 'Precio debe ser mayor a 0 para crear producto';
|
||||
} else {
|
||||
// Buscar o crear categoría "Importados"
|
||||
$categoria = \App\Models\Categoria::firstOrCreate(
|
||||
['nombre' => 'Importados'],
|
||||
['descripcion' => 'Productos creados automáticamente durante importación de compras']
|
||||
);
|
||||
|
||||
// Generar código de barras único si no se proporcionó
|
||||
$codigoBarras = !empty($row['codigo_barras']) ? $row['codigo_barras'] : null;
|
||||
|
||||
if (!$codigoBarras) {
|
||||
// Generar código único: IMP + timestamp + random
|
||||
do {
|
||||
$codigoBarras = 'IMP' . time() . rand(100, 999);
|
||||
} while (Producto::where('codigo_barras', $codigoBarras)->exists());
|
||||
}
|
||||
|
||||
$producto = Producto::create([
|
||||
'nombre' => $nombreProducto,
|
||||
'descripcion' => 'Creado automáticamente desde importación',
|
||||
'codigo_barras' => $codigoBarras,
|
||||
'categoria_id' => $categoria->id,
|
||||
'precio_compra' => $precioUnitario,
|
||||
'precio_venta' => round($precioUnitario * 1.3, 2), // 30% de margen por defecto
|
||||
'unidad_medida' => 'unidad',
|
||||
'estado' => true,
|
||||
'imagen' => '',
|
||||
]);
|
||||
|
||||
$productoCreado = true;
|
||||
$result['producto_creado'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Buscar bodega
|
||||
$bodega = null;
|
||||
if (!empty($row['bodega'])) {
|
||||
$bodega = Bodega::where('nombre', 'like', '%' . $row['bodega'] . '%')->first();
|
||||
} else {
|
||||
$bodega = Bodega::where('nombre', 'Principal')->first();
|
||||
}
|
||||
|
||||
if (!$bodega) {
|
||||
$result['valid'] = false;
|
||||
$result['errors'][] = 'Bodega no encontrada';
|
||||
}
|
||||
|
||||
// Validar cantidad
|
||||
$cantidad = isset($row['cantidad']) ? (int) $row['cantidad'] : 1;
|
||||
if ($cantidad <= 0) {
|
||||
$result['valid'] = false;
|
||||
$result['errors'][] = 'Cantidad debe ser mayor a 0';
|
||||
}
|
||||
|
||||
// Validar precio
|
||||
$precio = isset($row['precio_unitario']) ? (float) $row['precio_unitario'] : 0;
|
||||
if ($precio <= 0) {
|
||||
$result['valid'] = false;
|
||||
$result['errors'][] = 'Precio debe ser mayor a 0';
|
||||
}
|
||||
|
||||
// Calcular subtotal
|
||||
$subtotal = $cantidad * $precio;
|
||||
|
||||
// Preparar datos
|
||||
$result['data'] = [
|
||||
'codigo_barras' => $row['codigo_barras'] ?? '',
|
||||
'producto_nombre_excel' => $row['producto'] ?? '',
|
||||
'bodega_id' => $bodega?->id,
|
||||
'bodega_nombre' => $bodega?->nombre ?? 'No encontrada',
|
||||
'producto_id' => $producto?->id,
|
||||
'producto_nombre' => $producto?->nombre ?? 'No encontrado',
|
||||
'variante_id' => $variante?->id,
|
||||
'variante_info' => $variante ? $this->getVariantInfo($variante) : null,
|
||||
'cantidad' => $cantidad,
|
||||
'precio_unitario' => $precio,
|
||||
'subtotal' => $subtotal,
|
||||
'DetalleCompra' => $row['observaciones'] ?? $row['detalle'] ?? '',
|
||||
];
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene información formateada de la variante
|
||||
*/
|
||||
private function getVariantInfo($variante): string
|
||||
{
|
||||
$colorName = $variante->color?->name ?? 'Sin color';
|
||||
$sizeName = $variante->size?->name ?? 'Sin talla';
|
||||
return "$colorName / $sizeName";
|
||||
}
|
||||
|
||||
/**
|
||||
* Normaliza las claves del array
|
||||
*/
|
||||
private function normalizeKeys(array $row): array
|
||||
{
|
||||
$normalized = [];
|
||||
$mappings = [
|
||||
'codigo_de_barras' => 'codigo_barras',
|
||||
'codigo' => 'codigo_barras',
|
||||
'barcode' => 'codigo_barras',
|
||||
'precio' => 'precio_unitario',
|
||||
'precio_unit' => 'precio_unitario',
|
||||
'observacion' => 'observaciones',
|
||||
'detalle' => 'observaciones',
|
||||
'cantidad' => 'cantidad',
|
||||
'cant' => 'cantidad',
|
||||
'qty' => 'cantidad',
|
||||
'producto' => 'producto',
|
||||
'nombre' => 'producto',
|
||||
'nombre_producto' => 'producto',
|
||||
'articulo' => 'producto',
|
||||
'bodega' => 'bodega',
|
||||
];
|
||||
|
||||
foreach ($row as $key => $value) {
|
||||
$normalizedKey = strtolower(trim($key));
|
||||
$normalizedKey = str_replace(' ', '_', $normalizedKey);
|
||||
$normalizedKey = $this->removeAccents($normalizedKey);
|
||||
|
||||
if (isset($mappings[$normalizedKey])) {
|
||||
$normalized[$mappings[$normalizedKey]] = $value;
|
||||
} else {
|
||||
$normalized[$normalizedKey] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Elimina tildes
|
||||
*/
|
||||
private function removeAccents($string)
|
||||
{
|
||||
$unwanted = [
|
||||
'á' => 'a', 'é' => 'e', 'í' => 'i', 'ó' => 'o', 'ú' => 'u',
|
||||
'Á' => 'A', 'É' => 'E', 'Í' => 'I', 'Ó' => 'O', 'Ú' => 'U',
|
||||
'ñ' => 'n', 'Ñ' => 'N',
|
||||
];
|
||||
return strtr($string, $unwanted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reglas de validación
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'codigo_barras' => 'nullable|string',
|
||||
'producto' => 'nullable|string',
|
||||
'bodega' => 'nullable|string',
|
||||
'cantidad' => 'nullable|integer|min:1',
|
||||
'precio_unitario' => 'nullable|numeric|min:0',
|
||||
'observaciones' => 'nullable|string',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene los datos de vista preliminar
|
||||
*/
|
||||
public function getPreviewData(): array
|
||||
{
|
||||
return $this->previewData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene estadísticas de la importación
|
||||
*/
|
||||
public function getStats(): array
|
||||
{
|
||||
$valid = collect($this->previewData)->filter(fn($item) => $item['valid'])->count();
|
||||
$invalid = collect($this->previewData)->filter(fn($item) => !$item['valid'])->count();
|
||||
$productosCreados = collect($this->previewData)->filter(fn($item) => isset($item['producto_creado']) && $item['producto_creado'])->count();
|
||||
$total = count($this->previewData);
|
||||
$totalAmount = collect($this->previewData)
|
||||
->where('valid', true)
|
||||
->sum(fn($item) => $item['data']['subtotal']);
|
||||
|
||||
return [
|
||||
'total' => $total,
|
||||
'valid' => $valid,
|
||||
'invalid' => $invalid,
|
||||
'productos_creados' => $productosCreados,
|
||||
'total_amount' => $totalAmount,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Convierte los datos preliminares a formato para guardar
|
||||
*/
|
||||
public function getDetallesForSave(): array
|
||||
{
|
||||
return collect($this->previewData)
|
||||
->filter(fn($item) => $item['valid'])
|
||||
->map(fn($item) => [
|
||||
'bodega_id' => $item['data']['bodega_id'],
|
||||
'producto_id' => $item['data']['producto_id'],
|
||||
'variante_id' => $item['data']['variante_id'],
|
||||
'cantidad' => $item['data']['cantidad'],
|
||||
'precio_unitario' => $item['data']['precio_unitario'],
|
||||
'subtotal' => $item['data']['subtotal'],
|
||||
'DetalleCompra' => $item['data']['DetalleCompra'],
|
||||
'producto_nombre_snapshot' => $item['data']['producto_nombre'],
|
||||
'variante_info_snapshot' => $item['data']['variante_info'],
|
||||
])
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,300 @@
|
||||
<?php
|
||||
|
||||
namespace App\Imports;
|
||||
|
||||
use App\Models\Producto;
|
||||
use App\Models\Categoria;
|
||||
use App\Models\Bodega;
|
||||
use Maatwebsite\Excel\Concerns\ToModel;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadingRow;
|
||||
use Maatwebsite\Excel\Concerns\WithValidation;
|
||||
use Maatwebsite\Excel\Concerns\SkipsOnFailure;
|
||||
use Maatwebsite\Excel\Concerns\SkipsOnError;
|
||||
use Maatwebsite\Excel\Concerns\SkipsFailures;
|
||||
use Maatwebsite\Excel\Concerns\SkipsErrors;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class ProductosImport implements ToModel, WithHeadingRow, WithValidation, SkipsOnFailure, SkipsOnError
|
||||
{
|
||||
use SkipsFailures, SkipsErrors;
|
||||
|
||||
/**
|
||||
* Normaliza y prepara los datos antes de la validación.
|
||||
*/
|
||||
public function prepareForValidation($data, $index)
|
||||
{
|
||||
// Normalizar nombres de columnas
|
||||
$normalizedData = [];
|
||||
foreach ($data as $key => $value) {
|
||||
$normalizedKey = $this->normalizeColumnName($key);
|
||||
$normalizedData[$normalizedKey] = $value;
|
||||
}
|
||||
$data = $normalizedData;
|
||||
|
||||
// Código de barras a string
|
||||
if (isset($data['codigo_de_barras']) && is_numeric($data['codigo_de_barras'])) {
|
||||
$data['codigo_de_barras'] = (string) $data['codigo_de_barras'];
|
||||
}
|
||||
|
||||
// Estado a string
|
||||
if (isset($data['estado'])) {
|
||||
if (is_bool($data['estado']) || is_numeric($data['estado'])) {
|
||||
$data['estado'] = $data['estado'] ? 'Activo' : 'Inactivo';
|
||||
}
|
||||
}
|
||||
|
||||
// Unidad de medida a string
|
||||
if (isset($data['unidad_de_medida']) && !is_string($data['unidad_de_medida'])) {
|
||||
$data['unidad_de_medida'] = (string) $data['unidad_de_medida'];
|
||||
}
|
||||
|
||||
// Categoría por nombre
|
||||
if (!empty($data['categoria_nombre']) && empty($data['categoria_id'])) {
|
||||
$categoria = Categoria::firstOrCreate(
|
||||
['nombre' => $data['categoria_nombre']],
|
||||
['descripcion' => 'Categoría creada automáticamente durante importación']
|
||||
);
|
||||
$data['categoria_id'] = $categoria->id;
|
||||
}
|
||||
|
||||
// Categoría (id o nombre)
|
||||
if (!empty($data['categoria']) && empty($data['categoria_id'])) {
|
||||
if (is_numeric($data['categoria'])) {
|
||||
$data['categoria_id'] = $data['categoria'];
|
||||
} else {
|
||||
$categoria = Categoria::firstOrCreate(
|
||||
['nombre' => $data['categoria']],
|
||||
['descripcion' => 'Categoría creada automáticamente durante importación']
|
||||
);
|
||||
$data['categoria_id'] = $categoria->id;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normaliza el nombre de una columna.
|
||||
*/
|
||||
private function normalizeColumnName($name)
|
||||
{
|
||||
$mappings = [
|
||||
'código de barras' => 'codigo_de_barras',
|
||||
'codigo de barras' => 'codigo_de_barras',
|
||||
'categoría' => 'categoria',
|
||||
'categoria' => 'categoria',
|
||||
'descripción' => 'descripcion',
|
||||
'descripcion' => 'descripcion',
|
||||
'unidad de medida' => 'unidad_de_medida',
|
||||
'stock mínimo' => 'stock_minimo',
|
||||
'stock minimo' => 'stock_minimo',
|
||||
'stock máximo' => 'stock_maximo',
|
||||
'stock maximo' => 'stock_maximo',
|
||||
'precio compra' => 'precio_compra',
|
||||
'precio venta' => 'precio_venta',
|
||||
];
|
||||
$normalized = strtolower(trim($name));
|
||||
if (isset($mappings[$normalized])) {
|
||||
return $mappings[$normalized];
|
||||
}
|
||||
$normalized = str_replace(' ', '_', $normalized);
|
||||
$normalized = $this->removeAccents($normalized);
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Elimina tildes.
|
||||
*/
|
||||
private function removeAccents($string)
|
||||
{
|
||||
$unwanted = [
|
||||
'á' => 'a', 'é' => 'e', 'í' => 'i', 'ó' => 'o', 'ú' => 'u',
|
||||
'Á' => 'A', 'É' => 'E', 'Í' => 'I', 'Ó' => 'O', 'Ú' => 'U',
|
||||
'ñ' => 'n', 'Ñ' => 'N',
|
||||
];
|
||||
return strtr($string, $unwanted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene el ID de categoría.
|
||||
*/
|
||||
private function getCategoriaId(array $row): ?int
|
||||
{
|
||||
if (!empty($row['categoria_id']) && is_numeric($row['categoria_id'])) {
|
||||
return (int) $row['categoria_id'];
|
||||
}
|
||||
if (!empty($row['categoria_nombre'])) {
|
||||
$cat = Categoria::where('nombre', $row['categoria_nombre'])->first();
|
||||
if ($cat) return $cat->id;
|
||||
}
|
||||
if (!empty($row['categoria'])) {
|
||||
if (is_numeric($row['categoria'])) {
|
||||
return (int) $row['categoria'];
|
||||
}
|
||||
$cat = Categoria::where('nombre', $row['categoria'])->first();
|
||||
if ($cat) return $cat->id;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parsea unidad de medida.
|
||||
*/
|
||||
private function parseUnidadMedida($value): string
|
||||
{
|
||||
if (empty($value)) return 'unidad';
|
||||
$value = strtolower(trim($value));
|
||||
$map = [
|
||||
'unidad' => 'unidad',
|
||||
'unidades' => 'unidad',
|
||||
'u' => 'unidad',
|
||||
'docena' => 'docena',
|
||||
'docenas' => 'docena',
|
||||
'dz' => 'docena',
|
||||
'doc' => 'docena',
|
||||
];
|
||||
return $map[$value] ?? 'unidad';
|
||||
}
|
||||
|
||||
/**
|
||||
* Convierte estado a booleano.
|
||||
*/
|
||||
private function parseEstado($value): bool
|
||||
{
|
||||
if (is_bool($value)) return $value;
|
||||
if (is_numeric($value)) return (bool) $value;
|
||||
$value = strtolower(trim($value));
|
||||
return in_array($value, ['activo', 'active', '1', 'true', 'si', 'yes']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Crea o actualiza el producto y asigna stock a la bodega.
|
||||
*/
|
||||
public function model(array $row)
|
||||
{
|
||||
$categoriaId = $this->getCategoriaId($row);
|
||||
|
||||
// Determinar bodega
|
||||
$bodegaId = null;
|
||||
if (!empty($row['bodega_id'])) {
|
||||
$bodegaId = $row['bodega_id'];
|
||||
} elseif (!empty($row['bodega'])) {
|
||||
$bodega = Bodega::where('nombre', $row['bodega'])->first();
|
||||
$bodegaId = $bodega ? $bodega->id : null;
|
||||
} else {
|
||||
$bodega = Bodega::where('nombre', 'Principal')->first();
|
||||
$bodegaId = $bodega ? $bodega->id : null;
|
||||
}
|
||||
|
||||
// Actualizar por ID
|
||||
if (!empty($row['id']) && is_numeric($row['id'])) {
|
||||
$producto = Producto::find($row['id']);
|
||||
if ($producto) {
|
||||
$producto->update([
|
||||
'nombre' => $row['nombre'],
|
||||
'descripcion' => $row['descripcion'] ?? null,
|
||||
'codigo_barras' => $row['codigo_de_barras'] ?? null,
|
||||
'categoria_id' => $categoriaId,
|
||||
'precio_compra' => $row['precio_compra'],
|
||||
'precio_venta' => $row['precio_venta'],
|
||||
'stock_minimo' => $row['stock_minimo'] ?? null,
|
||||
'stock_maximo' => $row['stock_maximo'] ?? null,
|
||||
'unidad_medida' => $this->parseUnidadMedida($row['unidad_de_medida'] ?? $row['unidad_medida'] ?? 'unidad'),
|
||||
'estado' => $this->parseEstado($row['estado'] ?? 'Activo'),
|
||||
'imagen' => '',
|
||||
]);
|
||||
if ($bodegaId && isset($row['stock'])) {
|
||||
$producto->bodegas()->syncWithoutDetaching([
|
||||
$bodegaId => ['stock' => $row['stock']],
|
||||
]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Actualizar por código de barras
|
||||
if (!empty($row['codigo_de_barras'])) {
|
||||
$existente = Producto::where('codigo_barras', $row['codigo_de_barras'])->first();
|
||||
if ($existente) {
|
||||
$existente->update([
|
||||
'nombre' => $row['nombre'],
|
||||
'descripcion' => $row['descripcion'] ?? null,
|
||||
'categoria_id' => $categoriaId,
|
||||
'precio_compra' => $row['precio_compra'],
|
||||
'precio_venta' => $row['precio_venta'],
|
||||
'stock_minimo' => $row['stock_minimo'] ?? null,
|
||||
'stock_maximo' => $row['stock_maximo'] ?? null,
|
||||
'unidad_medida' => $this->parseUnidadMedida($row['unidad_de_medida'] ?? $row['unidad_medida'] ?? 'unidad'),
|
||||
'estado' => $this->parseEstado($row['estado'] ?? 'Activo'),
|
||||
'imagen' => '',
|
||||
]);
|
||||
if ($bodegaId && isset($row['stock'])) {
|
||||
$existente->bodegas()->syncWithoutDetaching([
|
||||
$bodegaId => ['stock' => $row['stock']],
|
||||
]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Crear nuevo producto
|
||||
$producto = new Producto([
|
||||
'nombre' => $row['nombre'],
|
||||
'descripcion' => $row['descripcion'] ?? null,
|
||||
'codigo_barras' => $row['codigo_de_barras'] ?? null,
|
||||
'categoria_id' => $categoriaId,
|
||||
'precio_compra' => $row['precio_compra'],
|
||||
'precio_venta' => $row['precio_venta'],
|
||||
'stock_minimo' => $row['stock_minimo'] ?? null,
|
||||
'stock_maximo' => $row['stock_maximo'] ?? null,
|
||||
'unidad_medida' => $this->parseUnidadMedida($row['unidad_de_medida'] ?? $row['unidad_medida'] ?? 'unidad'),
|
||||
'estado' => $this->parseEstado($row['estado'] ?? 'Activo'),
|
||||
'imagen' => '',
|
||||
]);
|
||||
$producto->save();
|
||||
if ($bodegaId && isset($row['stock'])) {
|
||||
$producto->bodegas()->attach($bodegaId, ['stock' => $row['stock']]);
|
||||
}
|
||||
return $producto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reglas de validación.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'nombre' => 'required|string|max:255',
|
||||
'descripcion' => 'nullable',
|
||||
'codigo_de_barras' => 'nullable',
|
||||
'categoria_id' => 'required|exists:categorias,id',
|
||||
'precio_compra' => 'required|numeric|min:0',
|
||||
'precio_venta' => 'required|numeric|min:0',
|
||||
'stock' => 'nullable|integer|min:0',
|
||||
'stock_minimo' => 'nullable|integer|min:0',
|
||||
'stock_maximo' => 'nullable|integer|min:0',
|
||||
'unidad_de_medida' => 'nullable',
|
||||
'unidad_medida' => 'nullable',
|
||||
'estado' => 'nullable',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Mensajes personalizados.
|
||||
*/
|
||||
public function customValidationMessages()
|
||||
{
|
||||
return [
|
||||
'nombre.required' => 'El nombre del producto es obligatorio.',
|
||||
'categoria_id.required' => 'La categoría es obligatoria.',
|
||||
'categoria_id.exists' => 'La categoría especificada no existe.',
|
||||
'precio_compra.required' => 'El precio de compra es obligatorio.',
|
||||
'precio_compra.numeric' => 'El precio de compra debe ser un número.',
|
||||
'precio_venta.required' => 'El precio de venta es obligatorio.',
|
||||
'precio_venta.numeric' => 'El precio de venta debe ser un número.',
|
||||
'stock.integer' => 'El stock debe ser un número entero.',
|
||||
'unidad_de_medida.in' => 'La unidad de medida debe ser: unidad o docena.',
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user