Files
RS_System/RS_system/Controllers/MovimientosInventarioController.cs

222 lines
8.5 KiB
C#

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Rs_system.Models;
using Rs_system.Services;
namespace Rs_system.Controllers;
[Authorize]
public class MovimientosInventarioController : Controller
{
private readonly IMovimientoService _movimientoService;
private readonly IArticuloService _articuloService;
private readonly IUbicacionService _ubicacionService;
private readonly IEstadoArticuloService _estadoService;
private readonly IPrestamoService _prestamoService;
public MovimientosInventarioController(
IMovimientoService movimientoService,
IArticuloService articuloService,
IUbicacionService ubicacionService,
IEstadoArticuloService estadoService,
IPrestamoService prestamoService)
{
_movimientoService = movimientoService;
_articuloService = articuloService;
_ubicacionService = ubicacionService;
_estadoService = estadoService;
_prestamoService = prestamoService;
}
// GET: MovimientosInventario
public async Task<IActionResult> Index()
{
var historial = await _movimientoService.GetHistorialGeneralAsync(50); // Limit 50 for performance
return View(historial);
}
// GET: MovimientosInventario/Create
// This is the "Wizard" or "Action Selector"
public async Task<IActionResult> Create(int? articuloId)
{
if (articuloId.HasValue)
{
var articulo = await _articuloService.GetByIdAsync(articuloId.Value);
if (articulo == null) return NotFound();
ViewBag.ArticuloId = articulo.Id;
ViewBag.ArticuloNombre = $"{articulo.Codigo} - {articulo.Nombre}";
ViewBag.UbicacionActual = articulo.UbicacionNombre;
ViewBag.EstadoActual = articulo.EstadoNombre;
ViewBag.TipoControl = articulo.TipoControl; // "UNITARIO" or "LOTE"
ViewBag.CantidadGlobal = articulo.CantidadGlobal; // For LOTE validation?
}
ViewBag.Articulos =
new SelectList(
(await _articuloService.GetAllAsync()).Select(x => new { x.Id, Nombre = $"{x.Codigo} - {x.Nombre}" }),
"Id", "Nombre", articuloId);
ViewBag.Ubicaciones = new SelectList(await _ubicacionService.GetAllAsync(), "Id", "Nombre");
ViewBag.Estados = new SelectList(await _estadoService.GetAllAsync(), "Id", "Nombre");
return View();
}
[HttpGet]
public async Task<IActionResult> BuscarArticulos(string term)
{
var articulos = await _articuloService.GetAllAsync();
if (!string.IsNullOrWhiteSpace(term))
{
term = term.ToLower();
articulos = articulos
.Where(a =>
(a.Nombre != null && a.Nombre.ToLower().Contains(term)) ||
(a.Codigo != null && a.Codigo.ToLower().Contains(term)) ||
(a.Descripcion != null && a.Descripcion.ToLower().Contains(term)))
.ToList();
}
// Limit results
var resultados = articulos.Take(20).Select(a => new {
a.Id,
a.Codigo,
a.Nombre,
Ubicacion = a.UbicacionNombre ?? "Sin ubicación",
Stock = a.CantidadGlobal
});
return Json(resultados);
}
// POST: MovimientosInventario/RegistrarTraslado
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> RegistrarTraslado(int articuloId, int nuevaUbicacionId, string observacion, int cantidad = 1)
{
var usuario = User.Identity?.Name ?? "Sistema";
// Use the new Quantity-Aware method
var result = await _movimientoService.RegistrarTrasladoCantidadAsync(articuloId, nuevaUbicacionId, cantidad, observacion, usuario);
if (result)
{
TempData["SuccessMessage"] = "Traslado registrado correctamente.";
return RedirectToAction(nameof(Index));
}
TempData["ErrorMessage"] = "Error al registrar el traslado. Verifique stock o campos.";
return RedirectToAction(nameof(Create), new { articuloId });
}
// POST: MovimientosInventario/RegistrarBaja
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> RegistrarBaja(int articuloId, string motivo, int cantidad = 1)
{
if (string.IsNullOrWhiteSpace(motivo))
{
TempData["ErrorMessage"] = "Debe especificar un motivo para la baja.";
return RedirectToAction(nameof(Create), new { articuloId });
}
var usuario = User.Identity?.Name ?? "Sistema";
var result = await _movimientoService.RegistrarBajaCantidadAsync(articuloId, cantidad, motivo, usuario);
if (result)
{
TempData["SuccessMessage"] = "Baja registrada correctamente.";
return RedirectToAction(nameof(Index));
}
TempData["ErrorMessage"] = "Error al registrar la baja.";
return RedirectToAction(nameof(Create), new { articuloId });
}
// POST: MovimientosInventario/RegistrarCambioEstado
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> RegistrarCambioEstado(int articuloId, int nuevoEstadoId, string observacion)
{
var usuario = User.Identity?.Name ?? "Sistema";
var result = await _movimientoService.RegistrarCambioEstadoAsync(articuloId, nuevoEstadoId, observacion, usuario);
if (result)
{
TempData["SuccessMessage"] = "Cambio de estado registrado correctamento.";
return RedirectToAction(nameof(Index));
}
TempData["ErrorMessage"] = "Error al registrar el cambio de estado. Verifique que el estado sea diferente al actual.";
return RedirectToAction(nameof(Create), new { articuloId });
}
// POST: MovimientosInventario/RegistrarPrestamo
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> RegistrarPrestamo(int articuloId, int cantidad, string personaNombre, string personaIdentificacion, DateTime? fechaDevolucionEstimada, string observacion)
{
if (string.IsNullOrWhiteSpace(personaNombre))
{
TempData["ErrorMessage"] = "Debe especificar el nombre de la persona a quien se presta el artículo.";
return RedirectToAction(nameof(Create), new { articuloId });
}
var usuario = User.Identity?.Name ?? "Sistema";
var result = await _prestamoService.RegistrarPrestamoAsync(articuloId, cantidad, personaNombre, personaIdentificacion, fechaDevolucionEstimada, observacion, usuario);
if (result)
{
TempData["SuccessMessage"] = "Préstamo registrado correctamente.";
return RedirectToAction(nameof(Index));
}
TempData["ErrorMessage"] = "Error al registrar el préstamo. Verifique stock disponible.";
return RedirectToAction(nameof(Create), new { articuloId });
}
// GET: MovimientosInventario/PrestamosActivos
public async Task<IActionResult> PrestamosActivos()
{
var prestamosActivos = await _prestamoService.GetPrestamosActivosAsync();
return View(prestamosActivos);
}
// POST: MovimientosInventario/RegistrarDevolucion
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> RegistrarDevolucion(long prestamoId, string observacion)
{
var usuario = User.Identity?.Name ?? "Sistema";
var result = await _prestamoService.RegistrarDevolucionAsync(prestamoId, observacion, usuario);
if (result)
{
TempData["SuccessMessage"] = "Devolución registrada correctamente.";
return RedirectToAction(nameof(PrestamosActivos));
}
TempData["ErrorMessage"] = "Error al registrar la devolución.";
return RedirectToAction(nameof(PrestamosActivos));
}
// POST: MovimientosInventario/RegistrarEntrada
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> RegistrarEntrada(int articuloId, int cantidad, string observacion)
{
var usuario = User.Identity?.Name ?? "Sistema";
var result = await _movimientoService.RegistrarEntradaCantidadAsync(articuloId, cantidad, observacion, usuario);
if (result)
{
TempData["SuccessMessage"] = "Entrada de inventario registrada correctamente.";
return RedirectToAction(nameof(Index));
}
TempData["ErrorMessage"] = "Error al registrar la entrada de inventario.";
return RedirectToAction(nameof(Create), new { articuloId });
}
}