Create new UIHint on sana : Drop down

 [DisplayName("ProductPage")]

    [DisplayColumn("Title")]
    public class ProductPage_Metadata : MetadataBase<IProductEnrichment>
    {
        
        ..............

 
        [Display(Name = "CustomerSegments", Order = 121)]
        [UIHint("Country")] 
       // [UIHint("CustomerSegments")]
        public object CustomerSegmentsIds { get; set; }
 
    }


public List<string>CustomerSegmentsIds { get; set; }

View > default > Shared > EditorTemplate > Country.

check Providertype also

@using Sana.Commerce
@using Sana.Commerce.Shop
 
@{
    var fieldTitle = Html.DisplayName(string.Empty).ToString();
    var name = string.Empty;
    var value = ViewData.Model as string;   
 
    var selectedId = ViewData.Model as string;
    var entityField = ViewData.Model as EntityTemplateFieldModel;
 
    var customerSegments = CommerceFrameworkBase.CustomerSegments.Provider.GetCustomerSegments().ToList();
 
 
    if (entityField != null)
    {
        fieldTitle = entityField.FieldTitle;
        name = entityField.Name;
        value = (string)entityField.Value;       
        selectedId = (string)entityField.Value;
    }
   
 
    var modelState = ViewData.ModelState[name];
    if (modelState != null && modelState.Value != null)
    {
        selectedId = modelState.Value.AttemptedValue;
    }
 
    var htmlAttributes = Html.GetTextBoxAttributes(fieldTitle, required: false);
    if (ViewData.ContainsKey("tabindex"))
    {
        htmlAttributes["tabindex"= ViewData["tabindex"];
    }
 
    <div class="ddlb">
        <select name="@Html.Name(name)" id="@Html.Id(name)" @Html.RenderAttributes(htmlAttributes)>
            <option disabled @When(!customerSegments.Any(cs => cs.Id.iEquals(value)), "selected")>
                @Sana.SimpleText("SelectCustomerSegmentPlaceholder""Select customer segment")
            </option>
 
            @{
                var isSelected = false;
 
                foreach (var item in customerSegments)
                {
                    isSelected = false;
                    if (value == item.Id)
                    {
                        isSelected = true;
                    }
                    <option selected="@isSelected" value="@item.Id">@item.Title.Or(item.Id).AsHtml() </option>
                }
 
            }
 
 
        </select>
    </div>
 
    
 
 
}
 
 




@using Sana.Commerce
@using ICountry = Sana.Commerce.Common.ICountry
@{
    var fieldTitle = Html.DisplayName(string.Empty).ToString();
    var name = string.Empty;
    var value = ViewData.Model as string;
    var countries = ViewBag.Countries as IList<ICountry>;
    var selectedId = ViewData.Model as string;
    var entityField = ViewData.Model as EntityTemplateFieldModel;
 
    var cStatment = CommerceFrameworkBase.CustomerSegments.Provider.GetCustomerSegments().ToList();
 
 
 
 
    if (entityField != null)
    {
        fieldTitle = entityField.FieldTitle;
        name = entityField.Name;
        value = (string)entityField.Value;
 
        if (entityField.Settings.Countries != null)
        {
            countries = entityField.Settings.Countries;
        }
        selectedId = (string)entityField.Value;
    }
    if (countries == null)
    {
        countries = CommerceFrameworkBase.Common.GetCountries(userCountriesOnly: true, visibleOnly: true);
    }
    var modelState = ViewData.ModelState[name];
    if (modelState != null && modelState.Value != null)
    {
        selectedId = modelState.Value.AttemptedValue;
    }
 
    var htmlAttributes = Html.GetTextBoxAttributes(fieldTitle, required: true);
    if (ViewData.ContainsKey("tabindex"))
    {
        htmlAttributes["tabindex"] = ViewData["tabindex"];
    }
    @*<div class="ddlb">
        <select name="@Html.Name(name)" id="@Html.Id(name)" @Html.RenderAttributes(htmlAttributes)>
            <option disabled @When(!countries.Any(country => country.Id.iEquals(value)), "selected")>@Sana.SimpleText("SelectCountryPlaceholder")</option>
            @foreach (var item in countries)
            {
                <option value="@item.Id" @Html.RenderAttributes(GetOptionHtmlAttributes(item, selectedId))>@item.Name.Or(item.Id).AsHtml()</option>
            }
        </select>
    </div>*@
 
 
    <div class="ddlb">
        <select name="@Html.Name(name)" id="@Html.Id(name)" @Html.RenderAttributes(htmlAttributes)>
            <option disabled @When(!countries.Any(country => country.Id.iEquals(value)), "selected")>@Sana.SimpleText("SelectCountryPlaceholder")</option>
            @foreach (var item in cStatment)
            {
                <option value="@item.Id">@item.Title.Or(item.Id).AsHtml()</option>
            }
        </select>
    </div>
 
 
 
}
 
 
@functions
{
    IDictionary<string, object> GetOptionHtmlAttributes(ICountry country, string selectedId)
    {
        var attributes = new Dictionary<string, object>();
        if (country.Id.iEquals(selectedId))
        {
            attributes["selected"] = "selected";
        }
        if (country.AddressUseZipPlus4)
        {
            attributes["data-zipPlus4"] = "true";
        }
        return attributes;
    }
}







revert / undo shop creatrion sql

   begin transaction


DECLARE @newWebsiteId nvarchar(50);

DECLARE @newWebsiteName nvarchar(50);

DECLARE @newWebsiteDomain nvarchar(50);


--SET @newWebsiteId = N'SANA_CH'; -- set a new website ID instead of 'NewWebsiteID'

--SET @newWebsiteName = N'SANA_CH'; -- set the name of the new website instead of 'New Website Name'

--SET @newWebsiteDomain = N'ravensburger-ch-beta.sanastores.net'; -- set the domain for new website instead of 'localhost'

--SELECT @defaultLanguage = Id FROM [Languages] WHERE [IsDefault] = 1;


 -- delete from [Websites] where id ='SANA_CH' -- @newWebsiteId

-- delete from [WebsiteLanguages] where [WebsiteId] ='SANA_CH' -- @newWebsiteId :: done

-- delete from  FederalMerchants_935.[dbo].[WebsiteDomains]  where [WebsiteId] = 'SANA_CH' :: done


 -- d-elete  AdminUsers manualy :: done

  --delete from FederalMerchants_935.[dbo].[FlexiPages] where [WebsiteId] = 'SANA_CH' --@newWebsiteId :: done

  --delete from FederalMerchants_935.[dbo].[Settings] where [WebsiteId] = 'SANA_CH' --@newWebsiteId :: done

Product Enrichments/Product Page admin add new fields

 

Ticket 100050: [Integria MVP] 3.4. Product details page changes


Need to Get details from GetProducts and save Product Enrichments on product index run 
to do 
Code idea get from: CategoryImportController > LinkProductPages()


public class ExtendedOfflineProductProvider : OfflineProductProviderIExtendedProductProvider
    {
        /// Ticket 100050: [Integria MVP] 3.4. Product details page changes
        /// <summary>
        /// Gets the admin data manager.
        /// </summary>
        protected virtual AdminDataManager DataManager
        {
            get { return AdminDataManager.Current; }
        }
 
        public override void SaveProducts(IEnumerable<IProductproducts)
        {
            base.SaveProducts(products);
 
            /// Ticket 100050: [Integria MVP] 3.4. Product details page changes
            LinkProductPages(products);
        }
 
        /// Ticket 100050: [Integria MVP] 3.4. Product details page changes
        /// <summary>
        /// Links the product pages to the currently imported navigation item.
        /// below Code from: CategoryImportController > LinkProductPages()
        /// </summary>
        /// <param name="products"></param>
        protected virtual void LinkProductPages(IEnumerable<IProductproducts)
        {
            using (var unit = DataManager.CreateUnitOfWork())
            {
                var productIds = products.Select(r => r.Id).ToArray();
                var enrichments = CommerceFrameworkBase.ProductContent.Provider.GetProductEnrichments(productIds)
                    .ToDictionary(i => i.ProductId, StringComparer.OrdinalIgnoreCase);
 
                foreach (var product in products)
                {
                    IProductEnrichment enrichment;
                    if (enrichments.TryGetValue(product.Id, out enrichment))
                    {
                        var IsValid = FillProductDetailLeveDescriptions(productenrichment);
                        if (IsValid)
                        {
                            Update(enrichment);
                        }
                    }
                    else
                    {
                        enrichment = ObjectFactory.Create<IProductEnrichment>();
                        enrichment.ProductId = product.Id;
 
                        // Save New Enrichments
                        var IsValid = FillProductDetailLeveDescriptions(productenrichment);
                        if (IsValid)
                        { 
                            Insert(enrichment);
                        }  
                    }
                }
                unit.Flush();
                unit.Commit();
            }
        }
 
        /// Ticket 100050: [Integria MVP] 3.4. Product details page changes
        /// <summary>
        /// This method will Fill Product level descriptions and check validity of updated Products. 
        /// </summary>
        /// <param name="product">product</param>
        /// <param name="enrichment">enrichment</param>
        /// isChecked :Flag use to identify current product need to be updated or not. True:Should insert or update, Else :ignore
        /// <returns></returns>
        private bool FillProductDetailLeveDescriptions(IProduct productIProductEnrichment enrichment)
        {
            bool isChecked = false// Flag use to identify current product need to be updated or not.
 
            if (!string.IsNullOrEmpty(((Product)product).Indications))
            {
                ((ProductEnrichment)enrichment).Description1 = ((Product)product).Indications;
                isChecked = true;
            }
            if (!string.IsNullOrEmpty(((Product)product).Dosage))
            {
                ((ProductEnrichment)enrichment).Description2 = ((Product)product).Dosage;
                isChecked = true;
            }
            if (!string.IsNullOrEmpty(((Product)product).Indications))
            {
                ((ProductEnrichment)enrichment).Description1 = ((Product)product).Indications;
                isChecked = true;
            }
            if (!string.IsNullOrEmpty(((Product)product).Cautions))
            {
                ((ProductEnrichment)enrichment).Description3 = ((Product)product).Cautions;
                isChecked = true;
            }
            if (!string.IsNullOrEmpty(((Product)product).CompanionTherapy))
            {
                ((ProductEnrichment)enrichment).Description4 = ((Product)product).CompanionTherapy;
                isChecked = true;
            }
            if (!string.IsNullOrEmpty(((Product)product).BeneficialFor))
            {
                ((ProductEnrichment)enrichment).Description5 = ((Product)product).BeneficialFor;
                isChecked = true;
            }
            if (!string.IsNullOrEmpty(((Product)product).Ingredients))
            {
                ((ProductEnrichment)enrichment).Description6 = ((Product)product).Ingredients;
                isChecked = true;
            }
            if (!string.IsNullOrEmpty(((Product)product).OtherInfo))
            {
                ((ProductEnrichment)enrichment).Description7 = ((Product)product).OtherInfo;
                isChecked = true;
            }
 
            ((ProductEnrichment)enrichment).LevelId1 = ProductLevel.Level01;
            ((ProductEnrichment)enrichment).LevelId2 = ProductLevel.Level02;
            ((ProductEnrichment)enrichment).LevelId3 = ProductLevel.Level03;
            ((ProductEnrichment)enrichment).LevelId4 = ProductLevel.Level04;
            ((ProductEnrichment)enrichment).LevelId5 = ProductLevel.Level05;
            ((ProductEnrichment)enrichment).LevelId6 = ProductLevel.Level06;
            ((ProductEnrichment)enrichment).LevelId7 = ProductLevel.Level07;
 
            return isChecked;
        }
 
 
        /// Ticket 100050: [Integria MVP] 3.4. Product details page changes
        /// <summary>
        /// Updates the specified entity with invoking all registered persistence handlers.
        /// All operations are executed in a single transaction.
        /// </summary>
        /// <param name="entity">The entity.</param>
        protected virtual void Update(object entity)
        {
            using (var unit = DataManager.CreateUnitOfWork())
            {
                OnBeforeUpdate(entity);
                DataManager.Save(entity);
                OnAfterUpdate(entity);
                unit.Commit();
            }
        }
 
        /// Ticket 100050: [Integria MVP] 3.4. Product details page changes
        /// <summary>
        /// Inserts the specified entity with invoking all registered persistence handlers.
        /// All operations are executed in a single transaction.
        /// </summary>
        /// <param name="entity">The entity.</param>
        protected virtual void Insert(object entity)
        {
            using (var unit = DataManager.CreateUnitOfWork())
            {
                OnBeforeSave(entity);
                DataManager.Save(entity);
                OnAfterSave(entity);
                unit.Commit();
            }
        }
 
        /// Ticket 100050: [Integria MVP] 3.4. Product details page changes
        /// <summary>
        /// Called before an entity is updated in the datastore.
        /// If not overridden in a derived class, invokes the corresponding event on all registered persistence handlers.
        /// </summary>
        /// <param name="entity">The entity.</param>
        protected virtual void OnBeforeUpdate(object entity)
        {
            PersistenceHandlers.Handle(h => h.OnBeforeUpdate(entity));
        }
 
        /// Ticket 100050: [Integria MVP] 3.4. Product details page changes
        /// <summary>
        /// Called after an entity has been updated in the datastore.
        /// If not overridden in a derived class, invokes the corresponding event on all registered persistence handlers.
        /// </summary>
        /// <param name="entity">The entity.</param>
        protected virtual void OnAfterUpdate(object entity)
        {
            PersistenceHandlers.Handle(h => h.OnAfterUpdate(entity));
        }
 
        /// Ticket 100050: [Integria MVP] 3.4. Product details page changes
        /// <summary>
        /// Called before a new entity is saved to the datastore.
        /// If not overridden in a derived class, invokes the corresponding event on all registered persistence handlers.
        /// </summary>
        /// <param name="entity">The entity.</param>
        protected virtual void OnBeforeSave(object entity)
        {
            PersistenceHandlers.Handle(h => h.OnBeforeSave(entity));
        }
 
        /// Ticket 100050: [Integria MVP] 3.4. Product details page changes
        /// <summary>
        /// Called after a new entity has been saved to the datastore.
        /// If not overridden in a derived class, invokes the corresponding event on all registered persistence handlers.
        /// </summary>
        /// <param name="entity">The entity.</param>
        protected virtual void OnAfterSave(object entity)
        {
            PersistenceHandlers.Handle(h => h.OnAfterSave(entity));
        }
 
 
    }








Open PDF doc in new tab without showing download popup.

 Project :PRL glass 

Ticket 102771: [PRL Glass] 3.3. Download Customer Statement report from My Account
Response.SetCookie(new HttpCookie("fileDownload""true") { HttpOnly = false });                       
                      
          Response.Buffer = true;
          Response.ContentType = "application/pdf";
 
          Response.AppendHeader("Content-Disposition""inline; filename=" + reportname + ".pdf");
 
          Response.Cache.SetCacheability(HttpCacheability.NoCache);
          Response.OutputStream.Write(memoryStreamReport0memoryStreamReport.Length);
 
          Response.End();


View\Default\Profile\Index.cshtml

// Ticket 102771: [PRL Glass] 3.3. Download Customer Statement report from My Account
            // Add Button with and set target = "_blank" to open in new window.
            @Sana.LinkButton(textKeyreportName.ToString(),
               url: Url.Action("CustomerStatmentReport""ErpFileDownload"new { customerId = customerId.ToString() }),
               cssClass"btn btn-report"defaultTextreportName.ToString(), htmlAttributesnew { rel = "nofollow", target = "_blank" })
           



public class ExtendedErpFileDownloadController : ErpFileDownloadController
    {
        protected override void RegisterSystemRoutes(SanaRouteCollection routes)
        {
            base.RegisterSystemRoutes(routes);
 
            // Ticket 102771: [PRL Glass] 3.3. Download Customer Statement report from My Account
            routes.MapSystemPageRoute(Name, "CustomerStatmentReport""CustomerStatmentReport""CustomerStatmentReport/files/Customer-Statment-Report.pdf");
        }
 
        // Ticket 102771: [PRL Glass] 3.3. Download Customer Statement report from My Account
        /// <summary>
        /// A GET action to get the customer statment report.
        /// </summary>
        /// <param name="customerId">The customer ID.</param> 
        /// <returns>Returns the order report.</returns>
        [Authorize]
        [HttpGet]
        public virtual ActionResult CustomerStatmentReport(string customerIdint maxTimeoutExceptionSkips = 5int sleepDurationBetweenAttempts = 10000)
        {
            if (customerId.IsEmptyString())
                return HttpNotFound();            
 
            Stream reportStream = null;
            var retryCount = maxTimeoutExceptionSkips;
            while (true)
            {
                try
                {
                    reportStream = ((ExtendedAttachmentApi)ShopApi.Attachments).LoadCustomerStatmentReport(customerId);
                }
                catch (SanaConnectionException ex)
                {
                    if (ex.InnerException == null || !(ex.InnerException is TimeoutException))
                        throw;
                    if (retryCount == 0)
                        throw;
                    Thread.Sleep(sleepDurationBetweenAttempts);
                    retryCount--;
                    continue;
                }
                break;
            }
 
            if (reportStream == null)
                return new HttpNotFoundResult();
            
            //Set report name.
            var reportname = "CustomerStatmentReport_" + customerId;
            
            //Get bytes from stream.
            var memoryStreamReport = ((MemoryStream)reportStream).ToArray();
 
            Response.SetCookie(new HttpCookie("fileDownload""true") { HttpOnly = false });
 
            Response.Buffer = true;
            Response.ContentType = "application/pdf";
            Response.AppendHeader("Content-Disposition""inline; filename=" + reportname + ".pdf");
            Response.Cache.SetCacheability(HttpCacheability.NoCache);
            Response.OutputStream.Write(memoryStreamReport0memoryStreamReport.Length);
            Response.End();
 
            return File(reportStream, System.Net.Mime.MediaTypeNames.Application.Pdf, reportname);            
        }
 
    }