DataTplOrderInvoice.cs
//
// This code is part of GrapeCity Documents for Word samples.
// Copyright (c) GrapeCity, Inc. All rights reserved.
//
using System;
using System.IO;
using System.Drawing;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Linq;
using GrapeCity.Documents.Word;

namespace GcWordWeb.Samples
{
    // This data template sample prints an invoice containing the list
    // of products in the purchase order.
    // The invoice data is generated for a randomly selected
    // order from the sample GcNwind database.
    public class DataTplOrderInvoice
    {
        public GcWordDocument CreateDocx(int _ = 0)
        {
            using (var ds = new DataSet())
            {
                // Load the sample database, fetch a random supplier
                // and a random order from that supplier:
                ds.ReadXml(Path.Combine("Resources", "data", "GcNWind.xml"));

                // Database tables used by the invoice:
                var dtSuppliers = ds.Tables["Suppliers"];
                var dtOrders = ds.Tables["OrdersCustomersEmployees"];
                var dtOrdersDetails = ds.Tables["EmployeesProductsOrders"];

                // Collect order data:
                var random = new Random();

                var fetchedIndex = random.Next(dtSuppliers.Select().Count());
                var supplier =
                    dtSuppliers.Select()
                    .Skip(fetchedIndex).Take(1)
                    .Select(it => new
                    {
                        SupplierID = Convert.ToInt32(it["SupplierID"]),
                        CompanyName = it["CompanyName"].ToString(),
                        ContactName = it["ContactName"].ToString(),
                        ContactTitle = it["ContactTitle"].ToString(),
                        Address = it["Address"].ToString(),
                        City = it["City"].ToString(),
                        Region = it["Region"].ToString(),
                        PostalCode = it["PostalCode"].ToString(),
                        Country = it["Country"].ToString(),
                        Phone = it["Phone"].ToString(),
                        Fax = it["Fax"].ToString(),
                        HomePage = it["HomePage"].ToString()
                    }).FirstOrDefault();

                fetchedIndex = random.Next(dtOrders.Select().Count());
                var order = dtOrders.Select()
                    .Skip(fetchedIndex).Take(1)
                    .Select(it => new
                    {
                        OrderDate = it["OrderDate"],
                        OrderID = Convert.ToInt32(it["OrderID"]),
                        CompanyName = it["CompanyName"].ToString(),
                        Name = $"{it["FirstName"]} {it["LastName"]}",
                        Address = $"{it["ShipAddress"]},\n{it["ShipCity"]} {it["ShipRegion"]} {it["ShipPostalCode"]} {it["ShipCountry"]}",
                        Email = GetEmail(it["FirstName"].ToString(), it["LastName"].ToString(), it["CompanyName"].ToString()),
                    }).FirstOrDefault();

                var orderDetails = dtOrdersDetails.Select()
                    .Select(it => new
                    {
                        OrderID = Convert.ToInt32(it["OrderID"]),
                        ProductName = it["ProductName"].ToString(),
                        UnitPrice = Convert.ToDecimal(it["UnitPrice"]),
                        Quantity = Convert.ToDecimal(it["Quantity"]),
                        Total = Convert.ToDecimal(it["UnitPrice"]) * Convert.ToDecimal(it["Quantity"]),
                    })
                    .Where(it => it.OrderID == order.OrderID)
                    .OrderBy(it => it.ProductName).ToList();

                // Finally, prep the integrated data source for the template:
                var data = new
                {
                    o = order,
                    ps = orderDetails,
                    total = orderDetails.Sum(od_ => od_.Total),
                };

                // Load the template DOCX, add the data source and process the template:
                var doc = new GcWordDocument();
                doc.Load(Path.Combine("Resources", "WordDocs", "InvoiceTemplate.docx"));
                doc.DataTemplate.DataSources.Add("ds", data);
                doc.DataTemplate.Process();

                // Done:
                return doc;
            }
        }

        // Generate a sample email address from other data:
        private string GetEmail(string firstName, string lastName, string companyName)
        {
            var x = new string(companyName.ToLower().Where(c_ => char.IsLetterOrDigit(c_)).ToArray());
            return $"{firstName.ToLower()}.{char.ToLower(lastName[0])}@{x}.com";
        }

        public static List<string[]> GetSampleParamsList()
        {
            return new List<string[]>()
            {
                new string[] { "@data-templates/Order Invoice", "Generate the invoice for a random order fetched from a database", null },
                new string[] { "@use-data-tpl/Order Invoice", "Generate the invoice for a random order fetched from a database", null },
            };
        }
    }
}