Example #1
0
        /// <summary>
        /// Generate an email content based on the time and the bill statement.
        /// </summary>
        /// <param name="bill"></param>
        /// <param name="month"></param>
        /// <param name="year"></param>
        /// <returns></returns>
        public Email GenerateEmail(BillStatement bill, int month, int year)
        {
            string emailTemplate = DomainResources.BILLING_STATEMENT_EMAIL_TEMPLATE;
            string subject       = $"Billing statement for {month}-{year}";

            string content = emailTemplate
                             .Replace("{name}", bill.Customer.Name)
                             .Replace("{address}", bill.Customer.Address)
                             .Replace("{city}", bill.Customer.City)
                             .Replace("{state}", bill.Customer.Address)
                             .Replace("{zip}", bill.Customer.Address)
                             .Replace("{bill_month}", month + "-" + year)
                             .Replace("{amount_due}", bill.AmountDue.ToString("C"));

            return(new Email(subject, content, bill.Customer, bill));
        }
Example #2
0
        /// <summary>
        /// Generate the bill for a customer.
        /// Note:
        ///     this action is idempotent. If the bill is generated, it will be retrieved.
        /// </summary>
        /// <param name="cust"></param>
        /// <param name="month"></param>
        /// <param name="year"></param>
        /// <returns></returns>
        public BillStatement GenerateBill(Customer cust, int month, int year)
        {
            string billedCustomerKey = $"{month}_{year}_{cust.CustomerId}";

            // if the bill is not generated, create it
            if (billedCustomerByTime[billedCustomerKey] == null)
            {
                decimal?      amountDue = GetAmountDue(cust, month, year);
                BillStatement bill      = new BillStatement(cust, month, year, amountDue.GetValueOrDefault());

                cust.MonthlyStatements.Add(bill);
                customerRepository.SaveOrUpdate(cust);
                //remember customer bill statement for the month
                billedCustomerByTime[billedCustomerKey] = bill;
                return(bill);
            }

            // if the bill has been generated, just retrieve it.
            return(billedCustomerByTime[billedCustomerKey]);
        }
Example #3
0
        /// <summary>
        /// Generate and send the bill to all active customers for the month and year.
        /// Note:
        ///     This action is idempotent. If customer has already been emailed, the system will not send duplicate email.
        /// </summary>
        /// <param name="month">the month to bill customer.</param>
        /// <param name="year">the year to bill customer.</param>
        public void SendBillToActiveCustomers(int month, int year)
        {
            // Billing service does not support future date
            if (!DateTimeHelper.IsInFuture(month, year))
            {
                ISet <Email>     emails             = new HashSet <Email>();
                string           datetimeStamp      = $"{month}_{year}";
                IList <Customer> allActiveCustomers = this.customerRepository.GetAllActiveCustomers();

                foreach (Customer customer in allActiveCustomers)
                {
                    try
                    {
                        BillStatement bill = GenerateBill(customer, month, year);

                        // only send email if we have not done that.
                        string emailedCustomerKey = $"{customer.CustomerId}_{month}_{year}";
                        if (!emailedCustomerByTime.ContainsKey(emailedCustomerKey))
                        {
                            Email email = GenerateEmail(bill, month, year);

                            // remember the customer who was emailed
                            emailedCustomerByTime[emailedCustomerKey] = email;
                            emails.Add(email);
                        }
                    }
                    //Should not block the whole billing cycle if a customer failed
                    catch (Exception ex)
                    {
                        Logger.Error(ex);
                        Logger.Error($"Unable to generate bill for {customer.CustomerId}:{customer.Name} for the {month}-{year}");
                    }
                }

                //storing the generated email for reporting purpose
                invoiceGeneratedByTime[datetimeStamp] = emails;
                emailRepository.SendMultiple(emails);
            }
        }