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 System;
using System.Data;
using System.Data.SqlClient;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using 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/xhtml1-transitional.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, sans-serif;}</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]    Script Date: 09/08/2011 23:47:21 ******/
SET ANSI_NULLS ON
GO

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:

Anterior | Siguiente

1 comentario:

  1. Hay un error en el StoreProcedure que genera el reporte en el join de venta y venta_detalle, el StoreProcedure quedaria así:



    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=D.id_venta
    JOIN productos P ON D.id_producto=P.id_producto
    WHERE V.fecha_registro BETWEEN @FECHA_INI AND @FECHA_FIN

    ResponderEliminar