Order Confirmation Email

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
14 years ago
What about changing the order confirmation email to the customer and store owner so that it includes a replica of an invoice showing all order details, addresses, billing and shipping, all products ordered and quantities, totals, shipping, tax, etc.?

Thanks,

Larry
14 years ago
To my knowledge its on the road map.
14 years ago
To test this basic functionality in v1.11 you can add the following code to the body of the 'order confirmation' email message template:

%Order.Product(s)%

Its very basic, just product name/amount/price
no totals, no VAT etc.
14 years ago
alter/change the following to the /libraries/Nop.Common/Messages/MessageManager.cs

Line 159 REPLACE HTML table with:

/// <summary>
/// Convert a collection to a HTML table
/// </summary>
/// <param name="table">Order product variant collection</param>
/// <param name="CusSubTotal">Subtotal order customer costr</param>
/// <param name="CusTaxTotal">Taxtotal customercost</param>
/// <param name="CusTotal">total customer cost</param>
/// <param name="CusShipTotal">Shipping customer cost</param>
/// <param name="LanguageID">Language identifier</param>
/// <returns>HTML table of products</returns>
private static string ProductListToHtmlTable(OrderProductVariantCollection table, string CusSubTotal, string CusTaxTotal, string CusTotal, string CusShipTotal, int LanguageID)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("<table class=\"table\" border=\"0\" style=\"border:1px solid grey;padding:2px;border-collapse:collapse;\"><thead><tr>");

            sb.AppendLine("<th class=\"header\" style=\"text-align:left;\">" + LocalizationManager.GetLocaleResourceString("Order.ProductsGrid.Name", LanguageID) + "</th>");
            sb.AppendLine("<th class=\"header\" style=\"text-align:right;\">" + LocalizationManager.GetLocaleResourceString("Order.ProductsGrid.Quantity", LanguageID) + "</th>");
            sb.AppendLine("<th class=\"header\" style=\"text-align:right;\">" + LocalizationManager.GetLocaleResourceString("Order.ProductsGrid.Price", LanguageID) + "</th>");
            sb.AppendLine("</tr></thead><tbody>");

            for (int i = 0; i <= table.Count - 1; i++)
            {
                sb.AppendLine("<tr>");
                //TODO add attributes description table[i].AttributeDescription                
                sb.AppendLine("<td class=\"row\" style=\"text-align:left;\">" + table[i].ProductVariant.FullProductName + "</td>");
                sb.AppendLine("<td class=\"row\" style=\"text-align:right;\">" + table[i].Quantity + "</td>");
                sb.AppendLine("<td class=\"row\" style=\"text-align:right;\">" + table[i].PriceInCustomerCurrency + "</td>");
                sb.AppendLine("</tr>");              
            }
            sb.AppendLine("<tr><td style=\"text-align:right;border-top:1px solid grey;\" colspan=\"2\"><strong>" + LocalizationManager.GetLocaleResourceString("Order.Sub-Total", LanguageID) + "</strong></td> <td style=\"text-align:right;\"><strong>" + CusSubTotal + "</strong></td></tr>");
            sb.AppendLine("<tr><td style=\"text-align:right;\" colspan=\"2\"><strong>" + LocalizationManager.GetLocaleResourceString("Order.Tax", LanguageID) + "</strong></td> <td style=\"text-align:right;\"><strong>" + CusTaxTotal + "</strong></td></tr>");
            sb.AppendLine("<tr><td style=\"text-align:right;\" colspan=\"2\"><strong>" + LocalizationManager.GetLocaleResourceString("Order.Shipping", LanguageID) + "</strong></td> <td style=\"text-align:right;\"><strong>" + CusShipTotal + "</strong></td></tr>");
            sb.AppendLine("<tr><td style=\"text-align:right;border-bottom:1px solid grey;\" colspan=\"2\"><strong>" + LocalizationManager.GetLocaleResourceString("Order.OrderTotal", LanguageID) + "</strong></td> <td style=\"text-align:right;\"><strong>" + CusTotal + "</strong></td></tr>");
            sb.AppendLine("</tbody></table>");
            return sb.ToString();
}



Then line 840 ALTER/CHANGE:
tokens.Add("Order.Product(s)", ProductListToHtmlTable(order.OrderProductVariants,LanguageID));


TO:


