ASP .NET 4.5 Web Forms - Incluindo o carrinho de compras- V
Este tutorial descreve a lógica de negócios necessária para adicionar um carrinho ao nosso site ASP .NET Web Forms. Quando você tiver concluído este tutorial, os usuários serão capazes de adicionar, remover e modificar os produtos em seu carrinho de compras.
Obs: Acompanhe todas as partes do curso neste link: http://www.macoratti.net/Cursos/aspn_450.htm
O que você vai aprender:
Os recursos introduzidos neste artigo são:
Este artigo foi integralmente baseado no artigo original : http://www.asp.net/web-forms/tutorials/aspnet-45/getting-started-with-aspnet-45-web-forms/shopping-cart (com algumas alterações e portado para a linguagem VB .NET)
Criando um carrinho de compras
Em artigo anteriores, nesta série de tutoriais, adicionamos páginas e códigos para visualizar os dados do produto a partir de um banco de dados.
Neste tutorial, você vamos criar um carrinho de compras para gerir os produtos que os usuários estão interessados em comprar. Os usuários serão capazes de procurar e adicionar itens ao carrinho de compras, mesmo que não esteja registrado ou logado.
Para gerenciar o acesso ao carrinho de compras, vamos atribuir aos usuários uma identificação única usando um identificador exclusivo (GUID), quando o usuário acessa o carrinho pela primeira vez. Vamos armazenar esse ID utilizando o estado da sessão ASP.NET.
O
estado da sessão no ASP.NET é um local conveniente para
armazenar informações específicas do usuário que irá
expirar após o usuário deixar o site. Embora uso indevido de estado da sessão pode ter implicações de desempenho em sites maiores, a sua utilização com moderação funciona bem para fins de demonstração. |
Adicionando um Item do Carrinho (CarrinhoItem) como uma classe do modelo
Já definimos em nossa aplicação o esquema para a categoria e dados do produto, criando classes para representar as categorias e os produtos na pasta Models.
Vamos agora incluir uma nova classe para definir o esquema para o carrinho de compras. Posteriormente vamos incluir uma classe para manipular os dados de acesso a tabela CarrinhoItem. Esta classe irá fornecer a lógica de negócio para adicionar, remover e atualizar itens no carrinho de compras.
Na janela Solution Explorer clique com o botão direito do mouse sobre a pasta Models e selecione Add -> New Item;
Na janela Add New Item selecione Visual Basic -> Code e o template Class informando o nome CarrinhoItem.vb e clicando no botão Add;
A seguir digite o código abaixo neste arquivo:
Imports System.ComponentModel.DataAnnotations Namespace WingtipToys.Models Public Class CarrinhoItem <Key> _ Public Property ItemId() As String Get Return m_ItemId End Get Set(value As String) m_ItemId = value End Set End Property Private m_ItemId As String Public Property CarrinhoId() As String Get Return m_CarrinhoId End Get Set(value As String) m_CarrinhoId = value End Set End Property Private m_CarrinhoId As String Public Property Quantidade() As Integer Get Return m_Quantidade End Get Set(value As Integer) m_Quantidade = value End Set End Property Private m_Quantidade As Integer Public Property DataCriacao() As System.DateTime Get Return m_DataCriacao End Get Set(value As System.DateTime) m_DataCriacao = value End Set End Property Private m_DataCriacao As System.DateTime Public Property ProdutoId() As Integer Get Return m_ProdutoId End Get Set(value As Integer) m_ProdutoId = value End Set End Property Private m_ProdutoId As Integer Public Overridable Property Produto() As Produto Get Return m_Produto End Get Set(value As Produto) m_Produto = value End Set End Property Private m_Produto As Produto End Class End Namespace |
A classe CarrinhoItem
possui 6 propriedades:
|
A classe carrinhoItem contém o esquema que vai definir cada produto que o usuário adiciona ao carrinho de compras. Esta classe é igual as demais classes de esquema que criamos anteriormente.
Por convenção, o Entity Framework Code-First espera que a chave primária da tabela Carrinhotem seja ou CarrinhoItemId ou ID. No entanto, o código sobrescreve o comportamento padrão usando o atributo data annotation [Key]. O atributo Key da propriedade ItemId especifica que a propriedade ItemID é a chave primária.
A propriedade CarrinhoId especifica o ID do usuário que está associado com o item para comprar. Você vai adicionar código para criar esse ID de usuário quando o usuário acessa o carrinho de compras. Este ID também será armazenado como uma variável de sessão ASP.NET.
Atualizando o Contexto Produto
Além de adicionar a classe CarrinhoItem, vamos precisar atualizar a classe de contexto de banco de dados que gerencia as classes de entidade e que fornece acesso a dados para o banco de dados. Para fazer isso, vamos adicionar a classe carrinhoItem à classe ProdutoContexto.
Na janela Solution Explorer, abra a pasta Models e selecione e abra o arquivo ProdutoContexto.vb;
A seguir inclua a linha de código : Public Property CarrinhoItens() As DbSet(Of CarrinhoItem) conforme mostrada abaixo:
Imports System.Data.Entity Namespace WingtipToys.Models Public Class ProdutoContexto Inherits DbContext Public Sub New() MyBase.New("WingtipToys") End Sub Public Property Categorias() As DbSet(Of Categoria) Public Property Produtos() As DbSet(Of Produto) Public Property CarrinhoItens() As DbSet(Of CarrinhoItem) End Class End Namespace |
O código do arquivo ProdutoContexto.vb adiciona o namespace System.Data.Entity para que tenhamos acesso a todo o núcleo de funcionalidade do Entity Framework. Esta funcionalidade inclui a capacidade de consultar, inserir, atualizar e excluir dados, trabalhando com objetos fortemente tipados. A classe ProdutoContexto também acrescenta acesso à classe CarrinhoItem.
Gerenciando a lógica de negócios do carrinho de compras
Vamos criar a classe CarrinhoCompras em uma nova pasta esta classe vai manipular o acesso aos dados da tabela CarinhoItem e também incluir a lógica de negócio para adicionar, remover e atualizar os itens no carrinho de compras.
A lógica de carrinho de compras que você irá adicionar conterá a funcionalidade para gerenciar as seguintes ações:
A página do carrinho de compras (Carrinho.aspx) e a classe carrinho de compras serão utilizados em conjunto para acessar os dados do carrinho de compras. A página do carrinho de compras irá exibir todos os itens que o usuário adiciona ao carrinho de compras.
Além da página do carrinho de compras e de classe, vamos criar uma página (IncluirNoCarrinho.aspx) para adicionar produtos ao carrinho de compras. Vamos adicionar código à página ProdutoLista.aspx e na página ProdutoDetalhes.aspx que irá fornecer um link para a página IncluirNoCarrinho.aspx, de modo que o usuário possa adicionar produtos ao carrinho de compras.
O diagrama a seguir mostra o processo básico que ocorre quando o usuário adiciona um produto no carrinho de compras.
Quando o usuário clicar no link Adicionar ao carrinho de compras na página ProdutoLista.aspx ou na página ProdutoDetalhes.aspx, o aplicativo irá navegar até a página IncluirNoCarrinho.aspx e automaticamente para a página Carrinho.aspx. A página IncluirNoCarrinho.aspx irá adicionar o produto selecionado no carrinho de compras, chamando um método na classe Carrinho e a página Carrinho.aspx exibirá os produtos que foram adicionados ao carrinho de compras.
A classe CarrinhoActions será adicionada a uma pasta separada no aplicativo de modo que haverá uma distinção clara entre o modelo (pasta Models), as páginas (pasta raiz) e lógica (pasta Logic).
Clique com o botão direito sobre o nome do projeto e selecione a opção Add New Folder;
Informe nome da pasta como Logic;
Clique com o botão direito sobre a pasta Logic e selecione Add-> New Item;
Inclua uma nova classe chamada CarrinhoActions.vb e substitua o código pelo código a seguir:
Imports System Imports System.Collections.Generic Imports System.Linq Imports System.Web Imports WingTipToys.WingtipToys.Models Namespace WingtipToys.Logic Public Class CarrinhoActions Public Property CarrinhoId() As String Get Return m_CarrinhoId End Get Set(value As String) m_CarrinhoId = value End Set End Property Private m_CarrinhoId As String Private _db As New ProdutoContexto() Public Const CarrinhoSessaoChave As String = "CarrinhoId" Public Sub IncluirNoCarrinho(id As Integer) ' Retorna o produto do banco de dados CarrinhoId = GetCarrinhoId() Dim carrinhoItem = _db.CarrinhoItens.SingleOrDefault(Function(c) c.CarrinhoId = CarrinhoId AndAlso c.ProdutoId = id) If carrinhoItem Is Nothing Then ' Cria um novo item no carrinho se não existir carrinhoItem = New CarrinhoItem() With { _ .ItemId = Guid.NewGuid().ToString(), _ .ProdutoId = id, _ .CarrinhoId = CarrinhoId, _ .Produto = _db.Produtos.SingleOrDefault(Function(p) p.ProdutoID = id), _ .Quantidade = 1, _ .DataCriacao = DateTime.Now _ } _db.CarrinhoItens.Add(carrinhoItem) Else ' se o item não existe acrescenta um unidade carrinhoItem.Quantidade += 1 End If _db.SaveChanges() End Sub Public Function GetCarrinhoId() As String If HttpContext.Current.Session(CarrinhoSessaoChave) Is Nothing Then If Not String.IsNullOrWhiteSpace(HttpContext.Current.User.Identity.Name) Then HttpContext.Current.Session(CarrinhoSessaoChave) = HttpContext.Current.User.Identity.Name Else ' Gera um novo GUID aleatorio usado usando a classe System.Guid Dim tempCartId As Guid = Guid.NewGuid() HttpContext.Current.Session(CarrinhoSessaoChave) = tempCartId.ToString() End If End If Return HttpContext.Current.Session(CarrinhoSessaoChave).ToString() End Function Public Function GetCarrinhoItems() As List(Of CarrinhoItem) CarrinhoId = GetCarrinhoId() Return _db.CarrinhoItens.Where(Function(c) c.CarrinhoId = CarrinhoId).ToList() End Function End Class End Namespace |
O método IncluirNoCarrinho permite que os produtos individuais a sejam incluídos no carrinho de compras com base na identificação do produto. O produto será adicionado ao carrinho mas se o carrinho já contiver um item para o produto terá sua quantidade incrementada em uma unidade.
O método GetCarrinhoId retorna o ID do carrinho. O ID de carrinho é usado para rastrear os itens que um usuário tem em seu carrinho de compras. Se o usuário não tiver o ID do carrinho existente, um novo ID será. Se o usuário estiver conectado como um usuário registrado, a identificação do carrinho está definido como sendo o seu nome de usuário. No entanto, se o usuário não estiver conectado, o ID do carrinho será definido para um valor único (um GUID). Um GUID garante que apenas um carrinho será criado para cada usuário, com base na sua sessão.
O método GetCarrinhotItens retorna uma lista de itens do carrinho de compras para o usuário. Mais adiante veremos que o model binding será usado para exibir os itens dos no carrinho usando o método GetCarrinhoItens.
Incluindo itens no carrinho
Vamos criar uma página de processamento chamada IncluirNoCarrinho.aspx que será usada para adicionar novos produtos no carrinho de compras do usuário. Esta página irá chamar o método IncluirNoCarrinho na classe Carrinho que acabamos de criar. A página InclulirNoCarrinho.aspx vai esperar que um ID do produto seja passada a ela. Este ID de produto será usado ao chamar o método IncluirNoCarrinho na classe Carrinho.
Na janela Solution Explorer clique com o botão direito do mouse sobre o projeto e seleciona Add e a seguir New Item;
Inclua uma página Web Form com o nome IncluirNoCarrinho.aspx a partir da janela Add new Item;
A seguir selecione o arquivo IncluirNoCarrinho.aspx e clique com o botão direito sobre ele selecionando View Code e definindo o código abaixo no code-behind:
Imports System.Linq Imports System.Web Imports System.Web.UI Imports System.Web.UI.WebControls Imports System.Diagnostics Imports WingTipToys.WingtipToys.Logic Namespace WingtipToys Partial Public Class IncluirNoCarrinho Inherits System.Web.UI.Page Protected Sub Page_Load(sender As Object, e As EventArgs) Dim rawId As String = Request.QueryString("ProdutoID") Dim produotId As Integer If Not [String].IsNullOrEmpty(rawId) AndAlso Integer.TryParse(rawId, produotId) Then Dim usuariosCarrinhoCompras As New CarrinhoActions() usuariosCarrinhoCompras.IncluirNoCarrinho(Convert.ToInt16(rawId)) Else Debug.Fail("ERROR : Falta o produtoId para chamar IncluirNoCarrinho.aspx") Throw New Exception("ERROR : Não se pode carregar IncluirNoCarrinho.aspx sem definir um ProdutoId.") End If Response.Redirect("Carrinho.aspx") End Sub End Class End Namespace |
Quando a página IncluirNoCarrinho.aspx for carregada um ID do produto é obtido a partir da query string de consulta. Em seguida, uma instância da classe carrinho de compras é criada e usada para chamar o método IncluirNoCarrinho.
Este método, contido no arquivo CarrinhoActions.vb, inclui a lógica para adicionar o produto selecionado no carrinho de compras ou aumentar a quantidade de produto selecionado.
Se o produto não tiver sido adicionado ao carrinho de compras, o produto é adicionado à tabela de CarrinhoItem do banco de dados.
Se o produto já tiver sido adicionado ao carrinho de compras e o usuário adicionar um item adicional do mesmo produto, a quantidade de produto é incrementada na tabela CarrinhoItem. Finalmente, a página redireciona o usuário para a página Carrinho.aspx que vamos criar em seguida; nesta página o usuário vê uma lista atualizada dos itens no carrinho.
O ID de usuário é usado para identificar os produtos que estão associados a um determinado usuário e este ID é adicionado na tabela CarrinhoItem cada vez que o usuário adiciona um produto no carrinho de compras.
Criando a interface Carrinho de Compras
Vamos criar a página Carrinho.aspx exibirá os produtos que o usuário adicionou ao seu carrinho de compras e fornecer a capacidade de adicionar, remover e atualizar itens no carrinho de compras.
No menu Project clique em Add New Item e na janela Add New Item selecione o item Web Form using Master Page informando o nome Carrinho.aspx;
Selecione a master page Site.Master e clique em OK;
A seguir defina o código abaixo nesta página:
<%@ Page Title="" Language="vb" AutoEventWireup="false" MasterPageFile="~/Site.Master" CodeBehind="Carrinho.aspx.vb" Inherits="WingTipToys.Carrinho" %> <asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server"> </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="FeaturedContent" runat="server"> <div id="CarrinhoTitulo" runat="server" class="ContentHead"><h1>Carrinho de Compras</h1></div> <asp:GridView ID="CarrinhoLista" runat="server" AutoGenerateColumns="False" ShowFooter="True" GridLines="Vertical" CellPadding="4" ItemType="WingtipToys.WingtipToys.Models.CarrinhoItem" CssClass="CarrinhoListaItem" SelectMethod="GetCarrinhoItens" Width="600"> <AlternatingRowStyle CssClass="CarrinhoListaItemAlt" /> <Columns> <asp:BoundField DataField="ProdutoID" HeaderText="ID" SortExpression="ProduotID" /> <asp:BoundField DataField="Produto.ProdutoNome" HeaderText="Nome" SortExpression="ProdutoNome" /> <asp:BoundField DataField="Produto.PrecoUnitario" HeaderText="Preço (un.)" DataFormatString="{0:c}"/> <asp:TemplateField HeaderText="Quantidade"> <ItemTemplate> <asp:TextBox ID="QuantidadeComprada" Width="40" runat="server" Text="<%#: Item.Quantidade%>"></asp:TextBox> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="Total "> <ItemTemplate> <%#: String.Format("{0:c}", ((Convert.ToDouble(Item.Quantidade)) * Convert.ToDouble(Item.Produto.PrecoUnitario)))%> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="Remover Item"> <ItemTemplate> <asp:CheckBox id="Remover" runat="server"></asp:CheckBox> </ItemTemplate> </asp:TemplateField> </Columns> <FooterStyle CssClass="CarrinhoListaFooter"/> <HeaderStyle CssClass="CarrinhoListaHead" /> </asp:GridView> <div> <p></p> <strong> <asp:Label ID="LabelTotalText" runat="server" Text="Total Pedido: "></asp:Label> <asp:Label CssClass="NormalBold" id="lblTotal" runat="server" EnableViewState="false"></asp:Label> </strong> </div> <br /> </asp:Content> <asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server"> </asp:Content> |
A página Carrinho.aspx inclui um controle GridView chamado CarrinhoLista. Este controle utiliza o model binding para vincular os dados do carrinho de compras do banco de dados com o controle GridView.
Quando você define a propriedade ItemType do controle GridView, a expressão de ligação de dados Item está disponível na marcação do controle e o controle torna-se fortemente tipado.Com isso você pode selecionar detalhes do objeto do item usando o IntelliSense.
Para configurar um controle de dados para usar o Model Binding para selecionar dados, defina a propriedade SelectMethod do controle. Na marcação acima, definimos o SelectMethod para usar o método GetCarrinhotens que retorna uma lista de objetos CarrinhoItem.
O controle GridView chama o método no momento apropriado do ciclo de vida da página e vincula automaticamente os dados retornados.(O método GetCarrinhotens ainda precisa ser criado.)
Retornando os itens dos carrinho de compras
Nossa próxima tarefa é criar o código no code-behind da página Carrinho.aspx para recuperar e preencher os itens e exibi-los no carrinho de compras.
Na janela Solution Explorer clique com o botão direito do mouse sobre a página Carrinho.aspx e selecione View Code;
A seguir defina o código abaixo no code-behind:
Imports System Imports System.Collections.Generic Imports System.Linq Imports System.Web Imports System.Web.UI Imports System.Web.UI.WebControls Imports WingTipToys.WingtipToys.Models Imports WingTipToys.WingtipToys.Logic Public Class Carrinho Inherits System.Web.UI.Page Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load End Sub Public Function GetCarrinhoItens() As List(Of CarrinhoItem) Dim actions As New CarrinhoActions() Return actions.GetCarrinhoItens() End Function End Class |
O controle GridView chama o método GetCarrinhotens no momento apropriado do ciclo de vida da página e vincula automaticamente os dados retornados. O método GetCarrinhotens cria uma instância do objeto CarrinhoActions e em seguida o código usa essa instância para retornar os itens no carrinho chamando o método GetCarrinhoItens.
Adicionando produtos ao carrinho
Quando a página ProdutoLista.aspx ou ProdutoDetalhes.aspx é exibida, o usuário será capaz de adicionar o produto ao carrinho de compras usando um link. Quando o usuário clicar no link, o aplicativo navega para a página de processamento chamada IncluirNoCarrinho.aspx. Esta página vai chamar o método IncluirNoCarrinho da classe Carrinho.
Vamos adicionar um link Incluir no carrinho em ambas as páginas sendo que este link incluirá o ID do produto que será retornado a partir do banco de dados.
Na janela Solution Explorer abra o arquivo ProdutoLista.aspx e copie o código abaixo para criar o link para incluir o produto pelo seu id:
<a href="/IncluirNoCarrinho.aspx?produtoID=<%#:Item.ProdutoID %>">
<span class="ProdutoListaItem"> <b>Incluir no Carrinho<b> </span> </a> |
Abaixo vemos um trecho do arquivo ProdutoLista.aspx com o código acima incluído:
Agora abra o arquivo ProdutoDetalhes.aspx e inclua o mesmo de código para criar o link conforme mostra o trecho de código abaixo:
1, 2, 3 ... Testando
Vamos executar a aplicação e verificar se as funcionalidades incluídas para inclusão de produtos estão funcionando;
Clique com o botão direito do mouse sobre a página Default.aspx e selecione Set As Start Page;
Pressione CTRL+F5 para rodar a aplicação;
Selecione Carros a partir do menu de navegação de categorias;
A seguir escolha um item e clique no link Incluir no Carrinho:
A página carrinho.aspx irá exibir o item selecionado com opções para alterar a quantidade e uma checkbox para selecionar a remoção do item;
Calculando o exibindo os valores dos itens no carrinho
Vamos agora definir um método chamado GetTotal na classe Carrinho para exibir a quantidade total do pedido;
Na janela Solution Explorer selecione o arquivo CarrinhoActions na pasta Logic e inclua o método GetTotal na classe conforme o código a seguir:
Public Function GetTotal() As Decimal CarrinhoId = GetCarrinhoId() ' Multiplica o preço pela quantidade do produto para obter ' o preço atual dos produtos no carrinho ' soma todos os totaisl para obter o total do carrinho Dim total As System.Nullable(Of Decimal) = Decimal.Zero total = CType((From carrinhoItens In _db.CarrinhoItens Where carrinhoItens.CarrinhoId = CarrinhoId Select CType(carrinhoItens.Quantidade, System.Nullable(Of Integer)) _ * carrinhoItens.Produto.PrecoUnitario).Sum(), System.Nullable(Of Decimal)) Return If(total, Decimal.Zero) End Function |
Primeiro, o método GetTotal obtém a identificação do carrinho de compras para o usuário. Em seguida, o método obtém o total do carrinho multiplicando-se o preço do produto pela quantidade do produto para cada produto listado no carrinho.
Alterando a exibição no carrinho de compras
Vamos modificar o código da página Carrinho.aspx para chamar o método GetTotal e exibir esse total na página quando ela for carregada.
Selecione o arquivo Carrinho.aspx e clique com o botão direito do mouse sobre ele escolhendo a opção View Code;
A seguir inclua o código destacado em azul no evento Load da página abaixo no arquivo:
Imports System.Collections.Generic Imports System.Linq Imports WingTipToys.WingtipToys.Models Imports WingTipToys.WingtipToys.Logic Public Class Carrinho Inherits System.Web.UI.Page Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Dim usuarioCarrinhoCompra As New CarrinhoActions() Dim TotalCarrinho As Decimal = 0 TotalCarrinho = usuarioCarrinhoCompra.GetTotal() If TotalCarrinho > 0 Then ' exibe o Total. lblTotal.Text = [String].Format("{0:c}", TotalCarrinho) Else LabelTotalText.Text = "" lblTotal.Text = "" CarrinhoTitulo.InnerText = "O carrinho de compras esta vazio" End If End Sub Public Function GetCarrinhoItens() As List(Of CarrinhoItem) Dim actions As New CarrinhoActions() Return actions.GetCarrinhoItens() End Function End Class |
Quando a página Carrinho.aspx for carregada ela carrega o objeto carrinho de compras e, em seguida, recupera o total do carrinho de compras, chamando o método GetTotal da classe Carrinho. Se o carrinho de compras está vazio, uma mensagem será exibida informando o fato ao usuário.
1, 2, 3 ... Testando
Vamos executar a aplicação e verificar se as funcionalidades incluídas para inclusão de produtos e exibição dos totais estão funcionando;
Clique com o botão direito do mouse sobre a página Default.aspx e selecione Set As Start Page;
Pressione CTRL+F5 para rodar a aplicação;
Selecione Carros a partir do menu de navegação de categorias e a seguir selecione um produto e clique no link - Incluir no Carrinho;
Repetida o procedimento selecionando outra categoria e outro produto de forma a ter mais de item no seu carrinho;
Abaixo vemos o resultado para a seleção de dois produtos distintos:
Verificamos que o total esta sendo obtido corretamente a partir das quantidades e preços dos produtos no carrinho.
Incluindo os botões para atualizar e realizar o checkout no carrinho de compras
Para permitir que os usuários modifiquem o carrinho de compras, vamos adicionar um botão de atualização e um botão para fazer o Checkout na página do carrinho de compras.
Abra o arquivo Carrinho.aspx e selecione o modo Source de exibição;
Para adicionar o botão Atualizar e no botão CheckOut na página Carrinho.aspx, adicione a marcação em amarelo para a marcação existente, como mostra o seguinte código:
Quando o usuário clicar no botão Atualizar, o manipulador de eventos btnAtualizar_Click será chamado. Este manipulador de eventos irá chamar o código que vamos adicionar logo a seguir.
Em seguida, você pode atualizar o código contido no arquivo Carrinho.aspx.vb para percorrer os itens do carrinho e chamar os métodos RemoveItem e UpdateItem.
Abra o arquivo code-behind Carrinho.aspx.vb e inclua o código destacado em azul no arquivo:
Imports System.Collections.Generic Imports System.Linq Imports WingTipToys.WingtipToys.Models Imports WingTipToys.WingtipToys.Logic Imports System.Collections.Specialized Imports System.Collections Imports System.Web.ModelBinding Public Class Carrinho Inherits System.Web.UI.Page Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Dim usuarioCarrinhoCompra As New CarrinhoActions() Dim TotalCarrinho As Decimal = 0 TotalCarrinho = usuarioCarrinhoCompra.GetTotal() If TotalCarrinho > 0 Then ' exibe o Total. lblTotal.Text = [String].Format("{0:c}", TotalCarrinho) Else LabelTotalText.Text = "" lblTotal.Text = "" CarrinhoTitulo.InnerText = "O carrinho de compras esta vazio" btnAtualizar.Visible = False End If End Sub Public Function GetCarrinhoItens() As List(Of CarrinhoItem) Dim actions As New CarrinhoActions() Return actions.GetCarrinhoItens() End Function Public Function AtualizaItensCarrinho() As List(Of CarrinhoItem) Dim usuariosCarrinho As New CarrinhoActions() Dim carrinhoId As String = usuariosCarrinho.GetCarrinhoId() Dim carrinhoAtualiza As CarrinhoActions.CarrinhoAtualiza() = New CarrinhoActions.CarrinhoAtualiza(CarrinhoLista.Rows.Count - 1) {} For i As Integer = 0 To CarrinhoLista.Rows.Count - 1 Dim rowValues As IOrderedDictionary = New OrderedDictionary() rowValues = GetValues(CarrinhoLista.Rows(i)) carrinhoAtualiza(i).ProdutoId = Convert.ToInt32(rowValues("ProdutoID")) Dim cbRemove As New CheckBox() cbRemove = DirectCast(CarrinhoLista.Rows(i).FindControl("Remove"), CheckBox) carrinhoAtualiza(i).RemoveItem = cbRemove.Checked Dim quantidadeTextBox As New TextBox() quantidadeTextBox = DirectCast(CarrinhoLista.Rows(i).FindControl("QuantidadeComprada"), TextBox) carrinhoAtualiza(i).QuantidadeComprada = Convert.ToInt16(quantidadeTextBox.Text.ToString()) Next usuariosCarrinho.AtualizaCarrinhoBD(carrinhoId, carrinhoAtualiza) CarrinhoLista.DataBind() lblTotal.Text = [String].Format("{0:c}", usuariosCarrinho.GetTotal()) Return usuariosCarrinho.GetCarrinhoItens() End Function Public Shared Function GetValues(row As GridViewRow) As IOrderedDictionary Dim values As IOrderedDictionary = New OrderedDictionary() For Each cell As DataControlFieldCell In row.Cells If cell.Visible Then ' Extrai os valores da celula cell.ContainingField.ExtractValuesFromCell(values, cell, row.RowState, True) End If Next Return values End Function Protected Sub btnAtualizar_Click(sender As Object, e As EventArgs) Handles btnAtualizar.Click AtualizaItensCarrinho() End Sub End Class |
Quando o usuário clica no botão Atualizar na página Carrinho.aspx o método AtualizaItensCarrinho() é chamado. Este método recebe os valores atualizados para cada item no carrinho de compras. Em seguida, o método AtualizaCarrinhoBD(que será criado mais adiante) para adicionar ou remover itens do carrinho de compras.
Uma vez que o banco de dados foi atualizado para refletir as atualizações do carrinho de compras, o controle GridView é atualizado na página do carrinho de compras, chamando o método DataBind para o GridView. Além disso, o valor total do pedido na página do carrinho de compras é atualizado para refletir a lista atualizada dos itens.
Atualizando e removendo itens do carrinho de compras
Na página Carrinho.aspx, podemos ver que os controles foram adicionados para atualizar a quantidade de um item e remover um item. Agora, vamos adicionar o código que vai fazer esses controles funcionarem.
Abra o arquivo CarrinhoAction.vb na pasta Logic;
Inclua o código destacado em azul neste arquivo:
Imports System Imports System.Collections.Generic Imports System.Linq Imports System.Web Imports WingTipToys.WingtipToys.Models Namespace WingtipToys.Logic Public Class CarrinhoActions Public Property CarrinhoId() As String Get Return m_CarrinhoId End Get Set(value As String) m_CarrinhoId = value End Set End Property Private m_CarrinhoId As String Private _db As New ProdutoContexto() Public Const CarrinhoSessaoChave As String = "CarrinhoId" Public Sub IncluirNoCarrinho(id As Integer) ' Retorna o produto do banco de dados CarrinhoId = GetCarrinhoId() Dim carrinhoItem = _db.CarrinhoItens.SingleOrDefault(Function(c) c.CarrinhoId = CarrinhoId AndAlso c.ProdutoId = id) If carrinhoItem Is Nothing Then ' Cria um novo item no carrinho se não existir carrinhoItem = New CarrinhoItem() With { _ .ItemId = Guid.NewGuid().ToString(), _ .ProdutoId = id, _ .CarrinhoId = CarrinhoId, _ .Produto = _db.Produtos.SingleOrDefault(Function(p) p.ProdutoID = id), _ .Quantidade = 1, _ .DataCriacao = DateTime.Now _ } _db.CarrinhoItens.Add(carrinhoItem) Else ' se o item não existe acrescenta um unidade carrinhoItem.Quantidade += 1 End If _db.SaveChanges() End Sub Public Function GetCarrinhoId() As String If HttpContext.Current.Session(CarrinhoSessaoChave) Is Nothing Then If Not String.IsNullOrWhiteSpace(HttpContext.Current.User.Identity.Name) Then HttpContext.Current.Session(CarrinhoSessaoChave) = HttpContext.Current.User.Identity.Name Else ' Gera um novo GUID aleatorio usado usando a classe System.Guid Dim tempCartId As Guid = Guid.NewGuid() HttpContext.Current.Session(CarrinhoSessaoChave) = tempCartId.ToString() End If End If Return HttpContext.Current.Session(CarrinhoSessaoChave).ToString() End Function Public Function GetCarrinhoItens() As List(Of CarrinhoItem) CarrinhoId = GetCarrinhoId() Return _db.CarrinhoItens.Where(Function(c) c.CarrinhoId = CarrinhoId).ToList() End Function Public Function GetTotal() As Decimal CarrinhoId = GetCarrinhoId() ' Multiplica o preço pela quantidade do produto para obter ' o preço atual dos produtos no carrinho ' soma todos os totaisl para obter o total do carrinho Dim total As System.Nullable(Of Decimal) = Decimal.Zero total = CType((From carrinhoItens In _db.CarrinhoItens Where carrinhoItens.CarrinhoId = CarrinhoId Select CType(carrinhoItens.Quantidade, System.Nullable(Of Integer)) _ * carrinhoItens.Produto.PrecoUnitario).Sum(), System.Nullable(Of Decimal)) Return If(total, Decimal.Zero) End Function Public Function GetCarrinho(context As HttpContext) As CarrinhoActions Dim carrinho = New CarrinhoActions() carrinho.CarrinhoId = carrinho.GetCarrinhoId() Return carrinho End Function Public Sub AtualizaCarrinhoBD(carrinhoId As String, CarrinhoItemAtualiza As CarrinhoAtualiza()) Using db = New ProdutoContexto() Try Dim CartItemCount As Integer = CarrinhoItemAtualiza.Count() Dim myCart As List(Of CarrinhoItem) = GetCarrinhoItens() For Each carrinhoItem In myCart ' Itera através de todas aslinhas na lista de carrinho For i As Integer = 0 To CartItemCount - 1 If carrinhoItem.Produto.ProdutoID = CarrinhoItemAtualiza(i).ProdutoId Then If CarrinhoItemAtualiza(i).QuantidadeComprada < 1 OrElse CarrinhoItemAtualiza(i).RemoveItem = True Then RemoveItem(carrinhoId, carrinhoItem.ProdutoId) Else UpdateItem(carrinhoId, carrinhoItem.ProdutoId, CarrinhoItemAtualiza(i).QuantidadeComprada) End If End If Next Next Catch exp As Exception Throw New Exception("ERRO: Não foi possível atualizar o Banco de dados - " + exp.Message.ToString(), exp) End Try End Using End Sub Public Sub RemoveItem(removeCarrinhoID As String, removeProdutoID As Integer) Using db = New ProdutoContexto() Try Dim meuItem = (From c In db.CarrinhoItens Where c.CarrinhoId = removeCarrinhoID _ AndAlso c.Produto.ProdutoID = removeProdutoID).FirstOrDefault() If meuItem IsNot Nothing Then ' db.DeleteObject(meuItem); db.CarrinhoItens.Remove(meuItem) db.SaveChanges() End If Catch exp As Exception Throw New Exception("ERROR: Não foi possível Remover o Item do Carrinho - " + exp.Message.ToString(), exp) End Try End Using End Sub Public Sub UpdateItem(atualizaCarrinhoID As String, atualizaProdutoID As Integer, quantidade As Integer) Using db = New ProdutoContexto() Try Dim meuItem = (From c In db.CarrinhoItens Where c.CarrinhoId = atualizaCarrinhoID AndAlso c.Produto.ProdutoID = atualizaProdutoID).FirstOrDefault() If meuItem IsNot Nothing Then meuItem.Quantidade = quantidade db.SaveChanges() End If Catch exp As Exception Throw New Exception("ERROR: Não foi possível atualizar o item do carrinho - " & exp.Message.ToString(), exp) End Try End Using End Sub Public Sub CarrinhoVazio() CarrinhoId = GetCarrinhoId() Dim carrinhoItens = _db.CarrinhoItens.Where(Function(c) c.CarrinhoId = CarrinhoId) For Each carrinhoItem In carrinhoItens _db.CarrinhoItens.Remove(carrinhoItem) Next ' Salva as mudanças _db.SaveChanges() End Sub Public Function GetContador() As Integer CarrinhoId = GetCarrinhoId() ' Obtem a contagem de cada item no carrinho e as soma Dim contador As System.Nullable(Of Integer) = (From carrinhoItems In _db.CarrinhoItens Where carrinhoItems.CarrinhoId = CarrinhoId Select CType(carrinhoItems.Quantidade, System.Nullable(Of Integer))).Sum() ' Retorna 0 se todas as entradas forem nulas Return If(contador, 0) End Function Public Structure CarrinhoAtualiza Public ProdutoId As Integer Public QuantidadeComprada As Integer Public RemoveItem As Boolean End Structure End Class End Namespace |
O método AtualizaCarrinhoBD, chamado a partir do método AtualizaItensCarrinho() na página Carrinho.aspx.vb, contém a lógica para atualizar ou remover itens do carrinho de compras. O método AtualizaCarrinhoBD percorre todas as linhas dentro da lista carrinho de compras.
Se um item de carrinho de compras foi marcado para ser removido, ou a quantidade for menor do que um, o método RemoveItem é chamado. Caso contrário, o item do carrinho de compras está marcado para atualizações e o método UpdateItem é chamado. Depois que o item do carrinho de compras foi removido ou atualizado, as alterações dos dados são salvas.
A estrutura CarrinhoAtualiza é usada para armazenar todos os itens do carrinho de compras. O método AtualizaCarrinhoBD usa a estrutura CarrinhoAtualiza para determinar se qualquer um dos elementos precisa de ser atualizado ou removido.
No próximo tutorial, vamos usar o método CarrinhoVazio para limpar o carrinho de compras após a compra de produtos. No momento vamos usar o método GetContador que acabamos de incluir para determinar quantos itens estão no carrinho de compras.
Incluindo um contador no carrinho de compras
Para permitir que o usuário veja o número total de itens no carrinho de compras, vamos adicionar um contador na página Site.Master. Este contador também vai atuar como um link para o carrinho de compras.
Na janela Solution Explorer abra o arquivo Site.Master e faça as alterações conforme o código destacado em abaixo no trecho de código deste arquivo:
A seguir vamos atualizar o code-behind Site.Master.vb com o código abaixo:
Antes da que a página seja processada no navegador, o evento Page_PreRender é gerado.
No manipulador Page_PreRender, a contagem total do carrinho de compras é determinada chamando o método GetContador. O valor retornado é adicionado à extensão carrinhoContador incluído na marcação da página Site.Master.
As tags <span> permitem que os elementos internos sejam devidamente renderizados. Quando qualquer página do site é exibida, o total do carrinho de compras será mostrado.
O usuário também poderá clicar no total do carrinho de compras para visualizar o carrinho de compras.
1, 2, 3 ... Testando e concluindo
Vamos executar o aplicativo agora para ver como podemos adicionar, excluir e atualizar os itens no carrinho de compras. O total carrinho de compras irá refletir o custo total de todos os itens no carrinho de compras.
Após concluir todas as implementações discutidas neste tutorial nosso carrinho de compras suporta a adição, exclusão e atualização de itens que o usuário tenha selecionado para compra. Além de implementar a funcionalidade de carrinho de compras, você aprendeu como exibir itens de carrinho de compras em um controle GridView e calcular o total do pedido.
Ufa... acabamos...
No próximo tutorial vamos incluir as funcionalidades de registro e autenticação do usuário: Autorizando e registrando o usuário - VI
Referências: