public async Task <IActionResult> Apply(Guid?id) { var validateToken = await ValidatedToken(_configuration, _getHelper, "movimiento"); if (validateToken != null) { return(validateToken); } //cambiar por permiso para aplicar que se debe agregar como acción. if (!await ValidateModulePermissions(_getHelper, moduloId, eTipoPermiso.PermisoEscritura)) { return(RedirectToAction(nameof(Index))); } if (id == null) { TempData["toast"] = "Identificador incorrecto."; return(RedirectToAction(nameof(Index))); } if (EntradaAplicada((Guid)id)) { TempData["toast"] = "Entrada aplicada no se permiten cambios."; return(RedirectToAction(nameof(Details), new { id })); } var entrada = await _getHelper.GetEntradaByIdAsync((Guid)id); if (entrada == null) { TempData["toast"] = "Identificador de la entrada inexistente."; return(RedirectToAction(nameof(Index))); } entrada.Aplicado = true; _context.Update(entrada); var detalle = await _getHelper.GetEntradaDetalleByEntradaIdAsync(entrada.EntradaID); if (detalle == null) { TempData["toast"] = "Por favor, ingrese al menos un movimiento."; return(RedirectToAction(nameof(Details), new { id })); } var existencias = new List <ExistenciaViewModel>(); foreach (var item in detalle) { Guid _almacenId = (Guid)item.AlmacenID; Guid _productoId = (Guid)item.ProductoID; decimal _cantidad = (decimal)item.Cantidad; decimal _precioCosto = (decimal)item.PrecioCosto; if (item.Productos.Unidades.Pieza) { _cantidad = (int)_cantidad; } if (item.Productos.Unidades.Paquete) { _productoId = item.Productos.Paquete.PiezaProductoID; _precioCosto = (decimal)item.PrecioCosto / item.Productos.Paquete.CantidadProductoxPaquete; _cantidad = item.Productos.Paquete.CantidadProductoxPaquete * _cantidad; item.Productos.PrecioCosto = (decimal)item.PrecioCosto; } item.Productos.PrecioVenta = (decimal)item.PrecioVenta; var existencia = existencias .FirstOrDefault(e => e.ProductoID == _productoId && e.AlmacenID == _almacenId); if (existencia == null) { existencias.Add(new ExistenciaViewModel() { AlmacenID = _almacenId, ExistenciaEnAlmacen = _cantidad, ExistenciaID = Guid.NewGuid(), ProductoID = _productoId, PrecioCosto = _precioCosto }); } else { existencia.PrecioCosto = ( (existencia.ExistenciaEnAlmacen * existencia.PrecioCosto) + (_cantidad * _precioCosto) ) / (existencia.ExistenciaEnAlmacen + _cantidad); existencia.ExistenciaEnAlmacen += _cantidad; } } foreach (var item in existencias) { Guid _almacenId = (Guid)item.AlmacenID; var existencia = await _getHelper .GetExistenciaByProductoIdAndAlmacenIdAsync(item.ProductoID, _almacenId); if (existencia == null) { _context.Existencias.Add(new Existencia() { AlmacenID = _almacenId, ExistenciaEnAlmacen = item.ExistenciaEnAlmacen, ExistenciaID = Guid.NewGuid(), ProductoID = item.ProductoID }); } else { existencia.ExistenciaEnAlmacen += item.ExistenciaEnAlmacen; _context.Update(existencia); } } var productos = existencias.GroupBy(e => e.ProductoID) .Select(g => new { produdtoID = g.Key, existencia = g.Sum(p => p.ExistenciaEnAlmacen), precioCosto = (g.Sum(p => p.ExistenciaEnAlmacen * p.PrecioCosto) / g.Sum(p => p.ExistenciaEnAlmacen)) }) .ToList(); foreach (var p in productos) { var producto = await _context.Productos .FirstOrDefaultAsync(p => p.ProductoID == p.ProductoID); var existenciaActual = await _context.Existencias .Where(p => p.ProductoID == p.ProductoID) .SumAsync(e => e.ExistenciaEnAlmacen); producto.PrecioCosto = ((p.existencia * p.precioCosto) + (producto.PrecioCosto * existenciaActual)) / (p.existencia + existenciaActual); _context.Update(producto); } try { await _context.SaveChangesAsync(); TempData["toast"] = "La entrada ha sido aplicada, no podrá realizar cambios en la información."; await BitacoraAsync("Aplicar", entrada); } catch (Exception ex) { string excepcion = ex.InnerException != null?ex.InnerException.Message.ToString() : ex.ToString(); TempData["toast"] = "Error al aplicar el movimieno, verifique bitácora de errores."; await BitacoraAsync("Aplicar", entrada, excepcion); } return(RedirectToAction(nameof(Details), new { id })); }