public async Task<IbisFileGeneratorResult<TransactionFile>> CreateAsync(ulong fileID, InvoiceRun invoiceRun)
        {
            TransactionFile transactionFile = new TransactionFile("WEE", fileID);

            var errors = new List<Exception>();
            var groups = invoiceRun.MemberUploads.GroupBy(mu => mu.Scheme);

            foreach (var group in groups)
            {
                List<InvoiceLineItem> lineItems = new List<InvoiceLineItem>();
                var lineItemErrors = new List<Exception>();

                foreach (MemberUpload memberUpload in group)
                {
                    DateTime submittedDate = memberUpload.SubmittedDate.Value;

                    string description = string.Format("Charge for producer registration submission made on {0:dd MMM yyyy}.",
                        submittedDate);

                    try
                    {
                        InvoiceLineItem lineItem = new InvoiceLineItem(
                            memberUpload.TotalCharges,
                            description);

                        lineItems.Add(lineItem);
                    }
                    catch (Exception ex)
                    {
                        lineItemErrors.Add(new SchemeFieldException(group.Key, ex));
                    }
                }

                errors.AddRange(lineItemErrors);

                string transactionReference = await transactionReferenceGenerator.GetNextTransactionReferenceAsync();

                if (lineItemErrors.Count == 0)
                {
                    try
                    {
                        Invoice invoice = new Invoice(
                            group.Key.IbisCustomerReference,
                            invoiceRun.IssuedDate,
                            TransactionType.Invoice,
                            transactionReference,
                            lineItems);

                        transactionFile.AddInvoice(invoice);
                    }
                    catch (Exception ex)
                    {
                        errors.Add(new SchemeFieldException(group.Key, ex));
                    }
                }
            }

            return new IbisFileGeneratorResult<TransactionFile>(errors.Count == 0 ? transactionFile : null, errors);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="InvoiceLineItemFileLine"/> class with the specified details.
        /// </summary>
        /// <param name="invoice">The invoice represented by this file line.</param>
        /// <param name="invoiceLineItem">The invoice line item represented by this file line.</param>
        public InvoiceLineItemFileLine(
            Invoice invoice,
            InvoiceLineItem invoiceLineItem)
        {
            if (invoice == null)
            {
                throw new ArgumentNullException("invoice");
            }

            if (invoiceLineItem == null)
            {
                throw new ArgumentNullException("invoiceLineItem");
            }

            Invoice = invoice;
            InvoiceLineItem = invoiceLineItem;
        }
        public async Task<IbisFileGeneratorResult<TransactionFile>> CreateAsync(ulong fileID, InvoiceRun invoiceRun)
        {
            Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB");

            var errors = new List<Exception>();
            TransactionFile transactionFile = new TransactionFile("WEE", fileID);

            foreach (MemberUpload memberUpload in invoiceRun.MemberUploads)
            {
                List<InvoiceLineItem> lineItems = new List<InvoiceLineItem>();

                var lineItemGroups = memberUpload.ProducerSubmissions
                    .Where(ps => ps.ChargeThisUpdate != 0)
                    .Where(ps => ps.Invoiced)
                    .GroupBy(ps => ps.ChargeThisUpdate)
                    .OrderBy(g => g.Key)
                    .Select(g => new { Charge = g.Key, Quantity = g.Count() })
                    .ToList();

                if (lineItemGroups.Count > 0)
                {
                    var lineItemErrors = new List<Exception>();

                    foreach (var lineItemGroup in lineItemGroups)
                    {
                        decimal amount = lineItemGroup.Charge * lineItemGroup.Quantity;

                        string description = string.Format("{0} producer registration charge{1} at {2:C}.",
                            lineItemGroup.Quantity,
                            lineItemGroup.Quantity != 1 ? "s" : string.Empty,
                            lineItemGroup.Charge);

                        InvoiceLineItem lineItem;
                        try
                        {
                            lineItem = new InvoiceLineItem(
                                amount,
                                description);

                            lineItems.Add(lineItem);
                        }
                        catch (Exception ex)
                        {
                            lineItemErrors.Add(ex);
                        }
                    }

                    errors.AddRange(lineItemErrors);

                    if (lineItemErrors.Count == 0)
                    {
                        string transactionReference = await transactionReferenceGenerator.GetNextTransactionReferenceAsync();

                        try
                        {
                            Invoice invoice = new Invoice(
                                memberUpload.Scheme.IbisCustomerReference,
                                invoiceRun.IssuedDate,
                                TransactionType.Invoice,
                                transactionReference,
                                lineItems);

                            transactionFile.AddInvoice(invoice);
                        }
                        catch (Exception ex)
                        {
                            errors.Add(ex);
                        }
                    }
                }
            }

            return new IbisFileGeneratorResult<TransactionFile>(errors.Count == 0 ? transactionFile : null, errors);
        }