Accelerate the power of Sitecore XC policies – Custom plugin to let content authors change settings in BizFx tools on runtime

Accelerate the power of Sitecore XC policies – Custom plugin to let content authors change settings in BizFx tools on runtime

For some time now, while working with Sitecore XC, I am struggling with the concept of policies. In general I really like that concept, how new policies are added to an environment and how things work. But more more I got requirements from customers, who wanted to be able to change those policies on their own. And of course you all now, that this is not possible. Policies are added, edited and maintained purely by developers. So either way you would have to exactly do that. Just change the setting all the time the customer wishes, or provide a smarter solution for that. And exactly that I tried to fulfill. Within this blog post I will first describe shortly the mechanism of policies and how they are maintained, will come back to he customer requirements, which are appearing more and more in all my projects and what that really means for us developers, till I finally present some extension for Sitecore XC OOTB logic to generically fulfill such requirements in an easy way.

Introduction to policies

If you are not familiar with the terms environments, policies and roles I strongly recommend you to read first one of my previous articles, which can be found here. But let me also try to sum up the essence of that article here a bit.

As you all might now, the normal way of storing any kind of configuration for Sitecore XC, is, to store it in a custom policy. A policy is nothing more than a piece of json file like seen below.

2020-03-18 20_07_55-esrvath02 - Remotedesktopverbindung

As you can see such a policy consists of 1 to n different properties, which can be set and maintained within that specific json file. These values are then mapped to custom .cs policy file to be then used ion runtime

2020-03-18 20_09_50-esrvath02 - Remotedesktopverbindung

Multiple of such policies are then combined together to one big environment Sitecore XC uses to execute pipelines, blocks commands and more for specific storefronts.

So in the end to speak in Sitecore XP terminology these polices are very similar to .config files or patches under the App Config/Include folder. As good as that works the trouble starts now in the way, of how such configs are maintained and deployed to other environments.

Process of how to bring changes of policies live

Boths types of configurations .config files and .json policies have the same weakness or better restrictions. They can normally not be maintained by content authors. The normal process of changing a value there and bringing it e.g. to production is in simple words the following

  • Change the value locally 
  • Commit and push these changes
  • Deploy this to the target environment 
  • Bootstrap environment so that json values are stored in DB to be used on runtime

So you can already imagine, that this is nothing an editor can do, and nothing, which can be done very quick. Because of that normally, in Sitecore XP you create global setting items, which can be maintained on runtime by content authors. Unfortunately nothing similar is existing in Sitecore XC – till now. ^^

Custom Settings plugin

So because I recognized, that there is definitely a lack in OOTB implementations, which make the life of content editors and developers more difficult, I thought, it makes sense to provide some new plugin to fill that gab.

What does it do?

With the newly created settings plugin you are now able to set previously defined policies values within a new BizFx application on runtime.

How does it look like?

In the screenshot below you can see the new application after integrating the setting plugin into a customer solution.

2020-03-16 10_05_19-esrvath02 - Remotedesktopverbindung

If you click on the settings application an overview of all existing settings is displayed. If no setting exists a default one is created automatically, which can be used.2020-03-16 10_06_14-esrvath02 - Remotedesktopverbindung

In the standard implementation of settings plugin you have 4 actions available to interact with settings, which can also be seen in the screenshot below

  • Add
  • Remove
  • Activate
  • Deactivate

Add: On click a new forms opens, where you can enter a Name and Display Name to create a new setting entity.

Remove: Removes the currently selected settings entity

Activate: Activates the currently selected settings entity. In addition it iterates through all other existing setting entities to disable them automatically, so there can be only one setting be active.

Deactivate: Deactivates currently selected settings entity

2020-03-16 10_06_39-esrvath02 - Remotedesktopverbindung

If you now click e.g. on the Default Setting entity, the corresponding entity view opens. After initially integrating the plugin, the settings entity will just have one single property is Active, like you can see below.

2020-03-18 20_27_51-esrvath02 - Remotedesktopverbindung

From this point on, you can now start filling the settings entity with all kind of policies you would like to edit on runtime.

How to integrate it into custom plugins?

So let’s start of how to integrate a custom plugin policy into the settings functionality.

Basically you need 4 different blocks to be able to display information in an accordion in an entity view, to provide an editor action on that accordion, to display a form to be able to edit properties and to be able to apply these changes to the current entity.

  • EntityViewXXX (Used to display data in accordion view)
  • FormEditXXX (Used in dialog to edit properties)
  • DoActionXXX (Used to apply edited properties from FormEdit to entity)
  • EnsureActionXXX (Used to provide edit button on new accordion view)

For all of you, who already extended entity views with new accordion views, know, that this needs some time to be fully implemented. Therefore the first thing I did for the settings plugin was, to make that process much easier for developer.

Base blocks

The settings plugin provides you with 3 different base blocks, which can also be seen below.

2020-03-16 10_11_28-esrvath02 - Remotedesktopverbindung

What you now just have to do to integrate your plugin into settings is, to create 4 different blocks and do the following steps

  • Inherit from the corresponding base blocks of settings plugin
  • Execute Base.Run method and provide policy as generic parameter and view  or action name in function parameter
  • Add all the new blocks to the specific pipelines in ConfigureSitecore.cs

2020-03-16 10_12_55-esrvath02 - Remotedesktopverbindung

Now let’s have a look at the whole code of the 4 blocks, where we use inheritance to use some basic functionality.

2020-03-16 10_13_05-esrvath02 - Remotedesktopverbindung2020-03-16 10_13_13-esrvath02 - Remotedesktopverbindung2020-03-16 10_13_21-esrvath02 - Remotedesktopverbindung2020-03-18 21_03_46-esrvath02 - Remotedesktopverbindung

As you can see, the whole implementation of all these 4 blocks consists of just one single line of code, where you just have to tell the function, which policy and which view name (Entity View) or which action name (DoAction and Form Edit) to use.

Last but not least add all the 4 blocks now to corresponding pipelines, like seen below

2020-03-18 20_52_50-esrvath02 - Remotedesktopverbindung

Policy Property Attribute

In addition to the base blocks, which can be used in custom plugin, you now just have to use the newly provided EditorSetting attribute on already existing plugin policies. In the screenshot below you can see an example, where I added the new attribute to all properties of the PimImporterPolicy you already know from the beginning.

2020-03-16 10_08_18-esrvath02 - Remotedesktopverbindung

After you added these attributes to the policy and reload the settings entity again, you will now see, that a new accordion has been loaded with all the properties you previously added via setting the editor setting attribute.

2020-03-16 10_07_14-esrvath02 - Remotedesktopverbindung

And of course also the edit functionality is directly fully working like seen below.

2020-03-16 10_12_02-esrvath02 - Remotedesktopverbindung

And lastly, of course if you confirm changes, the piece of code is also already working, which applies these changes automatically to the current settings entity.

Note: As you might see, there are of course currently some limitations, like list handling, which will be covered in more detail as improvement in the future. Right now you can also edit lists, which are treated as pipe separated strings.

In case you do not want to use every property of the policy, you can easily remove all the attributes from the properties you would like to exclude from settings functionality.

2020-03-17 09_47_41-esrvath02 - Remotedesktopverbindung2020-03-17 09_50_21-esrvath02 - Remotedesktopverbindung

In this example I removed the setting for start hour, end hour, pim endpoint because I do not want editors to edit such properties ^^. But in the end it is completely up to you, what you would like to be editable in settings entity.

Extensions

Now, after we added our policy to the settings entity, we also want to use it in our code. To do that, I also created some piece of code to do that. The same way you retrieve policy from commerce context, you can now also retrieve settings policy.

  • context.GetPolicy<T>() -> Grab policy from environment
  • context.GetSettingPolicy<T>(CommerceCommander commander) -> Grab policy from active setting entity with fallback logic to grab policy from environment

Below you can the whole and simple implementation of GetSettingPolicy with integrated fallback logic.

2020-03-16 10_10_50-esrvath02 - Remotedesktopverbindung

If we now think of possibilities how we could use the new settings in custom code.

Different ways to use setting policies together with OOTB environment policies

  • Overwrite whole policy
    • In such case just use the new extension method context.GetSettingPolicy<T>(…) and continue working with the returning policy
  • Overwrite just specific properties
    • Use Standard context.GetPolicy<T>() AND context.GetSettingPolicy<T>(…) to retrieve environment and setting policy to decide later on, which property to be used when and which fallback logic shall be applied
  • Completely standalone setting
    • Note that such policies are not stored in environment and cannot be retrieved via OOTB context.GetPolicy<T>() call
    • Use context.GetSettingPolicy<T>(…) to retrieve the setting policy

Because in our example, we removed some of the properties from the possibility to be edited in settings, we would have to apply approach number 2 from above. To do that, we first grab settings policy, beside with environment policy.

2020-03-16 10_09_36-esrvath02 - Remotedesktopverbindung

And then we can easily and individually apply our custom fallback logic for each property, like seen for mailsubject below.

2020-03-18 21_29_40-esrvath02 - Remotedesktopverbindung

Conclusion

Within this blog post I presented a newly created plugin called Plugin.Sample.Settings, with which you are now able to edit policy properties not only in json on development time, but also within BizFx tools in a new application on runtime.

This way it is much easier to edit specific settings per environment as developer or editor.

The whole code can be found in the following github repository

And as always, the code is not production ready and is not extensively tested. Therefore use this code as a starting point for your own implementation.

Sitecore XC – How to delete a massive number of categories / sellable items?

Lastly while working with Sitecore XC I had the task to clear a whole catalog. This means I wanted to delete all sellable items together with all categories. But the scenario, which is also possible could be, that you just want to delete all sellable item from a catalog, or you just want to clear a single category, without deleting it. So there could be many different use cases, which should be covered somehow.

Because I did not find anything useful within BizFx tools to delete them all at once, and no API Call within Postman, I decided to ask some Sitecore Architect directly.

The response unfortunately was, that such a case is not covered by OOTB commerce engine functionality. Either way I could use Clear Environment, but the really everything within my environment would be deleted, and not just categories and sellable items, or I could go directly into SQL server and delete entries from the entities table.

There is also a third way to achieve a cleared catalog. Of course you can use standard BizFX delete functionalities on categories. The trick is, that you go to a first level category of your catalog and click Delete.2020-02-29 14_44_31-Test Catalog

You are then asked if you would like to delete or just disassociate the current catalog.

2020-02-29 14_44_40-Test Catalog

In case you really want to delete everything, you can just choose Delete category. 

How deletion of categories works behind the scenes: Once you delete a category via BizFx tools, you should know, that the category is not really deleted immediately. What the authoring system does, if you click delete category is pretty simple. It just marks the category to be deleted and add it to a special commerce list. The trick now is, that the minion instances has a minion, which crawls the list in standard every 5 minutes, grabs the categories, checks if they really should be deleted and in the end delete the category. But it does even more. You know, that a category can be associated to other categories and / or sellable items. And that the number of such associations can be really massive in a complex catalog. Depending on the chosen Delete Option the process now either way grabs all associations for the current categories and just deletes the these, but keeps the entities behind them. Or grabs all the associations deletes them and iterates through every associated category recursively till it reaches the level of sellable items and starts to recursively deletes all the entities. So if you e.g. delete a first level category it does not just delete that category, but also all sub categories and all associated sellable items to this and all sub categories. Now you also should understand, why the BizFx click in the authoring engine does not directly execute the deletion process, but delegates the job to the minion instance. If you now do that on every first level category, the result is a cleared catalog. But of course that trick is only applicable , if you do not have duzend or hundreds of first level categories.

Because both proposed ways and the manual workaround were not really applicable in my situation, I decided to write some custom functionality, which achieves exactly this.

The outcome of a few hours of programming and testing were three new functionalities, which might also be useful for you at some point

  • Clear Catalog
  • Delete all Sellable items
  • Clear Category 

In the following small chapters I will describe all of the functionalities and what they do for you.

Clear catalog

First let’s have a look at a functionality, which is able to clear a catalog with one click.

Note: I would recommend to use such piece of functionality just in development or testing environments and only very wisely in production environments.

In the screenshot below you can see the very simple command.

2020-02-29 14_10_55-Alnatura.Experience.Commerce - Microsoft Visual Studio (Administrator)

This command uses a catalog name to do the following

  • While categories exist
    • grabs all categories of the current environment
    • filters all categories out, which are not belonging to the current catalog
    • Deletes the category
    • Again grabs all the categories 
    • Filters again for categories of the current catalog

Deletion of categories: We use here the PurgeCategoryCommand. This command is normally used by minion to delete marked categories. Because I want categories to be deleted immediately, I skip the mark operation and wait 5 minutes, and just call the delete operation behind the scenes directly. In the commented code above you can the the piece of code to mark a category to be deleted, so that a minion can grab it afterwards. Of course you can decide on your own the way, of how you would like to delete categories.

Iteration: If we directly delete a category, like shown above, we have to be careful, that after delete operation, not only this category, but all subcategories are now deleted, like described in the beginning. This means, that the list from earlier of all categories, now is not valid anymore. Because of that we have to grab a fresh list of categories of the catalog each time we delete a category. If we still would use that list and continue iteration, we would most likely hit a lot of categories, which are already deleted and would throw various errors on processing.

Delete all Sellable items

Because you could also have the use case, that you want to delete all sellable items, but would like to keep the whole category structure with all categories and associations, I also created a piece of code to just delete all sellable items from current catalog.

2020-02-29 14_11_36-Alnatura.Experience.Commerce - Microsoft Visual Studio (Administrator)

The code from the screenshot above is quiet similar to the previous code. We first grab all sellable items within the environment and filter for those belonging to the current catalog. Then we really can just iterate through all of them and use standard DeleteDellsbleItemCommand to delete one after another. This works really well for a small amount of items to be deleted. But for massive number of items to be deleted, I encountered some serious issues, which lead to a newly reported bug at Sitecore support. Read more about this here and how to work around that issue.

Clear Category

Last but not least, I also created a small helper to clear just a single category, which means to delete all sellable items associated to a specific category.

This time the code is a bit more complex. Not only because, we have to grab the associated sellable items but also, because I added here some piece of logic,which avoids accidential deletion of entities, even though they are still associated somewhere else.

But just let’s have a look at the code

2020-02-29 14_15_58-Alnatura.Experience.Commerce - Microsoft Visual Studio (Administrator)

At first we grab our category to be cleared. Then we use standard functionality FindEntitiesInListCommand with special parameter to grab all associated sellable items. Then of course again we can iterate through all items.

2020-02-29 14_16_30-Alnatura.Experience.Commerce - Microsoft Visual Studio (Administrator)

But this time, we do not just delete the sellable item, which we of course could do. This time the deletion operation is a bit more intelligent. First we just use standard IDeleteRelationshipPipeline to delete association between category and sellable item. Then before we simple delete the sellable item, we check if the item can be deleted.

2020-02-29 14_16_43-Alnatura.Experience.Commerce - Microsoft Visual Studio (Administrator)

Above you can see the check if an item can be deleted. In case the current sellable item is not linked to any catalog or any other category anymore we can safely delete the sellable item. In all other cases the deletion of the sellable item would mean, that it would also disappear at various other linked places, which we might do not want.

Conclusion: So within this article we discussed some operations developer would like to execute on their local / testing catalogs to clear corrupt or broken entities to get a clean greenfield situation back. We learned how deletion of catalogs / categories and sellable items work and how to use that knowledge to extend OOTB functionality of commerce engine in a simple way.

Sitecore XC 9.0.3 – Architectural thoughts on how to grab / pass and persist entities

Today I would like write about a quiet important topic for developers in Sitecore XC, how to persist entities in commerce engine. Once you start implementing your own plugins most probably you will also add new blocks, pipelines and command. And of course if you do that, you will most probably have to manipulate / change data of entities and save them back to Database.

Before I come to the point, where I show you a scenario I encountered in a customer project, I would like to start with writing about how in general the workflow how entities are retrieved from the system, and of course you can save them back after changing some data within your blocks.

Possibilities to retrieve an entity

Let us start with the basic topic of how to retrieve entities within a block. I would say there are basically 3 ways of doing that.

  • From Database
  • From Context
  • From Args

But how do these 3 method differ from each others?

From Args: Let me start with the way of retrieving an entity via args. I guess it’s the most obvious and easiest way of getting an entity. Once you create a block you have to also give the block input and output parameters depending on the location, where you would like to hook in. For example if you would like to create a new block for the IAddCartLinesPipeline and want to hook n between AddCartLineBlock and AddContactBlock, you can see the output parameter of AddCartLineBlock is Sitecore.Commerce.Plugin.Carts.Cart and the input parameter of AddContactBlock is also Sitecore.Commerce.Plugin.Carts.Cart.

2019-03-21 09_50_30-Customer.Sample.Solution - Microsoft Visual Studio (Administrator)

So to properly hook into that pipeline at that location, just create a block with input type matching the output type of the previous block and output type matching the input type of the next block.

2019-03-21 09_53_48-Customer.Sample.Solution - Microsoft Visual Studio (Administrator)

If your new block now needs to modify the given cart, you now can easily access it via args object of the Run method, modify it and pass it on to the next block.

2019-03-21 09_57_56-Customer.Sample.Solution - Microsoft Visual Studio (Administrator)

From Context: The next possibility to get entities within your block is to use the given CommercePipelineExecutionContext. Such an approach you have to do if you want to access entities, which are not OOTB passed via arguments through the pipeline to your block. Within your block you just have to access CommerceContext and extract your entity and you are able to change data, which are automatically updated in context.

2019-03-21 10_16_52-192.168.101.10 - Remotedesktopverbindung

In this example we are in the standard RMA pipeline of sitecore. Within that pipeline an object of type ReturnMerchandiseAuthorization is passed through the blocks. In addition the corresponding order object is saved to context, where you are able to get it from. Of course one prerequisite of doing that is, that some previous block saved the necessary entity to the context, from which you now want to grab it.

2019-03-21 10_08_46-192.168.101.10 - Remotedesktopverbindung

From Database: The last option to get an entity to be able to change data is the most direct one. To do that you just have to use the IFindEntityPipeline.

2019-03-21 10_59_40-192.168.101.10 - Remotedesktopverbindung

The result of that pipeline is a new instance of the entity based on the current state of the Database.

Possibility to save an entity

Now let’s shortly talk about, how you can save an entity to database again. This step is absolutely necessary when working with entities. If you would not save the changed entities in the end of processing back to Database, all the changes you made within the execution, within the pipelines and blocks, would be lost again.

Basically it is quiet easy to do that. To save an entity to database, you just have to call IPersistEntityPipeline with your entity.

2019-03-21 11_16_50-192.168.101.10 - Remotedesktopverbindung

Real world scenario

Now with these things in mind, let us have a look at an example I encountered, while working with Sitecore XC. The graphic below shows a sequence diagram of a pipeline created / used in Sitecore XC.

Example Pipeline Execution (1).png

Within this execution you can see, which pipelines are called when and from whom. In addition it shows, where the entity comes from, which is necessary to process.

Let me shortly describe the given scenario. It all starts with the execution of a first pipeline. Based on the given arguments the first block in the pipeline just grabs the necessary entity from Database. Because this entity is not part of the arguments, which are passed through the pipeline, this block also saves that entity to context. After doing something the first block of the first pipeline finishes and the second block is executed. As you would expect it, the second block grabs the necessary entity from context and does various changes to the entity. In between this block itself executes another pipeline. The parameter of that new pipeline this time is exactly that entity, so it can be passed via arguments of pipelines and blocks. So the first block of that second pipeline uses that argument to also do something with the entity. This goes on till block two of the second pipeline. This block again executes a new pipeline to let something execute. But this time there is a break in architectural concept. The parameter, which is passed is just an id of the entity, which is needed later on. The only possibility of pipeline three to access the entity now is to grab it again from database. After that, this pipeline makes some changes to the entity and directly saves it back to database. Now the execution of pipeline three ends and after that also of pipeline two. In the end of pipeline two, there is a block, which takes the entity, which was at that time passed via argument from pipeline one, and saves the entity back to database. Then also pipeline two ends. Within the first, initial pipeline, now a block is executed, which is responsible for grabbing the entity from context and saves it permanently back to database to persist all the changes made in between.

What are the problems of that composition of pipelines?

The main question, you could also ask yourself at this point is:

How does the entity look like in the end of the overall processing?

The answer is quiet clear. It does not look like we would expect it to be.  What I observed in the given scenario was an entity, which was in deed saved a few times, but always with a different state. Let me also describe, what most probably led to the inconsistency within the system.

As you know it from the beginning, we have multiple ways of getting an entity and that we always have to persist an entity to permanently save it. Within the given scenario, we have the problem, that all the ways of retrieving an entity for processing is mixed up together.In our scenario the main pain point lies in Pipeline 4 Block 1. This pipeline completely ignores given context and object within that context. The reason was quiet obvious. The pipeline was initially not designed to be placed, where it was finally placed, so it was not know, that there is an object in context, which can be used at this point, and more over, depending on the scenario, where it is used, there is not always a given entity in context, which could be used. In our scenario Pipeline 1 Block 1 prepares the context. If these pipelines are not there on other scenarios, also the context would not be prepared.  But the workaround, which was approached there lead to the visible inconsistency.

Assume you have your entity and you are changing it within your pipelines and blocks. These changes are saved in the end to context. Now, when we enter the last pipeline, we grab a new instance of our entity from database. This results in a new entity, which of course does not include all the changes made earlier in the execution. Within that block we make some new changes like adding a necessary component with additional information. Once we save that entity it is permanently saved to database. The result is an updated entity in database, which only includes the changes of that specific block and nothing more.

Now, we could imagine, we have to scenarios. The first would be, that this new entity is given back to the previous blocks and pipelines and then be used in context. The other scenario would be to return nothing and just continue working on the saved entity in context. Let me say at this point, that both approaches are not optimal. It would only shift the problem and only the things, which are lost and overwritten would change.

In out scenario nothing was returned, so we continued working on the context entity object. In the end we know, that the last block now grabs the context object and again saves that entity to database to permanently save all the changes made while execution. But because, we never returned the new entity from the last pipeline, our context entity does not know these changes and on our last save, these changes are not included. In the following graphic you can see the operations, which directly have an influence on each others.

2019-03-21 13_18_42-Example Pipeline Execution_ Lucidchart

The reaction of the commerce system to such scenarios is now quiet different.  In best case you directly get a commerce engine error, which tells you that there is a concurrency exception, that the version you try to save is outdated.

“MessageDate”: “XXXXXXXXXXXXXXXXXX”,
“Code”: “Error”,
“Text”: “SQL:block:persistentity.Update.Exception: SQL.UpdateEntity.Fail: Id=’Entity-Catalog-Support Dummy’|Try=’1’|Environment=’Entity-CommerceEnvironment-HabitatAuthoring’|Message=’Concurrency error: The Entity version supplied (3) is no longer the current version.’|Number=’50000’|Procedure=’dbo.sp_CommerceEntitiesUpdateWithSharding’|Line=’26′”,
“CommerceTermKey”: “SQL:block:persistentity”