string CusSubTotal = string.Format("{0} ({1})", order.OrderSubtotalInCustomerCurrency.ToString("N"), order.CustomerCurrencyCode);
string CusTaxTotal = string.Format("{0} ({1})", order.OrderTaxInCustomerCurrency.ToString("N"), order.CustomerCurrencyCode);
string CusTotal = string.Format("{0} ({1})", order.OrderTotalInCustomerCurrency.ToString("N"), order.CustomerCurrencyCode);
string CusShipTotal = string.Format("{0} ({1})", order.OrderShippingInCustomerCurrency.ToString("N"), order.CustomerCurrencyCode);
tokens.Add("Order.Product(s)", ProductListToHtmlTable(order.OrderProductVariants, CusSubTotal, CusTaxTotal, CusTotal, CusShipTotal, LanguageID));



then rebuild Nop.Common

In admin go to: Content Management > Templates > Message templates and alter OrderPlaced.CustomerNotification message and add

Order:
%Order.Product(s)%

to the message body.
14 years ago
Any chance I could also implement this code change in nopcommercenosource? Just adding "%Order.Product(s)%" to the message template does not seem to work.
Help will be much appreciated with this
Silvia
14 years ago
This seems to have changed slightly with v1.3. Here is the code to add instead which also displays the discounted amount.


        /// <summary>
        /// Convert a collection to a HTML table
        /// </summary>
        /// <param name="table">Order product variant collection</param>
        /// <param name="CusSubTotal">Subtotal order customer costr</param>
        /// <param name="CusTaxTotal">Taxtotal customercost</param>
        /// <param name="CusTotal">total customer cost</param>
        /// <param name="CusShipTotal">Shipping customer cost</param>
        /// <param name="LanguageID">Language identifier</param>
        /// <returns>HTML table of products</returns>
        private static string ProductListToHtmlTable(OrderProductVariantCollection table, string CusDiscount, string CusSubTotal, string CusTaxTotal, string CusTotal, string CusShipTotal, int LanguageID)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("<table class=\"table\" border=\"0\" style=\"border:1px solid grey;padding:2px;border-collapse:collapse;\"><thead><tr>");

            sb.AppendLine("<th class=\"header\" style=\"text-align:left;\">" + LocalizationManager.GetLocaleResourceString("Order.ProductsGrid.Name", LanguageID) + "</th>");
            sb.AppendLine("<th class=\"header\" style=\"text-align:right;\">" + LocalizationManager.GetLocaleResourceString("Order.ProductsGrid.Quantity", LanguageID) + "</th>");
            sb.AppendLine("<th class=\"header\" style=\"text-align:right;\">" + LocalizationManager.GetLocaleResourceString("Order.ProductsGrid.Price", LanguageID) + "</th>");
            
            sb.AppendLine("</tr></thead><tbody>");
            
            Language language = LanguageManager.GetLanguageByID(LanguageID);
            if (language == null)
                language = NopContext.Current.WorkingLanguage;

            for (int i = 0; i <= table.Count - 1; i++)
            {
                sb.AppendLine("<tr>");
                //TODO add attributes description table[i].AttributeDescription    
                //add encoded text box attribute
                sb.AppendLine("<td class=\"row\">" + table[i].ProductVariant.FullProductName + "</td>");
                sb.AppendLine("<td class=\"row\">" + table[i].Quantity + "</td>");

                Order order = table[i].Order;
                string priceStr = string.Empty;
                switch (order.CustomerTaxDisplayType)
                {
                    case TaxDisplayTypeEnum.ExcludingTax:
                        priceStr = PriceHelper.FormatPrice(table[i].PriceExclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, language, false);
                        break;
                    case TaxDisplayTypeEnum.IncludingTax:
                        priceStr = PriceHelper.FormatPrice(table[i].PriceInclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, language, true);
                        break;
                }
                sb.AppendLine("<td class=\"row\">" + priceStr + "</td>");
                sb.AppendLine("</tr>");
            }
            sb.AppendLine("<br />");
            sb.AppendLine("<tr><td style=\"text-align:right;border-top:1px solid grey;\" colspan=\"2\"><strong>" + LocalizationManager.GetLocaleResourceString("Products.DiscountAmount", LanguageID) + "</strong></td> <td style=\"text-align:right;\"><strong>" + CusDiscount + "</strong></td></tr>");
            sb.AppendLine("<tr><td style=\"text-align:right;\" colspan=\"2\"><strong>" + LocalizationManager.GetLocaleResourceString("Order.Sub-Total", LanguageID) + "</strong></td> <td style=\"text-align:right;\"><strong>" + CusSubTotal + "</strong></td></tr>");
            sb.AppendLine("<tr><td style=\"text-align:right;border-top:1px solid grey;\" colspan=\"2\"><strong>" + LocalizationManager.GetLocaleResourceString("Order.Tax", LanguageID) + "</strong></td> <td style=\"text-align:right;\"><strong>" + CusTaxTotal + "</strong></td></tr>");
            sb.AppendLine("<tr><td style=\"text-align:right;border-bottom:1px solid grey\" colspan=\"2\"><strong>" + LocalizationManager.GetLocaleResourceString("Order.Shipping", LanguageID) + "</strong></td> <td style=\"text-align:right;\"><strong>" + CusShipTotal + "</strong></td></tr>");
            sb.AppendLine("<tr><td style=\"text-align:right;border-bottom:1px solid grey;\" colspan=\"2\"><strong>" + LocalizationManager.GetLocaleResourceString("Order.OrderTotal", LanguageID) + "</strong></td> <td style=\"text-align:right;\"><strong>" + CusTotal + "</strong></td></tr>");
            sb.AppendLine("</tbody></table>");
            return sb.ToString();
        }


