Esempio n. 1
0
        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 }));
        }