update permission of Frontend folder

 update permision of Frontaend folder 



site > right click you site > Edit Permissiions > select site name from list > edit 



or if still happens the error check web.config

 <features>
                <feature name="EditWebsiteDomains" enabled="true" />
                <feature name="DebugErpRequest" enabled="true" />
                <feature name="ManageAddons" enabled="true" />
                <feature name="UploadAddons" enabled="false" />
                <feature name="ManageDesignPacks" enabled="false" />
                <feature name="UploadDesignPacks" enabled="false" />
                <feature name="ManageLanguagePacks" enabled="true" />
                <feature name="UploadLanguagePacks" enabled="true" />
                <feature name="ManageAdminLanguagePacks" enabled="true" />
            </features>
        </sanaCommerce>


sometime the pipeline reset the permission of the Frontend folder which leads to this kind if issues.


Sana Popup cancel and continue

 



_templateDetails.cshtml
<td class="text-center delete-btn">
                <a class="hyp hyp-remove btn-delete-icon" data-src="@CurrentView.Url.Action("Remove")">                  
                    @CurrentView.Sana.SimpleText("")
                </a>
            </td>

page.ordertemplate.js

// Ticket 79482: [Wave 2] 3.7.1.EDITABLE QUICK ORDERING TEMPLATES
    // Remove item/s form Template details page.
    $(document).on("click""#orderTemplateDetailsPage .hyp-remove"function (event) {       
        event.preventDefault();
 
        templateToDealte = "";
        templateToClarCashe = "";
        deletedRow = "";
 
        var dataToDelete = {},
            $row = $(this).closest('tr');
 
        dataToDelete.src = $(this).attr('data-src');
        dataToDelete.product = $row.attr('data-templatelineid');
        dataToDelete.basket = $row.attr('data-basketid');
 
        ($row.hasClass('row-header'? $row.nextUntil('.upper-row': $row)
            .find('input[type=text]')
            .prop('disabled''true');
 
        deletedRow = $row;
        templateToDealte = dataToDelete.product;
        templateToClarCashe = dataToDelete.basket;
 
        Sana.OrderTemplateItemDeletePopup.open();
 
    });


When User click OK button 

_templateDetails.cshtml ()

<div id="deleteOrderTemplateItemPopup" class="text-center" style="displaynone;">
                            <div id="deleteOrderTemplateItemBody" class="popup-cnt">
                                <div class="cnt-column">
                                    <h2> @Sana.SimpleText("TemplateItem_Delete_Warning_Header""Warning")</h2>
                                    <p>@Sana.SimpleText("TemplateItem_Delete_Warning_Message""TemplateItem Delete Warning Message")</p>
                                </div>
                                <div class="ftr-column">
                                    <button class="btn-cancel btn btn-close-dialog btn-small btn-cancel-color">
                                        @Sana.SimpleText("ButtonText_Cancel")
                                    </button>
                                    <button id="confirmItemDelete" class="btn btn-small">@Sana.SimpleText("OK""OK")</button>
                                </div>
                            </div>
                        </div>

page.ordertemplatedetails.js

// Ticket 79482: [Wave 2] 3.7.1.EDITABLE QUICK ORDERING TEMPLATES
    // When Click delete Order TemplateItem Popup's Ok button Call controller method.
    $(document).on("click""#deleteOrderTemplateItemPopup #confirmItemDelete"function (event) {
 
        event.preventDefault();
 
        $.ajax({
            type: "POST",
            url: '/profile/ordertemplates/deleteline',
            data: JSON.stringify({ lineId: templateToDealte, basketId: templateToClarCashe }),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (data) {
                if (data.success && deletedRow && deletedRow !== "") {
                    deletedRow.remove();
                    $(deletedRow).closest('inner-row').remove();
                }
                $('#deleteOrderTemplateItemPopup').dialog("close");
 
                templateToDealte = "";
                templateToClarCashe = "";
                deletedRow = "";
 
                var rows = $('.gvi-order-details >  tbody > tr');
 
                $.map(rows, function (row) {
                    if ($(row).hasClass('collapsiblePanel-title')) {
                        var nextRow = $(row).next();
                        if ($(nextRow).length === 0 || $(nextRow).hasClass('collapsiblePanel-title')) {
                            $(row).closest('tr.collapsiblePanel-title').remove();
                        }
                    }
                });
            }
        });
    });


ExtendedOrderTemplatesController

public class ExtendedOrderTemplatesController : OrderTemplatesController
 {
  protected override void RegisterSystemRoutes(SanaRouteCollection routes)
   {
    routes.MapActionRoute(controller: Name, action: "DeleteTemplateLine", urlPath: "profile/ordertemplates/deleteline");
    

ExtendedOrderTemplatesController

// Ticket 79482: [Wave 2] 3.7.1. EDITABLE QUICK ORDERING TEMPLATES
        /// <summary>
        /// This method will delete template line
        /// use page.ordertemplatedetails.js
        /// </summary>
        /// <param name="deleteItem">DeleteItemModel</param>
        /// <returns></returns>
        [HttpPost]
        [ValidateInput(false)]
        [RequireAbility(AbilityTo.SaveOrderTemplate)]
        public virtual ActionResult DeleteTemplateLine(DeleteItemModel deleteItem)
        {
            if (deleteItem != null)
            {
                ((ExtendedOrderTemplatesApi)ShopApi.OrderTemplates).RemoveTemplateLine(deleteItem.lineId, deleteItem.basketId);
 
                return Json(new { success = true, responseText = "" }, JsonRequestBehavior.AllowGet);
            }
            return Json(new { success = false, responseText = "" }, JsonRequestBehavior.AllowGet);
        }









Change Date format

Project : Tallahesse914 GIT 

https://sanacommerce.visualstudio.com/Sana%20Projects/_workitems/edit/77068

update the culture  

public static class CustomHtmlExtensions
    {
        /// <summary>
        /// Converts the .NET date format to jQuery UI date format.
        /// If <paramref name="dateFormat"/> is not specified, the format from the current culture is used.
        /// </summary>
        /// <param name="htmlHelper">The HTML helper.</param>
        /// <param name="dateFormat">The .NET date format.</param>
        /// <returns>Returns the date format used by jQuery UI.</returns>
        /// 77068-Delete duplicate products & Date format
        public static string GetCustomJQueryUIDateFormat(this HtmlHelper htmlHelper, string dateFormat = null)
        {
            //switch the date format from US to AUS format (Date / Month/ Year)
            System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo("en-AU");
 
            if (dateFormat == null)
                dateFormat = System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortDatePattern;
 
            dateFormat = dateFormat.Replace("dddd""DD").Replace("ddd""D");
 
            if (dateFormat.Contains("MMMM"))
                dateFormat = dateFormat.Replace("MMMM""MM");
            else if (dateFormat.Contains("MMM"))
                dateFormat = dateFormat.Replace("MMM""M");
            else if (dateFormat.Contains("MM"))
                dateFormat = dateFormat.Replace("MM""mm");
            else
                dateFormat = dateFormat.Replace("M""m");
 
            return dateFormat.Contains("yyyy"? dateFormat.Replace("yyyy""yy": dateFormat.Replace("yy""y");
        }
    }


Inputs.cshtml  /Sana.Commerce.Startersite/Views/Default/Helpers/Inputs.cshtml

@helper DatePicker(IDictionary<stringobject> htmlAttributes)
{
    htmlAttributes["class"= (htmlAttributes.GetOrDefault("class"+ " datepicker").Trim();
    var obj = new { dateFormat = CurrentView.Html.GetCustomJQueryUIDateFormat(), firstDay = htmlAttributes.GetOrDefault("firstDay") };


This will update always when using Date pickers 

public class ExtendedRequestInitializer : RequestInitializer
    {
        protected override void SetLanguage(ShopContext shopContext, int languageId)
        {            
            shopContext.CommerceContext.LanguageId = languageId;
            var cultureInfo = CultureInfo.GetCultureInfo(languageId);
            //Thread.CurrentThread.CurrentCulture = cultureInfo;
            //Thread.CurrentThread.CurrentUICulture = cultureInfo;

            // Ticket 77068: Delete duplicate products & Date format
            Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo("en-AU");
            Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo("en-AU");
        }
    }



Order details page 

public class ExtendedOrdersController : OrdersController
    {       
        protected override dynamic CreateOrderListJsonItem(IOrder order, OrderListFilterInputModel filter, string returnUrl = null)
        {
            var val = base.CreateOrderListJsonItem(order, filter, returnUrl);
 
            // Ticket 77068: Delete duplicate products & Date format
            // Date formate has been Changed to "dd/MM/yyyy"
            val.DocumentDate = order.DocumentDate.GetValueOrDefault(order.OrderDate).ToString("dd/MM/yyyy");
            return val;
        }
    }


_Lines

@helper SimpleProductLine(SimpleProductLine productLine, bool showLineDiscounts, bool showUnitOfMeasure, bool showShippingStatus)
{
    var line = (IOrderLine)productLine.SalesLine;
    var isCancelled = Model.Order.Status == OrderStatus.Cancelled || line.IsCancelled;
    <tr class="upper-row row-simple-product @When(isCancelled, "order-line-cancelled")">
        <td>@line.ProductId</td>
        <td>
            <span class="product-title font-bigger">@line.ProductTitle</span>
        </td>
        @{
            var shipmentDate = line.ShipmentDate.GetValueOrDefault().ToString("dd/MM/yyyy");
        }
 
        @When(showShippingStatus, @<td>@ShippingStatus(line)</td>)
        @When(!Shop.IsB2cCustomer, @<td>@shipmentDate</td>)
        @When(Model.ShowPrices, @<td class="col-price">@line.Price.FormatAsPrice(Model.Order.CurrencyId)</td>)


Details.cshtml

@using Sana.Commerce
@{
    var order = Model.Order;
 
    Layout = LayoutPaths.Profile;
    PageInfo.Title = (order.DocumentId.AsHtml(encode: true+ " " + Sana.SimpleText("OrderType_" + order.OrderType.Value.ToString())).AsHtml();
    ViewBag.PageKey = order.OrderType == OrderType.Quote ? "Quotes" : "Orders";
    bool orderOrQuote = order.DocumentType == "Order" || order.DocumentType == "Quote";
    var customerType = ShopApi.UserState.GetCustomerType(Shop);
 
    var shipmentDate = order.ShipmentDate.HasValue ? order.ShipmentDate.GetValueOrDefault().ToString("dd/MM/yyyy") : null;
    var requestedDeliveryDate = order.RequestedDeliveryDate.HasValue ? order.RequestedDeliveryDate.GetValueOrDefault().ToString("dd/MM/yyyy") : null;
    var promisedDeliveryDate = order.PromisedDeliveryDate.HasValue ? order.PromisedDeliveryDate.GetValueOrDefault().ToString("dd/MM/yyyy") : null;
    var orderDate = order.OrderDate.ToString("dd/MM/yyyy");
    var documentDate = order.DocumentDate.HasValue ? order.DocumentDate.GetValueOrDefault().ToString("dd/MM/yyyy") : null;
    var dueDate = order.DueDate.HasValue ? order.DueDate.GetValueOrDefault().ToString("dd/MM/yyyy") : null;
    var paymentDiscountDate = order.PaymentDiscountDate.HasValue ? order.PaymentDiscountDate.GetValueOrDefault().ToString("dd/MM/yyyy": null;
  
var leftProperties = new List<Prop>
{
        Prop.ForAll("OrderNumber", orderOrQuote ? order.DocumentId : order.OriginalOrderId),
        Prop.ForAll("ShippingStatus", Shop.Settings.IsOrderShippingStatusVisible(customerType) ? ShippingStatus(order) : null),
        Prop.ForAll("OrderDetail_ShippingMethod", order.ShippingMethodName.Or(null)),
        Prop.ForAll("OrderDetail_ShippingTrackingLink", Html.TrackingLinkOrNumber(order).Or(null)),
        Prop.ForB2B("ShipmentDate"shipmentDate), // order.ShipmentDate.ToShortDateString()
        Prop.ForB2B("OrderDetail_LocationCode", order.LocationCode),
        Prop.ForB2B("RequestedDeliveryDate"order.RequestedDeliveryDate.ToShortDateString().Or(null)),
        Prop.ForB2B("OrderDetail_PromisedDeliveryDate"order.PromisedDeliveryDate.ToShortDateString().Or(null)),
        Prop.ForB2B("OrderDetail_SalesPersonCode", order.SalesPerson.Or(order.SalesPersonId).Or(null)),
        Prop.ForB2B("OrderDetail_SellToContact", order.Contact.Or(order.ContactId)),
        Prop.ForB2B("ReferenceNumber", order.ReferenceNo.Or(null)),
        Prop.ForB2B("Comments", Html.NewLinesToHtmlBreaks(order.Comment)),
};


OrderTemplates.cshtml






@foreach (var template in Model.Templates)
                        {
                            <tr>
                                <td class="cell-check-box text-center">
                                    <label>
                                        <span class="chb"><input name="templateIds" type="checkbox" value="@template.Basket.Id" data-bind="checked: checkedValues" /><ins><!----></ins></span>
                                    </label>
                                </td>
                                <td>
                                    <a class="font-title" data-bind="click: openTemplate" data-id="@template.Basket.Id">@template.Basket.Name</a>
                                </td>
                                <td>@template.Basket.CreatedDate.ToString("dd/MM/yyyy")</td>
                            </



---------------------------------------------------------------------------------

if we receiving a casting problem when the user change language 

borsig


protected override void FillSalesLineProperties(TypedValueDictionary fields, ISalesLine salesLine)
        {
            //----- above code remove for clearance ----- 
 
            // Fixing DeliveryDate casting issue.
            //fields.ReadDate("Deliverydate").GetValueOrDefault();
            Date DeliveryDate = Date.Empty;
            var dateString = fields.ReadString("Deliverydate");  
            if (!dateString.IsNullOrWhiteSpace())
            {
                var date = DateTime.Parse(dateString, new CultureInfo("en-US"true));
                DeliveryDate = new Date(date);               
 
 
            }


convert dateTime to Sana .Date 

var date = DateTime.Parse(dateString, new CultureInfo("en-US"true));
Sana.Date DeliveryDate = new Date(date);





Configure Multiple Web store on (Live)

Check list need to get from customer side

1)Webshop ID 

2)Webshop URL (Live)

3)ERP webservice URL + credentials in case different from current one (beta and live)

4)Admin e-mail address of the live web shop URL (in order for the SSL certificate to be ordered by Sana hosting) 

email should have the following format.


double check user already maped the server details form their side 

 Verify whether url pointed to our server

Hi xxx, 

Thanks for the information,

It seems the live URL (www.wahlnl.store) is not mapped with our server,

could you please map the DNS of live URL to our server IP: <This is hosted ip 51.5.145.193.>

--------------------
eg wahl-beta.sanastores.net
 if u dont know the IP address , just log to server by RDP, and on brower type "whats my ip" 


1.Request license if not already created

Refer to the Configure Multiple Web store on (Beta) for more details


2.Request Certificate for the new webshop 

https://sanacommerce.visualstudio.com/Sana%20Hosting/_dashboards/dashboard/8dc80a0e-5113-49a4-bc3b-d813559d7d73

created ticket for New SSL Certificate for Champion Power Equipment.

https://sanacommerce.visualstudio.com/Sana%20Hosting/_workitems/edit/77686?src=WorkItemMention&src-action=artifact_link


Ravensburger CH: https://sanacommerce.visualstudio.com/Sana%20Hosting/_workitems/edit/107575


3. Create a new webshop 

eg: ChampionPowerCALive

 When you created a new webshop it required to have an NT popup because the site needs to be tested before granting access to the public users. (to Show NT popup Anonymous Authentication need to be Disabled).

 When we want to add a new webshop to Live, we do not directly bind the website URL to exist Live Web site (as we do in Beta sites).  we create the new webshop separately.


1.Authentication
2. Current Live Website

3.Newly created web site for With NT Popup



because IIS only provides one Authentication configuration (NT Popup) per site. (it does not support multiple NT Popup even we bind to different hostnames for one web site)

if the current shop is already on Live, Then its Anonymous Authentication is Enabled (NT popup is been disabled ).

As a solution for this, we create a new Webshop on IIS (ChampionPowerCALiveand set it's NT popup Enabled. to enable the NT Popup, we set as following (Image: 3.Newly created web site for With NT Popup)

Anonymous Authentication - Disable 

Basic Auth - Enabled.


 4. Add new licenses to the Live environment.

 add to bin folder/ backup old and 

Task service folder.


5. Select new SSL certificate

right click your Live site > site Binding > Edit > SSL certificate > select the correct / new license file.

 




if the certificate not installed correctly, it will show as following 








6. Run the script and add new web store to live > restart a pool





7. Need to change the app pool of the newly created site

for this example, we set  "ChampionPowerCALive" to the Original Live site app pool.

web site ChampionPowerLive and ChampionPowerCALive both use ChampionPowerLive app pool

else it will get an error on the new webshop.




8. Then go to the new webshop and the popup need to be displayed.

 



9.Bind after testing

after testing, we don't need an additional webshop with NT popup,

then add domain url of additional shop to live bindings


if You recive run time error 

add domain default shop 






created ticket for New SSL Certificate for Champion Power Equipment.

https://sanacommerce.visualstudio.com/Sana%20Hosting/_workitems/edit/77686?src=WorkItemMention&src-action=artifact_link

video call by Aji

https://photos.google.com/photo/AF1QipMjrVXN7aQlGjQ5FIbAyFXtSC1jpsuDUbv3ROF-


10. Check new Webshop name has been configured from the ERP side. by run Test connection.

else inform to customer. 

eg:

Hi XXXX, 

We have successfully created a new beta shop (SanaStoreCA). It seems the new webshop has not been configured from the ERP side.

Can you please check on this issue.