In worst case, the save is successfully executed AND the changes you made in between are completely overwritten.

Now imagine you would have returned the changed object back to the previous block and that you would have updated the context. Of course this would have saved the changes made in pipeline four. BUT because you would just overwrite the context object and you grabbed the entity from database, ALL the changes made earlier would be completely lost and overwritten at this point. So the issue would only be shifted.

What should be done?

Now the question is, how can you get rid of all these problems and issues?

The answer of that is also quiet simple. Do not make things more complicated, than they are already. Of course it is possible to call pipelines within pipelines within pipelines and split up the tasks. But then you have to keep an eye on every single pipeline; what goes on, what comes out, what is present in context. And all the time try to avoid grabbing exiting and adapted entities again from database.

In general, when you design a pipeline always keep in mind, that one of the first blocks checks and initializes everything and that, if possible, just the last block is responsible for saving the entity. If you work with pipelines in between, keep in mind to give the new pipeline the current entity and also to take it back after execution, so all the changes are just made on one single instance of the entity.

Conclusion

Within the today’s article you had an insight in a real world scenario I observed in a customer project. You learned about, how to get, handle and save entities in pipelines and what issues might happen, if you are not aware of what all the pipelines and blocks do while execution. In the end you also got some personal hints to also avoid such scenarios and get consistent data in the end.

Sitecore Commerce Connect – Connecting Sitecore XP and XC

Within this article I would like to deal with some groundwork regarding Sitecore XC. As hopefully all of you know Sitecore XC is an extension to standard Sitecore XP, which enriches Sitecore with a powerful commerce engine. The big question is:

Does everyone of you know how exactly XP and XC are connected, and how you can have influence on this connection?

To answer that question, I would like to give you a general overview of that connection layer, which is called Commerce Connect.

Therefore I would like to start with the standard definition Sitecore gives us within doc.sitecore.net.

“Sitecore Commerce Connect is the Sitecore commerce API for storefront developers and is an integration layer between a front-end webshop solution and a back-end external commerce system. The back-end system can be any e-commerce system for which Commerce Connect connectors have been created by Sitecore or a third-party vendor.”

Architecture

Now we want to have a look, how this Commerce Connect is integrated within a common commerce scenario with XP and XC components and where we can see that piece of software. For that, let us have a look at the following graphic.

2018-10-19 19_32_15-Sitecore XC From A to Z.pptx - PowerPoint

This graphic show a standard architecture overview of a standard Sitecore XC integration. As a base we always have standard Sitecore XP, at this point with related software like, SIF and SxA, which we optionally can use for Sitecore XC. On top of that we have the commerce engine of Sitecore XC. Now highlighted the imported area of the diagram, where we can see the connection of XP and XC. Commerce Connect is installed with the installation of two packages “Sitecore Commerce Connect Core” which installs the basic Commerce Connect module and “Sitecore Commerce Engine Connect” which installs very specific functionality, which is used to implement the connection between Sitecore XP and XC. This package, patches all the general implementations, with concrete implementations for Sitecore XC. Commerce Connect in the end then acts as a middleware with which it is very easy to communicate with the commerce engine via standard and predefined interfaces, pipelines and so on.

Now lets have a look, what we get, when we have installed the Commerce Connect packages. This is especially imported, if you have the need to add, delete or modify something for your custom business needs.

Items

Lets first investigate the items we get. In the content editor we get a new area called “Commerce” as you can see below.

2018-10-19 19_35_49-Sitecore XC From A to Z.pptx - PowerPoint

In scenarios, where you connect other external commerce systems to Sitecore XP, this area is even more imported, than in the case, where we integrate Sitecore XC. The most imported sections under the Commerce item are

  • Commerce Control Panel
    • Commerce Engine Settings
      • Commerce Terms
      • Shared Settings
      • Storefronts

Nowadays the section Catalog is not used anymore from the Content Editor, because Sitecore XC has its own tool for handling Commerce Catalogs, the Merchandise Manager. Therefore the Sitecore recommendation is not to use Content Editor anymore for dealing with  catalog data.

Within the section Commerce Terms we set all the commerce related texts, which are used within the Sitecore XC Business Tools. Lets have a look how, with the example of adding a custom condition to the Promotion Manager. To add a custom condition it is enough to create a class like seen below.

2018-10-21 13_47_42-Customer.Sample.Solution - Microsoft Visual Studio

Within the ConfigureSitecore file just register the new rules and conditions with the following command.

2018-10-21 13_55_14-Customer.Sample.Solution - Microsoft Visual Studio

After you did that, you have only one single step left to do. Now you have to go tho the Content Editor under the Commerce Terms section and find, in this case, the area for Conditions. There you add a new Item, which has exactly the same name, than the used in the Attribute EntityIdentifier. Within this Item you now can add your individual text for your new condition. You can also use placeholder for custom input with the syntax [PROPERTYNAME] and a property within you class of type IRuleValue<TYPE>. 

2018-10-21 13_50_31-Content Editor

If you correctly did that, you can just open the Promotion Manager and the under the conditions list your custom condition with your individual text.

2018-10-21 14_11_56-HappyHour

2018-10-21 14_12_17-HappyHour

You can see the new condition with its entity name, and if you choose it, choose your custom input, in this case StartHour and EndHour.

I think the sections Shared Settings and Storefronts are quiet self explaining. Within Storefront you create your individual Storefronts for you Sitecore instance and link them to the specific environments, these storefronts should use.

NOTE: Currently there is a bug in the choice of environments. The field for choosing an environment was deleted in the last version, so for every storefront Sitecore always falls back to the standard environment, which is set in the /Y.Commerce.Engine/Sitecore.Commerce.Engine.Connect.config.

2018-10-21 14_07_01-C__inetpub_wwwroot_commerce.sc_App_Config_Include_Y.Commerce.Engine_Sitecore.Com.png

To get rid of that, just go to the Storefront template and add the field again to the template

On the left side, we see, how the field should look like, in the example of Sitecore Commerce 8.2.1. On the right side, we see, that the Environment field is gone within Sitecore XC. The logic in the background is still there, so it is enough to manually add that field again to storefront template. Sitecore already registered that as a bug.

Pipelines

Now lets go on to the next stuff, we get after installing Commerce Connect.

As you can see in the graphic above we get a bunch of new config file and within these configs a bunch of new commerce related pipelines. These pipelines are an essential part of Commerce Connect. Within the graphic above you can for demonstration reason see the AddCartLines pipeline. The left graphic shows, what is installed within the standard Commerce Connect packages, from Sitecore Commerce Connect Core. There we only get a standard pipeline with some really basic processors, which in the end only trigger analytics events and handle xDB stuff. The magic we get with a new config file, which we get after installing Sitecore Commerce Engine Connect. The right graphic shows, that the new config file patches the existing pipeline with custom processors, especially e.g with the processor AddCartLines. These patches and processors hold all the business related logic to establish a proper connection to the external commerce system, in this case Sitecore XC. These processors in the end make the rest API calls and communicate with the commerce engine. Both configs together build a fully working and functional pipeline to on the one hand trigger external system logic, and on the other hand track everything within Sitecore XP xDB.

The question now is, how are these pipelines  be triggered. The answer comes in the next chapter API.

API

Last but not least, what I want to mention within my article is the OOTB available API Sitecore Commerce Connect gives us to interact with external commerce systems. From the previous chapter, you already know, that we got a bunch of different pipelines. Now we see, how we can trigger these pipelines from code.  Sitecore Commerce Connect is delivered with a various number of so called Service Provider. If you use these service provider from Commerce Connect, in the end the corresponding pipelines are called and executed and you do not have to take care of anything else, just using these service provider correctly.

Bild3

Above you can see such a service provider call from an implementation of Sitecore Comemrce 8.2.1. As you can see, there is some piece of business logic with grabs the parameter, checks them and builds up the necessary request object for our commerce connect call. Then the commerce connect call, in this case, UpdateCartLines is executed with its request object. As result we get a very specific result object, which holds the information, if the call was successful, if not the error, and the inner object, in this case the modified cart object, which we then can use for our further purposes.

All these Commerce Connect calls are structured in the same way. They have their own request and result object, and only have to be triggered correctly.

Within Sitecore Commerce 8.2.1 we still had to implement our business logic around the commerce connect service provider.

But from Sitecore XC on, we do not have to do that anymore, cause from that time on, Sitecore integrated commerce functionality into the SxA including such implementation for commerce connect service provider.

As you can see in the image below, you can find these implementations in the DLL Sitecore.Commerce.XA.Foundation.Connect.dll und the namespace Sitecore.Commerce.XA.Foundation.Connect.Managers2018-10-19 19_44_14-JetBrains dotPeek

There you can find the various Managers to interact with Commerce Connect, like CartManager, CatalogManager etc.2018-10-19 19_44_27-JetBrains dotPeek

If you have a closer look at on of these Managers like the ICartManager, you can see all the available implementations, which can be used within your Sitecore XP solution, without the need to write a single line of code.

2018-10-19 19_45_21-JetBrains dotPeek

Note: If you reflector through the implementations, you will notice, that some of the functionalities of Commerce Connect are not implemented right now. These functionalities, then would have to be implemented by you on XP and if necessary on XC side, to be fully working.

2018-10-21 14_35_08-JetBrains dotPeek.png

Conclusion

Within this article you learned how Sitecore XP and XC are connected. You saw the different parts like, items, pipelines and API you get with the installed middleware. And especially how you can influence the standard behavior and where you have to make your changes for your custom business needs.

Sitecore XC 9.0.2 – Walkthrough of creating your own product importer with various pitfalls

Sitecore XC 9.0.2 – Walkthrough of creating your own product importer with various pitfalls

This time I would like to show you, how to create a custom product importer within Sitecore Commerce Engine as a custom plugin. For demonstration reason I also created a small github repo with all the code I present within this article.

Note: This code should be used only for demonstration and learning purpose. It has not been tested extensively right now, and should give you only an idea, of how to create your own importer within Sitecore Commerce Engine. Based on that implementation, your development could be much faster, without stepping into every pitfall 😉

Idea

If you followed my blog posts, you will have noticed, that I have already written about the engine in general, revealed some misunderstandings in architecture and concepts and put everything together to create a new demo plugin based on some real customer business needs.

This time I though again about a topic, which comes from real world requirements and which might be complicated to implement without any previous idea or help. The outcome now is a plugin, which demonstrates, how to import all kind of commerce stuff related to a catalog.

Basic Architecture

The basic architecture used by commerce engine in general consists of Pipelines. Examples of such pipelines are ICalculateSellableItemSellPricePipeline or ICreateCategoryPipeline. Pipelines itselves consists of a various number of Blocks, which are executed one after another, while running through the pipline. If you want to have a look at all the pipelines and blocks used by commerce engine, you can read about it in the Chapter The Node Configuration File explained below.

The NodeConfiguration file explained

Beside the standard commerce engine log file, you can additionally find a NodeConfiguration_***.log file under /wwwroot/logs folder, like seen below.

2018-09-09 13_42_32-logs.png

For every startup of the application such configuration file is created. It holds all the information about used and configured pipelines of the current commerce engine.

2018-09-09 13_42_01-_C__inetpub_wwwroot_CommerceAuthoring_Sc9_wwwroot_logs_NodeConfiguration_Deploym.png

An example of such a NodeConfiguration file you can see above. In the beginning it has some basic information about the instance. After that the structure is always the same. You see a pipeline with its same and parameter and with a small indent all the blocks also with parameters.