And


string CusDiscount = string.Format("{0} ({1})", order.OrderDiscount.ToString("N"), order.CustomerCurrencyCode);
            string CusSubTotal = string.Format("{0} ({1})", order.OrderSubtotalExclTaxInCustomerCurrency.ToString("N"), order.CustomerCurrencyCode);            
            string CusTaxTotal = string.Format("{0} ({1})", order.OrderTaxInCustomerCurrency.ToString("N"), order.CustomerCurrencyCode);
            string CusTotal = string.Format("{0} ({1})", order.OrderTotalInCustomerCurrency.ToString("N"), order.CustomerCurrencyCode);
            string CusShipTotal = string.Format("{0} ({1})", order.OrderShippingExclTaxInCustomerCurrency.ToString("N"), order.CustomerCurrencyCode);
            tokens.Add("Order.Product(s)", ProductListToHtmlTable(order.OrderProductVariants, CusDiscount, CusSubTotal, CusTaxTotal, CusTotal, CusShipTotal, LanguageID));
14 years ago
And here is our version:

        /// <summary>
        /// Convert a collection to a HTML table
        /// </summary>
        /// <param name="order">Order</param>
        /// <param name="LanguageID">Language identifier</param>
        /// <returns>HTML table of products</returns>
        private static string ProductListToHtmlTable(Order order, int LanguageID)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("<table class=\"table\" border=\"0\" style=\"border:1px solid grey;padding:2px;border-collapse:collapse;\"><thead><tr>");

            sb.AppendLine("<th class=\"header\" style=\"text-align:left;\">" + LocalizationManager.GetLocaleResourceString("Order.ProductsGrid.Name", LanguageID) + "</th>");
            sb.AppendLine("<th class=\"header\" style=\"text-align:right;\">" + LocalizationManager.GetLocaleResourceString("Order.ProductsGrid.Price", LanguageID) + "</th>");
            sb.AppendLine("<th class=\"header\" style=\"text-align:right;\">" + LocalizationManager.GetLocaleResourceString("Order.ProductsGrid.Quantity", LanguageID) + "</th>");
            sb.AppendLine("<th class=\"header\" style=\"text-align:right;\">" + LocalizationManager.GetLocaleResourceString("Order.ProductsGrid.Total", LanguageID) + "</th>");

            sb.AppendLine("</tr></thead><tbody>");

            Language language = LanguageManager.GetLanguageByID(LanguageID);
            if (language == null)
                language = NopContext.Current.WorkingLanguage;

            OrderProductVariantCollection table = order.OrderProductVariants;
            for (int i = 0; i <= table.Count - 1; i++)
            {
                sb.AppendLine("<tr>");

                sb.AppendLine("<td class=\"row\">" + table[i].ProductVariant.FullProductName);
                if (!String.IsNullOrEmpty(table[i].AttributeDescription))
                {
                    sb.AppendLine("<br />");
                    sb.AppendLine(table[i].AttributeDescription);
                }
                if (!String.IsNullOrEmpty(table[i].TextOption))
                {
                    sb.AppendLine("<br />");
                    sb.AppendLine(table[i].TextOption);
                }
                sb.AppendLine("</td>");

                string priceStr = string.Empty;
                switch (order.CustomerTaxDisplayType)
                {
                    case TaxDisplayTypeEnum.ExcludingTax:
                        priceStr = PriceHelper.FormatPrice(table[i].PriceExclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, language, false);
                        break;
                    case TaxDisplayTypeEnum.IncludingTax:
                        priceStr = PriceHelper.FormatPrice(table[i].PriceInclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, language, true);
                        break;
                }
                sb.AppendLine("<td class=\"row\">" + priceStr + "</td>");

                sb.AppendLine("<td class=\"row\">" + table[i].Quantity + "</td>");

                string priceTotalStr = string.Empty;
                switch (order.CustomerTaxDisplayType)
                {
                    case TaxDisplayTypeEnum.ExcludingTax:
                        priceTotalStr = PriceHelper.FormatPrice(table[i].PriceExclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, language, false);
                        break;
                    case TaxDisplayTypeEnum.IncludingTax:
                        priceTotalStr = PriceHelper.FormatPrice(table[i].PriceInclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, language, true);
                        break;
                }
                sb.AppendLine("<td class=\"row\">" + priceTotalStr + "</td>");
                
                sb.AppendLine("</tr>");
            }
            sb.AppendLine("<br />");
            
            //totals
            string CusSubTotal = string.Empty;
            string CusShipTotal = string.Empty;
            string CusPaymentMethodAdditionalFee = string.Empty;
            string CusTaxTotal = string.Empty;
            string CusTotal = string.Empty;
            switch (order.CustomerTaxDisplayType)
            {
                case TaxDisplayTypeEnum.ExcludingTax:
                    {
                        CusSubTotal = PriceHelper.FormatPrice(order.OrderSubtotalExclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, language, false);
                        CusShipTotal = PriceHelper.FormatShippingPrice(order.OrderShippingExclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, language, false);
                        CusPaymentMethodAdditionalFee = PriceHelper.FormatPaymentMethodAdditionalFee(order.PaymentMethodAdditionalFeeExclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, language, false);
                    }
                    break;
                case TaxDisplayTypeEnum.IncludingTax:
                    {
                        CusSubTotal = PriceHelper.FormatPrice(order.OrderSubtotalInclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, language, true);
                        CusShipTotal = PriceHelper.FormatShippingPrice(order.OrderShippingInclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, language, true);
                        CusPaymentMethodAdditionalFee = PriceHelper.FormatPaymentMethodAdditionalFee(order.PaymentMethodAdditionalFeeInclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, language, true);
                    }
                    break;
            }

            bool dislayShipping = order.ShippingStatus != ShippingStatusEnum.ShippingNotRequired;

            bool displayPaymentMethodFee = true;
            if (order.PaymentMethodAdditionalFeeExclTaxInCustomerCurrency == decimal.Zero)
            {
                displayPaymentMethodFee = false;
            }

            bool displayTax = true;
            if (TaxManager.HideTaxInOrderSummary && order.CustomerTaxDisplayType == TaxDisplayTypeEnum.IncludingTax)
            {
                displayTax = false;
            }
            else
            {
                if (order.OrderTax == 0 && TaxManager.HideZeroTax)
                {
                    displayTax = false;
                }
                else
                {
                    CusTaxTotal = string.Format("{0} ({1})", order.OrderTaxInCustomerCurrency.ToString("N"), order.CustomerCurrencyCode);
                }
            }

            CusTotal = string.Format("{0} ({1})", order.OrderTotalInCustomerCurrency.ToString("N"), order.CustomerCurrencyCode);

            sb.AppendLine("<tr><td style=\"text-align:right;\" colspan=\"2\"><strong>" + LocalizationManager.GetLocaleResourceString("Order.Sub-Total", LanguageID) + "</strong></td> <td style=\"text-align:right;\"><strong>" + CusSubTotal + "</strong></td></tr>");
            if (dislayShipping)
            {
                sb.AppendLine("<tr><td style=\"text-align:right;\" colspan=\"2\"><strong>" + LocalizationManager.GetLocaleResourceString("Order.Shipping", LanguageID) + "</strong></td> <td style=\"text-align:right;\"><strong>" + CusShipTotal + "</strong></td></tr>");
            }
            if (displayTax)
            {
                sb.AppendLine("<tr><td style=\"text-align:right;\" colspan=\"2\"><strong>" + LocalizationManager.GetLocaleResourceString("Order.Tax", LanguageID) + "</strong></td> <td style=\"text-align:right;\"><strong>" + CusTaxTotal + "</strong></td></tr>");
            }
            if (displayPaymentMethodFee)
            {
                sb.AppendLine("<tr><td style=\"text-align:right;\" colspan=\"2\"><strong>" + LocalizationManager.GetLocaleResourceString("Order.PaymentMethodAdditionalFee", LanguageID) + "</strong></td> <td style=\"text-align:right;\"><strong>" + CusPaymentMethodAdditionalFee + "</strong></td></tr>");
            }
            sb.AppendLine("<tr><td style=\"text-align:right;\" colspan=\"2\"><strong>" + LocalizationManager.GetLocaleResourceString("Order.OrderTotal", LanguageID) + "</strong></td> <td style=\"text-align:right;\"><strong>" + CusTotal + "</strong></td></tr>");
            sb.AppendLine("</tbody></table>");
            return sb.ToString();
        }
14 years ago
This is probably a dumb question, but where is this file located?  I don't see a directory or sub titled "libraries".
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.