Ticket 93818: [Holz Pichler] 3.3. Item variants – “range value” attributes
Cache methods on Manager.
Project Kavo
ExtendedProductCategoryManager
/// Ticket 88704: [Kavo] 3.9. PDP – RELATED ITEMS /// <summary> /// Get product categories by product child level. /// </summary> /// <param name="level">product's child level</param> /// <returns></returns> public virtual IProductCategoryCollection GetProductCategoriesByLevel(int level) { bool fromCache; var categories = CacheManager.FromCache(ErpCollectionCacheKey<IProductCategory>() + "CategoriesByLevel" + level, () => ((ExtendedOfflineProductCategoryProvider)Provider).GetProductCategoriesByLevel(level), out fromCache); return categories; }
use a unique key for cacheKey
/// Ticket 88704: [Kavo] 3.9. PDP – RELATED ITEMS /// <summary> /// Get related product item. /// </summary> /// <param name="categoryId"></param> /// <returns></returns> public virtual IRelatedProductSet GetRelatedProductSetByCategoryId(string categoryId) { var cacheKey = CacheKey.ForContentCollection<IRelatedProductSet>(categoryId); var list = CommerceFrameworkBase.Content.GetContentCacheContainer() .FromCache(cacheKey, () => ((ExtendedOfflineProductProvider)Provider).GetRelatedProductSetByCategoryId(categoryId)); return list; }
cache with List exampe.
ExtendedProductManager
/// Ticket 88704: [Kavo] 3.9. PDP – RELATED ITEMS /// <summary> /// Get related product items by category ids. /// </summary> /// <param name="categoryId">category id</param> /// <returns>related product item</returns> public virtual IList<IRelatedProductSet> GetRelatedProductSetsByCategoryIds(List<string> categoryIdList) { string categoryIdListString = string.Join(" ", categoryIdList.ToArray()); var cacheKey = CacheKey.ForContentCollection<IRelatedProductSet>(categoryIdListString); var list = CommerceFrameworkBase.Content.GetContentCacheContainer() .FromCache(cacheKey, () => ((ExtendedOfflineProductProvider)Provider).GetRelatedProductSetsByCategoryIds(categoryIdList)); return list; }
another simple way to cache
ExtendedCommonManager
public IPIMModelsDataCollection GetPIMModels(string makeId) { var key = CacheKey.ForContentCollection<PIMModelsData>() + "PIMModels" + makeId; return CacheManager.FromCache(key, () => ((ExtendedOfflineCommonProvider)Providers.Offline.Common).GetPIMModels(makeId)); }
public IPIMMakesDataCollection GetPIMMakes() { var key = CacheKey.ForContentCollection<PIMMakesData>() + "PIMMakes"; return CacheManager.FromCache(key, () => ((ExtendedOfflineCommonProvider)Providers.Offline.Common).GetPIMModels()); }
Short Notes
How to get matching items from two List by LinQ
var CategoryIdList = product.CategoryIds; var relatedProductItems = ((ExtendedProductManager)CommerceFrameworkBase.Products).GetRelatedProductItems(); var relatedProductItemsList = relatedProductItems.Where(m => CategoryIdList.Contains(m.CategoryId)).ToList();
not matching (use (not) ! for statment)
var relatedProductItemsList = relatedProductItems.Where(m => !CategoryIdList.Contains(m.CategoryId)).ToList();
anothr way
var basketRangeValueFields = ((BasketLine)basketLine).RangeValueList; var machingRangeValueFields = excictingLineRangeValues.Where(x => basketRangeValueFields.Any(y => x.Id == y.Id && x.Value == y.Value)).ToList(); var result = (machingRangeValueFields.Count == basketRangeValueFields.Count);
multiple fields check with two list
// Ticket 93818: [Holz Pichler] 3.3.Item variants – “range value” attributes. var excictingLineRangeValues = ((BasketLine)line1).RangeValueList; var newLineRangeValues = ((BasketLine)line2).RangeValueList; if (excictingLineRangeValues != null && newLineRangeValues != null) { var machingRangeValueFields = excictingLineRangeValues.Where(x => newLineRangeValues.Any(y => x.Name == y.Name && x.Id == y.Id && x.Value == y.Value)).ToList(); var result = (machingRangeValueFields.Count == newLineRangeValues.Count); return result; }
How to call constant data on Sana admin
Kavo : AdminMenuInitializer.
Topmedia:
CreateAdminMenuLink(Admin.ResourceManager.GetString(Sana.Commerce.Constants.ProductFinder), urlHelper.Action("ProductFinder", "ProductIndex"), PermissionOn.SearchSettings)),
Drop Down
<div class="form-group"> @Html.LabelFor(x => Model.SelectedProductType, htmlAttributes: new { @class = "control-label col-md-2" }) <br /> <div class=""> @Html.DropDownListFor(x => Model.SelectedProductType, new SelectList(Model.ProductTypes, "Code", "Name"), " Select" , htmlAttributes: new { @class = "form-control", id = "ProductType" }) @Html.ValidationMessageFor(x => x.SelectedProductType, "", new { @class = "text-danger" }) </div> </div>
Website ID
var websiteId = CommerceFrameworkBase.Context.WebsiteId;
reload page by controler
return Redirect(Request.UrlReferrer.ToString());
Selected Web shop lanuage
var culture = CultureInfo.GetCultureInfo(currentLanguage);
Customer is b2b or b2cvar shopContext = ShopContext.GetCurrent(); shopContext.IsB2cCustomer |
Loggin time out :
Add this to Web config File after two minutes it will logout
<!--Increase the frontend login session expires time --> <add key="FrontendAuthenticationTimeout" value="2" />
Customer segment :
How to identify current customer match with customer segments
eg:Intergria helthcare> ExtendedProductController > UpdateProductTabDescriptions > line97
ShopApi.UserState.IsCurrentUserInSegment(Shop, customerSegmentIndications)
Add Logs views
Admin Paging Grid Creation.
Ex: Kavo . // Ticket 88704: [Kavo] 3.9. PDP – RELATED ITEMS
RelatedProductsController
get value from entity fields
Project Kavo : ExtendedProfileControllers. >
GetB2BCustomerCreationEmailTags
//Get Tax No from Entity fields var taxNo = model.Customer.Fields.Values.Where(x => x.Name == "TaxNo").FirstOrDefault().Value; replaceTags.Add("TAXNO", GetCountryName(taxNo.ToString()));
create new Table in Databses in sana and map hibernate
kavo Project.
create table in DB , add script to database update folder
D:\development\Florette_935_2\DatabaseUpdates
create new hbm or update existing.
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false" namespace="Sana.Commerce.Catalog" assembly="Sana.Commerce.Sdk">
<class name="RelatedProductItems" table="RelatedProductItems"> <id name="Id" type="Guid"> <generator class="guid" /> </id> <property name="WebsiteId" type="string" length="50" not-null="true" /> <property name="CategoryId" type="string" length="50" not-null="false" /> <property name="ProductSetId" type="Guid" length="50" not-null="true" /> </class>
need to set correct name space . else get an error.
eh:Catalog.hbm.xml
namespace="Sana.Commerce.Catalog" <-----
RelatedProductitem.cs
namespace Sana.Commerce.Catalog <--------- { [Serializable] [DataContract(Name = "RelatedProductItem", Namespace = "")] public class RelatedProductItem : IRelatedProductItem { /// <summary> /// Gets or sets the stock range identifier. /// </summary> [IgnoreDataMember] public Guid Id { get; set; } /// <summary> /// Gets or sets the website identifier. /// </summary> [IgnoreDataMember] public string WebsiteId { get; set; } /// <summary> /// Gets or sets the category identifier. /// </summary> [DataMember] public string CategoryId { get; set; } /// <summary> /// Gets or sets the out of stock value. /// </summary> [DataMember] public Guid ProductSetId { get; set; } }
namespace Sana.Commerce.Catalog { /// Ticket 88704: [Kavo] 3.9. PDP – RELATED ITEMS /// <summary> /// Describes related product item. /// </summary> public interface IRelatedProductSet : IIdentityObject { /// <summary> /// Gets or sets the website identifier. /// </summary> string WebsiteId { get; set; } /// <summary> /// Gets or sets the category identifier. /// </summary> string CategoryId { get; set; } /// <summary> /// Gets or sets the Product set id. /// </summary> Guid ProductSetId { get; set; } } }
Top media Ticket 100006: [Topmedia] 3.1. Search – Product Finder
create table on DB
CREATE TABLE [dbo].[ProductTypes]( [Id] [uniqueidentifier] NOT NULL, [WebsiteId] [nvarchar](50) NOT NULL, [Code] [nvarchar](50) NULL, [Name] [nvarchar](100) NULL, CONSTRAINT [PK_ProductTypes] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO ALTER TABLE [dbo].[ProductTypes] WITH CHECK ADD CONSTRAINT [FK_ProductTypes_ProductTypes] FOREIGN KEY([Id]) REFERENCES [dbo].[ProductTypes] ([Id]) GO ALTER TABLE [dbo].[ProductTypes] CHECK CONSTRAINT [FK_ProductTypes_ProductTypes] GO
common.hbm.xml
<class name="ProductType" table="ProductTypes" polymorphism="explicit"> <id name="Id" type="Guid"> <generator class="guid" /> </id> <property name="WebsiteId" type="string" length="50" not-null="true" /> <property name="Code" type="string" length="50" not-null="false" /> <property name="Name" type="string" length="100" not-null="false" /> </class>
When u want to get datafrom DB use OfflineCommonProvider
from ERP use ExtendedCommonProvider
How to call these methods . This is calling on General import runing
public class ExtendedSyncTask: SyncTask { protected override void Synchronize() { base.Synchronize(); var offlineCommonProvider = Providers.Offline.Common; var onlineCommonProvider = Providers.Common; // Ticket 100006: [Topmedia] 3.1. Search – Product Finder // Get Prodcuct type data from ERP. var pickupLocations = ((ExtendedCommonProvider)onlineCommonProvider).GetProductTypes(); ((ExtendedOfflineCommonProvider)offlineCommonProvider).DeleteAllProductTypes(); ((ExtendedOfflineCommonProvider)offlineCommonProvider).SaveProductTypes(pickupLocations); taskLog.Add(this, "Saved product types."); } }
Get data from ERP (online)
public class ExtendedCommonProvider : CommonProvider, IExtendedCommonProvider { public virtual IList<IProductType> GetProductTypes() { var request = new List<XElement>(); var result = ExecuteRequest("GetProductTypes", request); var productTypes = result.Elements("ProductType").Select(e => ((ExtendedCommonXmlParser)Parser).ParseProductType(e)).ToList(); foreach (var item in productTypes) { item.WebsiteId = Context.WebsiteId; } return productTypes; } }
get data from DB offline
public class ExtendedOfflineCommonProvider : OfflineCommonProvider, IExtendedCommonProvider { /// Ticket 100006: [Topmedia] 3.1. Search – Product Finder /// <summary> /// Delete all product types. /// </summary> public virtual void DeleteAllProductTypes() { WrapDataAccessException(() => { using (var sm = CreateSessionManager(false)) { var productTypes = GetProductTypes(); foreach (var productType in productTypes) { sm.Session.Delete(productType); } sm.Commit(); } }, "Cannot delete pickup locations for {0} website".FormatWith(Context.WebsiteId)); } /// Ticket 100006: [Topmedia] 3.1. Search – Product Finder /// <summary> /// Get product types. /// </summary> /// <returns></returns> public virtual IList<IProductType> GetProductTypes() { using (var sm = CreateSessionManager(true)) { var productTypes = sm.Session.CreateCriteria(GetRegisteredType<IProductType>()) .Add(NHibernate.Criterion.Restrictions.Eq("WebsiteId", CommerceFrameworkBase.Context.WebsiteId)) .List<IProductType>(); return productTypes; } } /// Ticket 100006: [Topmedia] 3.1. Search – Product Finder /// <summary> /// Save product types. /// </summary> /// <param name="productTypes"></param> public virtual void SaveProductTypes(IList<IProductType> productTypes) { WrapDataAccessException(() => { using (var sm = CreateSessionManager(false)) { productTypes.Each(c => sm.Session.SaveOrUpdate(c)); sm.Commit(); } }, "Cannot save pickup location"); } }
order confirmation e-mail not working. check list
Send order confirmation e-mail : always send order conf.
1. Check db > PaymentTransactionInfos table > ConfirmationEmailSent set to true :
2. If true : hosting issue
If false sana issue . Check db have any multiple data for same order
{
var checkoutProcess = transaction.CheckoutProcessName;
if (checkoutProcess == CheckoutProcesses.EditOrder || checkoutProcess == CheckoutProcesses.EditQuote)
return true;
return false;
}