Beispiel #1
0
        public async Task <IActionResult> Post([FromBody] EgresoDetalle egreso)
        {
            if (!ModelState.IsValid)
            {
                return(HttpBadRequest(ModelState));
            }
            var usuarioId = User.Id();
            var egresoId  = await egresos.CrearAsync(usuarioId, egreso);

            var result = await egresos.ObtenerUnicoAsync(egresoId);

            return(CreatedAtRoute("GetEgreso", new { id = egresoId }, result));
        }
Beispiel #2
0
        public async Task <int> CrearAsync(int usuarioId, EgresoDetalle egreso)
        {
            if (egreso == null)
            {
                throw new ArgumentNullException(nameof(egreso));
            }

            if (egreso.Productos == null || egreso.Productos.Count() == 0)
            {
                throw new InvalidOperationException("No puede crear un egreso sin productos.");
            }
            var tieneProductosRepetidos = egreso.Productos.GroupBy(x => new { x.ProductoId, x.MarcaId, x.UnidadId }).Where(x => x.Count() > 1).Any();

            if (tieneProductosRepetidos)
            {
                throw new InvalidOperationException("Un egreso no puede tener un producto repetido con la misma marca y unidad de medida (debe crear dos egresos distintos)");
            }

            var hayProductosSinCantidad = egreso.Productos.Any(x => x.Cantidad <= 0);

            if (hayProductosSinCantidad)
            {
                throw new InvalidOperationException("Un egreso no puede contener productos con valores menores o iguales a cero");
            }

            var existeBodega = await db.Bodegas.AnyAsync(x => x.Id == egreso.BodegaId);

            if (!existeBodega)
            {
                throw new InvalidOperationException($"No existe una bodega con id {egreso.BodegaId}");
            }

            var productosIds        = egreso.Productos.Select(x => x.ProductoId).Distinct().ToArray();
            var cantidadDeProductos = await db.Productos.CountAsync(x => productosIds.Contains(x.Id));

            var existenTodosLosProductos = cantidadDeProductos == productosIds.Length;

            if (!existenTodosLosProductos)
            {
                throw new InvalidOperationException("Al menos uno de los productos indicados no existe");
            }

            var marcasParaLosProductos = await db.ProductoMarcas.Where(x => productosIds.Contains(x.ProductoId)).ToArrayAsync();

            var unidadesParaLosProductos = await db.ProductoUnidadesDeMedida.Where(x => productosIds.Contains(x.ProductoId)).ToArrayAsync();

            foreach (var item in egreso.Productos)
            {
                if (!marcasParaLosProductos.Any(x => x.MarcaId == item.MarcaId && x.ProductoId == item.ProductoId))
                {
                    throw new InvalidOperationException($"No existe una marca con id {item.MarcaId} o no está asignada al producto con id {item.ProductoId}");
                }
                if (!unidadesParaLosProductos.Any(x => x.UnidadDeMedidaId == item.UnidadId && x.ProductoId == item.ProductoId))
                {
                    throw new InvalidOperationException($"No existe una unidad de medida con id {item.UnidadId} o no está asignada al producto con id {item.ProductoId}");
                }
            }

            if (egreso.Fecha == default(DateTime))
            {
                egreso.Fecha = DateTime.UtcNow;
            }

            var nuevoEgreso = new Egreso
            {
                Fecha     = egreso.Fecha.ToUniversalTime(),
                UsuarioId = usuarioId,
                BodegaId  = egreso.BodegaId
            };

            if (egreso.Productos != null && egreso.Productos.Count() > 0)
            {
                nuevoEgreso.Productos = egreso.Productos.Select(producto => new EgresoProducto {
                    Egreso           = nuevoEgreso,
                    ProductoId       = producto.ProductoId,
                    UnidadDeMedidaId = producto.UnidadId,
                    Cantidad         = producto.Cantidad,
                    MarcaId          = producto.MarcaId
                }).ToList();
            }

            db.Egresos.Add(nuevoEgreso);

            var existencias = await db.Existencias.Include(x => x.Cantidades).Where(x => productosIds.Contains(x.ProductoId)).ToListAsync();

            foreach (var item in egreso.Productos)
            {
                var productoId    = item.ProductoId;
                var nuevaCantidad = item.Cantidad;
                var marcaId       = item.MarcaId;
                var unidadId      = item.UnidadId;
                var existencia    = existencias.FirstOrDefault(x => x.ProductoId == productoId);
                if (existencia == null)
                {
                    throw new InvalidOperationException($"No hay existencias suficientes para el producto {item.ProductoId}");
                }
                else
                {
                    var cantidad = existencia.Cantidades.FirstOrDefault(x => x.UnidadDeMedidaId == unidadId && x.MarcaId == marcaId);
                    if (cantidad == null)
                    {
                        throw new InvalidOperationException($"No hay existencias suficientes para el producto {item.ProductoId}");
                    }
                    else
                    {
                        if (cantidad.Cantidad < nuevaCantidad)
                        {
                            throw new InvalidOperationException($"La cantidad que se desea sacar del producto {item.ProductoId} es mayor a la cantidad disponible");
                        }
                        else
                        {
                            cantidad.Cantidad -= nuevaCantidad;
                        }
                    }
                }
            }

            await db.SaveChangesAsync();

            return(nuevoEgreso.Id);
        }