2018-09-09 13_39_57-_C__inetpub_wwwroot_CommerceAuthoring_Sc9_wwwroot_logs_NodeConfiguration_Deploym.png

Above you can see one specific pipeline, the IGetSellableItemPipeline in detail. In red you can see the fully qualified name and in brackets the parameter used by that pipeline. In yellow I highlighted all the block, which belong to the IGetSellableItemPipeline. There are blocks like GetSellableItemBlock or GetSellableItemCatalogBlock.  If this pipeline is executed all the blocks are respectively executed one after another from top to bottom. In green you can see two types highlighted. Every pipeline and every block consists of those information. The first parameter describes the input paramter used by the pipeline or the specific pipeline block. And the second parameter describes the output in the end.

Note: The output parameter of one block has to match to the input parameter of the next block 😉

Of course you are always able to create your own pipelines within your plugins from scratch or hook into existing pipelines by adding your own blocks. This is done by adding them correctly within the ConfigureSitecore.cs file. An example of such a configuration is seen below.

2018-09-09 13_59_18-Customer.Sample.Solution - Microsoft Visual Studio.png

The Magic of Pipelines & Commands

The question now is, how do we build now our own import functionality with these information?

If you have a closer look to all the Pipelines, you will recognize, that there are a lot of pipelines we can directly use. For example we have all kind of pipelines to handle a catalog. The ones, which are interesting for us are for example CreateCatalogPipeline, GetCatalogPipeline, EditCatalogPipeline. The big advantage is, that these pipleines are parts of the commerce engine implementation, that they are already used by other parts of the commerce engine, for example within the UI interactions inside the Commerce Business tools and that they consist of all the blocks, which handle underlying functionality, like interacting directly with the database.

To use now such pipelines, commerce engine provides us with corresponding command classes. These commands are responsible for collecting needed parameters, creating the proper argument class, which the pipeline needs including verification and in the end to execute the corresponding pipeline properly. So we also get rid of all the logic to properly execute pipelines.

Whats import to know now for us is, that if we want to use commerce engine functionality within our custom plugin, we only have to find the proper command class, instantiate it and use its built in Process method to initiate the corresponding pipeline, which itself initiates the corresponding pipeline blocks.

Basic structure of the importer project

Based on the information we found out in the chapter before, we now can start implementing our own importer.

Below you can see the basic structure of the Plugin.Sample.Importer project.

2018-09-09 14_26_18-Customer.Sample.Solution - Microsoft Visual Studio

This implementation consists of

  • dedicated importer classes, each responsible for a specific commerce entity type (Catalog, Category, SellableItem, SellableItemVariation) within Services
  • dedicated input parameter classes for the importer within Models
  • an extension class for handling some logic within parameterDTOs within Extensions
  • and a Controller within Controllers, which acts as external interface to test all the implemented functionality with Postman.
  • Next Step: Next step would be to create an own Importer Minion within Minions, which interacts with an external PIM system, retrieves all the Catalog information, including Categories, SellableItems and SellableItemVariations and uses all the Services to import these information into the Commerce Engine.

Implementation of the importer

Now we will have a closer look at the individual implementations of the importers. Each one handled in a separated sub chapter, cause even if the basic approach of every importer is the same, importing a catalog, a category, a product, or variant, has its own pitfalls and procedures we have to obtain to get it work.

Catalog Importer

As we already know from the previous chapters, if we want to build our own importer, we can use commerce engine OOTB functionality to do so. So lets have a look at the implementation

2018-09-09 14_49_56-Customer.Sample.Solution - Microsoft Visual Studio

Above you can directly see all the commands used by my catalog import. There are basic ones like GetCatalogCommand, EditCatalogCommand or CreateCatalogCommand. But there are also some ones, which are not so obvious, that they have to be used for proper result. These Commands are for example AssociateCatalogToBookCommand, DisassociateCatalogToBookCommand for Price- and Promotionbook handline or AssociateCatalogToInventorySetCommand and DisassociateCatalogFromInventorySetCommand.

Maybe some of you ask yourself, how can you find out, that these commands are needed? The answer is again, as always, I reflectored the existing code and existing pipelines, like DoUxActionPipelineWithin that Pipeline every UX interaction is handled from the Business Tools, including creating and editing catalogs and other commerce entities. While reflectoring this pipeline, I found out about the existence of these pipelines and commands, which are needed to fulfill such needs.2018-09-09 14_50_14-Customer.Sample.Solution - Microsoft Visual Studio

All these commands of course can be instantiated via Constructor Injection as seen above. Maybe to now get an idea of why it is useful to have such kind of implementation ready, cause even if you use existing pipelines and commands, you have to know about them and use them properly, which is in deed not so easy without any experience or trial and error. But now lets have a look at the code.

The ExecuteImporter function accepts as parameter the current context, the previously mentioned parameter object and a flag if existing catalog should be updated if already existing.

2018-09-09 15_05_10-Customer.Sample.Solution - Microsoft Visual Studio

Now we can examine the single steps of importing / updating a catalog

  1. The first step of our function is, that we try to create a catalog based on the provided data. This command returns null if the catalog already exists, based on the provided Name. Otherwise it would return an instance of the created catalog.2018-09-09 15_05_19-Customer.Sample.Solution - Microsoft Visual Studio
  2. Next step if to check if the catalog was created previously or not to determine if it is allowed to be updated2018-09-09 15_05_25-Customer.Sample.Solution - Microsoft Visual Studio
  3. If the catalog was already existing, we now want to get this catalog from the commerce engine to work with that later on2018-09-09 15_05_33-Customer.Sample.Solution - Microsoft Visual Studio
  4. The next step is very catalog specific. It is about associating the current catalog to a Pricebook, Promotionbook and DefaultInventorySet. To achieve an edit within these properties, we have to be careful, when to call associate and have to be sure that, if it was already associated, it is disassociated before. The code below checks if the current catalog is already associated and if so, if the new association is different than before. If so it automatically disassociates the current book and associates the new one, if it is existing within Commerce Engine. For now these steps are done for both books and the inventory set in the same way only with the individual command.2018-09-09 15_05_42-Customer.Sample.Solution - Microsoft Visual Studio
  5. The last step now is to edit the current catalog entity and set the new information, including the information about Pricebook, Promotionbook and DefaultInventorySet.  Note: Be careful, that these information match the associations done in the step before! It is possible to add here other names, than used in the assoication commands and therefore produce a missmatch. Note-2: Currently there seems to be an issue with programmatic associations and the Business Tools UX. It is possible that, even when you correctly use the commands for association and disassociation, the UX will display wrong, old information even if the engine itself has done the changes correctly. You can check, that the engine already did the changes and the UX display old information, if you then want to manually disassociate the catalog from the price book, that this is not possible and ends in an error message, that the catalog is not associated to the price book, even if it is displayed in the list below.2018-09-01 08_05_48-Microsoft Edge.png So it is possible, that if you have changed the price book this way, the Business Tools will still display the catalog as part of the old price book, even if it is not anymore. Sitecore currently checks if the behavior is a feature wish or bug. Current Ticket ID is 515201. I will add a public reference number later on if one is existing2018-09-09 15_05_51-Customer.Sample.Solution - Microsoft Visual Studio

Category Importer

Next we will have a deeper look at the category import functionality. Compared to the catalog importer, this one is much less specific, as you will see below.

2018-09-09 15_34_30-Customer.Sample.Solution - Microsoft Visual Studio

You can directly see, that we don’t need that extensive number of commands. We only need commands for creation, get, edit, association and “disassociation”.

The ExecuteImport has also nearly the same strcuture, than it was with the Catalog importer. Only the paramerter object has a different type for the specific category needs.2018-09-09 16_49_09-Customer.Sample.Solution - Microsoft Visual Studio

  1. The first step again is, that we try to create a new entity, this time of type category. Therefore we build up the entity ID of the category.2018-09-09 16_49_16-Customer.Sample.Solution - Microsoft Visual Studio
  2. Next we check if the category already existed and if we are permitted to update it.2018-09-09 16_49_22-Customer.Sample.Solution - Microsoft Visual Studio
  3. If the category exists, we try to get an instance of that.2018-09-09 16_49_27-Customer.Sample.Solution - Microsoft Visual Studio
  4. With that instance we try to update the values of that category, in case it was not created previously. If it would be created previously, an edit would be useless, so we try to skip that step then.2018-09-09 16_49_36-Customer.Sample.Solution - Microsoft Visual Studio
  5. In the end, we have to handle parent associations of the given category. Based on the list of given parents, we associate each as parent with the current category. One special thing at this point is, that we have to be careful, if the parent is a category or the catalog itself. Therefore we have to build up the parentId string diffrently.2018-09-09 16_49_46-Customer.Sample.Solution - Microsoft Visual Studio

Note: Maybe some of your already have seen it. Within step 5, when we associate parents to our category, there is missing one thing, which is essential. Currently we do NOT disassociate parents from the current category. Based on the current associations on the category and the given parentName list from the parameters and the deleteRelationShipCommand it would be possible to also do that. But right now this is not so easy to raelize. Below you see, a first approach of doing that

2018-09-09 17_08_01-Customer.Sample.Solution - Microsoft Visual Studio

As mentioned earlier, with the deleteRelationshipCommand, everything would work well. The problem here is to get all the needed information. Parameters are SourceName, TargetName and RelationShipType. The first problem started with the relationshipType of type string.

What do we have to insert here? 

You can see within the comment above, that I found out, what the possible values are, which can be inserted. How I did that? – Again with reflection.

First I had a look a the DeleteRelationshipPipeline and saw the two block belonging to that.

2018-09-09 17_14_02-_C__inetpub_wwwroot_CommerceAuthoring_Sc9_wwwroot_logs_NodeConfiguration_Deploym.png

Then I examined the two blocks, till I found the place where the relationshipType is used and found out the possible values.

2018-09-09 17_13_36-JetBrains dotPeek.png

So this problem was solved. The next issue was now to fill sourceName and targetName properly. TargetName is no problem, cause its the current category entity. But the sourceName is a problem I did not solve till now. You can see, that I experimented with a hardcoded value, which worked perfectly fine. But how do I find out all the current associated categories / catalog from the current category, to find out which one is missing and therefore has to be disassociated. The category class holds information about parentCategoriesList and parentCatalogList as seen above in the code snippet. But there properties only hold Sitecore Item IDs and not entity IDs of commerce engine. At this point I stopped the investigation and opened a Sitecore ticket, of how to properly retrieve a list of parent categories / catalog. Once I get these information, I can continue implementing the disassociation.

Product Importer

 The approach of the implementation of the product importer is nearly the same, than with the category importer. Therefore I will only show an overview of the whole process and will only point out some differences.

2018-09-09 17_47_30-Customer.Sample.Solution - Microsoft Visual Studio

Above you can the the whole process from creation, update check, product retrieval, edit and association, like it is also within category importer. Again we have here the disassociation not implemented, cause of the same reasons.

One special issue I encountered with the editSellableItemCommand. This command accepts an existing instance of a sellableitem as parameter. Therefore I first use getSellableItemCommand to retieve an instance of the current sellableItem, edit it with the new values like, displayName, Description, tags etc. and use that changed instance in the edit command. Unfortunatly this currently throws an harsh SQL server PK already existing exception. It seems that the edit command tries to create a new entity of that already existing sellableItem, which would explain the given error. This issue was also already reported to Sitecore Support.

Another strange thing with this importer was the usage of the getSellableItemCommand.  This command accepts an ItemId as parameter. At first I though I have to easily insert the entityId of the sellableitem, in the way I also added catalog or category entity IDs. The result was an error like this.

