Blog posts by Sørby
2017-09-27T23:08:20.0000000Z
/blogs/sorby/
Optimizely World
Add Commerce to an Alloy Web Site
/blogs/sorby/dates/2017/9/add-commerce-to-an-alloy-web-site/
2017-09-27T23:08:20.0000000Z
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<p><strong>I frequently get the question about how to add Commerce to an existing CMS site.</strong></p>
<p><strong>I dreaded that question 5 years ago, but now adding Epi Commerce to an existing web site has really become easy in Visual Studio. It is simply a matter of adding the EPiserver.Commerce nuget package and you are ready. If your site has been based on the Alloy template in Visual Studio there is just a few steps you need to take to have it working seamlessly.</strong></p>
<p>In this post I will guide you through the different steps that needs to be changed.</p>
<h2>Create a new site based on the Alloy (MVC) template </h2>
<p>Start by creating a web site by using the Visual Studio template.</p>
<p>Note! It is important to navigate to the site and add an admin account before adding the EPiServer.Commerce nuget package. </p>
<h2>Remove dependency on SitePageData for the layout</h2>
<p>Much could be said about the SiteContextActionFilter and the use of an IResultFilter for the layout of the site. I will not change that implementation in this blog, but rather adjust it to be less reliant on SitePageData.</p>
<pre class="language-csharp"><code>var model = viewModel as IPageViewModel<SitePageData>; //this code is problematic when we add Commerce. SitePageData inherits from PageData and will not in any way work for Commerce content.</code></pre>
<h3><br />Use ISiteContent for SitePageData</h3>
<p>As A first approach, I will change the layout to use ISiteContent and not SitePageData. This inteface will be added to the Business.Rendering namespace</p>
<p>This change will affect the following files:</p>
<ul>
<li>IPageViewModel.cs</li>
<li>PageViewModel.cs</li>
<li>PageContextActionFilter.cs</li>
<li>SitePageData.cs (Add the new interface to this class)</li>
<li>Layout views
<ul>
<li>_LeftNavigation.cshtml</li>
<li>_TwoPlusOne.cshtml</li>
<li>_Root.cshtml</li>
</ul>
</li>
<li>Partial views
<ul>
<li>Footer.cshtml</li>
<li>Header.cshtml</li>
<li>ReadOnly.cshtml</li>
<li>SubNavigation.cshtml</li>
</ul>
</li>
</ul>
<p>After changing the code to use the new interface several properties needs to be moved to ISiteContent.</p>
<pre class="language-csharp"><code>using EPiServer.Core;
using System.Globalization;
namespace AlloyCommerce.Business.Rendering
{
public interface ISiteContent
{
ContentReference ContentLink { get; set; }
CultureInfo Language { get; set; }
string LanguageBranch { get; }
string MetaTitle { get; set; }
string MetaDescription { get; set; }
}
}</code></pre>
<h2>Add Epi Commerce</h2>
<p>Add Episerver Commerce to the site simply by adding the nuget package <em>EPiServer.Commerce</em> </p>
<h2>Add definition classes for the catalog</h2>
<p>[CatalogContentType(DisplayName ="Category/Node",<br /> GroupName ="Commerce",<br /> MetaClassName ="Alloy_Node", <br /> GUID = "094A1AFE-727A-44A0-A074-36BA07F2D092")]<br /> public class AlloyNode : NodeContent, ISiteContent<br /> {<br /> public virtual string LanguageBranch<br /> {<br /> get { return this.Language.Name; }<br /> }</p>
<p> public virtual string MetaTitle { get; set; }<br /> public virtual string MetaDescription { get; set; }<br /> }</p>
<h2>Add a controller for the category content items</h2>
<pre class="language-csharp"><code>public class AlloyCategoryController : ContentControllerBase<AlloyNode>
{
public ActionResult Index(AlloyNode currentContent)
{
var model = PageViewModel.Create<AlloyNode>(currentContent);
return View(model);
}
}
</code></pre>
<p><br /><br /></p>
<p>Base Controller:</p>
<pre class="language-csharp"><code>public abstract class ContentControllerBase<T> : ContentController<T>, IModifyLayout
where T : CatalogContentBase
{</code></pre>
<p><br /><br /></p>
<p>The view model for catalog content can now be created like the page view models are. This is not going to be sufficient for all content, but in these cases the view model can be created as a separate view model file with additional properties.</p>
<p><img src="/link/b4545e15385342fba6f173ed635f71c3.aspx" alt="Image Alloy Commerce.PNG" /></p>
<p>Catalog UI presenting a Category node with on-page-edit. This node will contain, in the near future, planning products (iPad, Phones etc) sold by Alloy.</p>
<h2>Much more needs to be done</h2>
<p>This example does not give a fully featured commerce site. There are no productes, shipping, checkout, cart, etc. For all of that, please take a look at the Episerver reference site(s) in the public github account (<a href="http://github.com/episerver">http://github.com/episerver</a>).</p>
<h2>Where to find the code</h2>
<p>The repository is located at <a href="https://github.com/pettersorby/AlloyCommerce">https://github.com/pettersorby/AlloyCommerce</a>. </p>
<h2>Thank you!</h2>
<p>The commerce team should be praised for all their efforts in making this journey this easy! Thank you, Magnus and the rest of the team.</p>
</body>
</html>
Missing translations in XML translation files
/blogs/sorby/dates/2016/5/summary-on-missing-translations/
2016-05-29T23:16:39.0000000Z
<p><strong>Most Episerver sites involve working with language files. These files are sadly often neglected during the development phase and give both developers and editors a headache when launch date closes in on the project.</strong></p> <p>There is no silver bullet to magically solve the challenges of translation, but I will here give a small contribution on how to gain insight on missing translation texts.</p> <p>The Episerver Localization Service provides <strong>[Missing text….]</strong> output to spot missing translations, but often these texts are hidden I e-mail templates, validation texts or other, not so visible, places.</p> <p><strong></strong> </p> <p>The image below shows a Spanish version of Alloy where translation fallback have been turned off. There are several [Missing text ‘key’ for Spanish] displayed.</p> <p><a href="/link/046f50a2171446dd92332296b1c7b9a9.aspx"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="/link/695a05dbad1744d282b129faedf02af8.aspx" width="737" height="772" /></a></p> <p> </p> <p>In the Alloy sample site the translation files are mostly located in the Views.xml file in the Resources directory and this file is referred in the web.config file</p> <div id="codeSnippetWrapper" style="font-size: 8pt; overflow: auto; cursor: text; border-top: silver 1px solid; font-family: 'Courier New', courier, monospace; border-right: silver 1px solid; width: 97.5%; border-bottom: silver 1px solid; padding-bottom: 4px; direction: ltr; text-align: left; padding-top: 4px; padding-left: 4px; border-left: silver 1px solid; margin: 20px 0px 10px; line-height: 12pt; padding-right: 4px; max-height: 200px; background-color: #f4f4f4"> <div id="codeSnippet" style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum1" style="color: #606060"> 1:</span> <span style="color: #0000ff"><</span><span style="color: #800000">episerver.framework</span><span style="color: #0000ff">></span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum2" style="color: #606060"> 2:</span> ....</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum3" style="color: #606060"> 3:</span> <span style="color: #0000ff"><</span><span style="color: #800000">localization</span> <span style="color: #ff0000">fallbackBehavior</span><span style="color: #0000ff">="Echo, MissingMessage"</span><span style="color: #0000ff">></span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum4" style="color: #606060"> 4:</span> <span style="color: #0000ff"><</span><span style="color: #800000">providers</span><span style="color: #0000ff">></span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum5" style="color: #606060"> 5:</span> <span style="color: #0000ff"><</span><span style="color: #800000">add</span> <span style="color: #ff0000">virtualPath</span><span style="color: #0000ff">="~/Resources/LanguageFiles"</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="languageFiles"</span> <span style="color: #ff0000">type</span><span style="color: #0000ff">="EPiServer.Framework.Localization.XmlResources.FileXmlLocalizationProvider, EPiServer.Framework"</span> <span style="color: #0000ff">/></span> </pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum6" style="color: #606060"> 6:</span> <span style="color: #0000ff"></</span><span style="color: #800000">providers</span><span style="color: #0000ff">></span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum7" style="color: #606060"> 7:</span> <span style="color: #0000ff"></</span><span style="color: #800000">localization</span><span style="color: #0000ff">></span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum8" style="color: #606060"> 8:</span> <span style="color: #0000ff"></</span><span style="color: #800000">episerver.framework</span><span style="color: #0000ff">></span></pre><!--CRLF--></div></div>
<p> </p>
<p>It is possible to have several providers added to the list of providers. The localization service will return the first value that matches the passed key. If one provider returnes null, the key is passed on to the next provider.</p>
<p>If all providers return ‘null’, the missing text is returned.</p>
<p> </p>
<p>To log missing translations, you can simply add a provider to log keys that have no previous provider.</p>
<div id="codeSnippetWrapper" style="font-size: 8pt; overflow: auto; cursor: text; border-top: silver 1px solid; font-family: 'Courier New', courier, monospace; border-right: silver 1px solid; width: 97.5%; border-bottom: silver 1px solid; padding-bottom: 4px; direction: ltr; text-align: left; padding-top: 4px; padding-left: 4px; border-left: silver 1px solid; margin: 20px 0px 10px; line-height: 12pt; padding-right: 4px; max-height: 200px; background-color: #f4f4f4">
<div id="codeSnippet" style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum1" style="color: #606060"> 1:</span> <span style="color: #0000ff"><</span><span style="color: #800000">localization</span> <span style="color: #ff0000">fallbackBehavior</span><span style="color: #0000ff">="Echo, MissingMessage"</span><span style="color: #0000ff">></span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum2" style="color: #606060"> 2:</span> <span style="color: #0000ff"><</span><span style="color: #800000">providers</span><span style="color: #0000ff">></span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum3" style="color: #606060"> 3:</span> <span style="color: #0000ff"><</span><span style="color: #800000">add</span> <span style="color: #ff0000">virtualPath</span><span style="color: #0000ff">="~/Resources/LanguageFiles"</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="languageFiles"</span> <span style="color: #ff0000">type</span><span style="color: #0000ff">="EPiServer.Framework.Localization.XmlResources.FileXmlLocalizationProvider, EPiServer.Framework"</span> <span style="color: #0000ff">/></span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><strong><span id="lnum4" style="color: #606060"> 4:</span> <span style="color: #0000ff"><</span><span style="color: #800000">add</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="missing_keys"</span> <span style="color: #ff0000">type</span><span style="color: #0000ff">="Alloy.Business.Localization.MissingKeyLoggerLocalizationProvider, Alloy"</span><span style="color: #0000ff">/></span></strong></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum5" style="color: #606060"> 5:</span> <span style="color: #0000ff"></</span><span style="color: #800000">providers</span><span style="color: #0000ff">></span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum6" style="color: #606060"> 6:</span> <span style="color: #0000ff"></</span><span style="color: #800000">localization</span><span style="color: #0000ff">></span></pre><!--CRLF--></div></div>
<p> </p>
<p><strong>Result:</strong></p>
<p><a href="/link/0e2a89e212474021a89c2dc2641abfe2.aspx"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="/link/0de778ebe593422aa4f3851204ce3c48.aspx" width="1005" height="193" /></a></p>
<p> </p>
<h2>The provider</h2>
<p>The code shows a simplified version of the attached code file.</p>
<p>The basic outline of the functionality is to create a dictionary with missing keys (language key + culture). Every 10 minutes the missing keys are written to a local file on the server. To remove duplicates that might be registered due to restarting the site etc., I recommend using Excel or some other tool <img class="wlEmoticon wlEmoticon-winkingsmile" style="border-top-style: none; border-left-style: none; border-bottom-style: none; border-right-style: none" alt="Winking smile" src="/link/ad1ab5ae2a1b4886b2abdd684d7a19e0.aspx" /></p>
<div id="codeSnippetWrapper"> </div>
<div id="codeSnippetWrapper">
<div id="codeSnippet" style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum1" style="color: #606060"> 1:</span> <span style="color: #0000ff">using</span> System;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum2" style="color: #606060"> 2:</span> <span style="color: #0000ff">using</span> System.Collections.Generic;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum3" style="color: #606060"> 3:</span> <span style="color: #0000ff">using</span> System.Globalization;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum4" style="color: #606060"> 4:</span> <span style="color: #0000ff">using</span> System.IO;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum5" style="color: #606060"> 5:</span> <span style="color: #0000ff">using</span> System.Linq;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum6" style="color: #606060"> 6:</span> <span style="color: #0000ff">using</span> EPiServer.DataAbstraction;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum7" style="color: #606060"> 7:</span> <span style="color: #0000ff">using</span> EPiServer.Framework.Localization;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum8" style="color: #606060"> 8:</span> <span style="color: #0000ff">using</span> EPiServer.ServiceLocation;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum9" style="color: #606060"> 9:</span> </pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum10" style="color: #606060"> 10:</span> </pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum11" style="color: #606060"> 11:</span> <span style="color: #0000ff">namespace</span> Alloy.Business.Localization</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum12" style="color: #606060"> 12:</span> {</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum13" style="color: #606060"> 13:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> MissingKeyLoggerLocalizationProvider : LocalizationProvider</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum14" style="color: #606060"> 14:</span> {</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum15" style="color: #606060"> 15:</span> Dictionary<<span style="color: #0000ff">string</span>, DateTime> languageKeys = <span style="color: #0000ff">new</span> Dictionary<<span style="color: #0000ff">string</span>, DateTime>();</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum16" style="color: #606060"> 16:</span> <span style="color: #0000ff">private</span> DateTime _latestLogDateTime = DateTime.MinValue;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum17" style="color: #606060"> 17:</span> </pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum18" style="color: #606060"> 18:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">string</span> GetString(<span style="color: #0000ff">string</span> originalKey, <span style="color: #0000ff">string</span>[] normalizedKey, CultureInfo culture)</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum19" style="color: #606060"> 19:</span> {</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum20" style="color: #606060"> 20:</span> <span style="color: #008000">//Concatenate key and culture ot create a unique key for dictionary</span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum21" style="color: #606060"> 21:</span> <span style="color: #0000ff">string</span> keyWithLanguage = originalKey + <span style="color: #006080">";"</span> + culture.Name;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum22" style="color: #606060"> 22:</span> <span style="color: #0000ff">if</span> (!languageKeys.ContainsKey(keyWithLanguage))</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum23" style="color: #606060"> 23:</span> {</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum24" style="color: #606060"> 24:</span> languageKeys.Add(keyWithLanguage, DateTime.Now);</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum25" style="color: #606060"> 25:</span> }</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum26" style="color: #606060"> 26:</span> </pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum27" style="color: #606060"> 27:</span> <span style="color: #008000">//Log all currently found keys</span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum28" style="color: #606060"> 28:</span> TimeSpan timeSinceLog = (DateTime.Now - _latestLogDateTime);</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum29" style="color: #606060"> 29:</span> <span style="color: #0000ff">if</span> (timeSinceLog > <span style="color: #0000ff">new</span> TimeSpan(0, 0, 10, 0))</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum30" style="color: #606060"> 30:</span> {</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum31" style="color: #606060"> 31:</span> LogDictionary();</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum32" style="color: #606060"> 32:</span> }</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum33" style="color: #606060"> 33:</span> <span style="color: #0000ff">return</span> <span style="color: #0000ff">null</span>; <span style="color: #008000">//return null to pass on to other providers</span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum34" style="color: #606060"> 34:</span> }</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum35" style="color: #606060"> 35:</span> </pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum36" style="color: #606060"> 36:</span> <span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> LogDictionary()</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum37" style="color: #606060"> 37:</span> {</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum38" style="color: #606060"> 38:</span> IEnumerable<<span style="color: #0000ff">string</span>> keyInfo = languageKeys.Keys.Select(x => $<span style="color: #006080">"Date:{languageKeys[x]};Key:{x}"</span>);</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum39" style="color: #606060"> 39:</span> </pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum40" style="color: #606060"> 40:</span> <span style="color: #0000ff">string</span> missingKeyLogPath = $<span style="color: #006080">@"c:\Temp\MissingKeys_{Name}.log"</span>;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum41" style="color: #606060"> 41:</span> </pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum42" style="color: #606060"> 42:</span> File.WriteAllLines(missingKeyLogPath, keyInfo);</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum43" style="color: #606060"> 43:</span> _latestLogDateTime = DateTime.Now;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum44" style="color: #606060"> 44:</span> }</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum45" style="color: #606060"> 45:</span> </pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum46" style="color: #606060"> 46:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> IEnumerable<ResourceItem> GetAllStrings(<span style="color: #0000ff">string</span> originalKey, <span style="color: #0000ff">string</span>[] normalizedKey, CultureInfo culture)</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum47" style="color: #606060"> 47:</span> {</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum48" style="color: #606060"> 48:</span> <span style="color: #0000ff">return</span> <span style="color: #0000ff">new</span> List<ResourceItem>();</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum49" style="color: #606060"> 49:</span> }</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum50" style="color: #606060"> 50:</span> </pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum51" style="color: #606060"> 51:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> IEnumerable<CultureInfo> AvailableLanguages</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum52" style="color: #606060"> 52:</span> {</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum53" style="color: #606060"> 53:</span> get { <span style="color: #0000ff">return</span> ServiceLocator.Current.GetInstance<ILanguageBranchRepository>().ListEnabled().Select(x => x.Culture); }</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum54" style="color: #606060"> 54:</span> }</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum55" style="color: #606060"> 55:</span> }</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum56" style="color: #606060"> 56:</span> }</pre><!--CRLF--></div></div>
<p> </p>
<p><a href="https://dl.dropboxusercontent.com/u/16971271/Blogfiles/MissingKeyLoggerLocalizationProvider.cs">MissingKeyLoggerLocalizationProvider.cs</a></p>
Faking inventory while waiting for integrations to finalize
/blogs/sorby/dates/2015/4/faking-inventory-while-waiting-for-integrations-to-finalize/
2015-04-10T20:54:11.5370000Z
<p>In many Commerce projects there will be dependent activities running in parallel. You might be waiting for a warehouse inventory service to be developed while the shopping experience is developed. To prevent a delay in progress on the site without manually adding inventory in Commerce Manager, you can fake the implementation of IWarehouseInventoryService. </p>
<h2>Implement a fake stock in the Catalog</h2>
<p><strong>Before</strong></p>
<p><img src="/link/5ae750e41bad4a92b1302edac2139415.aspx?id=120155" alt="Image BeforeStockFix.png" /></p>
<p><strong>Fake implementation</strong></p>
<pre class="language-csharp"><code> public class FakeWarehouseInventory : IWarehouseInventoryService
{
private IWarehouseInventory GetFakeInventory(CatalogKey catalogKey)
{
return GetFakeInventory(catalogKey, new Warehouse() {Code = "Default"});
}
private IWarehouseInventory GetFakeInventory(CatalogKey catalogKey, IWarehouse warehouse)
{
return new WarehouseInventory()
{
AllowBackorder = true,
AllowPreorder = true,
BackorderAvailabilityDate = DateTime.Now.AddDays(-1),
BackorderQuantity = 0,
CatalogKey = catalogKey,
InStockQuantity = 100,
InventoryStatus = InventoryTrackingStatus.Enabled,
PreorderAvailabilityDate = DateTime.Now.AddDays(5),
PreorderQuantity = 0,
ReorderMinQuantity = 0,
ReservedQuantity = 0,
WarehouseCode = warehouse.Code
};
}
public IWarehouseInventory Get(CatalogKey catalogKey, IWarehouse warehouse)
{
return GetFakeInventory(catalogKey, warehouse);
}
public IEnumerable<IWarehouseInventory> List(IEnumerable<CatalogKey> catalogKeys)
{
return catalogKeys.Select(GetFakeInventory) ;
}
public IEnumerable<IWarehouseInventory> ListTotals(IEnumerable<CatalogKey> catalogKeys)
{
return catalogKeys.Select(GetFakeInventory);
}</code></pre>
<p><strong> </strong></p>
<p><strong>Use an initializable module to override the default WarehouseInventoryService</strong></p>
<pre class="language-csharp"><code>[ModuleDependency(typeof(EPiServer.Commerce.Initialization.InitializationModule))]
public class InitializationModule : IConfigurableModule
{
public void Initialize(EPiServer.Framework.Initialization.InitializationEngine context)
{
CatalogRouteHelper.MapDefaultHierarchialRouter(RouteTable.Routes, false);
}
public void ConfigureContainer(ServiceConfigurationContext context)
{
context.Container.Configure(ce => ce.For<IWarehouseInventoryService>().Use<FakeWarehouseInventory>());
}
public void Preload(string[] parameters)
{
}
public void Uninitialize(EPiServer.Framework.Initialization.InitializationEngine context)
{
}
}</code></pre>
<p><strong>After</strong></p>
<p><strong><img src="/link/2e181fe8a1d64a33b9efec935b55b37f.aspx?id=120152" alt="Image AfterStockFix.png" /></strong></p>
<p>Download <a href="https://www.dropbox.com/s/67edi5h09pfzi01/FakeWarehouseInventory.cs?dl=0">FakeWarehouseInventory.cs</a></p>
<p>Of course, this approach will not work when you are testing features like tracking stock during purchases.</p>
<h2>Creating a purchase order</h2>
<p>In order to create a purchase order and make the workflows perform correctly with the fake data, you need to create your own fake implementation of IInventoryService.</p>
<p>Download a <a href="https://www.dropbox.com/s/bbs6gw96mtmk7gc/FakeInventoryService.cs?dl=0">FakeInventoryService.cs</a>.</p>
<p>More about warehouse here: <a href="/link/31e0303740974c29b3c22922afd0e7fa.aspx?id=83668">http://world.episerver.com/documentation/Items/Developers-Guide/EPiServer-Commerce/75/Warehouses-and-inventories/Multi-warehouse-implementations/</a></p>
Number of Carts getting out of control
/blogs/sorby/dates/2015/3/number-of-carts-getting-out-of-control/
2015-03-19T15:32:56.6700000Z
<p>If you do not carefully plan for cleaning up abandoned carts (<a href="/link/9cd1fc48989a4788bd127346d8f548b9.aspx">Forum post</a>), the number of carts will quickly get out of control. It is highly recommended to have the scheduled job for cleaning up old carts execute on a daily schedule (<a href="/link/55fe410f4f65482cab72fb59d47c7561.aspx?id=66786&documentId=commerce/7.5/9C98393C">RemovedExpiredCartsJob</a>). In this short blog post, I will guide you through the different commands you need to run to delete directly in the database. While it is possible to do this with the API, as this forum post shows (<a href="/link/8ce45492a5404e079ed397ba8f7d9015.aspx">http://world.episerver.com/Forum/Developer-forum/EPiServer-Commerce/Thread-Container/2012/6/How-can-we-clear-baskets-that-have-been-expired/</a>), it is much faster to delete with SQL directly.</p>
<pre class="language-csharp"><code>declare @from datetime = CONVERT (date, GETDATE()-500)
declare @to datetime = CONVERT (date, GETDATE()-10)
declare @ordergroupids TABLE
(
OrderGroupId INT
)
insert into @ordergroupids
select top 10000 ObjectId from OrderGroup_ShoppingCart
where Created between @from and @to
order by Created asc
</code></pre>
<p>The SQL statement above creates a temporary table and fills it with 10000 cart ids that are between 10 and 500 days old</p>
<p>There will be a need for several ids to correctly remove carts. The different identifiers are collected and saved in temporary tables.</p>
<pre class="language-csharp"><code>declare @orderformids table(OrderFormId INT)
insert into @orderformids
select OrderFormId from OrderForm where OrderGroupId in (select * from @ordergroupids)
declare @lineitemids table(LineItemId int)
insert into @lineitemids
select lineitemid from LineItem where OrderGroupId in (select * from @ordergroupids)
declare @shipmentids table(ShipmentId int)
insert into @shipmentids
select ShipmentId from Shipment where OrderGroupId in (select * from @ordergroupids)
declare @paymentids table(PaymentId int)
insert into @paymentids
select PaymentId from OrderFormPayment where OrderGroupId in (select * from @ordergroupids)
declare @orderaddressids table(OrderGroupAddressId int)
insert into @orderaddressids
select OrderGroupAddressId from OrderGroupAddress where OrderGroupId in (select * from @ordergroupids)</code></pre>
<p>Finally you can delete from the different related tables. Note! Depending on different payments in use, you might need to delete from other OrderFormPayment_[Type] tables.</p>
<pre class="language-csharp"><code>--Delete shipments
Delete from ShipmentEx_Localization where ObjectId in (select * from @shipmentids)
delete from ShipmentEx where ObjectId in (select * from @shipmentids)
delete from ShipmentDiscount where OrderGroupId in (select * from @ordergroupids)
delete from Shipment where OrderGroupId in (select * from @ordergroupids)
--Delete payments (payments may have been registered, but not completed)
delete from OrderFormPayment_Other_Localization where ObjectId in (select * from @paymentids)
delete from OrderFormPayment_Other where ObjectId in (select * from @paymentids)
delete from OrderFormPayment where OrderGroupId in (select * from @ordergroupids)
--Delete addresses
delete from OrderGroupAddressEx where ObjectId in (select * from @orderaddressids)
delete from OrderGroupAddressEx_Localization where ObjectId in (select * from @orderaddressids)
delete from OrderGroupAddress where OrderGroupId in (select * from @ordergroupids)
--Delete line items and related tables
delete from LineItemDiscount where LineItemId in (select * from @lineitemids)
delete from LineItemEx_Localization where ObjectId in (select * from @lineitemids)
delete from LineItemEx where ObjectId in (select * from @lineitemids)
delete from LineItem where OrderGroupId in (select * from @ordergroupids)
--Delete order form and related tables
delete from OrderFormDiscount where OrderFormId in ( select * from @orderformids)
delete from OrderFormEx_Localization where ObjectId in ( select * from @orderformids)
delete from OrderFormEx where ObjectId in ( select * from @orderformids)
delete from OrderForm where OrderGroupId in (select * from @ordergroupids)
--Delete shopping cart
delete from OrderGroup_ShoppingCart_Localization where ObjectId in (select * from @ordergroupids)
delete from OrderGroup_ShoppingCart where ObjectId in (select * from @ordergroupids)
--Delete order group
delete from OrderGroup where OrderGroupId in (select * from @ordergroupids)
</code></pre>
<p>Remember to activate the scheduled job after cleaning up to prevent things from getting out of control again.</p>
<h2>Quick warning / Disclaimer</h2>
<p>The scripts have been used in a running site and did remove 100 000+ carts, but I don't take any responsibility for any issues caused by its usage.</p>
<p>I strongly recommend trying it out in a test environment and use a transaction to be able to roll back.</p>
<p>If you spot an issue let me know!</p>
Introducing EPiServer Commerce Manager Enhancements
/blogs/sorby/dates/2015/2/enhancements-for-episerver-commerce-manager-introduced/
2015-03-01T11:48:21.2200000Z
<p>Commerce Manager comes with basic order search and -lists. To improve usability and make it easier to find orders we have developed various enhancements to Commerce Manager.</p>
<p>Included in the initial release:</p>
<ul>
<li>Improved Order Search with wildcard support for order and customer data</li>
<li>More fields in order lists</li>
<li>Filter orders per market</li>
<li>Additional filters</li>
<li>Order notes shown in lists</li>
</ul>
<h2>Installation</h2>
<p>Locate and install the <strong>EPiServer Commerce Manager Enhancements (EPiCode.CommerceManager.Enhancements)</strong> package from the EPiServer nuget feed. The installation overwrites some of the files in the Apps folder in Commerce Manager. You need to install the Commerce Manager Package prior to installing this package.</p>
<p>Note! Only install the package on Commerce Manager Sites!</p>
<h2>Additional columns and filters</h2>
<p><strong>Default view</strong></p>
<p><strong><img src="/link/5dc49d712fb44897be020ad9fe3f6936.aspx?id=118134" alt="Image InitialList.png" /></strong></p>
<p><strong>Updated view</strong></p>
<p><img src="/link/4b3954415ba743fdbfc28ede6bb8cc04.aspx?id=118154" alt="Image After Update2.png" /></p>
<p><span style="text-decoration: underline;">New columns</span></p>
<p><span>Created date, latest order note, market id, warehouse name and shipping are added to the view for both listings and search results.</span></p>
<p><span style="text-decoration: underline;">New filters</span></p>
<p><span>This week and this month will show orders for a given week number or month. The enhancements add new filters for “last 7 days” and “last 30 days”.</span></p>
<p><span>All filters include additional filters for market. This goes for both date range filters and order status filters.</span></p>
<p><span><img src="/link/a28e379f69414940806620d34d5a98d2.aspx?id=118150" alt="Image Orderstatus.png" /></span></p>
<p><span>Note! If you have several markets, the tree node filtering may clutter your left menu. By adding </span><strong>UseDropdownMarketFilter</strong><span> with value true to appSettings, you get a dropdown menu instead.</span></p>
<p><img src="/link/5209de4108804ed098fcb71f867e90a7.aspx?id=118151" alt="Image dropdown.png" /></p>
<h2><strong><span>Extended order search</span></strong></h2>
<p><img src="/link/211e184965bc47a2944d418918e6d847.aspx?id=118152" alt="Image search.png" /></p>
<p><strong><span>Wild card search</span></strong></p>
<p><span>All input fields (ID, Customer, Mail and Phone) have wild card options. The wildcard character ‘*’ may be entered anywhere in the search term. </span></p>
<p><span>Example:</span></p>
<p><span>Joh* -> John Doe, Johanna Barker, John Carlson</span></p>
<p><span>*on -> John Carlson, Karen Carlson</span></p>
<p><span>Jo*on -> John Carlson</span></p>
<p><strong><span>Search by date</span></strong></p>
<p><span>New date range options have been added including “Last 7 days”, “Last 30 days” and “Custom” with start and stop date. When searching by date, both created and modified are considered.</span></p>
<p><span> </span></p>
<h2><strong><span>How to contribute</span></strong></h2>
<p><span>Feel free to contribute by forking the repository <a href="https://github.com/BVNetwork/CommerceManagerEnhancements">https://github.com/BVNetwork/CommerceManagerEnhancements</a>. Pull requests are most welcome.</span></p>