using System; using System.Drawing; using System.IO; using System.Linq; using System.Text.RegularExpressions; using System.Windows.Forms; using HeuristicLab.Services.Optimization.Billing.Interfaces; using HeuristicLab.Services.Optimization.Billing.Model; namespace HeuristicLab.Services.Optimization.Billing.BillingEngine { public enum PlainTextInvoiceFormat { TXT, RTF, PDF } public class PlainTextInvoiceFormattingEngine : IInvoiceFormattingEngine { private const string defaultTemplatePath = @"BillingEngine\InvoiceTemplate.txt"; private string template; private string invoiceText; private PlainTextInvoiceFormat invoiceFormat; private string invoiceOutputPath; private IInvoiceDao invoiceDao; private IInvoiceDao InvoiceDao { get { if (invoiceDao == null) { invoiceDao = new FileSystemInvoiceDao(); } return invoiceDao; } } public PlainTextInvoiceFormattingEngine() : this(defaultTemplatePath, PlainTextInvoiceFormat.RTF) { } public PlainTextInvoiceFormattingEngine(string templatePath, PlainTextInvoiceFormat format) { if (!File.Exists(templatePath)) { throw new FileNotFoundException("Cannot find template file", templatePath); } template = File.ReadAllText(templatePath); if (format == PlainTextInvoiceFormat.PDF) { throw new Exception("PDF invoice format is currently not supported"); } invoiceFormat = format; } public string Generate(Invoice invoice) { invoiceText = string.Copy(template); invoiceText = invoiceText.Replace("{INVOICE_ID}", invoice.InvoiceId.ToString()); invoiceText = invoiceText.Replace("{ORGANIZATION_NAME}", invoice.User.ContactInformation.OrganizationName); invoiceText = invoiceText.Replace("{FIRSTNAME}", invoice.User.ContactInformation.FirstName); invoiceText = invoiceText.Replace("{LASTNAME}", invoice.User.ContactInformation.LastName); invoiceText = invoiceText.Replace("{STREET}", invoice.User.ContactInformation.Street); invoiceText = invoiceText.Replace("{POSTAL_CODE}", invoice.User.ContactInformation.PostalCode); invoiceText = invoiceText.Replace("{CITY}", invoice.User.ContactInformation.City); invoiceText = invoiceText.Replace("{INVOICE_DATE}", invoice.InvoiceDate.ToString("dd.MM.yyyy")); invoiceText = invoiceText.Replace("{ORDER_ID}", invoice.OrderId.ToString()); invoiceText = invoiceText.Replace("{USER_NAME}", invoice.User.Name); invoiceText = invoiceText.Replace("{PAYMENT_TERMS}", "2% 10, net 30 days"); invoiceText = invoiceText.Replace("{PAYMENT_DUE}", invoice.Due.Date.ToString("dd.MM.yyyy")); int itemNo = invoice.InvoiceLines.Count; int first = invoiceText.IndexOf("#BEGIN"); int last = invoiceText.LastIndexOf("#END"); string orderLineTextTemplate = invoiceText.Substring(first, last + 6 - first); invoiceText = invoiceText.Remove(first, last + 6 - first); foreach (InvoiceLine invoiceLine in invoice.InvoiceLines.Reverse()) { string invoiceLineText = string.Copy(orderLineTextTemplate); invoiceLineText = invoiceLineText.Replace("{ITEM}", (itemNo).ToString().PadRight(5)); itemNo--; invoiceLineText = invoiceLineText.Replace("{PRODUCT_NAME}", invoiceLine.Product.Name.PadRight(39)); invoiceLineText = invoiceLineText.Replace("{QUANTITY}", invoiceLine.Quantity.ToString().PadRight(9)); invoiceLineText = invoiceLineText.Replace("{PRODUCT_PRICE}", invoiceLine.ProductPrice.ToString("C2").PadLeft(10)); double totalPrice = invoiceLine.Quantity * invoiceLine.ProductPrice; invoiceLineText = invoiceLineText.Replace("{PRODUCT_TOTAL}", totalPrice.ToString("C2").PadLeft(11)); invoiceLineText = invoiceLineText.Remove(invoiceLineText.IndexOf("#BEGIN"), 7); invoiceLineText = invoiceLineText.Remove(invoiceLineText.IndexOf("#END"), 4); invoiceText = invoiceText.Insert(first, invoiceLineText); } invoiceText = invoiceText.Replace("{INVOICE_SUB_TOTAL}", string.Format("{0:C2}", invoice.Total - invoice.Tax).PadLeft(18)); invoiceText = invoiceText.Replace("{INVOICE_TAX}", invoice.Tax.ToString("C2").PadLeft(12)); invoiceText = invoiceText.Replace("{INVOICE_TOTAL}", invoice.Total.ToString("C2").PadLeft(14)); // remove all escape sequences and replace directory separator with a hyphen string customerName = Regex.Replace(invoice.User.ContactInformation.OrganizationName, "\\r\\n|\\[bnrt]", ""); customerName = customerName.Replace("/", "-"); if (invoiceFormat == PlainTextInvoiceFormat.RTF) { invoiceOutputPath = string.Format("{0}_{1}_{2}.rtf", invoice.InvoiceId, invoice.InvoiceDate.ToString("yyyMMdd"), customerName); RichTextBox richTextBox = new RichTextBox(); richTextBox.Text = invoiceText; richTextBox.SelectAll(); richTextBox.SelectionFont = new Font("Consolas", 10, FontStyle.Regular); //File.WriteAllText(invoiceOutputPath, richTextBox.Rtf); InvoiceDao.SaveDocument(invoiceOutputPath, richTextBox.Rtf); } else if (invoiceFormat == PlainTextInvoiceFormat.TXT) { invoiceOutputPath = string.Format("{0}_{1}_{2}.txt", invoice.InvoiceId, invoice.InvoiceDate.ToString("yyyMMdd"), customerName); //File.WriteAllText(invoiceOutputPath, invoiceText); InvoiceDao.SaveDocument(invoiceOutputPath, invoiceText); } else if (invoiceFormat == PlainTextInvoiceFormat.PDF) { throw new Exception("PDF invoice format is currently not supported"); } return invoiceOutputPath; } } }