Products Technologies Demo Docs Blog Support Company

MailMerge: Using Smart Business Objects to Calculate Batch Totals and Subtotals

Text Control's MailMerge class supports IEnumerable objects, DataSets, DataTables and Json as data sources for mail merge processes. A smart advantage of business objects is that a specific logic can be implemented into these classes. Consider the following business object: Order is the main object or Master Table for the mail merge process. It consists of Customer information, a Total and a collection of ProductBlocks. The ProductBlock class contains the sum of prices of all contained…

MailMerge: Using Smart Business Objects to Calculate Batch Totals and Subtotals

Text Control's MailMerge class supports IEnumerable objects, DataSets, DataTables and Json as data sources for mail merge processes. A smart advantage of business objects is that a specific logic can be implemented into these classes. Consider the following business object:

MailMerge: Using smart business objects to calculate batch totals and subtotals

Order is the main object or Master Table for the mail merge process. It consists of Customer information, a Total and a collection of ProductBlocks. The ProductBlock class contains the sum of prices of all contained Products.

public class ProductBlock
{
    private List<Product> _products;

    public List<Product> Products
    {
        get { return _products; }
        set
        {
            _products = value;

            foreach (Product product in _products)
            {
                this.BlockSum += product.Price;
            }
        }
    }

    public int BlockSum { get; internal set; }
}
public class Product
{
    public string Name { get; set; }
    public int Price { get; set; }
}

If a new list of products is added to the ProductBlock object, the BlockSum field is calculated automatically. Therefore, the total sum of a ProductBlock object is always accurate and must not be set manually.

The main object Order implements the INotifyPropertyChanged interface which is used to update the ObservableCollection of ProductBlocks. Each time, a new ProductBlock is added, the Total is calculated.

public class Order : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    // *** M E M B E R S ***
    private ObservableCollection<ProductBlock> _productBlocks;

    // *** P R O P E R T I E S ***
    public int Total { get; set; }
    public Customer Customer { get; set; }

    public ObservableCollection<ProductBlock> ProductBlocks
    {
        get { return _productBlocks; }
        set { _productBlocks = value; }
    }

    // *** C O N S T R U C T O R ***
    public Order()
    {
        _productBlocks = new ObservableCollection<ProductBlock>();
        _productBlocks.CollectionChanged += _productBlocks_CollectionChanged;
    }

    // Update the Total, if new blocks are added
    private void _productBlocks_CollectionChanged(object sender,
      System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        Total = 0;

        foreach (ProductBlock block in _productBlocks)
        {
            Total += block.BlockSum;
        }
    }
}
public class Customer
{
    public string Name { get; set; }
}

The following screenshot shows a sample template with a nested merge block. The outer block is ProductBlocks that contains a child block called Products. As Products is a list member of the object ProductBlock, it can be repeated in a separate nested block.

Template

The following code shows the creation of a data object and how to call the MergeObject method to start the merge process:

// create a new Order 
Order order = new Order()
{
    Customer = new Customer() { Name = "Peter Customer" }
};

// create a new ProductBlock
ProductBlock block = new ProductBlock();
block.Products = new List<Product>()
{
   new Product() { Name = "Product 1", Price = 200 },
   new Product() { Name = "Product 2", Price = 400 },
   new Product() { Name = "Product 3", Price = 800 }
};

// add the ProductBlock to the ObservableCollection
order.ProductBlocks.Add(block);

// create a second ProductBlock
ProductBlock block2 = new ProductBlock();
block2.Products = new List<Product>()
{
   new Product() { Name = "Product 4", Price = 231 },
   new Product() { Name = "Product 5", Price = 32424 },
   new Product() { Name = "Product 6", Price = 33 },
   new Product() { Name = "Product 7", Price = 332 },
};

order.ProductBlocks.Add(block2);

// merge the template with the business object
using (MailMerge mailMerge = new MailMerge())
{
    mailMerge.TextComponent = textControl1;
    mailMerge.MergeObject(order);
}

After merging the template, the ProductBlocks are repeated and the block sum is rendered at the end of each block. At the very end, the total sum is shown which has been calculated automatically inside the business object.

Merge results

Stay in the loop!

Subscribe to the newsletter to receive the latest updates.

Also See

This post references the following in the documentation:

  • TXTextControl.DocumentServer.MailMerge Class
  • TXTextControl.DocumentServer.MailMerge.MergeObject Method

Reporting

The Text Control Reporting Framework combines powerful reporting features with an easy-to-use, MS Word compatible word processor. Users can create documents and templates using ordinary Microsoft Word skills. The Reporting Framework is included in all .NET based TX Text Control products including ASP.NET, Windows Forms and WPF.

See Reporting products