private void SendOrderStatusChangeEmail(OrderInfo order)
        {
            // Get Store Currency Symbol
            if (!string.IsNullOrEmpty(StoreSettings.CurrencySymbol))
            {
                order.CurrencySymbol = StoreSettings.CurrencySymbol;
            }

            // Get Order Date Format
            string orderDateFormat = Localization.GetString("OrderDateFormat", LocalResourceFile);

            if (!string.IsNullOrEmpty(orderDateFormat))
            {
                order.DateFormat = orderDateFormat;
            }

            // Get Customer Email
            string customerEmail = CheckoutControl.BillingAddress.Email;

            // Get Admin Email
            string adminEmail = StoreSettings.DefaultEmailAddress;

            // Customer Order Email Template
            string customerSubjectEmail = Localization.GetString("CustomerStatusChangedEmailSubject", LocalResourceFile);
            string customerBodyEmail    = Localization.GetString("CustomerStatusChangedEmailBody", LocalResourceFile);

            // Extract or remove IFPAID token
            Match regPaidMatch = RegPaid.Match(customerBodyEmail);

            if (regPaidMatch.Success)
            {
                // If Status is Paid
                if (order.OrderStatusID == 7)
                {
                    // Replace IFPAID token by his content
                    string paidTemplate = regPaidMatch.Groups[1].ToString();
                    paidTemplate      = RegStripStartNewLine.Replace(paidTemplate, string.Empty);
                    paidTemplate      = RegStripEndNewLine.Replace(paidTemplate, string.Empty);
                    customerBodyEmail = RegPaid.Replace(customerBodyEmail, paidTemplate);
                }
                else // Remove IFPAID token
                {
                    customerBodyEmail = RegPaid.Replace(customerBodyEmail, string.Empty);
                }
            }

            // Admin Order Email Template
            string adminSubjectEmail = Localization.GetString("AdminStatusChangedEmailSubject", LocalResourceFile);
            string adminBodyEmail    = Localization.GetString("AdminStatusChangedEmailBody", LocalResourceFile);

            // Init Email Order Replacement Tokens
            EmailOrderTokenReplace tkEmailOrder = new EmailOrderTokenReplace
            {
                StoreSettings = StoreSettings,
                Order         = order
            };

            // Replace tokens
            customerSubjectEmail = tkEmailOrder.ReplaceEmailOrderTokens(customerSubjectEmail);
            customerBodyEmail    = tkEmailOrder.ReplaceEmailOrderTokens(customerBodyEmail);
            adminSubjectEmail    = tkEmailOrder.ReplaceEmailOrderTokens(adminSubjectEmail);
            adminBodyEmail       = tkEmailOrder.ReplaceEmailOrderTokens(adminBodyEmail);

            try
            {
                // Send Customer Email
                string result = Mail.SendMail(adminEmail, customerEmail, "", customerSubjectEmail, customerBodyEmail, "", HtmlUtils.IsHtml(customerBodyEmail) ? MailFormat.Html.ToString() : MailFormat.Text.ToString(), "", "", "", "");
                if (!string.IsNullOrEmpty(result))
                {
                    LogSMTPError(customerEmail, result);
                }

                // Send Store Admin Email
                result = Mail.SendMail(adminEmail, adminEmail, "", adminSubjectEmail, adminBodyEmail, "", HtmlUtils.IsHtml(adminBodyEmail) ? MailFormat.Html.ToString() : MailFormat.Text.ToString(), "", "", "", "");
                if (!string.IsNullOrEmpty(result))
                {
                    LogSMTPError(customerEmail, result);
                }
            }
            catch (Exception ex)
            {
                Exceptions.ProcessModuleLoadException(this, ex);
            }
        }
        protected virtual void GenerateOrderConfirmation()
        {
            OrderInfo order = CheckoutControl.Order;

            if (order != null)
            {
                // Store admin
                string adminDetailTemplate = string.Empty;
                bool   adminDetail         = false;
                // Customer
                string customerDetailTemplate = string.Empty;
                bool   customerDetail         = false;

                IAddressInfo billingAddress  = CheckoutControl.BillingAddress;
                IAddressInfo shippingAddress = CheckoutControl.ShippingAddress;

                // Get Customer Email
                string customerEmail = billingAddress.Email;

                // Get Admin Email
                string adminEmail = StoreSettings.DefaultEmailAddress;

                // Get Store Currency Symbol
                if (!string.IsNullOrEmpty(StoreSettings.CurrencySymbol))
                {
                    order.CurrencySymbol = StoreSettings.CurrencySymbol;
                }

                // Get Order Date Format
                string orderDateFormat = Localization.GetString("OrderDateFormat", LocalResourceFile);
                if (string.IsNullOrEmpty(orderDateFormat) == false)
                {
                    order.DateFormat = orderDateFormat;
                }

                // Customer Order Email Template
                string customerSubjectEmail    = Localization.GetString("CustomerOrderEmailSubject", LocalResourceFile);
                string customerBodyEmail       = Localization.GetString("CustomerOrderEmailBody", LocalResourceFile);
                string customerAddressTemplate = Localization.GetString("CustomerAddressTemplate", LocalResourceFile);

                // Extract Detail Order from Customer EmailTemplate
                Match regCustomerMatch = RegDetails.Match(customerBodyEmail);
                if (regCustomerMatch.Success)
                {
                    customerDetail         = true;
                    customerDetailTemplate = regCustomerMatch.Groups[1].ToString();
                    customerDetailTemplate = RegStripStartNewLine.Replace(customerDetailTemplate, string.Empty);
                    customerDetailTemplate = RegStripEndNewLine.Replace(customerDetailTemplate, string.Empty);
                }

                // Extract or remove IFDISCOUNT token
                Match regCustomerDiscountMatch = RegDiscount.Match(customerBodyEmail);
                if (regCustomerDiscountMatch.Success)
                {
                    if (order.CouponID != Null.NullInteger && order.Discount != Null.NullDecimal)
                    {
                        // Replace IFDISCOUNT token by his content
                        string discountTemplate = regCustomerDiscountMatch.Groups[1].ToString();
                        discountTemplate  = RegStripStartNewLine.Replace(discountTemplate, string.Empty);
                        discountTemplate  = RegStripEndNewLine.Replace(discountTemplate, string.Empty);
                        customerBodyEmail = RegDiscount.Replace(customerBodyEmail, discountTemplate);
                    }
                    else // Remove IFDISCOUNT token
                    {
                        customerBodyEmail = RegDiscount.Replace(customerBodyEmail, string.Empty);
                    }
                }

                // Extract or remove IFSHIPPINGCOST token
                Match regShippingCostMatch = RegShippingCost.Match(customerBodyEmail);
                if (regShippingCostMatch.Success)
                {
                    if (order.ShippingCost > 0)
                    {
                        // Replace IFSHIPPINGCOST token by his content
                        string shippingCostTemplate = regShippingCostMatch.Groups[1].ToString();
                        shippingCostTemplate = RegStripStartNewLine.Replace(shippingCostTemplate, string.Empty);
                        shippingCostTemplate = RegStripEndNewLine.Replace(shippingCostTemplate, string.Empty);
                        customerBodyEmail    = RegShippingCost.Replace(customerBodyEmail, shippingCostTemplate);
                    }
                    else // Remove IFSHIPPINGCOST token
                    {
                        customerBodyEmail = RegShippingCost.Replace(customerBodyEmail, string.Empty);
                    }
                }

                // Replace BillingAddress token (if present) by the the formated Billing Address
                if (customerBodyEmail.IndexOf("[BillingAddress]", StringComparison.InvariantCultureIgnoreCase) != Null.NullInteger)
                {
                    customerBodyEmail = customerBodyEmail.Replace("[BillingAddress]", billingAddress.Format(customerAddressTemplate));
                }

                // Extract or remove Shipping Address Template from Customer Email Template
                if (shippingAddress.AddressID != Null.NullInteger)
                {
                    // Remove Pickup Template
                    customerBodyEmail = RegPickup.Replace(customerBodyEmail, string.Empty);
                    // Replace Shipping Address Template
                    Match regShippingMatch = RegShipping.Match(customerBodyEmail);
                    if (regShippingMatch.Success)
                    {
                        string shippingTemplate = regShippingMatch.Groups[1].ToString();
                        shippingTemplate  = RegStripStartNewLine.Replace(shippingTemplate, string.Empty);
                        shippingTemplate  = RegStripEndNewLine.Replace(shippingTemplate, string.Empty);
                        customerBodyEmail = RegShipping.Replace(customerBodyEmail, shippingTemplate);
                    }

                    // Replace ShippingAddress token (if present) by the the formated Shipping Address
                    if (customerBodyEmail.IndexOf("[ShippingAddress]", StringComparison.InvariantCultureIgnoreCase) != Null.NullInteger)
                    {
                        customerBodyEmail = customerBodyEmail.Replace("[ShippingAddress]", shippingAddress.Format(customerAddressTemplate));
                    }
                }
                else
                {
                    // Remove Shipping Address Template
                    customerBodyEmail = RegShipping.Replace(customerBodyEmail, string.Empty);
                    // Replace Pickup Template
                    Match regPickupMatch = RegPickup.Match(customerBodyEmail);
                    if (regPickupMatch.Success)
                    {
                        string pickupTemplate = regPickupMatch.Groups[1].ToString();
                        pickupTemplate    = RegStripStartNewLine.Replace(pickupTemplate, string.Empty);
                        pickupTemplate    = RegStripEndNewLine.Replace(pickupTemplate, string.Empty);
                        customerBodyEmail = RegPickup.Replace(customerBodyEmail, pickupTemplate);
                    }
                }

                // Admin Order Email Template
                string adminSubjectEmail = Localization.GetString("AdminOrderEmailSubject", LocalResourceFile);
                string adminBodyEmail    = Localization.GetString("AdminOrderEmailBody", LocalResourceFile);

                // Extract Detail Order from Admin EmailTemplate
                Match regAdminMatch = RegDetails.Match(adminBodyEmail);
                if (regAdminMatch.Success)
                {
                    adminDetail         = true;
                    adminDetailTemplate = regAdminMatch.Groups[1].ToString();
                    adminDetailTemplate = RegStripStartNewLine.Replace(adminDetailTemplate, string.Empty);
                    adminDetailTemplate = RegStripEndNewLine.Replace(adminDetailTemplate, string.Empty);
                }

                // Extract or remove IFDISCOUNT token
                Match regAdminDiscountMatch = RegDiscount.Match(adminBodyEmail);
                if (regAdminDiscountMatch.Success)
                {
                    if (order.CouponID != Null.NullInteger && order.Discount != Null.NullDecimal)
                    {
                        // Replace IFDISCOUNT token by his content
                        string discountTemplate = regAdminDiscountMatch.Groups[1].ToString();
                        discountTemplate = RegStripStartNewLine.Replace(discountTemplate, string.Empty);
                        discountTemplate = RegStripEndNewLine.Replace(discountTemplate, string.Empty);
                        adminBodyEmail   = RegDiscount.Replace(adminBodyEmail, discountTemplate);
                    }
                    else // Remove IFDISCOUNT token
                    {
                        adminBodyEmail = RegDiscount.Replace(adminBodyEmail, string.Empty);
                    }
                }

                // Extract or remove IFSHIPPINGCOST token
                Match regAdminShippingCostMatch = RegShippingCost.Match(adminBodyEmail);
                if (regAdminShippingCostMatch.Success)
                {
                    if (order.ShippingCost > 0)
                    {
                        // Replace IFSHIPPINGCOST token by his content
                        string shippingCostTemplate = regAdminShippingCostMatch.Groups[1].ToString();
                        shippingCostTemplate = RegStripStartNewLine.Replace(shippingCostTemplate, string.Empty);
                        shippingCostTemplate = RegStripEndNewLine.Replace(shippingCostTemplate, string.Empty);
                        adminBodyEmail       = RegShippingCost.Replace(adminBodyEmail, shippingCostTemplate);
                    }
                    else // Remove IFSHIPPINGCOST token
                    {
                        adminBodyEmail = RegShippingCost.Replace(adminBodyEmail, string.Empty);
                    }
                }

                // Replace BillingAddress token (if present) by the the formated Billing Address
                if (adminBodyEmail.IndexOf("[BillingAddress]", StringComparison.InvariantCultureIgnoreCase) != Null.NullInteger)
                {
                    adminBodyEmail = adminBodyEmail.Replace("[BillingAddress]", billingAddress.Format(customerAddressTemplate));
                }

                // Extract or remove Shipping Address Template from Admin Email Template
                if (shippingAddress.AddressID != Null.NullInteger)
                {
                    // Remove Pickup Template
                    adminBodyEmail = RegPickup.Replace(adminBodyEmail, string.Empty);
                    // Replace Shipping Address Template
                    Match regShippingMatch = RegShipping.Match(adminBodyEmail);
                    if (regShippingMatch.Success)
                    {
                        string shippingTemplate = regShippingMatch.Groups[1].ToString();
                        shippingTemplate = RegStripStartNewLine.Replace(shippingTemplate, string.Empty);
                        shippingTemplate = RegStripEndNewLine.Replace(shippingTemplate, string.Empty);
                        adminBodyEmail   = RegShipping.Replace(adminBodyEmail, shippingTemplate);
                    }

                    // Replace ShippingAddress token (if present) by the the formated Shipping Address
                    if (adminBodyEmail.IndexOf("[ShippingAddress]", StringComparison.InvariantCultureIgnoreCase) != Null.NullInteger)
                    {
                        adminBodyEmail = adminBodyEmail.Replace("[ShippingAddress]", shippingAddress.Format(customerAddressTemplate));
                    }
                }
                else
                {
                    // Remove Shipping Address Template
                    adminBodyEmail = RegShipping.Replace(adminBodyEmail, string.Empty);
                    // Replace Pickup Template
                    Match regPickupMatch = RegPickup.Match(adminBodyEmail);
                    if (regPickupMatch.Success)
                    {
                        string pickupTemplate = regPickupMatch.Groups[1].ToString();
                        pickupTemplate = RegStripStartNewLine.Replace(pickupTemplate, string.Empty);
                        pickupTemplate = RegStripEndNewLine.Replace(pickupTemplate, string.Empty);
                        adminBodyEmail = RegShipping.Replace(adminBodyEmail, pickupTemplate);
                    }
                }

                // Init Email Order Replacement Tokens
                EmailOrderTokenReplace tkEmailOrder = new EmailOrderTokenReplace
                {
                    StoreSettings   = StoreSettings,
                    Order           = order,
                    BillingAddress  = billingAddress,
                    ShippingAddress = shippingAddress
                };

                // Replace tokens
                customerSubjectEmail = tkEmailOrder.ReplaceEmailOrderTokens(customerSubjectEmail);
                customerBodyEmail    = tkEmailOrder.ReplaceEmailOrderTokens(customerBodyEmail);
                adminSubjectEmail    = tkEmailOrder.ReplaceEmailOrderTokens(adminSubjectEmail);
                adminBodyEmail       = tkEmailOrder.ReplaceEmailOrderTokens(adminBodyEmail);

                // Order Details Template
                if (customerDetail || adminDetail)
                {
                    // Get Order Details
                    OrderController        orderController = new OrderController();
                    List <OrderDetailInfo> orderDetails    = orderController.GetOrderDetails(order.OrderID);
                    if (orderDetails != null)
                    {
                        // Update Stock Products if needed
                        if (StoreSettings.InventoryManagement)
                        {
                            DecreaseStock(orderDetails);
                        }

                        // Replace Order Detail Tokens
                        StringBuilder           customerDetailText = new StringBuilder();
                        StringBuilder           adminDetailText    = new StringBuilder();
                        OrderDetailTokenReplace tkOrderDetail      = new OrderDetailTokenReplace();

                        foreach (OrderDetailInfo detail in orderDetails)
                        {
                            tkOrderDetail.OrderDetail = detail;
                            if (customerDetail)
                            {
                                customerDetailText.AppendLine(tkOrderDetail.ReplaceOrderDetailTokens(customerDetailTemplate));
                            }
                            if (adminDetail)
                            {
                                adminDetailText.AppendLine(tkOrderDetail.ReplaceOrderDetailTokens(adminDetailTemplate));
                            }
                        }
                        if (customerDetail)
                        {
                            customerBodyEmail = RegDetails.Replace(customerBodyEmail, RegStripEndNewLine.Replace(customerDetailText.ToString(), string.Empty));
                        }
                        if (adminDetail)
                        {
                            adminBodyEmail = RegDetails.Replace(customerBodyEmail, RegStripEndNewLine.Replace(adminDetailText.ToString(), string.Empty));
                        }
                    }
                }

                try
                {
                    // Send Customer Email
                    string result = Mail.SendMail(adminEmail, customerEmail, "", customerSubjectEmail, customerBodyEmail, "", HtmlUtils.IsHtml(customerBodyEmail) ? MailFormat.Html.ToString() : MailFormat.Text.ToString(), "", "", "", "");
                    if (!string.IsNullOrEmpty(result))
                    {
                        LogSMTPError(customerEmail, result);
                    }

                    // Send Store Admin Email
                    result = Mail.SendMail(adminEmail, adminEmail, "", adminSubjectEmail, adminBodyEmail, "", HtmlUtils.IsHtml(adminBodyEmail) ? MailFormat.Html.ToString() : MailFormat.Text.ToString(), "", "", "", "");
                    if (!string.IsNullOrEmpty(result))
                    {
                        LogSMTPError(customerEmail, result);
                    }
                }
                catch (Exception ex)
                {
                    Exceptions.ProcessModuleLoadException(this, ex);
                }
            }
        }