Expecting a CatalogId, ProductId and optionally a VariantId in the ItemId: Entity-SellableItem-0000004. Correct format is ‘catalogId|productId|[variantId]’.

So i changed my parameter to “HahniCatalogFINAL2|0000004”. But this produced exactly the same error. Therefore I started again to reflect the logic to see, what is expected as parameter.

2018-09-09 17_56_40-JetBrains dotPeek

What I learned from that piece of code is, that even if VariantId is not mandatory, I have to add the pipe separator in the end, so that we get an array of length 3 after splitting. Otherwise nothing works. So in the end my parameter looked loke this “HahniCatalogFINAL2|0000004|”, which finally worked well.

Variant Importer

Variant importer again looks very similair to all the other importer, especially the product import. Cause most of the time, if we try to access a variant of a product, we first access the product and then access the variants on that product to edit them and then save again the whole product. Therefore most of the used commands are the same, then in the products importer.

2018-09-09 18_07_27-Customer.Sample.Solution - Microsoft Visual Studio

Below you see the basic approach of creating and editing variants.

2018-09-09 18_05_21-Customer.Sample.Solution - Microsoft Visual Studio.png

The only thing we have to know at this point is, that when we want to access product variants, we do that in first getting the product itself and then accessing the variants, edit them and saving again the whole sellable item. At this place we again have the same issue with editSellableItemCommand than we hat with product importer. In addition we do not need to set any association, because this is already done on creation time, with giving the entity ID of the product name.

How to test the Importer

To test all the created fucntionality, I added a dedicated CommandsController, which is responsible to expose all the ExecuteImports from my importer for external usage. Below you see the example of the CreateOrUpdateCatalog function which takes all the parameter, builds the parameter object and calls the ExecuteImport function of the CatalogImporter. In a real world scenario you would either way use such kind of external inferface or especially with PIM imports a scheduled task(Minion) to do all that.

2018-09-09 14_46_58-Customer.Sample.Solution - Microsoft Visual Studio

This function is registered within ConfigureOpsServiceApiBlock with its name, parameter and return type as seen below. 2018-09-09 14_47_10-Customer.Sample.Solution - Microsoft Visual Studio

The ConfigureOpsServiceApiBlock itself is registered within ConfigureSitecore.

2018-09-09 17_28_06-Customer.Sample.Solution - Microsoft Visual Studio

To test the controller call you can simply use a postman, like seen below.

2018-09-09 14_47_38-Customer.Sample.Solution - Microsoft Visual Studio

Conclusion

Within this article you learned about some architecture regarding commerce engine pipelines and commands. With these information, we were able to create some basic importer to demonstrate the usage of these commands and how they work together. In the end we created some basic plugin, with which we are able to build a new catalog with categories, sellable items and variants of sellable items. We learned how to avoid some tricky pitfalls, and which command has to be used with which parameter, to save our valuable time in the future.

But nevertheless we still have some issues and todos left open with editing sellable items and variants after creation and some mismatch in displaying changed associations within Business Tools. Hopefully in the near future we will get some feedback on these issues to finalize the basic functionalities.

Next steps then would be

  • Create a minion as demonstration of external PIM system integration
  • Add importer functionalities to also import custom view properties generated with the Composer
  • Implement proper disassociation of categories and sellable items based on provided information by Sitecore Support.

Sitecore XC 9.0.2 – How to retrieve Composer generated Templates within Sitecore Engine

In this article, I would like to show you, how easy it can be to retrieve properties from sellable Items, which were created by the Composer within the Business Tools.  You only have to know how. 😉

Currently I am building a small plugin within Commerce Engine. For that plugin, I wanted to store some additional information on my sellable items in my catalogs. From the version 9.0.2 we already know, that we are now able to extend our commerce entities within Business Tools, more special with Composer. I already wrote about that in one of my previous blog posts. But a big question now was, how am I able to access these newly created properties within my commerce engine e.g. in a block of a pipeline.

After testing a bit and with the help of Sitecore support I finally was now able to reach that target quiet well.

Demo Scenario

Assuming the case you added a new view in the Composer and inside the View a new Property e.g. Taxes. Now you create a new plugin, find a pipeline e.g. AddLineITemToCart and want to extend that pipeline with a custom block. This block should now have a look at the item which is going to be added, and depending on the value set in the Merchandise Manager it should react and do something with that. Because the Composer uses its own structure and you have to know how things are composed and saved, its not so easy to get access to these values.

Retrieve any Component within Commerce Engine

In general you are able to access nearly everything with the same approach. Sitecore Commerce uses a feature called composition. Normally in a object oriented application, we use inheritance to extend models or entities. Commerce Engine uses composition. This means, we have a “standard” model. And this model is extended by adding all kind of other components to that model.

2018-08-01 14_27_39-Postman.png

In this example you can see a “standard” cart but extended with a custom porperty LoyaltyComponent added via composition.

2018-08-01 14_28_13-Customer.Sample.Solution - Microsoft Visual Studio

2018-08-01 14_47_37-Customer.Sample.Solution - Microsoft Visual Studio

To achieve that you just have to create that new Component and use that component on your basic model. The result of that piece of code is the json output you see earlier.

Retrieve Components from Composer

Basically the same technique is used also for retrieving stuff created by the Composer. Lets assume we extended our sellable item template with a new view Custom Plugin View and property Taxes.

2018-07-31 20_09_30-Customer.Sample.Solution (wird ausgeführt) - Microsoft Visual Studio

How do we now retrieve this 0.07 ?

Honestly its quiet easy. With the information above and some Sitecore help you can see the result below.

2018-08-01 14_50_19-Customer.Sample.Solution - Microsoft Visual Studio

This example shows within the AddLineItemToCartPipeline, how we can get from the commerce context at first the sellableitem behind the lineitem from the pipeline. Next it retrieves the ComposerViewComponent from that item. Thats exactly the view we can see within Merchandise Manager. With this information we can the concrete composer view with the correct key in the next step. In the end we just have to access the properties list and access our needed property by key / name.  So within the taxValue property we exactly have the value stored we entered in Merchandise Manager within our view within our Taxes property.

The exact same ways you can enter various custom views, with various custom properties. It would not matter anymore. The general approach of getting that stuff is always the same.

 

Sitecore XC 9.0.2 – What has been changed?

After Sitecore released the new Sitecore XC some time ago and I was able to have a look at that new Version, I was really excited about that. One the one hand Sitecore finalized the transformation from old legacy Server to the new .NET Core Authoring System. But on the other Hand there were unfortunately some missing functionalities like easy template creation, publishing & versioning, commerce item deletion, or easy commerce user creation. Sitecore itself said, that all These missing functionalites are going to be added in the next Version- so 9.0.2.

Because of that I am even more excited to have a close look, what Sitecore added in that new release. For more Information just have a look at one of my previous articles Sitecore Commerce 9 – What is new?.

I know there are a lot of new features and improvements in this version, but in this article I would like to Focus on the new Features and changes Sitecore made, especially regarding the limitations I already figured out in the past and explained in some blog Posts.

Versioning & publishment of Commerce Item

From Version 9 on Sitecore totally removed the old legacy Microsoft commerce Server and replaced it completely with the authoring System based on .NET Core. So from now on every functionality had to be delivered by that new System. In the Microsoft commerce Server there was a technique called Staging which was responsible e.g. for a proper publishment of the commerce items like catalogs, products etc. The Problem now was, that this Feature has not been implemented in the Version 9.0.1. So there was the Problem, that CM and CD System shared all the commerce items and every Change on CM had a direct influence on the CD System. For the initial Problem just have a look at the detailed Explanation of an older blog post Sitecore XC – How to properly publish Commerce Items? 

With this new release Sitecore finally implemented a versioning & publishment of also commerce items. So from now on you can on the one Hand track changes made on commerce items and on the other Hand you are now able to Change commerce items and publish them at a time you define with a proper workflow mechanism. Most likely this mechanism is not the Standard item workflow, but a Special commerce workflow which is configured from inside the Business Tools, like already possible with Price cards and Promotions.

In one of the next blog post I will give a deep dive into that technique to have a look, how it is being used and what is special in using this especially for content authors and developers, so we can maximize the benefit of that Feature for the customers

Work with Commerce Templates

In older versions of Sitecore Commerce like 8.2.1 also the Feature of creating, adapting, deleting templates of commerce Content was taken over by the legacy Microsoft server. From Version 9 on this Server was totally removed, but also this functionality of manipulating templates of commerce Content was not fully implemented by Sitecore. The problem is, that commerce Content are no real items, and that templates of These items are only Synced with the external commerce system. A direct change withing Content Editor of These templates lead to a complete unexpected behavior of the commerce System. Sitecore XC totally relies on the data stored on the global and shared environment databases in the new entity structure. From within there, all changes are synced to sitecore to also have it within Sitecore XP. But changing it directly in the XP would not lead to a change in the XC functionality, which means, the Systems differ from each other, which lead to various errors. The problem now was, that it was obvisously not possible to Change templeates within Sitecore, but the feature to change it e.g. in the Business Tools, was not implemeted right now, which made it quit complicated to create your own commerce templates. For detailed Information just read an older blog post of me Sitecore XC – How to delete Commerce Items in Sitecore?

If you have a look at the release notes of the new release, the first new Feature is a so called Entity Composer within Business Tools to easily adapt commerce entities like adding custom Attributes. From what you can see in the Entity Composer Manual it is completly what was missing and should perfectly fill the gab described in my older blog post.

Of Course we Need to deeply have a look at this new application, how it works and if it is now really so easy to do all that. But at first look this look quiet promising for me. Of Course I will have a deeper look at that Feature in one of my next blog Posts.

Delete Commerce Content

While having a look at the older release of Sitecore XC and playing a bit with catalogs, categories and sellable items, I also tried to remove stuff which, was accidentally created. After searching for a while, I was not able to find any delete button within the Merchandise Manager. The only solution within the Manager was to disassociate items from each other, so they disappear. Other ways were deleting them directly from the SQL Server, which is possible, but quiet dangerous. See Details in the following article Sitecore XC – How to delete Commerce Items in Sitecore?

From what I can see in the Manuals and release notes, a deletion of commerce items is still not possible. The only Thing mentioned in the Manual is the disassociation of items, so they are removed then

Disassociate a subcategory from a parent category

If you disassociate a subcategory from a parent category, that subcategory and any subcategories or sellable items contained in it are removed from the catalog, unless the subcategory is already associated with other categories or the top level of the catalog. For example, if you have a subcategory of Refrigerators contained in the Appliances category, and a subcategory of Mini that is contained in the Refrigerators subcategory, and you decide to disassociate the Mini subcategory, that subcategory and all sellable items contained in it will be removed from the catalog. However, you can associate a subcategory and the sellable items it contains to a different parent category, or the top level catalog.

See Details in that Manual entry.  So by now the official way of removing unwanted categories or sellable items is to only disassociate them from each others. When I think about that procedure this also makes sense from the Analytics Point of view. Think of the following Scenario.

You create a catalog with some categories and some products. Now you are going to “remove” some products from your catalog because they are not sold anymore. What happens, if you remove the items is, that within Analytics you see a mystical item id which does not exist anymore e.g. in top sellers or other statistics. It is getting also getting worse if you later on want to add that product again. You would create a new Entity which creates a new item with a new item ID. So from that time on you also get two Analytics entries, which belong basically to the same product. This is most likely not wanted in production Environments. Therefore it is a good technique to just disassociate items and associate them again later on. We had already similar issues while implementation, which lead to the solution not to delete sellable items anymore in production, but to disable them and enable them later on if necessary.

