VB.NET 2008 - Protótipo para Sistema de Vendas com LINQ - III
Esta é a última parte do protótipo para sistema de vendas com LINQ. Se você esta chegando agora sugiro que leia os dois artigos anteriores:
Vou começar exibindo o formulário de vendas frmvendas do sistema:
Os controles
usados no formulário são: Dados do Cliente:
Dados do Produto:
Exibição das Vendas :
btnIncluir, btnExcluir,btnCancelar e btnSalvar Exibição do total: txtTotal |
Antes de entrar no código do formulário teremos que criar uma classe para poder tratar os detalhes do Pedido (Vendas);
Clique com o botão direito sobre o nome do projeto e selecione a opção Add new Item ;
Na janela New Item selecione o template Class e informe o nome detalhesPedidos.vb;
A seguir inclua o seguinte código nesta classe:
Public Class DetalhesPedidos Private _codProduto As String Private _nomeProduto As String Private _quantidade As Integer Private _preco As Double Private _subtotal As Double Private _estoqueProduto As Double Public Property EstoqueProduto() As Integer Get Return _estoqueProduto End Get Set(ByVal value As Integer) _estoqueProduto = value End Set End Property Public Property CodProduto() As String Get Return _codProduto End Get Set(ByVal value As String) _codProduto = value End Set End Property Public Property NomeProduto() As String Get Return _nomeProduto End Get Set(ByVal value As String) _nomeProduto = value End Set End Property Public Property Quantidade() As Integer Get Return _quantidade End Get Set(ByVal value As Integer) _quantidade = value End Set End Property Public Property Preco() As Double Get Return _preco End Get Set(ByVal value As Double) _preco = value End Set End Property Public Property Subtotal() As Double Get Return _subtotal End Get Set(ByVal value As Double) _subtotal = value End Set End Property End Class |
Na classe DetalhesPedidos
definimos 4 propriedades :
que serão usadas para tratarmos os detalhes dos pedidos. |
Voltando ao formulário de vendas a primeira coisa que temos que fazer é declarar as variáveis que usaremos na aplicação as quais são:
'Definir o objeto bd da classe JcmSoftDataContext Dim bd As New JcmSoftDataContext 'Definir objeto da clase DetalhesPedidos Dim oDetalhesPedidos As DetalhesPedidos Dim nomeProduto As String Dim codProduto As String Dim precoProduto As Double Dim codigoCliente As String Dim estoqueProduto As Integer 'Definir una LISTA de Objetos DetalhesPedidos Dim ArrDetalhesPedidos As New List(Of DetalhesPedidos) |
Perceba que eu declarei um
uma lista do tipo DetalhesPedidos usando
Generics; apenas para lembrar: List(Of T) - Representa uma lista
fortemente tipada de objetos que podem ser |
No evento Click do botão com 3 pontinhos ao lado do código do cliente temos o código que irá abrir o formulário frmClientes para que o usuário selecione o um cliente já cadastrado; em seguida usando o código do cliente escolhido é feita uma consulta LINQ para selecionar o Cliente que possui o código escolhido no formulário frmclientes e exibir os seus dados nos controles do formulário frmvendas;
Private Sub btnProcuraCliente_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnProcuraCliente.Click 'Instanciamos un Objeto Formulario frmClientes Dim dialogo As New frmClientes 'Mostramos o Formulario dialogo.ShowDialog() 'Se o resultado do Formulario e diferente de OK 'mostra uma mensagem que indica que não 'há nenhum cliente selecionado If dialogo.DialogResult = Windows.Forms.DialogResult.OK Then 'Usamos uma consulta LINQ para selecionar um cliente 'do qual recuperamos a variável codigoCliente declarada no 'Formulario frmClientes Dim cliente = From cli In bd.Clientes _ Where cli.clienteID = dialogo.codigo _ Select cli.clienteID, cli.nome, cli.email 'Carregamos os valores do resultado da consulta 'LINQ nos textbox do formulario Me.txtCodigoCliente.Text = cliente.ToList.Item(0).clienteID.ToString Me.txtNomeCliente.Text = cliente.ToList.Item(0).nome codigoCliente = cliente.ToList.Item(0).clienteID.ToString Else 'exibe mensagem ao usuário e limpa os campos do formulário MsgBox("Não foi selecionado nenhum cliente.") Me.txtCodigoCliente.Text = "" Me.txtNomeCliente.Text = "" codigoCliente = "" End If End Sub |
Da mesma forma no evento Click do botão temos o código que abra o formulário para o usuário selecionar um produto já cadastrado e em seguida obtendo o valor do código do produto escolhido , seleciona o produto e exibe o seus dados no formulário frmvendas;
Private Sub btnProcuraProduto_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnProcuraProduto.Click 'Instancia um formulario frmProdutos Dim dialogo As New frmProdutos 'exibe o formulario dialogo.ShowDialog() 'se o resultado do formulario é Ok If dialogo.DialogResult = Windows.Forms.DialogResult.OK Then 'cria uma consulta LINQ para exibir os produtos cadastrados Dim produto = From prod In bd.Produtos _ Where prod.ProdutoID = dialogo.codigo _ Select prod.ProdutoID, prod.Nome, prod.preco, prod.estoque 'obtem os valores e exibe nos controles TextBox do formulario Me.txtNomeProduto.Text = produto.ToList.Item(0).Nome.ToString Me.txtPrecoProduto.Text = produto.ToList.Item(0).preco.ToString 'atribui os valores as variáveis definidas no formulario nomeProduto = produto.ToList.Item(0).Nome.ToString codProduto = produto.ToList.Item(0).ProdutoID.ToString precoProduto = Convert.ToDouble(produto.ToList.Item(0).preco.ToString) estoqueProduto = Convert.ToInt32(produto.ToList.Item(0).estoque.ToString) 'poe o foco no textbox quantidade txtQuantidade.Focus() Else 'exibe mensagem ao usuário e limpa os campos do formulário MsgBox("Nenhum Produto foi selecionado.") Me.txtNomeProduto.Text = "" Me.txtPrecoProduto.Text = "" nomeProduto = "" codProduto = "" precoProduto = 0.0 End If |
O código relacionado ao botão Incluir esta descrito abaixo e usa o arrayList do tipo DetalhesPedidos para exibir os pedidos de vendas incluídos no controle DataGridView;
Private Sub btnIncluir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnIncluir.Click 'Verificamos a quantidade foi informada If txtQuantidade.Text = String.Empty Then MsgBox("Informe a quantidade requerida...") txtQuantidade.Focus() Exit Sub End If 'Verificamos se o nome do produto , preco e quantidade não estão vazios If txtNomeProduto.Text <> "" And txtPrecoProduto.Text <> "" And txtQuantidade.Text <> "" Then 'Verificamos se o estoque do produto não é menor do que o solicitado If Convert.ToInt32(estoqueProduto) < Convert.ToInt32(txtQuantidade.Text) Then 'Mostramos uma aviso ao usuário MsgBox("A quantidade requerida é Superior a do estoque") 'Como a quantidade solicitada é mario que o estoque 'perguntamos se o usuário deseja estabelecer o estoque atual 'com a nova quantidade informada If MessageBox.Show("Deseja estabelecer o estoque atual como a nova quantidade requerida",_ "Vendas", MessageBoxButtons.YesNo) = Windows.Forms.DialogResult.Yes Then 'Establecemos a nova quantidade em estoque txtQuantidade.Text = estoqueProduto 'Inicializamos o objeto da classe DetalhesPedidos oDetalhesPedidos = New DetalhesPedidos 'Preenchemos os valores '----------------------------------------------------------------- oDetalhesPedidos.Quantidade = Convert.ToInt32(txtQuantidade.Text) oDetalhesPedidos.CodProduto = codProduto oDetalhesPedidos.NomeProduto = nomeProduto oDetalhesPedidos.Preco = precoProduto oDetalhesPedidos.EstoqueProduto = estoqueProduto oDetalhesPedidos.Subtotal = precoProduto * Convert.ToInt32(txtQuantidade.Text) '------------------------------------------------------------------------ 'Verificamos se o produto esta na lista de pedidos 'e incluimos a lista de DetalhesPedidos If buscarDetalhesVendas(ArrDetalhesPedidos, oDetalhesPedidos) = False Then 'Agregamos o pedido a lista de DetalhesPedidos ArrDetalhesPedidos.Add(oDetalhesPedidos) End If 'Assciamos a lista de DetalhesPedidos como fonte de dados ao datagridview Me.dgvVendas.DataSource = ArrDetalhesPedidos Else 'Se não deseja estabelecer o estoque atual com a quantidade solicitada 'voltamos ao formulario para escolher outro produto btnProcuraProduto_Click(Nothing, Nothing) End If Else 'Como a quantidade requerida e menor que o estoque 'iniciamos o objeto da classe DetalhesPedidos oDetalhesPedidos = New DetalhesPedidos 'Preenchemos os valores no objeto oDetalhesPedidos.Quantidade = Convert.ToInt32(txtQuantidade.Text) oDetalhesPedidos.CodProduto = codProduto oDetalhesPedidos.NomeProduto = nomeProduto oDetalhesPedidos.Preco = precoProduto oDetalhesPedidos.EstoqueProduto = estoqueProduto oDetalhesPedidos.Subtotal = precoProduto * Convert.ToInt32(txtQuantidade.Text) 'Verificamos se o produto solicitado esta na lista de pedidos 'Se não estiver incluimos na lista de DetalhesPedidos If buscarDetalhesVendas(ArrDetalhesPedidos, oDetalhesPedidos) = False Then 'Incluimos o pedido a lista de DetalhesPedidos ArrDetalhesPedidos.Add(oDetalhesPedidos) End If 'Associamos a lista como origem da fonte de dados Me.dgvVendas.DataSource = ArrDetalhesPedidos.ToList End If End If 'Limpamos os textBox Me.limpar_produto() 'Calculamos o Total do Pedido Me.calcular_total() End Sub |
No botão Salvar temos o código que irá salvar os dados e atualizar o estoque de produtos; Nesta rotina estou usando um expressão lambda;
O que são Expressões Lambda ?
As expressões lambda foram incluídas no VS/VB 2008 para dar suporte a consultas LINQ. As cláusulas Where são assim compiladas como expressões lambdas e chamadas em itens aplicáveis do seu dataset. Podem ser consideradas uma forma de delegate que pode passar ou retornar outra função.
Para saber mais veja o meu artigo: ASP .NET - Usando LINQ
Private Sub btnSalvar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSalvar.Click 'Vamos usar o mapeamento feito pelo LINQ 'para efetivar as atualizações nas bases de dados Try 'A expressão lambda a seguir devolve um objeto Cliente 'Estamos usando o codigo do cliente para identificar unicamento o cliente Dim Cli As Cliente = bd.Clientes.Single(Function(p) p.clienteID = Me.txtCodigoCliente.Text) '------------------------------------------------- 'Cria um novo objeto Pedido '------------------------------------------------- Dim oPedido As New Pedido oPedido.data = Date.Now oPedido.clienteID = Cli.clienteID oPedido.Cliente = Cli '-------------------------------------------------- 'Obtendo os detalhes do pedido 'realizo a geração dos objetos Pedido 'vou percorrer o array dos detalhes do pedido '---------------------------------------------------- For Each o As DetalhesPedidos In ArrDetalhesPedidos 'Instancio um objeto Produto selecionando pelo codigo do produto Dim produto As Produto = bd.Produtos.Single(Function(a) a.ProdutoID = o.CodProduto.ToString()) 'Cria um novo detalhe do pedido Dim detPedido As New DetalhesPedido detPedido.Produto = produto detPedido.ProdutoID = produto.ProdutoID detPedido.Quantidade = o.Quantidade detPedido.Preco = o.Preco 'inclui os detalhes do pedido no pedido oPedido.DetalhesPedidos.Add(detPedido) '-altera a quantidade de estoque do produto produto.estoque = produto.estoque - o.Quantidade Next '------------------------------------------------------ 'Aqui atualizo a base de dados bd.SubmitChanges() MsgBox("Dados de Pedidos , Detalhes de Pedidos e Estoque atualizados com sucesso...") Catch ex As Exception MsgBox(ex.Message) Finally 'chama as rotinas para limpar clientes e produtos e vendas limpar_cliente() limpar_produto() limpar_venda() Me.calcular_total() End Try End Sub |
A função buscarDetalhesVendas recebe como parâmetro o arrayList do tipo DetalhesPedidos e pesquisa no arrayList por um determinado produto conferindo com a quantidade em estoque;
Public Function buscarDetalhesVendas(ByVal array As List(Of DetalhesPedidos), ByVal objDV As DetalhesPedidos) As Boolean 'Vreificamos se um produto ja foi solicitado For Each oDetPed As DetalhesPedidos In array If oDetPed.CodProduto = objDV.CodProduto Then Dim nQuantidade As Integer 'Se encontramos o produto na lista de pedidos 'incrementamos a quantidade solicitada 'com a quantidade solicitada anteriomente nQuantidade = oDetPed.Quantidade + objDV.Quantidade If nQuantidade <= oDetPed.EstoqueProduto Then oDetPed.Quantidade = nQuantidade oDetPed.Subtotal = oDetPed.Preco * oDetPed.Quantidade Else MsgBox("O estoque atual é insuficiente para a quantidade solicitada.") End If Return True End If Next Return False End Function |
O total exibido no formulário é calculado pela rotina calcular_total que percorre o arrayList e soma os valores dos produtos incluídos;
Sub calcular_total() Dim soma As Double 'calcula o valor total dos pedidos 'percorre o arrayList e soma o valor Subtotal For Each i As DetalhesPedidos In ArrDetalhesPedidos soma += i.Subtotal Next Me.txtTotal.Text = soma.ToString("C") End Sub |
Finalmente temos as rotinas para limpar os produtos, vendas e clientes;
Sub
limpar_produto() 'limpa os controles TextBox Me.txtQuantidade.Clear() Me.txtNomeProduto.Clear() Me.txtPrecoProduto.Clear() End Sub |
Sub
limpar_venda() 'Limpa a lista usando o metodo Clear ArrDetalhesPedidos.Clear() 'Atribuir a lista como origem de dados ao datagridview Me.dgvVendas.DataSource = ArrDetalhesPedidos.ToList End Sub |
Sub
limpar_cliente() 'Metodo para limpar os textBox Associados ao Cliente Me.txtCodigoCliente.Clear() Me.txtNomeCliente.Clear() End Sub |
O código esta comentado basta pegar o projeto completo e conferir o seu funcionamento. Com isso você tem um protótipo bem simples de um sistema de vendas básico que pode lhe dar algumas idéias para o seu próprio projeto.
Eu sei , é apenas VB .NET e LINQ , mas eu gosto...
referências:
José Carlos Macoratti