Crear un punto de venta con ASP y Sql Server

Anuncio
Crear un punto de venta con ASP.NET y SQL Server (Parte 1)
Diseño de la base de datos
Será una base de datos relacional, llamada pventa, muy básica, con la
siguiente estructura:
Y el script para crear labase de datos seria:
USE [pventa]
GO
/****** Object: Table [dbo].[users]
Script Date: 09/08/2011 17:27:43 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[users](
[user_login] [nvarchar](50) NOT NULL,
[user_password] [nvarchar](250) NULL,
[nombre] [nvarchar](150) NULL,
[activo] [bit] NOT NULL,
[ventas] [bit] NOT NULL,
[reportes] [bit] NOT NULL,
[administrar] [bit] NOT NULL,
[fecha_registro] [datetime] NOT NULL,
CONSTRAINT [PK_users] PRIMARY KEY CLUSTERED
(
[user_login] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[unidad_medida]
Script Date: 09/08/2011 17:27:43
******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[unidad_medida](
[id_unidad_medida] [smallint] NOT NULL,
[unidad_medida] [nvarchar](150) NULL,
CONSTRAINT [PK_unidad_medida] PRIMARY KEY CLUSTERED
(
[id_unidad_medida] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[productos]
Script Date: 09/08/2011 17:27:43
******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[productos](
[id_producto] [nvarchar](50) NOT NULL,
[producto] [nvarchar](250) NULL,
[id_unidad_medida] [smallint] NULL,
[p_compra] [float] NULL,
[p_venta] [float] NULL,
[existencia] [float] NULL,
CONSTRAINT [PK_productos] PRIMARY KEY CLUSTERED
(
[id_producto] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[venta]
Script Date: 09/08/2011 17:27:43 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[venta](
[id_venta] [int] IDENTITY(1,1) NOT NULL,
[fecha_registro] [datetime] NOT NULL,
[user_login] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_venta] PRIMARY KEY CLUSTERED
(
[id_venta] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[venta_detalle_tmp]
Script Date: 09/08/2011
17:27:43 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[venta_detalle_tmp](
[id_venta_detalle_tmp] [int] IDENTITY(1,1) NOT NULL,
[id_producto] [nvarchar](50) NOT NULL,
[cantidad] [float] NOT NULL,
[user_login] [nvarchar](50) NOT NULL,
[p_venta] [float] NOT NULL,
CONSTRAINT [PK_venta_detalle_tmp] PRIMARY KEY CLUSTERED
(
[id_venta_detalle_tmp] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[venta_detalle]
Script Date: 09/08/2011 17:27:43
******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[venta_detalle](
[id_venta_detalle] [int] IDENTITY(1,1) NOT NULL,
[id_venta] [int] NOT NULL,
[id_producto] [nvarchar](50) NOT NULL,
[cantidad] [float] NOT NULL,
[p_venta] [float] NOT NULL,
CONSTRAINT [PK_venta_detalle] PRIMARY KEY CLUSTERED
(
[id_venta_detalle] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Default [DF_users_fecha_registro]
Script Date: 09/08/2011
17:27:43 ******/
ALTER TABLE [dbo].[users] ADD CONSTRAINT [DF_users_fecha_registro] DEFAULT
(getdate()) FOR [fecha_registro]
GO
/****** Object: Default [DF_venta_fecha_registro]
Script Date: 09/08/2011
17:27:43 ******/
ALTER TABLE [dbo].[venta] ADD CONSTRAINT [DF_venta_fecha_registro] DEFAULT
(getdate()) FOR [fecha_registro]
GO
/****** Object: ForeignKey [FK_productos_unidad_medida]
Script Date:
09/08/2011 17:27:43 ******/
ALTER TABLE [dbo].[productos] WITH CHECK ADD CONSTRAINT
[FK_productos_unidad_medida] FOREIGN KEY([id_unidad_medida])
REFERENCES [dbo].[unidad_medida] ([id_unidad_medida])
GO
ALTER TABLE [dbo].[productos] CHECK CONSTRAINT [FK_productos_unidad_medida]
GO
/****** Object: ForeignKey [FK_venta_users]
Script Date: 09/08/2011 17:27:43
******/
ALTER TABLE [dbo].[venta] WITH CHECK ADD CONSTRAINT [FK_venta_users] FOREIGN
KEY([user_login])
REFERENCES [dbo].[users] ([user_login])
GO
ALTER TABLE [dbo].[venta] CHECK CONSTRAINT [FK_venta_users]
GO
/****** Object: ForeignKey [FK_venta_detalle_productos]
Script Date:
09/08/2011 17:27:43 ******/
ALTER TABLE [dbo].[venta_detalle] WITH CHECK ADD CONSTRAINT
[FK_venta_detalle_productos] FOREIGN KEY([id_producto])
REFERENCES [dbo].[productos] ([id_producto])
GO
ALTER TABLE [dbo].[venta_detalle] CHECK CONSTRAINT [FK_venta_detalle_productos]
GO
/****** Object: ForeignKey [FK_venta_detalle_venta]
Script Date: 09/08/2011
17:27:43 ******/
ALTER TABLE [dbo].[venta_detalle] WITH CHECK ADD CONSTRAINT
[FK_venta_detalle_venta] FOREIGN KEY([id_venta])
REFERENCES [dbo].[venta] ([id_venta])
GO
ALTER TABLE [dbo].[venta_detalle] CHECK CONSTRAINT [FK_venta_detalle_venta]
GO
/****** Object: ForeignKey [FK_venta_detalle_tmp_productos]
Script Date:
09/08/2011 17:27:43 ******/
ALTER TABLE [dbo].[venta_detalle_tmp] WITH CHECK ADD CONSTRAINT
[FK_venta_detalle_tmp_productos] FOREIGN KEY([id_producto])
REFERENCES [dbo].[productos] ([id_producto])
GO
ALTER TABLE [dbo].[venta_detalle_tmp] CHECK CONSTRAINT
[FK_venta_detalle_tmp_productos]
GO
/****** Object: ForeignKey [FK_venta_detalle_tmp_users]
Script Date:
09/08/2011 17:27:43 ******/
ALTER TABLE [dbo].[venta_detalle_tmp] WITH CHECK ADD CONSTRAINT
[FK_venta_detalle_tmp_users] FOREIGN KEY([user_login])
REFERENCES [dbo].[users] ([user_login])
GO
ALTER TABLE [dbo].[venta_detalle_tmp] CHECK CONSTRAINT
[FK_venta_detalle_tmp_users]
GO
Creamos elproyecto:
En la imagen se muestran las opciones que debemos seleccionar.
Se mostrará el explorador de soluciones como se muestra en la imagen:
Nuestro proyecto está vacío, por ahora crearemos varios objetos que
describimos a continuación.
Creación de la Página Maestra (main.master)
Modificamos el código HTMLpara que quede asi:
<%@ Master Language="C#" AutoEventWireup="true" CodeFile="main.master.cs"
Inherits="main" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Punto de Venta Web</title>
</head>
<body>
<form id="frmMain" runat="server">
<h1>SISTEMA PUNTO DE VENTA</h1>
<div style=" width:800px;">
<div id="menuh">
<ul>
<li><a href="default.aspx">Inicio</a></li>
<asp:Label ID="lblOpciones" runat="server" Text=""></asp:Label>
<li><asp:LinkButton ID="btnCerrarSesion" runat="server"
onclick="btnCerrarSesion_Click">Cerrar
Sesión</asp:LinkButton></li>
</ul>
</div>
<br />
<asp:ContentPlaceHolder id="cphMain" runat="server">
</asp:ContentPlaceHolder>
<h4>DESARROLLADO POR TYRODEVELOPER</h4>
</div>
</form>
</body>
</html>
Luego agregamos la página principal (default.aspx)
El código HTML quedaría:
<%@ Page Title="" Language="C#" MasterPageFile="~/main.master"
AutoEventWireup="true" CodeFile="default.aspx.cs" Inherits="_default" %>
<asp:Content ID="cntMain" ContentPlaceHolderID="cphMain" Runat="Server">
<h1>VENTAS</h1>
</asp:Content>
Para ejecutar nuestro sistema, nos vamos presionamos la combinación de
teclas Windows + R, y se muestra la siguiente pantalla:
Y al ejecutarlo, se verá lo siguiente en el explorador de Internet:
Ahora le daremos un poco de forma
Agregamos un documento CSS, como se muestra:
Al nuevo elemento le agregamos el siguiente código:
body {
font-family:Verdana
}
img{ border:0px;}
#menuh {
font: 80% "Trebuchet MS", Arial, Helvetica, sans-serif;
margin-top: 20px;
}
#menuh ul, li {
list-style-type: none;
}
#menuh ul {
margin: 0;
padding: 0;
}
#menuh li {
float: left;
}
#menuh a {
text-decoration: none;
color: #3366CC;
background: #F0F7FC;
display: block;
padding: 3px 10px;
text-align: center;
border: 1px solid #ACCFE8;
border-width: 1px 1px 1px 0;
}
Luego, arrastramos el archivo a la página maestra, así:
Si ejecutamos de nuevo el sistema, se vería así:
Nuestro sistema ya va agarrando fuerza.
Pantalla de Inicio de Sesión (login.aspx)
Ahora, tenemos que agregar un registro a la base de datos, en la tabla
users:
Agregamos una nueva página llamada login.aspx
Aquí debemos poner un poco de atención, porque hay que empezar a
programar, debemos tener abierto SQL Server Management Studio porque
escribiremos procedimientos almacenados al mismo tiempo que
programamos.
Este es el código HTML de login.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="login.aspx.cs"
Inherits="login" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Iniciar Sesión</title>
<link href="StyleSheet.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form id="form1" runat="server">
<div>
<table class="verde" >
<tr>
<td colspan="2" align="center" >
<h3> Inicio de Sesión </h3>
</td>
</tr>
<tr>
<td align="left" >Usuario:</td>
<td >
<asp:TextBox ID="txtUSER_LOGIN" runat="server" ToolTip="Usuario"
Width="150px"></asp:TextBox>
<asp:RequiredFieldValidator ID="reqUSER_LOGIN" runat="server"
ControlToValidate="txtUSER_LOGIN"
ErrorMessage="Debe introducir un nombre de
usuario">*</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td align="left" >Contraseña:</td>
<td align="left">
<asp:TextBox ID="txtPASSWORD" runat="server"
TextMode="Password"
ToolTip="Contraseña" Width="150px"></asp:TextBox>
</td>
</tr>
<tr>
<td colspan="2" align="left">
<asp:CheckBox ID="chkPersist" runat="server" Text="Recordar
usuario" />
</td>
</tr>
<tr>
<td colspan="2" align="center" >
<asp:Button ID="btnSubmit" runat="server"
OnClick="btnSubmit_Click" Text="Entrar" Font-Bold="True"
Width="100px" />
</td>
</tr>
</table>
<asp:Label ID="lblMensaje" runat="server" Text=""></asp:Label>
</div>
</form>
</body>
</html>
Creamos un procedimiento almacenado en SQL Server:
USE pventa
GO
IF EXISTS (SELECT 1 FROM sys.objects WHERE name='proc_USER_LOGIN)
DROP PROCEDURE proc_USER_LOGIN
GO
CREATE PROCEDURE [dbo].[proc_USER_LOGIN]
@USER_LOGIN NVARCHAR(50),
@USER_PASSWORD NVARCHAR(1000)
WITH ENCRYPTION
AS
DECLARE @FECHA_LIMITE DATETIME,
@DIA NVARCHAR(2),
@MES NVARCHAR(2),
@ANO NVARCHAR(4)
---FECHA--SET @DIA=CAST(DAY(GETDATE()) AS NVARCHAR(2))
SET @MES=CAST(MONTH(GETDATE()) AS NVARCHAR(2))
SET @ANO=CAST(YEAR(GETDATE()) AS NVARCHAR(4))
IF LEN(@DIA) = 1
SET @DIA='0+@DIA
IF LEN(@MES) = 1
SET @MES='0+@MES
---TERMINA FECHA--SET @FECHA_LIMITE='20161231--LIMITE 31 dic 2016
IF(GETDATE()>@FECHA_LIMITE)
GOTO ERROR
SELECT U.nombre
FROM USERS U
WHERE U.[USER_LOGIN]=@USER_LOGIN AND USER_PASSWORD=@USER_PASSWORD
AND U.ACTIVO=1
RETURN
ERROR:
RAISERROR('<br /><b>ERROR DE INICIO DE SESIÓN, CADUCO SU PERIODO DE
PRUEBA</b><br />,16,1)
GOTO FIN
RETURN
FIN:
GO
Luego, en login.aspx.cs
Modificamos las directivas using,para que queden asi:
using
using
using
using
using
using
using
System;
System.Data;
System.Data.SqlClient;
System.Web;
System.Web.UI;
System.Web.UI.WebControls;
System.Web.Security;
Agregamos el siguiente codigo (OJO, SI SE COLOCA MAL, HABRÁ
ERRORES):
private bool fnLogin(string prmUserLogin, string prmPassword)
{
bool _return = false;
try
{
SqlConnection cnnLogin = new SqlConnection(clsMain.CnnStr);
cnnLogin.Open();
string varSQL = "EXECUTE proc_USER_LOGIN @USER_LOGIN, @USER_PASSWORD";
SqlCommand cmdLogin = new SqlCommand(varSQL, cnnLogin);
SqlParameter paramUserLogin = cmdLogin.
Parameters.Add("@USER_LOGIN", SqlDbType.NVarChar, 50);
paramUserLogin.Value = prmUserLogin;
SqlParameter paramPassword = cmdLogin.
Parameters.Add("@USER_PASSWORD", SqlDbType.NVarChar, 50);
paramPassword.Value = prmPassword;
SqlDataReader drLogin = cmdLogin.ExecuteReader();
if (drLogin.Read()) {
Session.Add("USER_NAME", drLogin["nombre"].ToString());
_return = true;
}
else{
lblMensaje.Text = "Nombre de usuario o contraseña incorrectos";
_return = false;
}
drLogin.Close();
cnnLogin.Close();
return (_return);
}
catch (Exception ex)
{
lblMensaje.Text = ex.Message;
return (false);
}
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
lblMensaje.Text = "";
if (fnLogin(txtUSER_LOGIN.Text,txtPASSWORD.Text))
{
//correcto
FormsAuthentication.
RedirectFromLoginPage(txtUSER_LOGIN.Text, chkPersist.Checked);
}
}
Hasta aquí todo debe ir bien, solamente que es necesario agregar código
adicional.
Luego, agregamos la carpeta App_Code, de la siguiente manera:
Y agregamos una clase llamada clsMain, asi:
Y le ponemos el siguiente código a clsMain.cs:
using System;
using System.Configuration;
/// <summary>
/// Clase Main
/// </summary>
public class clsMain
{
public clsMain(){}
/// <summary>
/// Regresa la cadena de conexión
/// </summary>
public static string CnnStr
{
get
{
return (ConfigurationManager.
ConnectionStrings["dbCnnStr"].
ConnectionString);
}
}
/// <summary>
/// Lee el archivo de configuración
/// </summary>
/// <param name=prmKey">Llave a Leer</param>"
/// <returns></returns>
public static string WebConfig(string prmKey)
{
try
{
string value = ConfigurationManager.AppSettings[prmKey];
return (value);
}
catch
{
return ("");
}
}
}
Luego agregamos una clase llamada ISODates, y el código es el siguiente:
//TYRODEVELOPER
//SEPTIEMBRE 2011
using System;
namespace ISODates{
public class Dates{
/// <summary>
/// Devuelve una Fecha ISO para SQLServer
/// </summary>
/// <param name=prmDate">Fecha a convertir</param>"
/// <returns>Fecha ISO para SQL Server</returns>
/// <example>10 Abril 1980 10:25 a.m.= 19800410 10:25:00</example>
public static string SQLServerDate(DateTime prmDate){
string varYear = "1900";
string varMonth = "01";
string varDay = "01";
string varHour = "00";
string varMin = "00";
string varSec = "00";
varYear = prmDate.Year.ToString();
varMonth = prmDate.Month.ToString();
if (varMonth.Length == 1){
varMonth = "0" + varMonth;
}
varDay = prmDate.Day.ToString();
if (varDay.Length == 1){
varDay = "0" + varDay;
}
varHour = prmDate.Hour.ToString();
if (varHour.Length == 1){
varHour = "0" + varHour;
}
varMin = prmDate.Minute.ToString();
if (varMin.Length == 1){
varMin = "0" + varMin;
}
varSec = prmDate.Second.ToString();
if (varSec.Length == 1){
varSec = "0" + varSec;
}
return (varYear + varMonth + varDay +
" " + varHour + ":" + varMin + ":" + varSec);
}
/// <summary>
/// Devuelve una Fecha ISO para SQLServer
/// </summary>
/// <param name=prmDate">Fecha a convertir</param>"
/// <returns>Fecha ISO para SQL Server</returns>
/// <example>10 Abril 1980 = 19800410 00:00:00</example>
public static string SQLServerDateINI(DateTime prmDate){
string varYear = "1900";
string varMonth = "01";
string varDay = "01";
varYear = prmDate.Year.ToString();
varMonth = prmDate.Month.ToString();
if (varMonth.Length == 1){
varMonth = "0" + varMonth;
}
varDay = prmDate.Day.ToString();
if (varDay.Length == 1){
varDay = "0" + varDay;
}
return (varYear + varMonth + varDay +
" 00:00:00");
}
/// <summary>
/// Devuelve una Fecha ISO para SQLServer
/// </summary>
/// <param name=prmDate">Fecha a convertir</param>"
/// <returns>Fecha ISO para SQL Server</returns>
/// <example>10 Abril 1980 = 19800410 23:59:59</example>
public static string SQLServerDateFIN(DateTime prmDate){
string varYear = "1900";
string varMonth = "01";
string varDay = "01";
varYear = prmDate.Year.ToString();
varMonth = prmDate.Month.ToString();
if (varMonth.Length == 1){
varMonth = "0" + varMonth;
}
varDay = prmDate.Day.ToString();
if (varDay.Length == 1){
varDay = "0" + varDay;
}
return (varYear + varMonth + varDay +
" 23:59:59");
}
}
}
Después modificaremos el Web.config, para que quede asi:
<?xml version="1.0"?>
<!-Nota: como alternativa para editar manualmente este archivo puede utilizar la
herramienta Administración de sitios web para configurar los valores de la
aplicación. Utilice
la opción Sitio web->Configuración de Asp.Net en Visual Studio.
Encontrará una lista completa de valores de configuración y comentarios en
machine.config.comments, que se encuentra generalmente en
\Windows\Microsoft.Net\Framework\v2.x\Config
-->
<configuration>
<connectionStrings>
<add name="dbCnnStr" connectionString="Data Source=.;Initial
Catalog=pventa;User ID=webuser;Password=;" providerName="System.Data.SqlClient"/>
</connectionStrings>
<system.web>
<customErrors mode="Off"></customErrors>
<!-Establezca debug="true" en la compilación para insertar símbolos
de depuración en la página compilada. Dado que este
proceso afecta al rendimiento, debe establecer este valor como true
durante la depuración.
-->
<compilation debug="false" targetFramework="4.0">
<assemblies>
<add assembly="System.Design, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=B03F5F7F11D50A3A"/>
<add assembly="System.Web.Extensions, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Windows.Forms, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=B77A5C561934E089"/>
</assemblies>
</compilation>
<!-La sección <authentication> habilita la configuración
del modo de autenticación de seguridad utilizado por
ASP.NET para identificar a un usuario entrante.
-->
<authentication mode="Forms">
<forms name=".VENTASYS" loginUrl="login.aspx" defaultUrl="default.aspx"
protection="All" timeout="20" path="/" requireSSL="false"
slidingExpiration="true" cookieless="UseDeviceProfile" domain=""
enableCrossAppRedirects="false">
<credentials passwordFormat="SHA1"/>
</forms>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
<!-La sección <customErrors> habilita la configuración de
las acciones que se deben realizar si un error no controlado tiene
lugar
durante la ejecución de una solicitud. Específicamente,
permite a los desarrolladores configurar páginas de error html
que se mostrarán en lugar de un seguimiento de pila de errores.
<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
<error statusCode="403" redirect="NoAccess.htm" />
<error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>
-->
<pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID">
</pages>
<httpHandlers>
<add path="ChartImg.axd" verb="GET,HEAD"
type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler,
System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"
validate="false"/>
</httpHandlers>
</system.web>
<!-La sección system.webServer es necesaria para ejecutar ASPN.NET AJAX en
Internet
Information Services 7.0. No es necesaria para la versión anterior de
IIS.
-->
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<handlers>
<add name="ChartImageHandler" preCondition="integratedMode" verb="GET,HEAD"
path="ChartImg.axd"
type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler,
System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
</handlers>
</system.webServer>
<appSettings>
<add key="ChartImageHandler" value="Storage=file;Timeout=20;Url=~/rpt/;"/>
<add key="TICKET_HEADER_01" value="VENTAS S.A DE CV"/>
<add key="TICKET_HEADER_02" value="ENCABEZADO 02"/>
<add key="TICKET_HEADER_03" value="ENCABEZADO 03"/>
<add key="TICKET_HEADER_04" value="ENCABEZADO 04"/>
<add key="TICKET_FOOTER_01" value="GRACIAS POR SU COMPRA"/>
<add key="TICKET_FOOTER_02" value="PIÉ 02"/>
<add key="TICKET_FOOTER_03" value="PIÉ 03"/>
<add key="TICKET_FOOTER_04" value="PIÉ 04"/>
<add key="PROGRAMADOR_NOMBRE" value="JUAN GABRIEL CASTILLO"/>
<add key="PROGRAMADOR_MAIL" value="[email protected]"/>
<add key="PROGRAMADOR_MENSAJE" value="Gracias por adquirir este sistema."/>
<add key="GMAIL_USER" value=""/>
<add key="GMAIL_PASSWORD" value=""/>
<add key="GMAIL_HOST" value="smtp.gmail.com"/>
<add key="GMAIL_PORT" value="587"/>
<add key="GMAIL_URL" value="http://mail.google.com"/>
<add key="DEVELOPER_URL" value=""/>
</appSettings>
</configuration>
Poner especial atención a la llave “ConnectionStrings” ya que en esa
sección deben poner la configuración de su SQL Server.
Ahora agregaremos el código para cerrar la sesión, nos vamos a la página
main.master.cs y agregamos el siguiente código:
protected void btnCerrarSesion_Click(object sender, EventArgs e)
{
FormsAuthentication.SignOut();
Response.Redirect("default.aspx");
}
Ahora, si ejecutamos de nuevo el sistema, se mostrará la página de Login:
De acuerdo a los datos que introdujimos a la tabla users
Nombre de usuario: admin
Contraseña: admin
Luego, al introducir un nombre de usuario y contraseña correctos, veremos
la siguiente pantalla:
Y al dar clic al botón “Cerrar sesión” el sistema nos regresa a lapantalla de
Login.
Lo que haremos a continuación será el diseño de los permisos, es decir,
dependiendo de los permisos que tenga el usuario que inició sesión, serán
las opciones que podrá ver en el menu.
Crear un punto de venta con ASP.NET y SQL Server (Parte 2)
Permisos de la aplicación
Una vez llegada a esta parte, nuestro sistema ya nos exige un nombre de
usuario y una contraseña. Lo que sigue ahora es que cuando iniciemos
sesión, el sistema nos muestre las opciones a las que el usuario tiene
acceso. Modificaremos el código HTML de la página mail.master y el
código C# de la página main.master.cs
En la página main.master ubicamos el objeto lblOpciones el cual tiene el
siguiente código:
<asp:Label ID="lblOpciones" runat="server" Text=""></asp:Label>
Lo modificaremos para que quede:
<asp:Label ID="lblOpciones" runat="server"
Text="{ventas}{reportes}{administrar}"></asp:Label>
Le hemos agregado "{ventas}{reportes}{administrar}", haremos un Replace
de código HTML como se muestra en seguida.
Ahora vamos al código C# del archivo main.master.cs y escribiremos el
siguiente código:
void Permisos(string prmUSER_LOGIN){
try{
SqlConnection cnn = new SqlConnection(clsMain.CnnStr);
cnn.Open();
SqlCommand cmd = new SqlCommand("EXECUTE [proc_USERS_PERMISOS_MOSTRAR]'"
+ prmUSER_LOGIN + "'", cnn);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read()){
if (Convert.ToBoolean(dr["ADMINISTRAR"])){
lblOpciones.Text =
lblOpciones.Text.Replace("{administrar}","
 administrar.aspx\">Administrar
");
}
else{
lblOpciones.Text = lblOpciones.Text.Replace("{administrar}", "");
}
if (Convert.ToBoolean(dr["REPORTES"])){
lblOpciones.Text =
lblOpciones.Text.Replace("{reportes}", "
 reportes.aspx\">Reportes
");
}
else{
lblOpciones.Text = lblOpciones.Text.Replace("{reportes}", "");
}
if (Convert.ToBoolean(dr["VENTAS"])){
lblOpciones.Text =
lblOpciones.Text.Replace("{ventas}", "
 ventas.aspx\">Ventas
");
}
else {
lblOpciones.Text =
lblOpciones.Text.Replace("{ventas}", "");
}
}
dr.Close();
cmd.Dispose();
cnn.Close();
cnn.Dispose();
}
catch (Exception ex){
lblOpciones.Text = ex.Message;
}
}
Luego creamos el siguiente procedimiento almacenado:
USE [pventa]
GO
/****** Object: StoredProcedure [dbo].[proc_USERS_PERMISOS_MOSTRAR]
Date: 09/17/2011 23:10:05 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[proc_USERS_PERMISOS_MOSTRAR]
@USER_LOGIN NVARCHAR(50)
AS
SELECT U.* FROM USERS U WHERE U.[USER_LOGIN]=@USER_LOGIN
GO
Script
Después modificamos el Page_Load para que quede así:
protected void Page_Load(object sender, EventArgs e)
{
try {
Permisos(Context.User.Identity.Name);
}
catch (Exception ex) {
lblOpciones.Text = ex.Message;
}
}
Ahora ejecutamos de nuevo a aplicación, y al iniciar sesión veremos la
siguiente pantalla:
Podemos ver como se aplican los permisos. Crea varios usuarios en el SQL
Server y ponles diferentes permisos para que veas el efecto que tiene en la
pantalla.
Crear un punto de venta con ASP.NET y SQL Server (Parte 3)
Pantalla de Ventas
Agregamos un nuevo WebForm, llamado ventas.aspx como se muestra:
Le daremos el siguiente diseño:
El código HTML para lograr ese diseño:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ventas.aspx.cs"
Inherits="ventas" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Punto de Venta Web</title>
<link href="StyleSheet.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
//NO SALIR de esta pantalla
window.history.forward(1);
//Solo numeros
var nav4 = window.Event ? true : false;
function acceptNum(evt) {
// NOTE: Backspace = 8, Enter = 13, '0' = 48, '9' = 57, '.' = 46
var key = nav4 ? evt.which : evt.keyCode;
return (key <= 13 || (key >= 48 && key <= 57) || key == 46);
}
</script>
</head>
<body>
<form id="frmVentas" runat="server">
<div style="min-height:300px; width:580px;">
<div style="position:absolute; top:40px; background-color:#ADD8E6;
width:150px; left:400px; text-align:right; height:50px; font-size:20pt; bottom:
480px; vertical-align:middle;"> <asp:Label ID="lblTOTAL" runat="server" Text="$
0.00"></asp:Label></div>
<fieldset style="min-height:300px; " >
<legend>Ventas</legend>
<table style="margin:10px;">
<tr>
<td>Clave:</td>
<td>Cantidad:</td>
<td rowspan="2">
<asp:Button ID="btnAgregar" ValidationGroup="Add"
OnClick="btnAgregar_Click"
Height="50" runat="server" Text="Agregar" />
</td>
</tr>
<tr>
<td>
<asp:TextBox ID="txtID_PRODUCTO" MaxLength="50"
runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="reqtxtID_PRODUCTO"
ValidationGroup="Add"
ControlToValidate="txtID_PRODUCTO" runat="server"
ErrorMessage="*"></asp:RequiredFieldValidator>
</td>
<td>
<asp:TextBox ID="txtCANTIDAD" MaxLength="10" Width="90"
runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="reqtxtCANTIDAD"
ValidationGroup="Add"
ControlToValidate="txtCANTIDAD" runat="server"
ErrorMessage="*"></asp:RequiredFieldValidator>
</td>
</tr>
</table>
<asp:GridView ID="grdVentas" AutoGenerateColumns="False"
OnRowDataBound="grdVentas_RowDataBound"
Width="100%" ShowFooter="True" runat="server">
<Columns>
<asp:BoundField HeaderText="Clave" DataField="id_producto">
<ItemStyle HorizontalAlign="Left" />
<HeaderStyle HorizontalAlign="Left" />
</asp:BoundField>
<asp:BoundField HeaderText="Descripcion" DataField="producto" >
<ItemStyle HorizontalAlign="Left" />
<HeaderStyle HorizontalAlign="Left" />
</asp:BoundField>
<asp:BoundField HeaderText="Cantidad" DataField="cantidad"
HtmlEncode="False"
DataFormatString="{0:N0}" >
<ItemStyle HorizontalAlign="Right" />
<HeaderStyle HorizontalAlign="Right" />
</asp:BoundField>
<asp:BoundField HeaderText="Precio" DataField="p_venta"
HtmlEncode="False"
DataFormatString="{0:C}" >
<ItemStyle HorizontalAlign="Right" />
<HeaderStyle HorizontalAlign="Right" />
</asp:BoundField>
<asp:BoundField HeaderText="Total" DataField="TOTAL"
HtmlEncode="False"
DataFormatString="{0:C}" >
<ItemStyle HorizontalAlign="Right" />
<HeaderStyle HorizontalAlign="Right" />
</asp:BoundField>
</Columns>
<EmptyDataTemplate>
<h2>No hay registros.</h2>
<br />
<b>Instrucciones para agregar articulos:</b><br /><br />
1. Proporcione la clave del articulo<br />
2. Proporcione la cantidad<br />
3. Presione "Agregar"
</EmptyDataTemplate>
</asp:GridView>
<table style="width:100%">
<tr>
<td style="text-align:center;">
<asp:Button ID="btnGrabar" OnClick="btnGrabar_Click"
Width="100"
Height="50" runat="server" Text="Grabar" />
<asp:Button ID="btnCancelar" OnClick="btnCancelar_Click"
Width="100"
Height="50" runat="server" Text="Cancelar" />
</td>
</tr>
</table>
<asp:Label ID="lblMessage" runat="server" Text=""></asp:Label>
</fieldset>
</div>
</form>
</body>
</html>
Luego creamos los siguientes procedimientos almacenados:
USE [pventa]
GO
/****** Object: StoredProcedure [dbo].[proc_LISTA_TEMP_VENTAS]
09/08/2011 17:14:38 ******/
SET ANSI_NULLS ON
GO
Script Date:
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[proc_LISTA_TEMP_VENTAS]
@USER_LOGIN NVARCHAR(50)
AS
SELECT T.id_venta_detalle_tmp,P.id_producto,
P.producto, T.cantidad, T.p_venta,
(T.cantidad * T.p_venta) AS TOTAL
FROM productos P JOIN venta_detalle_tmp T ON P.id_producto=T.id_producto
JOIN unidad_medida M ON P.id_unidad_medida=M.id_unidad_medida
WHERE T.user_login=@USER_LOGIN
GO
USE [pventa]
GO
/****** Object: StoredProcedure [dbo].[proc_TEMP_VENTAS]
09/08/2011 17:14:49 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[proc_TEMP_VENTAS]
@USER_LOGIN NVARCHAR(50),
@ID_PRODUCTO NVARCHAR(50),
@CANTIDAD FLOAT
Script Date:
AS
/*GRABAR TMEP_VENTAS*/
BEGIN TRANSACTION tVTA
DECLARE @PRECIO FLOAT,@IVA FLOAT,@EXISTENCIA FLOAT,@CANT FLOAT, @PORC_DESC
FLOAT
SELECT @EXISTENCIA=EXISTENCIA FROM productos WHERE ID_PRODUCTO=@ID_PRODUCTO
SET @PORC_DESC=0
SELECT TOP(1) @PRECIO = p_venta,@ID_PRODUCTO=ID_PRODUCTO FROM productos
WHERE ID_PRODUCTO=@ID_PRODUCTO
IF @PRECIO IS NULL
GOTO ERROR_A
IF EXISTS(SELECT ID_PRODUCTO FROM venta_detalle_tmp
WHERE ID_PRODUCTO=@ID_PRODUCTO AND user_login=@USER_LOGIN)
BEGIN
--EDITAR
SELECT @CANT = CANTIDAD FROM venta_detalle_tmp
WHERE ID_PRODUCTO=@ID_PRODUCTO AND user_login=@USER_LOGIN
IF(@CANTIDAD<=(@EXISTENCIA-@CANT))
BEGIN
UPDATE venta_detalle_tmp
SET CANTIDAD = CANTIDAD + @CANTIDAD
WHERE user_login = @USER_LOGIN
AND ID_PRODUCTO=@ID_PRODUCTO AND user_login=@USER_LOGIN
END
ELSE
GOTO ERROR_EXIST
END
ELSE
BEGIN
--INSERTAR
IF(@CANTIDAD<=@EXISTENCIA)
BEGIN
INSERT INTO
venta_detalle_tmp(user_login,ID_PRODUCTO,CANTIDAD,p_venta)
VALUES(@USER_LOGIN,@ID_PRODUCTO,@CANTIDAD,@PRECIO)
END
ELSE
GOTO ERROR_EXIST
END
IF @@ERROR<> 0 GOTO ERROR
COMMIT TRANSACTION tVTA
RETURN
ERROR:
RAISERROR('No se puede agregar el registro,16,1)
ROLLBACK TRANSACTION tVTA
GOTO FIN
RETURN
ERROR_A:
RAISERROR('El articulo no existe,16,1)
ROLLBACK TRANSACTION tVTA
GOTO FIN
RETURN
ERROR_EXIST:
RAISERROR('No hay suficientes existencias,16,1)
ROLLBACK TRANSACTION tVTA
GOTO FIN
RETURN
FIN:
GO
USE [pventa]
GO
/****** Object: StoredProcedure [dbo].[proc_VENTA]
17:14:58 ******/
SET ANSI_NULLS ON
GO
Script Date: 09/08/2011
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[proc_VENTA]
@USER_LOGIN NVARCHAR(50)
AS
BEGIN TRANSACTION tVTAs
DECLARE @FOLIO_VENTA INT
IF NOT EXISTS(SELECT ID_PRODUCTO FROM venta_detalle_tmp WHERE
user_login=@USER_LOGIN )
GOTO NOOPER
--GRABAMOS LA VENTA
INSERT INTO VENTA(user_login,fecha_registro)
VALUES(@USER_LOGIN,GETDATE())
--OBTENEMOS EL FOLIO DE LA VENTA
SELECT @FOLIO_VENTA=@@IDENTITY
--INSERTAMOS EL DETALLE DE LA VENTA
INSERT INTO VENTA_DETALLE(id_venta,ID_PRODUCTO,CANTIDAD,P_VENTA)
SELECT @FOLIO_VENTA,ID_PRODUCTO,CANTIDAD,P_VENTA
FROM venta_detalle_tmp WHERE user_login=@USER_LOGIN
--ACTUALIZAMOS LAS EXISTENCIAS GENERALES
UPDATE productos
SET productos.EXISTENCIA =
productos.EXISTENCIA-venta_detalle_tmp.[CANTIDAD]
FROM venta_detalle_tmp
WHERE productos.ID_PRODUCTO =
venta_detalle_tmp.ID_PRODUCTO
AND venta_detalle_tmp.user_login= @USER_LOGIN
--BORRAMOS LA TABLA TEMPORAL
DELETE FROM venta_detalle_tmp WHERE user_login = @USER_LOGIN
IF @@ERROR <> 0
GOTO ERROR
SELECT @FOLIO_VENTA
COMMIT TRANSACTION tVTAs
RETURN
ERROR:
RAISERROR('No se puede grabar la venta,16,1)
ROLLBACK TRANSACTION tVTAs
GOTO FIN
RETURN
NOOPER:
RAISERROR('No hay registros en la lista de ventas,16,1)
ROLLBACK TRANSACTION tVTAs
GOTO FIN
RETURN
FIN:
GO
Luego ponemos el código de ventas.aspx.cs:
double varTOTAL = 0;
protected void Page_Load(object sender, EventArgs e){
try{
if (!Page.IsPostBack){
//leer datos
txtCANTIDAD.Attributes.Add("onkeypress", "return acceptNum(event)");
ReadData(User.Identity.Name);
}
}
catch (Exception ex){
lblMessage.Text = ex.Message;
}
}
void ReadData(string prmUSER_NAME){
lblMessage.Text = "";
try{
varTOTAL = 0;
SqlConnection cnnReadData =
new SqlConnection(clsMain.CnnStr);
string varSQL = "EXECUTE [proc_LISTA_TEMP_VENTAS] '" + prmUSER_NAME +
"'";
SqlCommand cmdReadData = new SqlCommand(varSQL, cnnReadData);
cnnReadData.Open();
DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter(varSQL, cnnReadData);
da.Fill(ds, "DATOS");
grdVentas.DataSource = ds.Tables["DATOS"];
grdVentas.DataBind();
ds.Dispose();
cmdReadData.Dispose();
cnnReadData.Close();
cnnReadData.Dispose();
}
catch (Exception ex){
lblMessage.Text = ex.Message;
}
}
bool Temp_Ventas(string prmUSER_LOGIN, string prmID_PRODUCTO, double
prmCANTIDAD){
//Para cargar la venta TEMPORAL
try{
SqlConnection cnnTempVentas = new SqlConnection(clsMain.CnnStr);
cnnTempVentas.Open();
SqlCommand cmdTempVentas = new SqlCommand();
cmdTempVentas.Connection = cnnTempVentas;
cmdTempVentas.CommandText = "EXECUTE [proc_TEMP_VENTAS] '" +
prmUSER_LOGIN + "','" + prmID_PRODUCTO + "'," + prmCANTIDAD + "";
cmdTempVentas.ExecuteNonQuery();
cnnTempVentas.Close();
cmdTempVentas.Dispose();
cnnTempVentas.Dispose();
txtID_PRODUCTO.Text = "";
txtCANTIDAD.Text = "1";
return (true);
}
catch (Exception ex){
lblMessage.Text = ex.Message;
return (false);
}
}
protected void grdVentas_RowDataBound(object sender, GridViewRowEventArgs e){
if (e.Row.RowType == DataControlRowType.DataRow){
// add the UnitPrice and QuantityTotal to the running total variables
varTOTAL += Convert.ToDouble(DataBinder.Eval(e.Row.DataItem, "TOTAL"));
}
else if (e.Row.RowType == DataControlRowType.Footer){
e.Row.Cells[3].Text = "TOTAL";
e.Row.Cells[3].HorizontalAlign = HorizontalAlign.Right;
e.Row.Cells[3].VerticalAlign = VerticalAlign.Top;
// for the Footer, display the running totals
e.Row.Cells[4].Text = varTOTAL.ToString("C");
e.Row.Cells[4].HorizontalAlign = HorizontalAlign.Right;
e.Row.Cells[4].VerticalAlign = VerticalAlign.Top;
e.Row.Font.Bold = true;
lblTOTAL.Text = varTOTAL.ToString("C");
//establecemos en blanco las celdas que no tienen dato
}
}
protected void btnAgregar_Click(object sender, EventArgs e){
try {
if (Temp_Ventas(User.Identity.Name,txtID_PRODUCTO.Text,
Convert.ToDouble(txtCANTIDAD.Text))) {
ReadData(User.Identity.Name);
}
}
catch (Exception ex){
lblMessage.Text = ex.Message;
}
}
private int RealizaVenta(string prmUSER_LOGIN)
{
try{
int varTICKET = 0;
SqlConnection cnnGrabar = new SqlConnection(clsMain.CnnStr);
cnnGrabar.Open();
SqlCommand cmdGrabar = new SqlCommand();
cmdGrabar.Connection = cnnGrabar;
cmdGrabar.CommandText = "EXECUTE [proc_VENTA] '" + prmUSER_LOGIN + "'";
varTICKET = Convert.ToInt32(cmdGrabar.ExecuteScalar());
//LIBERAMOS LOS RECUSROS
cnnGrabar.Close();
cnnGrabar.Dispose();
cmdGrabar.Dispose();
//mostramos la info
return (varTICKET);
}
catch (Exception ex){
lblMessage.Text =ex.Message;
return (0);
}
}
private bool CancelarVenta(string prmUSER_LOGIN){
try{
SqlConnection cnnCancelar = new SqlConnection(clsMain.CnnStr);
cnnCancelar.Open();
SqlCommand cmdCancelar =
new SqlCommand( "DELETE FROM venta_detalle_tmp WHERE user_login =
'"+prmUSER_LOGIN +"'",cnnCancelar);
cmdCancelar.ExecuteNonQuery();
cnnCancelar.Close();
cnnCancelar.Dispose();
cmdCancelar.Dispose();
return (true);
}
catch (Exception ex){
lblMessage.Text = ex.Message;
return (false);
}
}
protected void btnGrabar_Click(object sender, EventArgs e){
try {
int varTICKET = RealizaVenta(User.Identity.Name);
if (varTICKET != 0) {
Response.Redirect("default.aspx");
}
}
catch (Exception ex) {
lblMessage.Text = ex.Message;
}
}
protected void btnCancelar_Click(object sender, EventArgs e){
try{
if (CancelarVenta(User.Identity.Name)){
Response.Redirect("default.aspx");
}
}
catch (Exception ex) {
lblMessage.Text = ex.Message;
}
}
Antes de continuar, entremos ala base de datos y agreguemos unidades de
medida y articulos.
Asi se ve nuestro formulario con articulos:
Crear un punto de venta con ASP.NET y SQL Server (Parte 4)
Reporte de Ventas
Hasta aqui ya hicimos la parte mas complicada de todo, sin embargo, lo
anterior no tiene ningun sentido si no podemos sacar reportes. Esa será
nuestra tarea ahora, obtener el reporte de Ventas.
Agregamos una nueva página llamada reportes.aspx, marcar la opción
"Select master page" y seleccionen man.master:
El código HTML será:
<%@ Page Title="" Language="C#" MasterPageFile="~/main.master"
AutoEventWireup="true"
CodeFile="reportes.aspx.cs" Inherits="reportes" %>
<asp:Content ID="cntMain" ContentPlaceHolderID="cphMain" Runat="Server">
<h3><a href="rpt-ventas.aspx">Reporte de Ventas</a></h3>
</asp:Content>
Ahora agregamos una nueva página llamada rpt-ventas.aspx, marcar la
opción "Select master page" y seleccionen man.master (como en el caso
anterior) y el código HTML será el siguiente::
<%@ Page Title="" Language="C#" MasterPageFile="~/main.master"
AutoEventWireup="true"
CodeFile="rpt-ventas.aspx.cs" Inherits="rpt_ventas" %>
<asp:Content ID="cntMain" ContentPlaceHolderID="cphMain" Runat="Server">
<h3>Reporte de Ventas</h3>
<table style="width:100%;">
<tr>
<td style=" border-right-style:dotted; border-right-color:Silver;
width:200px; border-right-width:1px; vertical-align:top; text-align:left;">
<a href="javascript:" onclick="VerReporte(0);">Ver Reporte</a>
<a href="javascript:" onclick="VerReporte(1);">Exportar</a>
</td>
<td style=" width:580px; vertical-align:top; text-align:left;">
<table >
<tr>
<td>Fecha inicio:</td>
<td>
<asp:TextBox ID="txtFECHA_INI" Width="80"
runat="server"></asp:TextBox>
</td>
</tr>
<tr>
<td>Fecha final:</td>
<td>
<asp:TextBox ID="txtFECHA_FIN" Width="80"
runat="server"></asp:TextBox>
</td>
</tr>
</table>
</td>
</tr>
</table>
<p>Escriba un rango de fechas y seleccione "Ver reporte" para ver en formato
HTML,
o seleccione "Exportar" para enviarlo a Excel</p>
<script type="text/javascript">
function VerReporte(op) {
objFINI = document.getElementById("ctl00_cphMain_txtFECHA_INI");
objFFIN = document.getElementById("ctl00_cphMain_txtFECHA_FIN");
if ((objFINI.value != '') && (objFFIN.value != '')) {
if (op == 0) {
window.open('rpt-ventas-ver.aspx?fini=' + objFINI.value +
'&ffin=' + objFFIN.value + '&op=0');
}
else {
window.open('rpt-ventas-ver.aspx?fini=' + objFINI.value +
'&ffin=' + objFFIN.value + '&op=1'); }
}
else {
alert('Debe indicar la fecha inicial y la fecha final');
}
}
</script>
</asp:Content>
En el Page_Load ponemos el siguiente código:
protected void Page_Load(object sender, EventArgs e)
{
txtFECHA_INI.Text = DateTime.Now.ToShortDateString();
txtFECHA_FIN.Text = DateTime.Now.ToShortDateString();
}
Agregamos una nueva página llamada rpt-ventas-ver.aspx, pero en este
caso NO SELECCIONAREMOS la master page, el código HTML sería el
siguiente:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="rpt-ventas-ver.aspx.cs"
Inherits="rpt_ventas_ver" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Reporte de Ventas</title>
</head>
<body>
<form id="frmReporte" runat="server">
<div>
<asp:Label ID="lblMessage" runat="server" Text=""></asp:Label>
<asp:GridView ID="grdLista" OnRowDataBound="grdLista_RowDataBound"
Width="100%"
ShowFooter="True" AutoGenerateColumns="False" runat="server" >
<Columns>
<asp:BoundField HeaderText="Id " DataField="id_venta" >
<HeaderStyle HorizontalAlign="Left" />
<ItemStyle HorizontalAlign="Left" Width="40" />
</asp:BoundField>
<asp:BoundField HeaderText="Fecha" DataField="fecha_registro"
HtmlEncode="False" DataFormatString="{0:dd/MM/yyyy HH:mm}" >
<HeaderStyle HorizontalAlign="Left" />
<ItemStyle HorizontalAlign="Left" Width="200" />
</asp:BoundField>
<asp:BoundField HeaderText="Clave" DataField="id_producto"
HtmlEncode="False" >
<HeaderStyle HorizontalAlign="Center" />
<ItemStyle HorizontalAlign="Center" Width="70" />
</asp:BoundField>
<asp:BoundField HeaderText="Descripción" DataField="producto"
<HeaderStyle HorizontalAlign="Left" />
<ItemStyle HorizontalAlign="Left" />
</asp:BoundField>
<asp:BoundField HeaderText="Precio" DataField="p_venta"
HtmlEncode="False"
DataFormatString="{0:C}" >
<HeaderStyle HorizontalAlign="Right" />
<ItemStyle HorizontalAlign="Right" Width="70" />
</asp:BoundField>
>
<asp:BoundField HeaderText="Cantidad" DataField="cantidad"
HtmlEncode="False"
DataFormatString="{0:N}" >
<HeaderStyle HorizontalAlign="Right" />
<ItemStyle HorizontalAlign="Right" Width="70" />
</asp:BoundField>
<asp:BoundField HeaderText="Total" DataField="TOTAL"
HtmlEncode="False"
DataFormatString="{0:C}" >
<HeaderStyle HorizontalAlign="Right" />
<ItemStyle HorizontalAlign="Right" Width="70" />
</asp:BoundField>
</Columns>
<EmptyDataTemplate>
<h1>No hay datos para mostrar, intente con otras fechas</h1>
</EmptyDataTemplate>
</asp:GridView>
</div>
</form>
</body>
</html>
en el código de rpt-ventas-ver.aspx.cs, verificamos las directivas using:
using
using
using
using
using
using
using
System;
System.Data;
System.Data.SqlClient;
System.Web;
System.Web.UI;
System.Web.UI.WebControls;
System.Web.UI.HtmlControls;
Luego y el resto del código:
int varTotal = 0;
int varTotalX = 0;
protected void Page_Load(object sender, EventArgs e){
try{
if (!Page.IsPostBack){
Response.Clear();
Response.Buffer = true;
if (Request.Params["op"] == "1"){
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("Content-Disposition",
"attachment;filename=RptVentas.xls");
}
Response.ContentEncoding = System.Text.Encoding.Default;
//Cagamos los Datos
ReadData(ISODates.Dates.SQLServerDateINI(Convert.ToDateTime(Request.Params["fini"
])),
ISODates.Dates.SQLServerDateFIN(Convert.ToDateTime(Request.Params["ffin"])));
Response.Write(HTML()); //Llamada al procedimiento HTML
Response.End();
}
}
catch (Exception ex){
lblMessage.Text = ex.Message;
}
}
void ReadData(string prmFECHA_INI, string prmFECHA_FIN){
try
{
SqlConnection cnn = new SqlConnection(clsMain.CnnStr);
cnn.Open();
SqlDataAdapter da = new SqlDataAdapter("EXECUTE [dbo].[proc_RPT_VENTAS]
'" + prmFECHA_INI + "','" + prmFECHA_FIN + "'", cnn);
DataSet ds = new DataSet();
da.Fill(ds, "DATOS");
grdLista.DataSource = ds.Tables["DATOS"];
grdLista.DataBind();
cnn.Close();
cnn.Dispose();
ds.Dispose();
da.Dispose();
}
catch (Exception ex){
lblMessage.Text = ex.Message;
}
}
protected void grdLista_RowDataBound(object sender, GridViewRowEventArgs e) {
if (e.Row.RowType == DataControlRowType.DataRow){
varTotal += Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "TOTAL"));
}
else if (e.Row.RowType == DataControlRowType.Footer){
varTotalX = varTotal / 2;
e.Row.Cells[5].Text = "TOTAL:";
e.Row.Cells[5].HorizontalAlign = HorizontalAlign.Right;
e.Row.Cells[6].HorizontalAlign = HorizontalAlign.Right;
e.Row.Cells[6].Text = varTotalX.ToString("C");
}
}
//El procedimiento HTML que se encarga de dar o mantener formatos según
corresponda:
public string HTML(){
Page page1 = new Page();
HtmlForm form1 = new HtmlForm();
grdLista.EnableViewState = false;
if (grdLista.DataSource != null){
grdLista.DataBind();
}
grdLista.EnableViewState = false;
page1.EnableViewState = false;
page1.Controls.Add(form1);
form1.Controls.Add(grdLista);
System.Text.StringBuilder builder1 = new System.Text.StringBuilder();
System.IO.StringWriter writer1 = new System.IO.StringWriter(builder1);
HtmlTextWriter writer2 = new HtmlTextWriter(writer1);
writer2.Write("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0
Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1transitional.dtd\">\n<html
xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n<title>Reporte</title>\n<meta
http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\" />\n<style
type=\"text/css\">body{font-family : Tahoma, Verdana, Arial, sansserif;}</style>\n</head>\n<body>\n");
writer2.Write("<table style=\"width:100%\"><tr><td></td>" +
"<td style=\"text-align:center;\"><b>TYRODEVELOPER</b><br />SISTEMA PUNTO
DE VENTA WEB<br />REPORTE DE VENTAS</td>" +
"<td></td></tr></table>");
writer2.Write(String.Format("Reporte entre las fechas: {0} y {1}<br />Total:
{2}",
Request.Params["fini"].ToString(), Request.Params["ffin"].ToString(),
varTotalX.ToString("C")));
page1.DesignerInitialize();
page1.RenderControl(writer2);
writer2.Write("\n</body>\n</html>");
page1.Dispose();
page1 = null;
return builder1.ToString();
}
Creamos el siguiente procedimiento almacenado:
USE [pventa]
GO
/****** Object: StoredProcedure [dbo].[proc_RPT_VENTAS]
09/08/2011 23:47:21 ******/
SET ANSI_NULLS ON
GO
Script Date:
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[proc_RPT_VENTAS]
@FECHA_INI DATETIME,
@FECHA_FIN DATETIME
AS
SELECT V.id_venta,V.fecha_registro, P.id_producto,P.producto,
D.cantidad,D.p_venta, D.cantidad*D.p_venta AS TOTAL
FROM
venta V JOIN venta_detalle D ON V.id_venta=V.id_venta
JOIN productos P ON D.id_producto=P.id_producto
WHERE V.fecha_registro BETWEEN @FECHA_INI AND @FECHA_FIN
GO
Al ejecutarlo, vemos la siguiente pantalla:
Luego, vemos la siguiente pantalla:
Si seleccionamos "Ver reporte", vemos la siguiente pantalla:
Si seleccionamos "Exportar", vemos la siguiente pantalla:
Crear un punto de venta con ASP.NET y SQL Server (Parte 5)
Usuarios del Sistema
Para terminar este tutorial desarrollaremos la pantalla de usuarios del
sistema, poniendo atención se puede aprender como hacer también la
pantalla de productos y unidades de medida.
Agregamos una nueva página llamada administrar.aspx, seleccioamos la
Master page (main.master). el código HTML de administrar.aspx:
<%@ Page Title="" Language="C#" MasterPageFile="~/main.master" AutoEventWireup="true"
CodeFile="administrar.aspx.cs" Inherits="administrar" %>
<asp:Content ID="cntMain" ContentPlaceHolderID="cphMain" Runat="Server">
<h3><a href="user-lista.aspx">Usuarios del Sistema</a></h3>
</asp:Content>
Luego agregamos una página llamada users-lista.aspx, la cualtendrá la
siguiente apariencia:
Para lograr esaapariencia, este es el código HTML:
<asp:content contentplaceholderid="cphMain" id="cntMain" runat="Server">
<h3>
Usuarios del Sistema</h3>
<table style="width: 100%;">
<tbody>
<tr>
<td style="border-right-color: silver; border-right-style: dotted; border-rightwidth: 1px; text-align: left; vertical-align: top; width: 200px;"><a
href="http://www.blogger.com/user.aspx?id=0">Nuevo Usuario</a>
</td>
<td style="text-align: left; vertical-align: top; width: 580px;"><asp:label
id="lblMessage" runat="server" text=""></asp:label>
<asp:gridview autogeneratecolumns="False" id="grdLista" runat="server"
width="100%">
<columns>
<asp:templatefield>
<itemtemplate>
<a %="" href="http://www.blogger.com/user.aspx?id=<%#Eval("
user_login?)="">">Editar</a>
</itemtemplate>
<itemstyle width="16">
<headertemplate>
Editar
</headertemplate>
</itemstyle></asp:templatefield>
<asp:boundfield datafield="user_login" headertext="Usuario">
<headerstyle horizontalalign="Left">
<itemstyle horizontalalign="Left">
</itemstyle></headerstyle></asp:boundfield>
<asp:boundfield datafield="nombre" headertext="Nombre completo">
<headerstyle horizontalalign="Left">
<itemstyle horizontalalign="Left">
</itemstyle></headerstyle></asp:boundfield>
</columns>
</asp:gridview>
</td>
</tr>
</tbody></table>
</asp:content>
Luego, el código C# en user-lista.aspx.cs:
protected void Page_Load(object sender, EventArgs e){
try{
if (!Context.User.Identity.IsAuthenticated){
FormsAuthentication.RedirectToLoginPage("login.aspx");
}
else{
if (!Page.IsPostBack){
ReadData();
}
}
}
catch (Exception ex){
lblMessage.Text = ex.Message;
}
}
void ReadData() {
try{
SqlConnection cnn = new SqlConnection(clsMain.CnnStr);
cnn.Open();
SqlDataAdapter da = new SqlDataAdapter("SELECT user_login, nombre " +
" FROM users ", cnn);
DataSet ds = new DataSet();
da.Fill(ds, "USERS");
grdLista.DataSource = ds.Tables["USERS"];
grdLista.DataBind();
cnn.Close();
cnn.Dispose();
ds.Dispose();
da.Dispose();
}
catch (Exception ex){
lblMessage.Text = ex.Message;
}
}
Luego sigue agregar la página user.aspx, la cual tendrá el siguiente diseño:
El código HTML:
<asp:content contentplaceholderid="cphMain" id="cntMain" runat="Server">
<h3>
Usuarios del Sistema</h3>
<table style="width: 100%;">
<tbody>
<tr>
<td style="border-right-color: silver; border-right-style: dotted; border-rightwidth: 1px; text-align: left; vertical-align: top; width: 200px;"><asp:linkbutton
id="btnGrabar" onclick="btnGrabar_Click" runat="server" tooltip="Clic aqui para
grabar">Grabar</asp:linkbutton>
<a href="http://www.blogger.com/user-lista.aspx">Cancelar</a>
</td>
<td style="text-align: left; vertical-align: top; width: 580px;"><table>
<tbody>
<tr>
<td>Usuario:</td>
<td><asp:textbox id="txtUSER_LOGIN" maxlength="50" runat="server"
width="150"></asp:textbox>
</td>
</tr>
<tr>
<td>Nombre:</td>
<td><asp:textbox id="txtNOMBRE" maxlength="50" runat="server"
width="150"></asp:textbox></td>
</tr>
<tr>
<td>Contraseña:</td>
<td><asp:textbox id="txtUSER_PASSWORD" maxlength="50" runat="server"
width="150"></asp:textbox></td>
</tr>
<tr>
<td>Activo:</td>
<td><asp:checkbox id="chkACTIVO" runat="server">
</asp:checkbox></td>
</tr>
<tr>
<td>Ventas:</td>
<td><asp:checkbox id="chkVENTAS" runat="server">
</asp:checkbox></td>
</tr>
<tr>
<td>Reportes:</td>
<td><asp:checkbox id="chkREPORTES" runat="server">
</asp:checkbox></td>
</tr>
<tr>
<td>Administrar:</td>
<td><asp:checkbox id="chkADMINISTRAR" runat="server">
</asp:checkbox></td>
</tr>
</tbody></table>
</td>
</tr>
</tbody></table>
<asp:label id="lblMensaje" runat="server" text=""></asp:label>
</asp:content>
Luego, el código C# de user.aspx.cs:
protected void Page_Load(object sender, EventArgs e){
try{
if (!Page.IsPostBack){
if (!Context.User.Identity.IsAuthenticated){
FormsAuthentication.RedirectToLoginPage("login.aspx");
}
else{
if (Request.Params["id"].ToString() == "0"){
//Nuevo
btnGrabar.Enabled = true;
}
else{
//editar
txtUSER_LOGIN.Enabled = false;
ReadData(Request.Params["id"].ToString());
}
}
}
}
catch (Exception ex){
lblMensaje.Text = ex.Message;
}
}
void ReadData(string prmUSER_LOGIN){
try{
SqlConnection cnn = new SqlConnection(clsMain.CnnStr);
cnn.Open();
SqlCommand cmd = new SqlCommand("SELECT * FROM users WHERE user_login ='"+
prmUSER_LOGIN +"'", cnn);
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read()){
txtUSER_LOGIN.Text = dr["USER_LOGIN"].ToString();
txtUSER_PASSWORD.Text = dr["USER_PASSWORD"].ToString();
txtNOMBRE.Text = dr["NOMBRE"].ToString();
chkACTIVO.Checked = Convert.ToBoolean(dr["ACTIVO"]);
chkVENTAS.Checked = Convert.ToBoolean(dr["VENTAS"]);
chkREPORTES.Checked = Convert.ToBoolean(dr["REPORTES"]);
chkADMINISTRAR.Checked = Convert.ToBoolean(dr["ADMINISTRAR"]);
}
dr.Close();
cnn.Close();
cmd.Dispose();
cnn.Dispose();
}
catch (Exception ex){
lblMensaje.Text = ex.Message;
}
}
bool fnRegistro(string prmUSER_LOGIN, string prmUSER_PASSWORD, string prmNOMBRE,
int prmACTIVO, int prmREPORTES, int prmVENTAs, int prmADMINISTRAR){
try{
SqlConnection cnn = new SqlConnection(clsMain.CnnStr);
cnn.Open();
string varSQL = "execute proc_USERS '" + prmUSER_LOGIN + "'," +
"'" + prmUSER_PASSWORD + "','" + prmNOMBRE + "'," + prmACTIVO + "," +
prmREPORTES + "," +
"" + prmVENTAs + "," + prmADMINISTRAR + " ";
SqlCommand cmd = new SqlCommand(varSQL, cnn);
cmd.ExecuteNonQuery();
cnn.Close();
cnn.Dispose();
cmd.Dispose();
return (true);
}
catch (Exception ex){
lblMensaje.Text = ex.Message;
return (false);
}
}
protected void btnGrabar_Click(object sender, EventArgs e){
try{
if (fnRegistro(txtUSER_LOGIN.Text,txtUSER_PASSWORD.Text,txtNOMBRE.Text,
Convert.ToInt32(chkACTIVO.Checked), Convert.ToInt32(chkREPORTES.Checked),
Convert.ToInt32(chkVENTAS.Checked), Convert.ToInt32(chkADMINISTRAR.Checked))) {
Response.Redirect("user-lista.aspx");
}
}
catch (Exception ex){
lblMensaje.Text = ex.Message;
}
}
Para terminar, escribimos el siguiente procedimiento almacenado en el SQL
Server:
USE [pventa]
GO
/****** Object: StoredProcedure [dbo].[proc_USERS]
******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[proc_USERS]
@USER_LOGIN NVARCHAR(50),
@USER_PASSWORD VARCHAR(8000),
@NOMBRE NVARCHAR(50),
@ACTIVO BIT,
@REPORTES BIT,
@VENTAS BIT,
@ADMINISTRAR BIT
AS
/*
USUARIOS DEL SISTEMA
FECHA:24-OCT-2011
PROGRAMADOR:J. GABRIEL CASTILLO
MAIL: [email protected],[email protected]
*/
Script Date: 09/23/2011 15:07:40
BEGIN TRANSACTION tUSERS
IF NOT EXISTS(SELECT 1 FROM users WHERE user_login=@USER_LOGIN)
BEGIN
INSERT INTO USERS(USEr_LOGIN,USER_PASSWORD,NOMBRE,activo,reportes,ventas,administrar)
VALUES(@USER_LOGIN,@USER_PASSWORD,@NOMBRE,@ACTIVO,@REPORTES,@VENTAS,@ADMINISTRAR)
END
ELSE
BEGIN
UPDATE USERS SET
NOMBRE=@NOMBRE,
activo=@ACTIVO,
reportes=@REPORTES,
ADMINISTRAR=@ADMINISTRAR,
VENTAS=@VENTAS
WHERE user_login=@USER_LOGIN
END
COMMIT TRANSACTION tUSERS
RETURN
ERROR:
RAISERROR('No se puede ejecutar la acción solicitada,16,1)
ROLLBACK TRANSACTION tUSERS
GOTO FIN
RETURN
FIN:
GO
Descargar