But for development and testing Environments, it would be still a big Advantage to have some Kind of OOTB delete functionality, because if testing and development developers and users often create a lot of garbage you want to clean up from time to time.

So hopefully it is already now possible to delete commerce Content or it is going to be implemented in a later Version.

UPDATE:

As I have mentioned, within the official documentation I did not find any reference to a newly added delete functionality within commerce applications. But now that I have installed the latest Sitecore XC version, I was glad to finally see a delete button within Sitecore Business Tools.

2018-07-30 18_41_10-Microsoft Edge

2018-07-30 18_41_50-Microsoft Edge

Finally you can now delete catalogs, categories, products, variants with one click, as seen above.

Create Commerce User within Business Tools

On of the limitations of the older release was quiet annoying and not very obvious. Within Sitecore XC you are able to create Commerce User either way with the Storefront (SxA) and therefore the Commerce Connect API or directly in the Customer Manager within the Business Tools. Within the Storefront everything also went quiet well and the creation of the user worked perfectly fine. But when you tried to create a user within the Customer Manager you had the problem, that everything went well and a user is created. But on the second look, I recognized, that there was no password set within the creating and that there was no possibility to set it afterwards. So in the end this user was not really usable without a password. See this article for detailed Information Sitecore XC – How to create a Commerce User.

If I have now a look at this release and especially at the Manual of the customer Manager, I can see that some Kind of Password Managing in the Manager is still missing. From what I can see in the Manual you are able to do the following things.

A Customer Service Representative (CSR) or Customer Service Representative Administrator can perform the following tasks on customer accounts:

  • Edit customer accounts. This includes:
    • Editing names, phone numbers, and email addresses.
    • Changing the language associated with the account.
    • Changing or adding addresses to the account.
  • Track customer orders.

See the customer Manual for detailed Information.

To be sure, I will definitely have a deeper look after Installation to see, if it is really not possible  till now. But as always, the second way of customer creation still works and is the first choice of customer creation for Sitecore.

Possibility of data migration from 8.2 to 9.0.2

I did not mention some limitations here, because I never tried to make such an upgrade within my initial Analysis. But in deed in was not OOTB possible to migrate all your Profile or catalog data created in the old legacy Server to the new authoring System and the global and shared databases. The only way was to Export your data from the legacy Server via XML and write your own plugin to use that XML to Import them in your new authoring System.

With this new release of Sitecore XC Sitecore provided an OOTB command line tool to migrate all your data from legacy Server. Here you can find the tool and the guide for detailed Information. This will definitely be a huge benefit for all developers and Partners and will safe a lot of time and money, who have already implemented a Commerce solution based on Sitecore Commerce 8.2.1 and now think of an upgrade to the newest Version.

In one of my later blog post, I will try to do such a Migration and share all the made experiences with the new tool.

Summary

To sum up, this new release has a lot of improvements, bugfixes and new Features and I really think Sitecore again made a big step Forward to have a powerful and stable commerce System. A lot of limitations from the older Releases I recognized were now completely implemented together with a lot of other Features.

I am really excited to install this Version on my own to experience all These new Features by myself. Stay tuned for more deep dives and experiences…

Sitecore Rich Text Editor (RTE) – Customize the colorset automatically in a multisite context

Recently I got a customer request to customize the sitecore rte to use automatically an individual color set, depending on the the site context, where the rte is being used. Because I think that this requirement is quiet cool, it helps the content authors a lot and the solution is pretty simple but effective, i would like to share the solution with you.

For that i will first show step by step, how the rte can be customized in general by overwriting the common rich text configuration class. After that I will point out, how easy the adaption of the used color set is. And at the end I will describe in detail the architectural idea of adapting the color set completely automatically.

Customize your RTE

To customize your rte in general you have to follow only two steps.

First implement a new cs class e.g. “CustomRichTextEditorConfiguration”, which can basically look like this:

///
/// Custom RTE Editor Config Class
///
public class CustomRichtextEditorConfiguration : EditorConfiguration
{
   ///
   /// c'tor
   ///
   public CustomRichtextEditorConfiguration(Item profile)
   : base(profile)
   {
   }

   ///
   /// Overload of setup editor
   ///
   protected override void SetupEditor()
   {
      // Custom Code
   }
}

Based on that class you can start your customization and e.g. the the colors, stylesheets to use for the editor and so on…

Second we have to register that new class as our new Rich Text Editor Configuration class. We do that by simply add a new configuration file under “/app_config/include”

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <settings>
      <setting name="CustomizedColorSet" value="true" />
      <setting name="HtmlEditor.DefaultConfigurationType"
value="YOURNAMESPACE.CustomRichtextEditorConfiguration,YOURASSEMBLY"
patch:instead="setting[@name='HtmlEditor.DefaultConfigurationType']"/>
    </settings>
  </sitecore>
</configuration>

Thats all. Now everytime a RTE is beeing opened, your configuration class in the SetupEditor() is entered to execute your adaptions.

Set new colors

Normally, when you open the RTE without customization, you get a default set of colors provided by the rte itself.

2017-04-25 09_40_30-Content Editor

To customize that color set you easily use our previously built class. In that class we can access the stored color set and possibly modify it via the following way

base.Editor.Colors.Add("#FF0000");

where the inserted color is in hex format.

NOTE: If you easily add new colors this way, sitecore overrides the default color set and starts a new one.

2017-04-25 07_49_09-Content Editor

To handle that problem, store the default color set in a temporary variable and add these colors again to the rte if you want them to be displayed, too.

Automatically add a individual colorset depending on the site context

At first I want to say some words to the architecture of our multi site environment, so you get a better understanding, of the challenge and why the customer wants that kind of requirement.

In our project we provided the customer with a single page type, because the microsites are only one pager and a base set of various modules, like text, slider, maps and so on. The problem with the provided features, was, that all of the microsites at the end looked the same, because they uses all the same templates and the same standard styles. To solve that we provided the customer with a full possibly of customizing each microsite individually. That means, the content author can add content as he did before, but now can also set various style rules e.g. background colors, font colors, sizes, fonts and so on. With that feature each microsite got its own look and feel and each micrsoite could look totally different, depending on the requirements of a specific site. The basic approach or that was on the one hand side the introduction of an global setting item, which stores all possible values, the author can change, and on the other hand to use all these values to create the css for each site dynamically on save of that settings item.

2017-04-25 07_18_39-Content Editor

The wish of the customer now was, that when the content author adds an rte on the site the defined color set is generated out of the provided colors in the settings item, so the look and feel of the page and the specific corporate brand is correct, without searching the correct color in the default color set.

To solve that problem i did basically the following steps described as pseudocode

2017-04-25 08_25_37-unbenannt - TeXstudio

Note:

  1. The colorset has to provide a datastructure to removoe duplicated entries, otherwise every occurence of the color in the settings item is displayed in the color set of the rte seperatly.
  2. You can find out the current Item Id by accessing the query prameter of your httpcontext at the query string parameter “id”
  3. You can implement the Find Root Page simply by traversing up to the root item of your current Item. Do not use the current Site based on the url directly, because in a multisite context you cannot ensure, that a content author uses a dedicated url for content editing. In our cases e.g. the authors all use a common url to enter the sitecore backend. So the safest way of retrieving the root item is to find it based on the the location of the current item and traverse through the content tree.
  4. To identify if a specific Itemfield is a color field, we used a dedicated field name notation. All our colorfields start with the prefix “hex_” so we can easily identify them programmatically by checking on “startswith” or something like that.

The result of that implementation is the following. For demonstation reason I created two settings, a Red Color Setting and a “Raindbow” setting to demonstrate the difference after opening the rte.

The next screens show an extraction of the settings item together with its output in the rte

You can see that the color set of the rte is taken from the edited colors of the settings item. If an author changes entries in the settings item the rte automatically adapts itself to that changes.

I hope this little article helps some of you in customizing your rte.

Erfahrungen mit dem Sitecore Experience Accelerator

Nun gibt es den Sitecore Experience Accelerator (kurz SxA) schon eine Weile.  Allerdings gibt es nur relativ wenige Entwickler, die sich wirklich einmal bislang damit auseinander gesetzt haben. Da ich die Idee hinter dem SxA wirklich gut finde, war es nun auch für mich Zeit sich einmal detaillierter damit auseinander zu setzen. Den besten Rahmen hierfür bot der diesjährige Sitecore Hackathon, da eine der dort gestellten Aufgaben die Entwicklung eines neuen SxA Modules war. Bei diesem habe ich zusammen mit Sascha Heyer. und Marina Gluzberg. als Team “Sitecore Triumvirate” teilgenommen. In diesem kleinen Artikel stelle ich den Weg von der Ideenfindung über die Implementierung bis hin zum Ergebnis einmal dar und zeige, wie gut das Entwickeln mit dem SxA in der Praxis funktioniert.

Was ist der SxA

Für alle, die noch nicht wissen, was genau der SxA eigentluch ist. Der SxA dient in erster Linie dazu, die time to market also die sogenannte Phase 1 zu minimieren, umso Ressourcen, Zeit und Kosten zu sparen, damit diese in die wichtigen Anforderungen für bspw. Personalisierung, also eine Phase 2 investiert werden können. Weiterführende Details hierzu kann man bei Sitecore selbst oder diversen Blogbeiträgen, wie Initial thoughts on Sitecore Experience Accelerator (SXA) oder Sitecore Experience Accelerator – What It Is And Why It Matters nachlesen, da ich hier nicht speziell mehr darauf eingehen werde.

Ideenfindung

Kommen wir aber direkt einmal zum interessanten Teil, der praktischen Arbeit mit dem SxA. Das erste was hier anstand, war natürlich das Entwickeln einer Idee. Hier sind wir allerdings sehr schnell, nachdem wir uns die bestehenden Feature angeschaut haben, bei Forms ausgekommen. Wenn man den Bereich Forms aufklappt, erkennt man dort nur eine “Web forms for Marketers” (kurz: WFFM) integration.

2017-03-19 18_01_31-.png
Abb. 1 SxA Features im Bereich Forms

Da wir einerseits bereits in der Vergangenheit so unsere Schwierigkeiten mit WFFM hatten und wir hier klares Optimierungspotential sahen, hatten wir uns dazu entschieden ein neues Formularmodul für den SxA zu bauen. Der Leitgedanke dabei sollte sein das Pflegen von Formularen intiuitiver und einfacher zu gestalten.

Architektur

Da Sitecore selbst es als Best Practice ansieht, aber auch weil der SxA selbst diese Architektur nutzt, haben wir uns bei der Implementierung des neuen Features strikt nach der Helix Architektur gehalten. Das heißt einerseits die Strukturierung der Solution in die Bereiche Foundation, Feature und Project, anderseits, dass alle Bestandteile bspw. eines Featurs innerhalb des Featureprojekts liegt und keine Abhängigkeiten zu anderen Featuren existieren, sondern nur in die darunter liegende Foundationschicht. Abb. 2 veranschaulicht die angelegte Solution.

2017-03-19 18_07_50-Hackathon.Sitecore.Triumvirate - Microsoft Visual Studio
Abb 2. Aufbau der Solution

