Ejemplo n.º 1
0
        public int InvoiceRun(DateTime callCutoffDate)
        {
            if (runInProgress)
            {
                throw new InvoiceRunInProgressException();
            }
            runInProgress = true;

            try
            {
                // SRD-PCMS-40 (001-62) Only invoice once per month
                DateTime? lastInvoiceDate = _invoiceSettings.LastInvoiceRunPerformedDate;
                if (lastInvoiceDate != null && lastInvoiceDate.Value.Month == callCutoffDate.Month && lastInvoiceDate.Value.Year == callCutoffDate.Year)
                {
                    LoggingUtility.LogDebug("InvoiceRun", "AirtimeBilling.Services.InvoicingService",
                                            string.Format(
                                                "Attempted Invoice Run more than once in the same month. Last Run Date={0}.  Current Date={1}",
                                                lastInvoiceDate.Value, _dateTime.Now));

                    throw new InvoiceRunFrequencyException();
                }

                int runNumber = 0;
                using (var ts = new TransactionScope())
                {
                    var rootAccounts = _accountRepository.GetAllRootAccounts();
                    if (rootAccounts.Count == 0)
                    {
                        LoggingUtility.LogDebug("InvoiceRun", "InvoicingService",
                                                "An Invoice Run was Started but no accounts were found.");
                        return 0;
                    }

                    runNumber = _numberGeneratorService.NextInvoiceRunNumber();

                    DateTime fromDate = DateTime.MinValue;
                    if (lastInvoiceDate.HasValue)
                    {
                        fromDate = lastInvoiceDate.Value.AddDays(1);
                    }

                    var context = new InvoiceRunContext(runNumber, fromDate, callCutoffDate);
                    var factory = new InvoiceFactory(_invoiceSettings, _dateTime, _contractRepository,
                                                                _accountRepository,
                                                                _planRepository, _networkRepository, _contractService, _companyRepository,
                                                                _contactRepository,
                                                                _numberGeneratorService, context);

                    foreach (var rootAccount in rootAccounts)
                    {
                        var invoice = factory.GenerateInvoice(rootAccount);
                        if (invoice == null) continue;

                        _invoiceRepository.InsertInvoice(invoice);
                        if (invoice.Id == null)
                        {
                            // TODO Return failure reason and log.
                            return 0;
                        }

                        rootAccount.LogActivity("Invoice Number '" + invoice.InvoiceNumber + "' created in Invoice Run " + runNumber);

                        rootAccount.AmountPaid = 0;
                        rootAccount.PreviousBill = invoice.CurrentBill;

                        if (!_accountRepository.UpdateAccount(rootAccount)) {
                            return 0;
                        }
                    }

                    _invoiceSettings.LastInvoiceRunPerformedDate = callCutoffDate;

                    ts.Complete();
                }

                // Report generation times out the transaction.
                // Report generation doesn't participate in the ambient transaction so
                // there's no real reason to do it in the transaction.
                var invoices = _invoiceRepository.FindInvoicesByRunNumber(runNumber);
                foreach (var invoice in invoices)
                    _invoiceHardcopyRepository.Save(invoice);

                // SRD-PCMS-54 (001-76) Invoice data file emailed
                // Now make a manual process to cope with credit cards.
                //SendCustomerInvoiceInEmail(runNumber);

                return runNumber;
            }
            catch (Exception ex)
            {
                LoggingUtility.LogException(ex);
                throw;
                //return 0;
            }
            finally
            {
                runInProgress = false;
            }
        }