278 lines
9.7 KiB
C#
278 lines
9.7 KiB
C#
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Rs_system.Data;
|
|
using Rs_system.Models;
|
|
using Rs_system.Models.ViewModels;
|
|
|
|
namespace Rs_system.Services;
|
|
|
|
public class ArticuloService : IArticuloService
|
|
{
|
|
private readonly ApplicationDbContext _context;
|
|
private readonly IFileStorageService _fileStorageService;
|
|
|
|
public ArticuloService(ApplicationDbContext context, IFileStorageService fileStorageService)
|
|
{
|
|
_context = context;
|
|
_fileStorageService = fileStorageService;
|
|
}
|
|
|
|
public async Task<IEnumerable<ArticuloViewModel>> GetAllAsync(string? search = null, int? categoriaId = null, int? ubicacionId = null, int? estadoId = null)
|
|
{
|
|
var query = _context.Articulos
|
|
.Include(a => a.Categoria)
|
|
.Include(a => a.Estado)
|
|
.Include(a => a.Ubicacion)
|
|
.Where(a => !a.Eliminado)
|
|
.AsQueryable();
|
|
|
|
if (!string.IsNullOrWhiteSpace(search))
|
|
{
|
|
var term = search.ToLower();
|
|
query = query.Where(a =>
|
|
a.Nombre.ToLower().Contains(term) ||
|
|
a.Codigo.ToLower().Contains(term) ||
|
|
a.Modelo.ToLower().Contains(term) ||
|
|
a.Marca.ToLower().Contains(term) ||
|
|
a.NumeroSerie.ToLower().Contains(term));
|
|
}
|
|
|
|
if (categoriaId.HasValue)
|
|
query = query.Where(a => a.CategoriaId == categoriaId);
|
|
|
|
if (ubicacionId.HasValue)
|
|
query = query.Where(a => a.UbicacionId == ubicacionId);
|
|
|
|
if (estadoId.HasValue)
|
|
query = query.Where(a => a.EstadoId == estadoId);
|
|
|
|
return await query
|
|
.OrderByDescending(a => a.CreadoEn)
|
|
.Select(a => new ArticuloViewModel
|
|
{
|
|
Id = a.Id,
|
|
Codigo = a.Codigo,
|
|
Nombre = a.Nombre,
|
|
Descripcion = a.Descripcion,
|
|
Marca = a.Marca,
|
|
Modelo = a.Modelo,
|
|
NumeroSerie = a.NumeroSerie,
|
|
Precio = a.Precio,
|
|
FechaAdquisicion = a.FechaAdquisicion,
|
|
ImagenUrl = a.ImagenUrl,
|
|
CategoriaId = a.CategoriaId,
|
|
CategoriaNombre = a.Categoria.Nombre,
|
|
EstadoId = a.EstadoId,
|
|
EstadoNombre = a.Estado.Nombre,
|
|
EstadoColor = a.Estado.Color,
|
|
UbicacionId = a.UbicacionId,
|
|
UbicacionNombre = a.Ubicacion.Nombre,
|
|
Activo = a.Activo,
|
|
CantidadGlobal = a.CantidadGlobal
|
|
})
|
|
.ToListAsync();
|
|
}
|
|
|
|
public async Task<ArticuloViewModel?> GetByIdAsync(int id)
|
|
{
|
|
var a = await _context.Articulos
|
|
.Include(a => a.Categoria)
|
|
.Include(a => a.Estado)
|
|
.Include(a => a.Ubicacion)
|
|
.FirstOrDefaultAsync(x => x.Id == id && !x.Eliminado);
|
|
|
|
if (a == null) return null;
|
|
|
|
return new ArticuloViewModel
|
|
{
|
|
Id = a.Id,
|
|
Codigo = a.Codigo,
|
|
Nombre = a.Nombre,
|
|
Descripcion = a.Descripcion,
|
|
Marca = a.Marca,
|
|
Modelo = a.Modelo,
|
|
NumeroSerie = a.NumeroSerie,
|
|
Precio = a.Precio,
|
|
FechaAdquisicion = a.FechaAdquisicion,
|
|
ImagenUrl = a.ImagenUrl,
|
|
CategoriaId = a.CategoriaId,
|
|
CategoriaNombre = a.Categoria.Nombre,
|
|
EstadoId = a.EstadoId,
|
|
EstadoNombre = a.Estado.Nombre,
|
|
EstadoColor = a.Estado.Color,
|
|
UbicacionId = a.UbicacionId,
|
|
UbicacionNombre = a.Ubicacion.Nombre,
|
|
Activo = a.Activo,
|
|
CantidadGlobal = a.CantidadGlobal,
|
|
// New Fields
|
|
TipoControl = a.TipoControl,
|
|
CantidadInicial = a.CantidadGlobal // Map Global Qty to CantidadInicial for Display
|
|
};
|
|
}
|
|
|
|
public async Task<bool> CreateAsync(ArticuloViewModel viewModel, string createdBy)
|
|
{
|
|
var strategy = _context.Database.CreateExecutionStrategy();
|
|
|
|
try
|
|
{
|
|
await strategy.ExecuteAsync(async () =>
|
|
{
|
|
using var transaction = await _context.Database.BeginTransactionAsync();
|
|
|
|
string? imagenUrl = null;
|
|
if (viewModel.ImagenFile != null)
|
|
{
|
|
imagenUrl = await _fileStorageService.SaveFileAsync(viewModel.ImagenFile, "articulos");
|
|
}
|
|
|
|
var articulo = new Articulo
|
|
{
|
|
Codigo = viewModel.Codigo,
|
|
Nombre = viewModel.Nombre,
|
|
Descripcion = viewModel.Descripcion,
|
|
Marca = viewModel.Marca,
|
|
Modelo = viewModel.Modelo,
|
|
NumeroSerie = viewModel.NumeroSerie,
|
|
Precio = viewModel.Precio,
|
|
FechaAdquisicion = viewModel.FechaAdquisicion,
|
|
ImagenUrl = imagenUrl,
|
|
CategoriaId = viewModel.CategoriaId,
|
|
EstadoId = viewModel.EstadoId,
|
|
UbicacionId = viewModel.UbicacionId,
|
|
Activo = viewModel.Activo,
|
|
Eliminado = false,
|
|
CreadoPor = createdBy,
|
|
CreadoEn = DateTime.UtcNow,
|
|
ActualizadoEn = DateTime.UtcNow,
|
|
// New Fields
|
|
TipoControl = viewModel.TipoControl ?? nameof(Articulo.TipoControlInventario.UNITARIO),
|
|
CantidadGlobal = (viewModel.TipoControl == nameof(Articulo.TipoControlInventario.LOTE)) ? viewModel.CantidadInicial : 1
|
|
};
|
|
|
|
_context.Articulos.Add(articulo);
|
|
await _context.SaveChangesAsync();
|
|
|
|
// If LOTE, initialize Existencia
|
|
if (articulo.TipoControl == nameof(Articulo.TipoControlInventario.LOTE))
|
|
{
|
|
var existencia = new Existencia
|
|
{
|
|
ArticuloId = articulo.Id,
|
|
UbicacionId = articulo.UbicacionId,
|
|
Cantidad = articulo.CantidadGlobal,
|
|
ActualizadoEn = DateTime.UtcNow
|
|
};
|
|
_context.Existencias.Add(existencia);
|
|
await _context.SaveChangesAsync();
|
|
}
|
|
|
|
await transaction.CommitAsync();
|
|
});
|
|
|
|
return true;
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public async Task<bool> UpdateAsync(ArticuloViewModel viewModel)
|
|
{
|
|
try
|
|
{
|
|
var articulo = await _context.Articulos.FindAsync(viewModel.Id);
|
|
if (articulo == null || articulo.Eliminado) return false;
|
|
|
|
if (viewModel.ImagenFile != null)
|
|
{
|
|
if (!string.IsNullOrEmpty(articulo.ImagenUrl))
|
|
{
|
|
await _fileStorageService.DeleteFileAsync(articulo.ImagenUrl);
|
|
}
|
|
articulo.ImagenUrl = await _fileStorageService.SaveFileAsync(viewModel.ImagenFile, "articulos");
|
|
}
|
|
|
|
articulo.Codigo = viewModel.Codigo;
|
|
articulo.Nombre = viewModel.Nombre;
|
|
articulo.Descripcion = viewModel.Descripcion;
|
|
articulo.Marca = viewModel.Marca;
|
|
articulo.Modelo = viewModel.Modelo;
|
|
articulo.NumeroSerie = viewModel.NumeroSerie;
|
|
articulo.Precio = viewModel.Precio;
|
|
articulo.FechaAdquisicion = viewModel.FechaAdquisicion;
|
|
articulo.CategoriaId = viewModel.CategoriaId;
|
|
articulo.EstadoId = viewModel.EstadoId;
|
|
articulo.UbicacionId = viewModel.UbicacionId;
|
|
articulo.Activo = viewModel.Activo;
|
|
articulo.ActualizadoEn = DateTime.UtcNow;
|
|
|
|
_context.Articulos.Update(articulo);
|
|
await _context.SaveChangesAsync();
|
|
return true;
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public async Task<bool> DeleteAsync(int id)
|
|
{
|
|
try
|
|
{
|
|
var articulo = await _context.Articulos.FindAsync(id);
|
|
if (articulo == null || articulo.Eliminado) return false;
|
|
|
|
articulo.Eliminado = true;
|
|
articulo.ActualizadoEn = DateTime.UtcNow;
|
|
|
|
_context.Articulos.Update(articulo);
|
|
await _context.SaveChangesAsync();
|
|
return true;
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public async Task<bool> ExistsCodigoAsync(string codigo, int? excludeId = null)
|
|
{
|
|
var query = _context.Articulos.AsQueryable();
|
|
if (excludeId.HasValue)
|
|
{
|
|
query = query.Where(a => a.Id != excludeId.Value);
|
|
}
|
|
return await query.AnyAsync(a => a.Codigo.ToLower() == codigo.ToLower() && !a.Eliminado);
|
|
}
|
|
|
|
public async Task<IEnumerable<(int Id, string Nombre)>> GetCategoriasAsync()
|
|
{
|
|
return await _context.Categorias
|
|
.Where(x => x.Activo && !x.Eliminado)
|
|
.OrderBy(x => x.Nombre)
|
|
.Select(x => new ValueTuple<int, string>(x.Id, x.Nombre))
|
|
.ToListAsync();
|
|
}
|
|
|
|
public async Task<IEnumerable<(int Id, string Nombre, string Color)>> GetEstadosAsync()
|
|
{
|
|
return await _context.EstadosArticulos
|
|
.Where(x => x.Activo && !x.Eliminado)
|
|
.OrderBy(x => x.Nombre)
|
|
.Select(x => new ValueTuple<int, string, string>(x.Id, x.Nombre, x.Color ?? "secondary"))
|
|
.ToListAsync();
|
|
}
|
|
|
|
public async Task<IEnumerable<(int Id, string Nombre)>> GetUbicacionesAsync()
|
|
{
|
|
return await _context.Ubicaciones
|
|
.Where(x => x.Activo && !x.Eliminado)
|
|
.OrderBy(x => x.Nombre)
|
|
.Select(x => new ValueTuple<int, string>(x.Id, x.Nombre))
|
|
.ToListAsync();
|
|
}
|
|
}
|