Hinsichtlich der konrekten Architektur des neuen Formularmoduls hatten wurde überlegt, inwieweit man eine einfache und intuitive Pflegbarkeit erzielen kann. Die Idee war nun, dass ein Redakteur zu Beginn eine Art Formularcontainer, ähnlich wie beim bestehenden Formmodul, auf die Seite zieht. Somit würde der Rahmen des neuen Formulars bestimmt werden. Ab hier soll sich nun das neue Modul vom bestehenden Abheben und weiterhin vollständig über die Toolbox des SxA pflegbar sein. Der Redakteur kann nun weiterhin entweder Formularmodule, wie einfache Eingabefelder, Checkboxen, Datepicker oder sogar den Sendenbutton in den Container plazieren. Andererseits allerdings auch alle anderen bestehenden SxA Module, wie Image-Text- , Slider-  oder Textmodule. Das besondere ist, dass sogar die gelieferten Splitter innerhalb des Formulars plaziert werden können, um so sogar innerhalb des Formuals Aufteilungen in Zeilen und Spalten zu untersützen. Dies ermöglicht es dem Redakteur vollständig individuelle Formulare mithilfe des Drag & Drops Features der Toolbox zu erstellen, was ein klares Alleinstellungsmerkmal gegenüber der bestehenden WFFM Integration darstellt.

Hürden bei der Implementierung

Da bei der Implementierung von SxA Featuren doch einiges zu beachten ist, stellte mich die Entwicklung neuer Module zu Beginn vor gewisse Herausforderungen. Allerdings muss ich direkt anmerken, dass mir die Anleitung “Walkthrough: Building a new rendering” hierbei sehr geholfen hat. Anhand dieser Dokumetnation war es gut nachvollziehbar, warum man genau, wann welche Komponenten benötigte.

An dieser Stelle würde ich gerne lediglich auf die beobachteten Probleme mit der Arbeit im SxA eingehen und an welchen Stellen es einige Zeit brauchte um das gewünschte Verhalten zu erzielen.

Die Implementierung der ersten Controller, Views und Rendering verlief noch vergleichsweise problemlos. Als wir jedoch das erste mal versuchten unsere neuen Renderings in der Toolbox auswählbar zu machen, trat das erste Problem auf. Wir haben im besten Erwarten einfach innerhalb von  “/sitecore/layout/Renderings/Feature/Experience Accelerator/” einen neuen Ordner mit dem Namen “Hackathon” angelegt, wo wir all unsere neuen Renderings abgelegt hatten. Diese hatten wir auch unter “/sitecore/content/Theme/Theme Theme/Presentation/Available Renderings” analog angelegt und hinzugefügt. Allerdings hat sich in der Toolbox nichts getan. Zum Vergleich hatten wir unsere Renderings in einen bestehenenden Ordner, wie Page Content abgelegt. Und natürlich wuden Sie direkt im Experience Editor in der Toolbox an der Stelle Page Content angezeigt. Es galt also unseren neuen Bereich “Hackathon” irgendwo zu “registrieren”, damit die Toolbox dies auch ausspielen kann. Da der Weg dorthin, doch recht umständlich ist, allerdings viele betreffen wurd, würde ich ihn gerne einmal hier beschreiben.

  1. Füge unter /settings/Feature einen Ordner mit dem Namen des neuen Moduls an
  2. Lege dort ein Site Setup Item vom Typ Site Setup Root an
  3. Füge ein Add Available Rendeirngs Item vom Type AddItem hinzu (Abb. 3)

    2017-03-21 10_43_12-Content Editor
    Abb. 3 Einstellungen am Hackathon Site Setup Item
  4. Füge unter /templates/Branches/Feature einen Ordner mit dem Namen des neuen Moduls an
  5. Lege darunter ein neues Branch Template an mit der Basis Available Rendering an
  6. Wähle nun in diesem Available Rendering Item mit dem Namen $name alle Renderings aus, die in der Toolbox auswählbar sein sollen. (Abb. 4 und 5)

Nach der Ausführung all dieser Steps kann beim Anlegen eines neuen Tenant das neue Feature asugewählt werden (Abb. 6) und es werden direkt in der Toolbox alle Renderings korrekt angezeigt (Abb. 7)

Das zweite große Problem trat auf, als wir anfingen, nach den ersten Rendering auch Themes zu customizen. Das Konzept, wie man Themes bearbeiten ist in der offiziellen Anleitung sehr gut und nachvollziehbar dokumentiert.

Allerdings ist der Prozess ein Theme zu exportieren, zu entpacken, die Dateien zu bearbeiten, das ganze wieder zu packen und dann wieder zu imporieren auf dauer sehr zeitraubend. In unserem kleinen Modul, kam es bereits vor, dass ich diesen Prozess mehrere Duzend male durchlaufen musste, insbesondere, wenn ich kleinere Syntaxfehler eingebeaut hatte, die ich erst erkannt hatte, als das Theme wieder in Sitecore integriert wurde.

Um das ganze etwas abzukürzen, habe ich einen Trick versucht, von dem ich aber in der Tat nur abraten kann. Sobald ein Theme in Sitecore angelegt wurde, liegt es innerhalb der Media Library unter “/sitecore/media library/Project” und dort unter dem Tenant Namen, wie in Abb. 8 beispielhaft erkennbar.

2017-03-21 11_02_37-Content Editor
Abb. 8 Teneantspezifische Themes in der Media Library

Innerhalb des Themes kann man dann auch sämtliche Ressourcen, wie Images, Styles und Skripte finden, wie in Abb. 9 beispielhaft erkennbar.

2017-03-21 11_04_36-Christian Handel says...
Abb. 9 Skriptresource in der Media Library

Ab diesem Punkt habe ich nun nurnoch das spezifische JS file via Download heruntergeladen, es bearbeitet und wieder hochgeladen. Dies funktionierte soweit auch wirklich gut, solange ich mich im Edit Mode bewegte. Die ernüchterung kam, als ich den Preview Mode öffnete und nichts mehr funktionierte. Das gesamte JS und CSS waren mit einem Schlag unbrauchbar geworden und es wurden JS Fehler mit dem Title: Namespace SX not found geworfen. Das einzige was noch halb, war das Theme zu löschen und komplett neu anzulegen und nach dem Schema der Anleitung zu arbeiten mit einem echten Export und Import. Hier gibt es sicherlich noch Verbesserungspotential im Umgang und der Plfege von Resourcen wie CSS und JS.

Resultat

Als Ergebnis nach 24 Stunden Arbeit während des Hackathons haben wir in der Tat eine erste Version des sogenannten “Form Composers” implementiert. Die Kernfeature des neuen Moduls sind

  • Leichtgewichtigkeit durch Reduktion auf Basisfeature und -funktionalitäten
  • Hohes Maß an Flexibilität durch Kombination von standard SxA und Formular modulen
  • Einfache Pflegbarkeit bspw. via Drag & Drop
  • Unterstützung von gängigen Standardformularfeldtypen, wie Single-Line-Text Checkbox oder Datepicker
  • Unterstützung eines Mailversands bei erfolgreichem Absenden
  • Untersützung von Pflichtfeldeingaben und Fehlerfallvalidierung bei nicht-Eingabe
  • Einfache Erweiterbarkeit mit neuen Feldtypen und Funktionalitäten

Durch den neuen Form Composer ist der Redakteur in der Lage auf einfachste Weise mittels Drag & Drop zuerst einen Container auf der Seite zu plazieren und diesen dann nach belieben mit weiteren Modulen zu befüllen. Diese Module können SxA eigene Module wie Slider oder Textmodule sein. Oder es sind die neuen Form Composer Feldtypen, wie Single Line Text, Checkbox oder Datepicker. Das besondere hier ist, dass sogar die SxA eigenen Splitter in Rows und Columns unterstützt werden, so dass der Darstellung des eigenen Formulars keine Grenzen gesetzt sind. So können bereits schnell einfache Formular zusammengeklickt werden, welche einfachste Anforderungen erfüllen, wie in Abb. 10 zu sehen.

2017-03-20 14_24_59-Sascha
Abb. 10 Pflege eines einfachen Formulars

Es können aber auch hoch-komplexe Formulare mit dem neuen Composer erstellt werden, welche in verschiedene Bereiche aufgeteilt ist, mit weiteren Modulen und weit verteilten Eingabefeldern. Ein Beispiel eines solchen Formulars ist in Abb. 11 zu sehen, wo wir zu Demonstrationszwekcen einmal eine Variation des Hackathonanmeldeformulars nachgebaut haben. Hier wurden in den Formularcontainer zuerst die verschiedensten Grids gepflegt, um eine geordnete Aufteilung zu erhalten. Innerhalb dieser Grids wurden dann sowohl standard Module, als auch eignee Formularmodule plaziert.

2017-03-20 14_24_04-Demo
Abb. 11 Pflege eines komplexen Formulars mittels des Form Composers

Das eingesendete Video zum Abschluss des Sitecore Hackathon 2017 zeigt auch noch sehr anschaulich, was alles möglich ist und welches Potential dieses Modul hat. Der gesamte Sourcecode mit Dokumentaion ist unter folgendem Repository zu finden, damit man sich auch selbst ein Bild der Implementierung machen kann.

So läasst sich sagen, dass mit diesem Ergebnis man bereits erkennen kann, dass es verglichsweise leicht ist, mittels des SxA neue Module zu bauen, oder bereits bestehende Module in Seiten wiederzuverwenden, um so individuell auf jeden Anwendungsfall oder Kundenwunsch eingehen zu können.

Fazit

Die Idee des SxA ist Webseiten schnell und einfach zu bauen. Nachdem ich nun einige Zeit damit verbracht habe die ersten eigenen Module und Seiten zu bauen, kann ich sagen, dass im SxA viel potential steckt. Mithilfe des Sets an Featuren kann man bereits viele standard Kundenanforderungen umsetzen. Mit der Zeit lässt sich dieses Set stets erweitern, so dass man diese auch für zukünftige Anforderungen nutzen kann. Theoretisch können während der Entwicklung von neuen Modulen, bereits mit dem bestehenden Set an Featuren Seiten via Wireframing gebaut werden. Mit den ersten Visual Designs kann bereits während weiterer Entwicklungen Content gepflegt werden. So erkennt man schon, dass viele Arbeiten, die früher seriell abliefen nun teils parallel stattfinden. Genau dieser Mehrwert hat in unserem kleinen Team bereits sehr gut funktioniert. Wir konnten auf bestehende Features des Sxa zurückgreifen und via Themes unseren individuellen Wünschen anpassen. Parallel zur finalen Contentpflege konnten noch weitere kleinere Implementierungen bzw. Themeanpassungen durchgeführt werden, so dass zum Schluss aus den gepflegten Wireframes, dem Content und den Themes die mit einem Klick eine fertige Seite entstanden ist.

Das praktische Arbeiten mit dem SxA zeigte an der ein oder anderen Stelle noch einige Schwächen. Es kam bspw. häufiger vor, dass der SxA bei der Pflege im Experience Editor leider noch abstürzte. Bei der Pflege bzw. dem Anpassen von Thems ist der Prozess das Theme erst herunterzuladen, zu entpacken, seine Änderungen durchzuführen, das ganze wieder zu packen und zum Schluss wieder zu importieren auf dauer sehr umständlich. In unserem Fall dieser Prozess einige dutzend mal durchgeführt werden, bis sowohl CSS als auch JS so waren wie sie sein sollten. Hier wäre es sicherlich sinnvoll dem Entwickler eine einfachere Möglichkeit zu geben Themes anzupassen.

Nichtsdestotrotz hat Sitecore mit dem SxA ein jetzt schon bemerkenswertes Modul erschaffen, welches das Potential hat die einfache Webseitenimplementierung mit Sitecore zu revolutionieren.

Sitecore Commerce 8.2.1 – How can the new commerce be classified ?

Recently, the new Sitecore Commerce has been released. In an earlier article, I have already dealt with the question of what the new Sitecore Commerce is and how it is technically built. Now I would like to focus on the question

