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