Use Case - Expense Report

ASP.NET User's Guide > Reporting and Mail Merge (DocumentServer.MailMerge)

This demo shows a master-detail report use case with a business object as the data source. The template contains master data (the purpose of the expense report, dates), employee information and the expenses in form of a table (detail information).

This example is part the Sample Explorer project which includes all samples in one. The sources for this sample project can be found here:

Language Project Location
C# %USERPROFILE%\Documents\TX Text Control 26.0.NET Server for ASP.NET\Samples\ASP.NET\CSharp\Sample Explorer\
VB.NET %USERPROFILE%\Documents\TX Text Control 26.0.NET Server for ASP.NET\Samples\ASP.NET\VB.NET\Sample Explorer\

You will find the source code and the ASPX page of this sample in the Solution structure tree under: Reporting\expenses.aspx

Example description

Simply Select a report from the GridView and click on Create report to start the merge process.

An expense report contains general data such as the purpose of the expense, the pay period and a statement number. Additionally, it should list the employee details and finally, the expenses itself. The class diagram of the business object is illustrated below:

The business object Expenses has some useful features. It contains XML Serialization attributes which allows us to use an XML data source that is deserialized into the business object automatically.

[XmlType("expenses", IncludeInSchema = true)] 
public class Expenses : List<Expense> 
    public List<Expense> expenses { get; set; } 

[Visual Basic]
<XmlType("expenses", IncludeInSchema := True)> _
Public Class Expenses
    Inherits List(Of Expense)
    <XmlElement("expense")> _
    Public Property expenses() As List(Of Expense)
            Return m_expenses
        End Get
            m_expenses = Value
        End Set
    End Property
    Private m_expenses As List(Of Expense)
End Class

The attributes define which XML element is mapped to which member of the object. An XmlSerializer is used to deserialize the XML in order to create a new instance of the business object.

XmlSerializer serializer = new XmlSerializer(typeof(Expenses)); 
Expenses expenses = (Expenses)serializer.Deserialize( 
    new StreamReader("expense_report_data.xml"));
[Visual Basic]
Dim serializer As New XmlSerializer(GetType(Expenses))
Dim expenses As Expenses = DirectCast(serializer.Deserialize( _
    New StreamReader("expense_report_data.xml")), Expenses)

Additionally, we don't need to store all values in our XML file (or database in real life applications). The business object contains the logic and the code to calculate specific field values internally. All inverted members in the above illustration are not imported from the XML, but calculated on the fly in the business object itself.

The following code shows how the Total value is calculated based on existing values:

public double Total 
        double dTotal = 0; 

        foreach (LineItem item in this.LineItems) 
            dTotal += item.line_total; 

        return dTotal - this.Advances; 
[Visual Basic]
Public ReadOnly Property Total() As Double
        Dim dTotal As Double = 0

        For Each item As LineItem In Me.LineItems
            dTotal += item.line_total

        Return dTotal - Me.Advances
    End Get
End Property

In order to start the merge process itself, only 1 line of code is required:

[Visual Basic]

Text Control's Reporting engine MailMerge is mapping the merge fields to the business object members and related objects automatically.