How can the new Sitecore Commerce be classified?

In order to answer this question adequately, I will first give an overview of what e-commerce really is, what commerce systems exist and what modern commerce systems have to do in order to survive the market. In the following, I will show the characteristic feature of the new Sitecore Commerce. In conclusion, I try to make an assessment as to whether the new Sitecore Commerce is able to keep up with its features.

Definition

To say what e-commerce is actually exactly, I start with quoting here simply the Wikipedia definition of e-commerce:

E-commerce is a transaction of buying or selling online. Electronic commerce draws on technologies such as mobile commerce, electronic funds transfer, supply chain management, Internet marketing, online transaction processing, electronic data interchange (EDI), inventory management systems, and automated data collection systems. Modern electronic commerce typically uses the World Wide Web for at least one part of the transaction’s life cycle although it may also use other technologies such as e-mail. …

Following this definition, e-commerce begins as soon as sales processes are processed online. This includes things such as “Online shopping”, “Online Marketplaces”, “B2C” (“Buisness to Customer”), “B2B (Buisness to Buisness) Transactions” etc.

Classification of commerce systems

If you look around the market, you will quickly see examples of various e-commerce systems. So there is “Amazon”, “eBay”, “Magento”, “uCommerce”, “hybris”, “Woo Commerce” to name just a few of the more well-known There are already a lot of commerce systems on the market. The question now is how does all these systems differ from each other?

To answer this question, we can try to classify e-commerce solutions very roughly into different categories, so as to recognize where the individual systems are located.

  • Entry-level solution
  • Professional applications
  • Enterprise-Systeme

Entry-level solutions are characterized by the fact that they are more suitable for simple business models with a small range of products, few connections to external interfaces and usually without programming knowledge. The budget for such solutions is also very low compared to other systems. However, these systems do not allow for large individualizations. Examples include “Woo Commerce” or “Drupal Commerce”.

Professional applications, on the other hand, already have higher requirements, for example because of a wider range of products. This makes it necessary to offer fancier and intelligent search and filter possibilities. In such solutions, it is very common to use various external interfaces, which then have to be connected, what results in a higher complexity. Also, because of these reasons, it is expected that visitor numbers will be significantly higher than entry-level solutions, resulting in higher performance requirements. Such solutions are generally also associated with higher costs, for example, in licensing or implementation. However, it is then also possible to customize the solution in a way, that the personal requirement are fulfilled. Examples of this would be “Magento” or “Shopware”.

Enterprise systems are located where highly complex customer and distribution structures prevail. On the one hand, the associated license costs for such solutions are many times higher than, for example, in professional applications. On the other hand, some high implementation costs are also necessary in order to tailor the solution to the complex, individual needs. The overall costs for such solutions are thus usually drastically higher than, for example, in simple professional applications. Examples of this would be “hybris” or “Intershop”.

Sales

As you can see from the outset, the individual e-commerce systems have their own strengths and weaknesses, positioning themselves in their own market segment. Fig. 1 shows in a very clear way a division into the market of the Top 1000 online shops

picture1
Fig. 1 Shopsystems  Top 1000 Online Shops (EHI/Statista: E-Commerce-Marktet Germany 2016)

Please note that the majority of the diagrams are either proprietary developments such as Amazon or eBay or simply could not be covered by the tool used.

As you can see, the various e-commerce systems exist and all have their own strengths and weaknesses, but the market is clearly dominated by the “proprietary developments”. The remaining e-commerce systems, which are based on certain technologies, already fall back very clearly and only make up a small share. In addition, it should also be clearly stated here that, although some market systems appear to be low on the market, sales are much higher. For this purpose, Fig. 2 can be used. Comparing these with Fig. 1, it can be seen, for example, that hybris has only smaller market shares, but generates higher sales than other systems with higher market shares. Therefore this must always be set in relation to each other.

Picture2.png
Fig. 2 Sales data of the Shop Systems Top 1000 (EHI/Statista: E-Commerce-Market Germany 2016)

As you can already see, the e-commerce market is highly competitive and highly professional.

Demands on commerce systems

The whole subject of e-commerce has been changing for years. Where in the past it was possible to offer their goods online in some way, the demands of the consumers have increased enormously these days. Both usability and design have become more important than ever, and are presumed to be “must-haves”, so differentiation to other shops or systems must take place at a different level. Nowadays it is the core point not to allow the user to make the actual purchase himself, but to accompany him over the entire Customer Journey and to bring him such a shopping experience. In concrete terms, this means to accompany the customer from the information-gathering, the actual purchase decision to the after-sale. Important aspects are, for example, to offer customized information to the customers individually and personalized. Another aspect is the recognition of a customer through various touchpoints, such as social media, emails or the web, across a variety of devices such as smartphones, tablets or notebooks. Such aspects allow to adress customers  with the right information at the right time

Sitecore Commerce feature und functionality

Exactly in this situation is now Sitecore with the new Commerce release. The question is, how does Sitecore deal with this market situation and is even more important, how is Sitecore related to the requirements and market segments. The answer to these questions is essential in order to be able to clarify at this early stage, for which customers, for example, Sitecore Commerce is at all possible, but also in order to clearly identify the differentiation characteristics of the claims. In order to answer these questions, however, let’s look at the commerce with regard to the feature once more.

At this point, I would like to start with an excerpt from the Sitecore Commerce documentation, where a few general technical corefeature are mentioned.

  1. A simple, lean, extensible framework as a core, with all higher-level functionality implemented as plugins.
  2. Provides opt-in complexity by allowing customers and partners to take dependencies on only the information model and behaviors that they need. This allows simple down-market hosted solutions to use complex global enterprise solutions without modifying the core architecture.
  3. Lightweight hosting.
  4. Using the existing Sitecore Connect pipelines for commerce runtime, with a new Service API for business user scenarios.
  5. Using the Sitecore Experience Platform for runtime shopping experience and business users.
  6. The existing subsystems remain in place for backwards compatibility, with opportunities for customers to migrate for newer capabilities and experiences.

Source: (2)

On some of these points, I would like to lay the main focus, as they generally provide a good overview of the scope of functions and the type of architecture.

The first two aspects are related to the architecture of Sitecore Commerce. Basically, the Commerce System is equipped with a basic set of services and features to set up and operate a basic commerce system. Such delivered features are listed in the following table.

Shopping Cart Manage interactions with a shopping cart.
Checkout Accept additional information during checkout.
Order Capture Capture an order after checkout.
Shops Shops support provides the ability to administrate multiple shops, both online branded and physical shops.
Catalog Abstract pipelines for integrating with other catalog systems.
Availability Manage the availability of sellable items.
Inventory Abstract artifacts for integrating with external inventory systems.
Entitlements Manage digital product ownership.
Fulfillment Manage orders fulfillment.
Payments Manage payment integration.
Sitecore Commerce Order Service Post-order capture support.
Sitecore Commerce Pricing Service Dynamic pricing that supports the ability to author and calculate at runtime pricing on products based on date, quantity and currency.
Sitecore Commerce Promotions Service Provides the ability to define and calculate at run time various promotions that the shop owner may wish to support.
Sitecore Commerce Entitlement Service Provides the ability to manage entitlement rights to digital assets to allow sales and support for digital products such as movies, games, or ebooks.
Views Business user focused API for a customizable business user experience.
Dynamic Pricing Manage pricing by date, currency and quantity in the shopping cart.
Promotions A promotion is a unique offer that you present to a targeted group of customers or prospects.
DevOps Support for extension through development and deployment.

Source: (3)

All these functionalities can be set up and administrated by providing business tools such as Customer and Order Manager, Price and Promotion Manager or Merchandising Manager. In my oppinion, this gives you a fairly good overview of the vast range of services offered by Sitecore Commerce and the rough way of administating, even if you do not know at this time, of course, what exactly is behind it. Basically, however, you can say that in terms of the demands on design and useability, for example, Sitecore Commerce has good potential to cover them. However, I had already pointed out in the beginning that this is nowadays not enough to be able to persist in the market permanently. Here, the differentiation factors are very important. Therefore, I now make an attempt to show how exactly this might look with Sitecore Commerce.

Differentiation factors

Now we come to the question of how Sitecore Commerce can differentiate itself from other commerce systems. Even before you have actually seen the system in action or even tried it, this is certainly hard to answer. However, you can now already hold some obvious feature. Here the points 4 and 5 from the previous listing are explicitly mentioned.

Because Sitecore is basically a CMS, which delivers now on top commerce functionality, Sitecore delvers out-of-the-box obviously all advantages or features from the Core Sitecore XP. ´Since the release of the version 7.5, when the xDB was integrated into Sitecore and was introduced the first time, the topics experience and personalization have been developed a lot. According to the Gartner Magic Quadrant 2016, in which the most common CMS systems are compared, Sitecore is clearly one of the leading CMS systems on the market, especially with the latest release of version 8.2, which is the basis for the new commerce. I will not go into the xDB and its feature here, but if you would like to know in detail what is behind the term xDB, you can look at these slides, which bring the whole concise to the point.

Specifically, data on user movements and actions can be gathered, for example, where and how they were on the page, what they looked at, and where they had even jumped from the website. The whole can, of course, also be collected in the area of commerce, where you can then see which products were viewed by customers, how they filled their trays, how often they visited the site, etc.

It is thus possible through the symbiosis of the standard Sitecore XP / Sitecore xDB and Commerce, to track the customer’s entire customer journey from entering via a touchpoint, such as the website directly, a newsletter, for example from the Sitecore EXM, or the social media over the surfing within the website up to the final purchase, neverthelesse which device like laptop, tablet or smartphone is used.  These data are then ideally suited to further improve the customers’ buying experience in the future and thus ultimately enable better user bindings and a higher rate of returnees.

In this context, of course, the complete product staging by means of personalization and the collected data can be designed completely individually for the customer. Starting from the content visible on the pages, which texts are displayed, to the offer of various discounts, advertising campaigns or coupons for different users or entire user groups, by means of personalized rules or data gathered by Sitecore XP.

I would also like to pay particular attention to the performance of Sitecore Commerce. This is the case when you read the documentation or also speak with Sitecore contacts, that special value was placed on a high-performance solution. On the one hand achieved by using .NET Core, the latest development of Microsoft, which is many times more powerful than the old .NET frameworks. Detailed benchmarks can be found here. On the other hand also by optimized pipelines and processes.

Where is Sitecore Commerce

Now that everything has been described, I finally try to answer the question regarding my point of view, how the new Sitecore Commerce can be potentially classified.

With Sitecore Commerce you get a performance-optimized system with a good basic set of common and interesting features. However, it is also possible to extend this basic set at any time, or even to completely customize it, in order to be able to respond to individual requirements of the customer or the market situation. Because of the Sitecore XP, you have nearly unlimited possibilities regarding personalization and experience. So I would order Sitecore in a first resume between professional applications and enterprise solutions. Sitecore, on the other hand, offers everything to meet the requirements of professional applications. On the other hand, it certainly has the potential to be used in the enterprise sector, as it certainly already offers many features differentiation characteristics that  can meet the special and individual requirements in the area of enterprise solutions.

If you take a last look at the demands on onlineshops, I see that Sitecore Commerce has the potential to do it very well by now. The combination of Sitecore XP and Sitecore Commerce has created a symbiosis that can provide a decisive differentiation factor to other systems.

I’m still looking forward to see how Sitecore will surprise us with its commerce system and the next releases and of course what can be seen in a further tecnical deep dive. The next thing you need to look at is whether Sitecore Commerce can hold all of these expectations and requirements, or even exceed them.