using Microsoft.Data.SqlClient; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DAL { public class DALItensLotes { private readonly string connectionString; public DALItensLotes(string conexao) { connectionString = conexao; }//Constructor #region CRUD - Create, Read, Update, Delete public bool Inserir(ModeloItensLotes modelo) { using SqlConnection conn = new(connectionString); string sql = @" INSERT INTO Itens_Lotes ( COD_ITEM, LOTE, QUANTIDADE, DATA_FABRICACAO, DATA_VALIDADE, NUMERO_NF, FORNECEDOR, OBSERVACAO, ATIVO, DATA_CADASTRO, DATA_ALTERACAO ) VALUES ( @COD_ITEM, @LOTE, @QUANTIDADE, @DATA_FABRICACAO, @DATA_VALIDADE, @NUMERO_NF, @FORNECEDOR, @OBSERVACAO, @ATIVO, @DATA_CADASTRO, @DATA_ALTERACAO )"; using SqlCommand cmd = new(sql, conn); PreencherParametros(cmd, modelo); conn.Open(); return cmd.ExecuteNonQuery() > 0; }//Inserir public bool Alterar(ModeloItensLotes modelo) { using SqlConnection conn = new(connectionString); string sql = @" UPDATE Itens_Lotes SET COD_ITEM=@COD_ITEM, LOTE=@LOTE, QUANTIDADE=@QUANTIDADE, DATA_FABRICACAO=@DATA_FABRICACAO, DATA_VALIDADE=@DATA_VALIDADE, NUMERO_NF=@NUMERO_NF, FORNECEDOR=@FORNECEDOR, OBSERVACAO=@OBSERVACAO, ATIVO=@ATIVO, DATA_ALTERACAO=@DATA_ALTERACAO WHERE ID_ITEM_LOTE=@ID_ITEM_LOTE"; using SqlCommand cmd = new(sql, conn); PreencherParametros(cmd, modelo); cmd.Parameters.AddWithValue("@ID_ITEM_LOTE", modelo.ID_ITEM_LOTE); conn.Open(); return cmd.ExecuteNonQuery() > 0; }//Alterar public bool Excluir(int id) { using SqlConnection conn = new(connectionString); string sql = @"DELETE FROM Itens_Lotes WHERE ID_ITEM_LOTE=@ID"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@ID", id); conn.Open(); return cmd.ExecuteNonQuery() > 0; }//Excluir private static void PreencherParametros(SqlCommand cmd, ModeloItensLotes modelo) { cmd.Parameters.AddWithValue("@COD_ITEM", modelo.COD_ITEM); cmd.Parameters.AddWithValue("@LOTE", modelo.LOTE); cmd.Parameters.AddWithValue("@QUANTIDADE", modelo.QUANTIDADE); cmd.Parameters.AddWithValue( "@DATA_FABRICACAO", (object?)modelo.DATA_FABRICACAO ?? DBNull.Value); cmd.Parameters.AddWithValue( "@DATA_VALIDADE", (object?)modelo.DATA_VALIDADE ?? DBNull.Value); cmd.Parameters.AddWithValue("@NUMERO_NF", modelo.NUMERO_NF); cmd.Parameters.AddWithValue("@FORNECEDOR", modelo.FORNECEDOR); cmd.Parameters.AddWithValue("@OBSERVACAO", modelo.OBSERVACAO); cmd.Parameters.AddWithValue("@ATIVO", modelo.ATIVO); cmd.Parameters.AddWithValue("@DATA_CADASTRO", modelo.DATA_CADASTRO); cmd.Parameters.AddWithValue( "@DATA_ALTERACAO", (object?)modelo.DATA_ALTERACAO ?? DBNull.Value); }//PreencherParametros #endregion #region Carregar - Load public ModeloItensLotes? Carregar(int id) { using SqlConnection conn = new(connectionString); string sql = @" SELECT * FROM Itens_Lotes WHERE ID_ITEM_LOTE=@ID"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@ID", id); conn.Open(); using SqlDataReader dr = cmd.ExecuteReader(); if (dr.Read()) return PreencherModelo(dr); return null; }//CarregarModeloPeloID public ModeloItensLotes? CarregarPorCodigo(string codigo) { using SqlConnection conn = new(connectionString); string sql = @" SELECT * FROM Itens_Lotes WHERE CODIGO=@CODIGO"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@CODIGO", codigo); conn.Open(); using SqlDataReader dr = cmd.ExecuteReader(); if (dr.Read()) return PreencherModelo(dr); return null; }//CarregarModeloPeloCodigo public ModeloItensLotes? CarregarPorLote(string lote) { using SqlConnection conn = new(connectionString); string sql = @" SELECT * FROM Itens_Lotes WHERE LOTE=@LOTE"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@LOTE", lote); conn.Open(); using SqlDataReader dr = cmd.ExecuteReader(); if (dr.Read()) return PreencherModelo(dr); return null; }//CarregarModeloPeloLote public bool ExisteCodigo(string codigo) { using SqlConnection conn = new(connectionString); string sql = @" SELECT COUNT(*) FROM Itens_Lotes WHERE CODIGO=@CODIGO"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@CODIGO", codigo); conn.Open(); return Convert.ToInt32(cmd.ExecuteScalar()) > 0; }//ExisteCodigo public bool ExisteLote(string lote) { using SqlConnection conn = new(connectionString); string sql = @" SELECT COUNT(*) FROM Itens_Lotes WHERE LOTE=@LOTE"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@LOTE", lote); conn.Open(); return Convert.ToInt32(cmd.ExecuteScalar()) > 0; }//ExisteLote private static ModeloItensLotes PreencherModelo(SqlDataReader dr) { return new ModeloItensLotes { ID_ITEM_LOTE = Convert.ToInt32(dr["ID_ITEM_LOTE"]), CODIGO = dr["CODIGO"]?.ToString() ?? string.Empty, COD_ITEM = dr["COD_ITEM"]?.ToString() ?? string.Empty, LOTE = dr["LOTE"]?.ToString() ?? string.Empty, QUANTIDADE = dr["QUANTIDADE"] != DBNull.Value ? Convert.ToDecimal(dr["QUANTIDADE"]) : 0, DATA_FABRICACAO = dr["DATA_FABRICACAO"] != DBNull.Value ? Convert.ToDateTime(dr["DATA_FABRICACAO"]) : null, DATA_VALIDADE = dr["DATA_VALIDADE"] != DBNull.Value ? Convert.ToDateTime(dr["DATA_VALIDADE"]) : null, NUMERO_NF = dr["NUMERO_NF"]?.ToString() ?? string.Empty, FORNECEDOR = dr["FORNECEDOR"]?.ToString() ?? string.Empty, OBSERVACAO = dr["OBSERVACAO"]?.ToString() ?? string.Empty, ATIVO = dr["ATIVO"] != DBNull.Value && Convert.ToBoolean(dr["ATIVO"]), DATA_CADASTRO = dr["DATA_CADASTRO"] != DBNull.Value ? Convert.ToDateTime(dr["DATA_CADASTRO"]) : DateTime.MinValue, DATA_ALTERACAO = dr["DATA_ALTERACAO"] != DBNull.Value ? Convert.ToDateTime(dr["DATA_ALTERACAO"]) : null }; }//PreencherModelo #endregion #region Listar - List public List Listar(string? codigo = null,string? codItem = null,string? lote = null,string? fornecedor = null, string? numeroNF = null, bool? ativo = null,DateTime? fabricacaoInicial = null,DateTime? fabricacaoFinal = null,DateTime? validadeInicial = null, DateTime? validadeFinal = null) { List lista = []; using SqlConnection conn = new(connectionString); string sql = @" SELECT * FROM Itens_Lotes WHERE 1=1"; using SqlCommand cmd = new(); if (!string.IsNullOrWhiteSpace(codigo)) { sql += " AND CODIGO LIKE @CODIGO"; cmd.Parameters.AddWithValue("@CODIGO", "%" + codigo + "%"); } if (!string.IsNullOrWhiteSpace(codItem)) { sql += " AND COD_ITEM=@COD_ITEM"; cmd.Parameters.AddWithValue("@COD_ITEM", codItem); } if (!string.IsNullOrWhiteSpace(lote)) { sql += " AND LOTE LIKE @LOTE"; cmd.Parameters.AddWithValue("@LOTE", "%" + lote + "%"); } if (!string.IsNullOrWhiteSpace(fornecedor)) { sql += " AND FORNECEDOR LIKE @FORNECEDOR"; cmd.Parameters.AddWithValue("@FORNECEDOR", "%" + fornecedor + "%"); } if (!string.IsNullOrWhiteSpace(numeroNF)) { sql += " AND NUMERO_NF LIKE @NUMERO_NF"; cmd.Parameters.AddWithValue("@NUMERO_NF", "%" + numeroNF + "%"); } if (ativo.HasValue) { sql += " AND ATIVO=@ATIVO"; cmd.Parameters.AddWithValue("@ATIVO", ativo.Value); } if (fabricacaoInicial.HasValue) { sql += " AND DATA_FABRICACAO>=@FAB_INI"; cmd.Parameters.AddWithValue("@FAB_INI", fabricacaoInicial.Value); } if (fabricacaoFinal.HasValue) { sql += " AND DATA_FABRICACAO<=@FAB_FIM"; cmd.Parameters.AddWithValue("@FAB_FIM", fabricacaoFinal.Value); } if (validadeInicial.HasValue) { sql += " AND DATA_VALIDADE>=@VAL_INI"; cmd.Parameters.AddWithValue("@VAL_INI", validadeInicial.Value); } if (validadeFinal.HasValue) { sql += " AND DATA_VALIDADE<=@VAL_FIM"; cmd.Parameters.AddWithValue("@VAL_FIM", validadeFinal.Value); } sql += " ORDER BY DATA_VALIDADE"; cmd.Connection = conn; cmd.CommandText = sql; conn.Open(); using SqlDataReader dr = cmd.ExecuteReader(); while (dr.Read()) { lista.Add(PreencherModelo(dr)); } return lista; }//Listar public List ListarPorProduto(string codigoProduto) { return Listar(codItem: codigoProduto); }//ListarPorProduto public List ListarPorFornecedor(string fornecedor) { return Listar(fornecedor: fornecedor); }//ListarPorFornecedor public List ListarPorNF(string numeroNF) { return Listar(numeroNF: numeroNF); }//ListarPorNF public List ListarPorLote(string lote) { return Listar(lote: lote); }//ListarPorLote public List ListarAtivos() { return Listar(ativo: true); }//ListarAtivos public List ListarInativos() { return Listar(ativo: false); }//ListarInativos public List ListarVencidos() { return Listar( validadeFinal: DateTime.Today); }//ListarVencidos public List ListarAVencer() { return Listar( validadeInicial: DateTime.Today, validadeFinal: DateTime.Today.AddDays(30)); }//ListarAVencer public List ListarPorPeriodoValidade(DateTime inicio,DateTime fim) { return Listar( validadeInicial: inicio, validadeFinal: fim); }//ListarPorPeriodoValidade public List ListarPorPeriodoFabricacao(DateTime inicio,DateTime fim) { return Listar( fabricacaoInicial: inicio, fabricacaoFinal: fim); }//ListarPorPeriodoFabricacao #endregion #region Controle de estoque - Stock control public bool SomarQuantidade(int idLote, decimal quantidade) { using SqlConnection conn = new(connectionString); string sql = @" UPDATE Itens_Lotes SET QUANTIDADE = QUANTIDADE + @QUANTIDADE, DATA_ALTERACAO = GETDATE() WHERE ID_ITEM_LOTE = @ID"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@QUANTIDADE", quantidade); cmd.Parameters.AddWithValue("@ID", idLote); conn.Open(); return cmd.ExecuteNonQuery() > 0; }//SomarQuantidade public bool BaixarQuantidade(int idLote, decimal quantidade) { using SqlConnection conn = new(connectionString); string sql = @" UPDATE Itens_Lotes SET QUANTIDADE = QUANTIDADE - @QUANTIDADE, DATA_ALTERACAO = GETDATE() WHERE ID_ITEM_LOTE = @ID AND QUANTIDADE >= @QUANTIDADE"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@QUANTIDADE", quantidade); cmd.Parameters.AddWithValue("@ID", idLote); conn.Open(); return cmd.ExecuteNonQuery() > 0; }//BaixarQuantidade public bool Entrada(int idLote, decimal quantidade) { return SomarQuantidade(idLote, quantidade); }//Entrada public bool Saida(int idLote, decimal quantidade) { return BaixarQuantidade(idLote, quantidade); }//Saida public bool AjustarQuantidade(int idLote, decimal novaQuantidade) { using SqlConnection conn = new(connectionString); string sql = @" UPDATE Itens_Lotes SET QUANTIDADE = @QUANTIDADE, DATA_ALTERACAO = GETDATE() WHERE ID_ITEM_LOTE = @ID"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@QUANTIDADE", novaQuantidade); cmd.Parameters.AddWithValue("@ID", idLote); conn.Open(); return cmd.ExecuteNonQuery() > 0; }//AjustarQuantidade public bool ZerarLote(int idLote) { return AjustarQuantidade(idLote, 0); }//ZerarLote public bool ExisteSaldo(int idLote) { using SqlConnection conn = new(connectionString); string sql = @" SELECT COUNT(*) FROM Itens_Lotes WHERE ID_ITEM_LOTE = @ID AND QUANTIDADE > 0"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@ID", idLote); conn.Open(); return Convert.ToInt32(cmd.ExecuteScalar()) > 0; }//ExisteSaldo public decimal SaldoLote(int idLote) { using SqlConnection conn = new(connectionString); string sql = @" SELECT ISNULL(QUANTIDADE,0) FROM Itens_Lotes WHERE ID_ITEM_LOTE = @ID"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@ID", idLote); conn.Open(); object valor = cmd.ExecuteScalar(); return valor != DBNull.Value ? Convert.ToDecimal(valor) : 0; }//SaldoLote public decimal SaldoProduto(string codigoProduto) { using SqlConnection conn = new(connectionString); string sql = @" SELECT ISNULL(SUM(QUANTIDADE),0) FROM Itens_Lotes WHERE COD_ITEM = @COD_ITEM AND ATIVO = 1"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@COD_ITEM", codigoProduto); conn.Open(); object valor = cmd.ExecuteScalar(); return valor != DBNull.Value ? Convert.ToDecimal(valor) : 0; }//SaldoProduto public bool TransferirQuantidade(int loteOrigem, int loteDestino, decimal quantidade) { using SqlConnection conn = new(connectionString); conn.Open(); using SqlTransaction trans = conn.BeginTransaction(); try { SqlCommand cmd = new(@" UPDATE Itens_Lotes SET QUANTIDADE = QUANTIDADE - @QTD, DATA_ALTERACAO = GETDATE() WHERE ID_ITEM_LOTE = @ORIGEM AND QUANTIDADE >= @QTD", conn, trans); cmd.Parameters.AddWithValue("@QTD", quantidade); cmd.Parameters.AddWithValue("@ORIGEM", loteOrigem); if (cmd.ExecuteNonQuery() == 0) { trans.Rollback(); return false; } cmd = new SqlCommand(@" UPDATE Itens_Lotes SET QUANTIDADE = QUANTIDADE + @QTD, DATA_ALTERACAO = GETDATE() WHERE ID_ITEM_LOTE = @DESTINO", conn, trans); cmd.Parameters.AddWithValue("@QTD", quantidade); cmd.Parameters.AddWithValue("@DESTINO", loteDestino); if (cmd.ExecuteNonQuery() == 0) { trans.Rollback(); return false; } trans.Commit(); return true; } catch { trans.Rollback(); throw; } }//TransferirQuantidade #endregion #region Controle de Validade - Validity Control public List LotesVencidos() { return Listar( validadeFinal: DateTime.Today, ativo: true); }//LotesVencidos public List LotesAVencer(int dias = 30) { return Listar( validadeInicial: DateTime.Today, validadeFinal: DateTime.Today.AddDays(dias), ativo: true); }//LotesAVencer public List LotesValidos() { using SqlConnection conn = new(connectionString); List lista = []; string sql = @" SELECT * FROM Itens_Lotes WHERE DATA_VALIDADE >= @DATA AND ATIVO = 1 ORDER BY DATA_VALIDADE"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@DATA", DateTime.Today); conn.Open(); using SqlDataReader dr = cmd.ExecuteReader(); while (dr.Read()) lista.Add(PreencherModelo(dr)); return lista; }//LotesValidos public List LotesSemValidade() { using SqlConnection conn = new(connectionString); List lista = []; string sql = @" SELECT * FROM Itens_Lotes WHERE DATA_VALIDADE IS NULL ORDER BY CODIGO"; using SqlCommand cmd = new(sql, conn); conn.Open(); using SqlDataReader dr = cmd.ExecuteReader(); while (dr.Read()) lista.Add(PreencherModelo(dr)); return lista; }//LotesSemValidade public int DiasParaVencer(int idLote) { ModeloItensLotes? lote = Carregar(idLote); if (lote == null) return -1; if (!lote.DATA_VALIDADE.HasValue) return int.MaxValue; return (lote.DATA_VALIDADE.Value.Date - DateTime.Today).Days; }//DiasParaVencer public int DiasVencido(int idLote) { ModeloItensLotes? lote = Carregar(idLote); if (lote == null) return 0; if (!lote.DATA_VALIDADE.HasValue) return 0; if (lote.DATA_VALIDADE.Value.Date >= DateTime.Today) return 0; return (DateTime.Today - lote.DATA_VALIDADE.Value.Date).Days; }//DiasVencido public DateTime? PrimeiroVencimento(string codigoProduto) { using SqlConnection conn = new(connectionString); string sql = @" SELECT MIN(DATA_VALIDADE) FROM Itens_Lotes WHERE COD_ITEM=@COD_ITEM AND DATA_VALIDADE IS NOT NULL AND ATIVO=1"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@COD_ITEM", codigoProduto); conn.Open(); object valor = cmd.ExecuteScalar(); if (valor == DBNull.Value || valor == null) return null; return Convert.ToDateTime(valor); }//PrimeiroVencimento public DateTime? UltimoVencimento(string codigoProduto) { using SqlConnection conn = new(connectionString); string sql = @" SELECT MAX(DATA_VALIDADE) FROM Itens_Lotes WHERE COD_ITEM=@COD_ITEM AND DATA_VALIDADE IS NOT NULL AND ATIVO=1"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@COD_ITEM", codigoProduto); conn.Open(); object valor = cmd.ExecuteScalar(); if (valor == DBNull.Value || valor == null) return null; return Convert.ToDateTime(valor); }//UltimoVencimento public bool ExisteLoteVencido(string codigoProduto) { using SqlConnection conn = new(connectionString); string sql = @" SELECT COUNT(*) FROM Itens_Lotes WHERE COD_ITEM=@COD_ITEM AND DATA_VALIDADE < @HOJE AND ATIVO=1"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@COD_ITEM", codigoProduto); cmd.Parameters.AddWithValue("@HOJE", DateTime.Today); conn.Open(); return Convert.ToInt32(cmd.ExecuteScalar()) > 0; }//ExisteLoteVencido public bool ExisteLoteAVencer(string codigoProduto, int dias = 30) { using SqlConnection conn = new(connectionString); string sql = @" SELECT COUNT(*) FROM Itens_Lotes WHERE COD_ITEM=@COD_ITEM AND DATA_VALIDADE BETWEEN @HOJE AND @DATA AND ATIVO=1"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@COD_ITEM", codigoProduto); cmd.Parameters.AddWithValue("@HOJE", DateTime.Today); cmd.Parameters.AddWithValue("@DATA", DateTime.Today.AddDays(dias)); conn.Open(); return Convert.ToInt32(cmd.ExecuteScalar()) > 0; }//ExisteLoteAVencer public decimal QuantidadeVencida(string codigoProduto) { using SqlConnection conn = new(connectionString); string sql = @" SELECT ISNULL(SUM(QUANTIDADE),0) FROM Itens_Lotes WHERE COD_ITEM=@COD_ITEM AND DATA_VALIDADE < @HOJE AND ATIVO=1"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@COD_ITEM", codigoProduto); cmd.Parameters.AddWithValue("@HOJE", DateTime.Today); conn.Open(); return Convert.ToDecimal(cmd.ExecuteScalar()); }//QuantidadeVencida public decimal QuantidadeAVencer(string codigoProduto, int dias = 30) { using SqlConnection conn = new(connectionString); string sql = @" SELECT ISNULL(SUM(QUANTIDADE),0) FROM Itens_Lotes WHERE COD_ITEM=@COD_ITEM AND DATA_VALIDADE BETWEEN @HOJE AND @DATA AND ATIVO=1"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@COD_ITEM", codigoProduto); cmd.Parameters.AddWithValue("@HOJE", DateTime.Today); cmd.Parameters.AddWithValue("@DATA", DateTime.Today.AddDays(dias)); conn.Open(); return Convert.ToDecimal(cmd.ExecuteScalar()); }//QuantidadeAVencer public decimal QuantidadeValida(string codigoProduto) { using SqlConnection conn = new(connectionString); string sql = @" SELECT ISNULL(SUM(QUANTIDADE),0) FROM Itens_Lotes WHERE COD_ITEM=@COD_ITEM AND DATA_VALIDADE >= @HOJE AND ATIVO=1"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@COD_ITEM", codigoProduto); cmd.Parameters.AddWithValue("@HOJE", DateTime.Today); conn.Open(); return Convert.ToDecimal(cmd.ExecuteScalar()); }//QuantidadeValida #endregion #region FEFO / FIFO - First Expired, First Out / First In, First Out public ModeloItensLotes? ObterFEFO(string codigoProduto) { using SqlConnection conn = new(connectionString); string sql = @" SELECT TOP 1 * FROM Itens_Lotes WHERE COD_ITEM=@COD_ITEM AND ATIVO=1 AND QUANTIDADE_DISPONIVEL>0 AND DATA_VALIDADE IS NOT NULL ORDER BY DATA_VALIDADE ASC"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@COD_ITEM", codigoProduto); conn.Open(); using SqlDataReader dr = cmd.ExecuteReader(); if (dr.Read()) return PreencherModelo(dr); return null; }//ObterFEFO public ModeloItensLotes? ObterFIFO(string codigoProduto) { using SqlConnection conn = new(connectionString); string sql = @" SELECT TOP 1 * FROM Itens_Lotes WHERE COD_ITEM=@COD_ITEM AND ATIVO=1 AND QUANTIDADE_DISPONIVEL>0 AND DATA_FABRICACAO IS NOT NULL ORDER BY DATA_FABRICACAO ASC"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@COD_ITEM", codigoProduto); conn.Open(); using SqlDataReader dr = cmd.ExecuteReader(); if (dr.Read()) return PreencherModelo(dr); return null; }//ObterFIFO public decimal QuantidadeDisponivel(int idLote) { using SqlConnection conn = new(connectionString); string sql = @" SELECT QUANTIDADE_DISPONIVEL FROM Itens_Lotes WHERE ID_ITEM_LOTE=@ID"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@ID", idLote); conn.Open(); object valor = cmd.ExecuteScalar(); return valor != DBNull.Value ? Convert.ToDecimal(valor) : 0; }//QuantidadeDisponivel public decimal QuantidadeReservada(int idLote) { using SqlConnection conn = new(connectionString); string sql = @" SELECT QUANTIDADE_RESERVADA FROM Itens_Lotes WHERE ID_ITEM_LOTE=@ID"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@ID", idLote); conn.Open(); object valor = cmd.ExecuteScalar(); return valor != DBNull.Value ? Convert.ToDecimal(valor) : 0; }//QuantidadeReservada public bool ReservarLote(int idLote, decimal quantidade) { using SqlConnection conn = new(connectionString); string sql = @" UPDATE Itens_Lotes SET QUANTIDADE_RESERVADA = QUANTIDADE_RESERVADA + @QTD, DATA_ALTERACAO = GETDATE() WHERE ID_ITEM_LOTE=@ID AND QUANTIDADE_DISPONIVEL>=@QTD"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@ID", idLote); cmd.Parameters.AddWithValue("@QTD", quantidade); conn.Open(); return cmd.ExecuteNonQuery() > 0; }//ReservarLote public bool LiberarLote(int idLote, decimal quantidade) { using SqlConnection conn = new(connectionString); string sql = @" UPDATE Itens_Lotes SET QUANTIDADE_RESERVADA = QUANTIDADE_RESERVADA - @QTD, DATA_ALTERACAO = GETDATE() WHERE ID_ITEM_LOTE=@ID AND QUANTIDADE_RESERVADA>=@QTD"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@ID", idLote); cmd.Parameters.AddWithValue("@QTD", quantidade); conn.Open(); return cmd.ExecuteNonQuery() > 0; }//LiberarLote public bool ConsumirReserva(int idLote, decimal quantidade) { using SqlConnection conn = new(connectionString); string sql = @" UPDATE Itens_Lotes SET QUANTIDADE = QUANTIDADE - @QTD, QUANTIDADE_RESERVADA = QUANTIDADE_RESERVADA - @QTD, DATA_ALTERACAO = GETDATE() WHERE ID_ITEM_LOTE=@ID AND QUANTIDADE_RESERVADA>=@QTD"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@ID", idLote); cmd.Parameters.AddWithValue("@QTD", quantidade); conn.Open(); return cmd.ExecuteNonQuery() > 0; }//ConsumirReserva public bool PodeAtenderVenda(int idLote, decimal quantidade) { return QuantidadeDisponivel(idLote) >= quantidade; }//PodeAtenderVenda public ModeloItensLotes? MelhorLote(string codigoProduto) { return ObterFEFO(codigoProduto); }//MelhorLote #endregion #region Indicadores - Indicators public int QuantidadeLotes() { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao)) { conexao.Open(); SqlCommand cmd = new SqlCommand( "SELECT COUNT(*) FROM Itens_Lotes", conexao); return Convert.ToInt32(cmd.ExecuteScalar()); } }//QuantidadeLotes public int QuantidadeProdutos() { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao)) { conexao.Open(); SqlCommand cmd = new SqlCommand( @"SELECT COUNT(DISTINCT COD_ITEM) FROM Itens_Lotes", conexao); return Convert.ToInt32(cmd.ExecuteScalar()); } }//QuantidadeProdutos public int QuantidadeLotesAtivos() { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao)) { conexao.Open(); SqlCommand cmd = new SqlCommand( @"SELECT COUNT(*) FROM Itens_Lotes WHERE ATIVO=1", conexao); return Convert.ToInt32(cmd.ExecuteScalar()); } }//QuantidadeLotesAtivos public int QuantidadeLotesInativos() { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao)) { conexao.Open(); SqlCommand cmd = new SqlCommand( @"SELECT COUNT(*) FROM Itens_Lotes WHERE ATIVO=0", conexao); return Convert.ToInt32(cmd.ExecuteScalar()); } }//QuantidadeLotesInativos public int QuantidadeVencidos() { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao)) { conexao.Open(); SqlCommand cmd = new SqlCommand( @"SELECT COUNT(*) FROM Itens_Lotes WHERE DATA_VALIDADE < GETDATE() AND ATIVO=1", conexao); return Convert.ToInt32(cmd.ExecuteScalar()); } }//QuantidadeVencidos public int QuantidadeAVencer(int dias) { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao)) { conexao.Open(); SqlCommand cmd = new SqlCommand( @"SELECT COUNT(*) FROM Itens_Lotes WHERE DATA_VALIDADE BETWEEN GETDATE() AND DATEADD(DAY,@DIAS,GETDATE()) AND ATIVO=1", conexao); cmd.Parameters.AddWithValue("@DIAS", dias); return Convert.ToInt32(cmd.ExecuteScalar()); } }//QuantidadeAVencer public int QuantidadeSemValidade() { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao)) { conexao.Open(); SqlCommand cmd = new SqlCommand( @"SELECT COUNT(*) FROM Itens_Lotes WHERE DATA_VALIDADE IS NULL", conexao); return Convert.ToInt32(cmd.ExecuteScalar()); } }//QuantidadeSemValidade public decimal QuantidadeTotalEstoque() { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao)) { conexao.Open(); SqlCommand cmd = new SqlCommand( @"SELECT ISNULL(SUM(QUANTIDADE),0) FROM Itens_Lotes WHERE ATIVO=1", conexao); return Convert.ToDecimal(cmd.ExecuteScalar()); } }//QuantidadeTotalEstoque public decimal QuantidadeDisponivelEstoque() { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao)) { conexao.Open(); SqlCommand cmd = new SqlCommand( @"SELECT ISNULL(SUM(QUANTIDADE_DISPONIVEL),0) FROM Itens_Lotes WHERE ATIVO=1", conexao); return Convert.ToDecimal(cmd.ExecuteScalar()); } }//QuantidadeDisponivelEstoque public decimal QuantidadeReservadaEstoque() { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao)) { conexao.Open(); SqlCommand cmd = new SqlCommand( @"SELECT ISNULL(SUM(QUANTIDADE_RESERVADA),0) FROM Itens_Lotes WHERE ATIVO=1", conexao); return Convert.ToDecimal(cmd.ExecuteScalar()); } }//QuantidadeReservadaEstoque public decimal MaiorQuantidade() { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao)) { conexao.Open(); SqlCommand cmd = new SqlCommand( @"SELECT ISNULL(MAX(QUANTIDADE),0) FROM Itens_Lotes", conexao); return Convert.ToDecimal(cmd.ExecuteScalar()); } }//MaiorQuantidade public decimal MenorQuantidade() { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao)) { conexao.Open(); SqlCommand cmd = new SqlCommand( @"SELECT ISNULL(MIN(QUANTIDADE),0) FROM Itens_Lotes WHERE QUANTIDADE>0", conexao); return Convert.ToDecimal(cmd.ExecuteScalar()); } }//MenorQuantidade #endregion #region Estatísticas - Statisticss public string ProdutoComMaisLotes() { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao)) { conexao.Open(); SqlCommand cmd = new SqlCommand(@" SELECT TOP 1 COD_ITEM FROM Itens_Lotes GROUP BY COD_ITEM ORDER BY COUNT(*) DESC", conexao); object obj = cmd.ExecuteScalar(); //return obj == null ? "" : obj.ToString(); return Convert.ToString(obj) ?? string.Empty; } }//ProdutoComMaisLotes public string ProdutoComMenosLotes() { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao)) { conexao.Open(); SqlCommand cmd = new SqlCommand(@" SELECT TOP 1 COD_ITEM FROM Itens_Lotes GROUP BY COD_ITEM ORDER BY COUNT(*) ASC", conexao); object obj = cmd.ExecuteScalar(); return Convert.ToString(obj) ?? string.Empty; } }//ProdutoComMenosLotes public string FornecedorComMaisLotes() { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao)) { conexao.Open(); SqlCommand cmd = new SqlCommand(@" SELECT TOP 1 FORNECEDOR FROM Itens_Lotes WHERE FORNECEDOR<>'' GROUP BY FORNECEDOR ORDER BY COUNT(*) DESC", conexao); object obj = cmd.ExecuteScalar(); return Convert.ToString(obj) ?? string.Empty; } }//FornecedorComMaisLotes public string FornecedorComMenosLotes() { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao)) { conexao.Open(); SqlCommand cmd = new SqlCommand(@" SELECT TOP 1 FORNECEDOR FROM Itens_Lotes WHERE FORNECEDOR<>'' GROUP BY FORNECEDOR ORDER BY COUNT(*) ASC", conexao); object obj = cmd.ExecuteScalar(); return Convert.ToString(obj) ?? string.Empty; } }//FornecedorComMenosLotes public decimal MediaQuantidadeLote() { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao)) { conexao.Open(); SqlCommand cmd = new SqlCommand(@" SELECT ISNULL(AVG(QUANTIDADE),0) FROM Itens_Lotes", conexao); return Convert.ToDecimal(cmd.ExecuteScalar()); } }//MediaQuantidadeLote public double MediaDiasValidade() { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao )) { conexao.Open(); SqlCommand cmd = new SqlCommand(@" SELECT ISNULL(AVG(DATEDIFF(DAY,GETDATE(),DATA_VALIDADE)),0) FROM Itens_Lotes WHERE DATA_VALIDADE IS NOT NULL", conexao); return Convert.ToDouble(cmd.ExecuteScalar()); } }//MediaDiasValidade public int ProdutosSemLote() { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao)) { conexao.Open(); SqlCommand cmd = new SqlCommand(@" SELECT COUNT(*) FROM Itens WHERE CODIGO NOT IN ( SELECT DISTINCT COD_ITEM FROM Itens_Lotes )", conexao); return Convert.ToInt32(cmd.ExecuteScalar()); } }//ProdutosSemLote public int LotesSemMovimento() { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao)) { conexao.Open(); SqlCommand cmd = new SqlCommand(@" SELECT COUNT(*) FROM Itens_Lotes WHERE DATA_ALTERACAO IS NULL", conexao); return Convert.ToInt32(cmd.ExecuteScalar()); } }//LotesSemMovimento public int LotesComEstoqueZero() { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao)) { conexao.Open(); SqlCommand cmd = new SqlCommand(@" SELECT COUNT(*) FROM Itens_Lotes WHERE QUANTIDADE<=0", conexao); return Convert.ToInt32(cmd.ExecuteScalar()); } }//LotesComEstoqueZero public int LotesComEstoquePositivo() { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao)) { conexao.Open(); SqlCommand cmd = new SqlCommand(@" SELECT COUNT(*) FROM Itens_Lotes WHERE QUANTIDADE>0", conexao); return Convert.ToInt32(cmd.ExecuteScalar()); } }//LotesComEstoquePositivo public decimal QuantidadeMediaPorProduto() { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao)) { conexao.Open(); SqlCommand cmd = new SqlCommand(@" SELECT ISNULL(AVG(Total),0) FROM ( SELECT SUM(QUANTIDADE) Total FROM Itens_Lotes GROUP BY COD_ITEM ) X", conexao); return Convert.ToDecimal(cmd.ExecuteScalar()); } }//QuantidadeMediaPorProduto public int QuantidadeProdutosComMaisDeUmLote() { using (SqlConnection conexao = new SqlConnection(DadosDaConexao.ObjetoStringConexao)) { conexao.Open(); SqlCommand cmd = new SqlCommand(@" SELECT COUNT(*) FROM ( SELECT COD_ITEM FROM Itens_Lotes GROUP BY COD_ITEM HAVING COUNT(*)>1 ) X", conexao); return Convert.ToInt32(cmd.ExecuteScalar()); } }//QuantidadeProdutosComMaisDeUmLote #endregion #region Relatórios- Reports public DataTable ListarTodos() { DataTable tabela = new(); using SqlConnection conexao = new(connectionString); conexao.Open(); SqlDataAdapter da = new(@" SELECT * FROM Itens_Lotes ORDER BY COD_ITEM, DATA_VALIDADE", conexao); da.Fill(tabela); return tabela; }//ListarTodos public DataTable RelatorioPorProduto(string codItem) { DataTable tabela = new(); using SqlConnection conexao = new(connectionString); conexao.Open(); SqlDataAdapter da = new(@" SELECT * FROM Itens_Lotes WHERE COD_ITEM=@COD_ITEM ORDER BY DATA_VALIDADE", conexao); da.SelectCommand.Parameters.AddWithValue( "@COD_ITEM", codItem); da.Fill(tabela); return tabela; }//RelatorioPorProduto public DataTable RelatorioPorFornecedor(string fornecedor) { DataTable tabela = new(); using SqlConnection conexao = new(connectionString); conexao.Open(); SqlDataAdapter da = new(@" SELECT * FROM Itens_Lotes WHERE FORNECEDOR=@FORNECEDOR ORDER BY COD_ITEM", conexao); da.SelectCommand.Parameters.AddWithValue( "@FORNECEDOR", fornecedor); da.Fill(tabela); return tabela; }//RelatorioPorFornecedor public DataTable RelatorioVencidos() { DataTable tabela = new(); using SqlConnection conexao = new(connectionString); conexao.Open(); SqlDataAdapter da = new(@" SELECT * FROM Itens_Lotes WHERE DATA_VALIDADE < GETDATE() AND ATIVO = 1 ORDER BY DATA_VALIDADE", conexao); da.Fill(tabela); return tabela; }//RelatorioVencidos public DataTable RelatorioAVencer(int dias) { DataTable tabela = new(); using SqlConnection conexao = new(connectionString); conexao.Open(); SqlDataAdapter da = new(@" SELECT * FROM Itens_Lotes WHERE DATA_VALIDADE BETWEEN GETDATE() AND DATEADD(DAY,@DIAS,GETDATE()) AND ATIVO = 1 ORDER BY DATA_VALIDADE", conexao); da.SelectCommand.Parameters.AddWithValue( "@DIAS", dias); da.Fill(tabela); return tabela; }//RelatorioAVencer public DataTable RelatorioSemValidade() { DataTable tabela = new(); using SqlConnection conexao = new(connectionString); conexao.Open(); SqlDataAdapter da = new(@" SELECT * FROM Itens_Lotes WHERE DATA_VALIDADE IS NULL", conexao); da.Fill(tabela); return tabela; }//RelatorioSemValidade public DataTable RelatorioEstoqueZero() { DataTable tabela = new(); using SqlConnection conexao = new(connectionString); conexao.Open(); SqlDataAdapter da = new(@" SELECT * FROM Itens_Lotes WHERE QUANTIDADE <= 0 ORDER BY COD_ITEM", conexao); da.Fill(tabela); return tabela; }//RelatorioEstoqueZero public DataTable RelatorioAtivos() { DataTable tabela = new(); using SqlConnection conexao = new(connectionString); conexao.Open(); SqlDataAdapter da = new(@" SELECT * FROM Itens_Lotes WHERE ATIVO = 1 ORDER BY COD_ITEM", conexao); da.Fill(tabela); return tabela; }//RelatorioAtivos public DataTable RelatorioInativos() { DataTable tabela = new(); using SqlConnection conexao = new(connectionString); conexao.Open(); SqlDataAdapter da = new(@" SELECT * FROM Itens_Lotes WHERE ATIVO = 0 ORDER BY COD_ITEM", conexao); da.Fill(tabela); return tabela; }//RelatorioInativos public DataTable RelatorioComReserva() { DataTable tabela = new(); using SqlConnection conexao = new(connectionString); conexao.Open(); SqlDataAdapter da = new(@" SELECT * FROM Itens_Lotes WHERE QUANTIDADE_RESERVADA > 0 ORDER BY COD_ITEM", conexao); da.Fill(tabela); return tabela; }//RelatorioComReserva public DataTable RelatorioSemSaldo() { DataTable tabela = new(); using SqlConnection conexao = new(connectionString); conexao.Open(); SqlDataAdapter da = new(@" SELECT * FROM Itens_Lotes WHERE QUANTIDADE = 0 ORDER BY COD_ITEM", conexao); da.Fill(tabela); return tabela; }//RelatorioSemSaldo public DataTable RelatorioDisponiveis() { DataTable tabela = new(); using SqlConnection conexao = new(connectionString); conexao.Open(); SqlDataAdapter da = new(@" SELECT * FROM Itens_Lotes WHERE QUANTIDADE_DISPONIVEL > 0 ORDER BY COD_ITEM, DATA_VALIDADE", conexao); da.Fill(tabela); return tabela; }//RelatorioDisponiveis #endregion #region Integração - Integration public bool AtualizarSaldoItem(string codigoItem) { decimal saldo = SaldoProduto(codigoItem); using SqlConnection conn = new(connectionString); string sql = @" UPDATE Itens SET ESTOQUE_DISP = @ESTOQUE WHERE CODIGO = @CODIGO"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue("@ESTOQUE", saldo.ToString()); cmd.Parameters.AddWithValue("@CODIGO", codigoItem); conn.Open(); return cmd.ExecuteNonQuery() > 0; }//AtualizarSaldoItem public bool AtualizarUltimaCompra(string codigoItem,DateTime dataCompra) { using SqlConnection conn = new(connectionString); string sql = @" UPDATE Itens SET ULTIMA_COMPRA = @DATA WHERE CODIGO = @CODIGO"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue( "@DATA", dataCompra.ToString("dd/MM/yyyy")); cmd.Parameters.AddWithValue( "@CODIGO", codigoItem); conn.Open(); return cmd.ExecuteNonQuery() > 0; }//AtualizarUltimaCompra public bool AtualizarFornecedorPrincipal(string codigoItem) { using SqlConnection conn = new(connectionString); string sqlFornecedor = @" SELECT TOP 1 FORNECEDOR FROM Itens_Lotes WHERE COD_ITEM=@COD_ITEM GROUP BY FORNECEDOR ORDER BY COUNT(*) DESC"; using SqlCommand cmd = new(sqlFornecedor, conn); cmd.Parameters.AddWithValue( "@COD_ITEM", codigoItem); conn.Open(); string fornecedor = Convert.ToString(cmd.ExecuteScalar()) ?? string.Empty; conn.Close(); sqlFornecedor = @" UPDATE Itens SET FORNECEDOR=@FORNECEDOR WHERE CODIGO=@CODIGO"; cmd.CommandText = sqlFornecedor; cmd.Parameters.Clear(); cmd.Parameters.AddWithValue( "@FORNECEDOR", fornecedor); cmd.Parameters.AddWithValue( "@CODIGO", codigoItem); conn.Open(); return cmd.ExecuteNonQuery() > 0; }//AtualizarFornecedorPrincipal public bool AtualizarValidadeProduto(string codigoItem) { DateTime? validade = PrimeiroVencimento(codigoItem); if (!validade.HasValue) return false; using SqlConnection conn = new(connectionString); string sql = @" UPDATE Itens SET VALIDADE=@VALIDADE WHERE CODIGO=@CODIGO"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue( "@VALIDADE", validade.Value.ToString("dd/MM/yyyy")); cmd.Parameters.AddWithValue( "@CODIGO", codigoItem); conn.Open(); return cmd.ExecuteNonQuery() > 0; }//AtualizarValidadeProduto public void RecalcularEstoqueProduto(string codigoItem) { AtualizarSaldoItem(codigoItem); AtualizarFornecedorPrincipal( codigoItem); AtualizarValidadeProduto( codigoItem); }//RecalcularEstoqueProduto #endregion #region Inteligencia de Negócios - Business Intelligence public ModeloItensLotes? MelhorLoteVenda(string codigoProduto) { // Hoje utiliza FEFO. // Futuramente poderá ler da configuração da empresa. return ObterFEFO(codigoProduto); }//MelhorLoteVenda public bool SugestaoReposicao(string codigoProduto) { decimal saldo = SaldoProduto( codigoProduto); using SqlConnection conn = new(connectionString); string sql = @" SELECT ESTOQUE_MIN FROM Itens WHERE CODIGO=@CODIGO"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue( "@CODIGO", codigoProduto); conn.Open(); decimal minimo = Convert.ToDecimal( cmd.ExecuteScalar() ?? 0); return saldo <= minimo; }//SugestaoReposicao public decimal CapitalParado() { using SqlConnection conn = new(connectionString); string sql = @" SELECT ISNULL( SUM( TRY_CONVERT(decimal(18,2), QUANTIDADE) ),0) FROM Itens_Lotes WHERE QUANTIDADE > 0"; using SqlCommand cmd = new(sql, conn); conn.Open(); return Convert.ToDecimal( cmd.ExecuteScalar()); }//CapitalParado public decimal CapitalVencido() { using SqlConnection conn = new(connectionString); string sql = @" SELECT ISNULL( SUM(QUANTIDADE),0) FROM Itens_Lotes WHERE DATA_VALIDADE < GETDATE()"; using SqlCommand cmd = new(sql, conn); conn.Open(); return Convert.ToDecimal( cmd.ExecuteScalar()); }//CapitalVencido public decimal CapitalAVencer(int dias) { using SqlConnection conn = new(connectionString); string sql = @" SELECT ISNULL( SUM(QUANTIDADE),0) FROM Itens_Lotes WHERE DATA_VALIDADE BETWEEN GETDATE() AND DATEADD( DAY, @DIAS, GETDATE())"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue( "@DIAS", dias); conn.Open(); return Convert.ToDecimal( cmd.ExecuteScalar()); }//CapitalAVencer public List ProdutosCriticos() { List lista = []; using SqlConnection conn = new(connectionString); string sql = @" SELECT DISTINCT COD_ITEM FROM Itens_Lotes WHERE DATA_VALIDADE < DATEADD( DAY, 15, GETDATE())"; using SqlCommand cmd = new(sql, conn); conn.Open(); using SqlDataReader dr = cmd.ExecuteReader(); while (dr.Read()) { lista.Add( dr["COD_ITEM"] .ToString()!); } return lista; }//ProdutosCriticos public ListLotesPrioritarios() { return Listar(validadeFinal:DateTime.Today.AddDays(15)); }//LotesPrioritarios public bool ExisteRiscoPerda(string codigoProduto) { return ExisteLoteAVencer( codigoProduto, 15); }//ExisteRiscoPerda public decimal SugestaoCompra(string codigoProduto) { using SqlConnection conn = new(connectionString); string sql = @" SELECT ESTOQUE_IDEAL FROM Itens WHERE CODIGO=@CODIGO"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue( "@CODIGO", codigoProduto); conn.Open(); decimal ideal = Convert.ToDecimal( cmd.ExecuteScalar() ?? 0); decimal atual = SaldoProduto( codigoProduto); if (ideal <= atual) return 0; return ideal - atual; }//SugestaoCompra public bool PossuiLotes(string codigoProduto) { using SqlConnection conn = new(connectionString); string sql = @" SELECT COUNT(*) FROM Itens_Lotes WHERE COD_ITEM=@COD_ITEM"; using SqlCommand cmd = new(sql, conn); cmd.Parameters.AddWithValue( "@COD_ITEM", codigoProduto); conn.Open(); return Convert.ToInt32( cmd.ExecuteScalar()) > 0; }//PossuiLotes #endregion //Concluida em 2026-07-20 //Versão 1.0.2 } }