<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="www.w3.org/2005/Atom" xmlns:sy="purl.org/rss/1.0/modules/syndication/" xmlns:dc="purl.org/dc/elements/1.1/" xmlns:content="purl.org/rss/1.0/modules/content/" xmlns:wfw="wellformedweb.org/CommentAPI/" xmlns:slash="purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Microsoft Dynamics Global Domain</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/dynamics-coe/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/dynamics-coe/feed.xml</link>
    <description />
    <lastBuildDate>Tue, 16 Apr 2019 05:05:50 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>AX7 Table Browser and Class Runner</title>
      <link>https://docs.microsoft.com/archive/blogs/dynamics-coe/ax7-systablebrowser-sysclassrunner</link>
      <pubDate>Thu, 29 Sep 2016 14:54:03 GMT</pubDate>
      <dc:creator><![CDATA[Eugen Glasow]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dynamics-coe/?p=295</guid>
      <description><![CDATA[Challenge 1: delete a worker in Dynamics AX "7" aka "Dynamics 365 for Operations" in the table...]]></description>
      <content:encoded><![CDATA[<h2>Challenge 1: delete a worker in Dynamics AX "7" aka "Dynamics 365 for Operations" in the table browser</h2>
Create a worker under <strong>Human resources &gt; Workers &gt; Employees</strong>. Now try to delete it. If you ever touched the Project setup settings etc of the employee, a message appears announcing that a "<span class="messageBar-message"><em>Worker cannot be deleted while dependant Resources exist. Delete dependant Resources and try again.</em>" Indeed, the system automatically creates a new work center for every new timesheet user.</span>

<span class="messageBar-message">Navigate to <strong>Organization administration &gt; Resources &gt; Resources</strong>. Locate the work center representing the employee and try to delete it. The result is a message "<em><span class="messageBar-message">Resources cannot be deleted while dependent ResResourceIdentifier exist. Delete dependent ResResourceIdentifier and try again</span></em>". There is no UI for the <em>ResResourceIdentifier </em>table which is especially reassuring in an Azure production environment where you are not allowed to run SQL scripts against the database.</span>

Solution: open the System Table Browser and delete the <em>ResResourceIdentifier</em> record by the <em>RecId</em> of the work center.

The table browser may be opened in the Visual Studio environment but it is just a URL that can be called in a browser as well. You just have to know the exact name of the table to do so: <strong>https://XXXaos.cloudax.dynamics.com/?<span style="color: #339966">mi=SysTableBrowser</span>&amp;<span style="color: #ff0000">tableName=ResResourceIdentifier</span></strong>

<span style="color: #000000"><a href="https://msdnshared.blob.core.windows.net/media/2016/09/SysTableBrowser.png"><img width="300" height="123" class="alignnone size-medium wp-image-305" alt="SysTableBrowser" src="https://msdnshared.blob.core.windows.net/media/2016/09/SysTableBrowser-300x123.png" /></a></span>

It's a pity that the precious SQL injection window where in previous versions of Dynamics AX you were able to execute <em>delete_from</em> and <em>update_recordset</em> statements is not presented anymore; a real loss indeed.
<h2>Challenge 2: execute an arbitrary X++ class in Dynamics AX "7" aka "Dynamics 365 for Operations"</h2>
In AX7 there are no more "jobs" to be executed at once on Ctrl-O, but a replacement exists: runnable classes as described here: <a href="https://blogs.msdn.microsoft.com/axsupport/2016/03/23/get-started-developing-in-ax-7/">https://blogs.msdn.microsoft.com/axsupport/2016/03/23/get-started-developing-in-ax-7/</a>

When executing a runnable class from Visual Studio the form SysClassRunner is called. This form parses the URL for the <em>cls</em> parameter and executes the respective class. You just need to know the URL syntax and the exact class name.

Let's start with something harmless: <strong>https://XXXaos.cloudax.dynamics.com/?<span style="color: #339966">mi=SysClassRunner</span>&amp;<span style="color: #ff0000">cls=SysDBInformation</span></strong>

&nbsp;

<a href="https://msdnshared.blob.core.windows.net/media/2016/09/warning.png"><img width="300" height="150" class="aligncenter size-medium wp-image-325" alt="warning" src="https://msdnshared.blob.core.windows.net/media/2016/09/warning-300x150.png" /></a>

Now you can try to drop all transactional, non-master data in your production database: <strong>https://XXXaos.cloudax.dynamics.com/?mi=SysClassRunner&amp;cls=SysDatabaseTransDelete</strong>

&nbsp;

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Migrate document attachments to AX7</title>
      <link>https://docs.microsoft.com/archive/blogs/dynamics-coe/migrate-document-attachments-to-ax7</link>
      <pubDate>Wed, 29 Jun 2016 20:24:42 GMT</pubDate>
      <dc:creator><![CDATA[Eugen Glasow]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dynamics-coe/?p=285</guid>
      <description><![CDATA[The Archive directory, Database and the Original location options for storing file attachments in...]]></description>
      <content:encoded><![CDATA[The <em>Archive directory</em>, <em>Database</em> and the <em>Original location</em> options for storing file attachments in the "New Dynamics AX" aka "Dynamics AX Online" aka AX7 are depreciated in favor of the <strong>Azure Storage</strong> or <strong>SharePoint</strong>. The option <em>Archive directory</em> (see <strong>Organization administration &gt; Document management &gt; Document types</strong>) now designates the Azure Blob Storage, the <em>Database</em> option is present but dysfunctional, and the <em>Original location</em> disappeared altogether.

What if you have to migrate existing attachments from an AX 2009 or AX 2012 system and leave them operational i. e. viewable from the original record?

In the cases <em>Archive directory</em> or <em>Original location</em> you are in deep trouble. You may try to copy the files to the Azure Storage by means of the <a href="https://azurestorageexplorer.codeplex.com/" target="_blank">Azure Storage Explorer</a>, but the name of the file must be converted into a deterministic GUID, and a link to this GUID has to be re-established in the <strong>DocuValue</strong> table. It also seems that the DLL managing files in Azure for AX7 relies on some metadata in the blob, and fails to produce a download URL from a faked GUID. I suggest writing a script in the legacy AX 2012 to absorb the external files to the database first.

For the “Database”-stored attachments there is [yet] no official upgrade path, but the below runnable class can quickly dump the files preserved in the <strong>DocuValue</strong> table to the Azure Storage through a memory stream, and rejuvenate the <strong>DocuValue</strong> table with the GUID and a link to the blob. The script also updates the <strong>Location</strong> in all file document types from <em>Database</em> to <em>Archive directory</em> (meaining the Azure Storage).
<blockquote>
<pre>class DocuFileMigrateDBtoAzure
{
    public static void main(Args _args)
    {
        DocuValue           docuValue;
        DocuRef             docuRef;
        DocuType            docType;
        System.IO.Stream    fileStream;
        Microsoft.Dynamics.AX.Framework.FileManagement.DocumentLocation         location;
        Microsoft.Dynamics.AX.Framework.FileManagement.IDocumentStorageProvider storageProvider;
        DataArea            dataArea;
        ;
        while select dataArea
        {
            changecompany(dataArea.id)
            {
                docType = null;
                docType.skipTTSCheck(true);
                while select forupdate docType
                    where docType.TypeGroup == DocuTypeGroup::File
                {
                    if (docType.FilePlace == DocuFilePlace::Database)
                    {
                        docType.FilePlace = DocuFilePlace::Archive;
                        docType.update();
                    }
                    storageProvider = Docu::GetStorageProvider(docType, false, curUserId());
                    if (storageProvider == null)
                        continue;
                    while select forupdate docuValue
                        where docuValue.StorageProviderId == 0
                           &amp;&amp; docuValue.Type == DocuValueType::Others
                    join docuRef
                        where docuRef.ValueRecId      == docuValue.RecId
                           &amp;&amp; docuRef.ActualCompanyId == docType.DataAreaId
                           &amp;&amp; docuRef.TypeId          == docType.TypeId
                    {
                        fileStream = Binary::constructFromContainer(docuValue.File).getMemoryStream();
                        if (fileStream.Length == 0)
                            continue;
                        docuValue.FileId = newGuid();
                        location = storageProvider.SaveFile(
                                docuValue.FileId,
                                storageProvider.GenerateUniqueName(docuValue.OriginalFileName),
                                System.Web.MimeMapping::GetMimeMapping(docuValue.OriginalFileName),
                                fileStream);
                        fileStream.Close();
                        if (location == null)
                            continue;
                        if (location.NavigationUri)
                        {
                            docuValue.Path = location.get_NavigationUri().ToString();
                        }
                        if (location.AccessUri)
                        {
                            docuValue.AccessInformation = location.get_AccessUri().ToString();
                        }
                        docuValue.StorageProviderId = storageProvider.ProviderId;
                        docuValue.update();
                    }
                }
            }
        }
    }
}</pre>
</blockquote>]]></content:encoded>
    </item>
    <item>
      <title>Mass create Worker-User relations in AX 2012</title>
      <link>https://docs.microsoft.com/archive/blogs/dynamics-coe/mass-create-worker-user-relations-in-ax-2012</link>
      <pubDate>Wed, 29 Jun 2016 19:32:08 GMT</pubDate>
      <dc:creator><![CDATA[Eugen Glasow]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dynamics-coe/?p=275</guid>
      <description><![CDATA[A relation between the worker and the system user records (System administration &gt; Common &gt;...]]></description>
      <content:encoded><![CDATA[A relation between the worker and the system user records (<strong>System administration &gt; Common &gt; Users &gt; User relations</strong>) is necessary to approve BOMs, enter timesheets or expense reports in Dynamics AX. The user records can be easily imported from the Active Directory, the Employee records can be migrated from a legacy ERP or a 3<sup>rd</sup> party system through the DIXF interface.

The DIXF in Dynamics AX CU9/CU10 can also fill the missing link between the two, but a simple idempotent X++ job can also be a viable solution to mass create missing DirPersonUser relations. The below script tries to match the users by the e-mail address, then by the First-Last name, then by the Last-First name etc.
<blockquote>
<pre>// Align the users and the workers by the e-mail address first, and the name second
public static void generateDirPersonUser()
{
    DirPersonUser               dirPersonUser, dirPersonUser2;
    UserInfo                    userInfo;
    SysUserInfo                 sysUserInfo;
    HcmWorker                   hcmWorker;
    LogisticsElectronicAddress  electronicAddress;
    DirPerson                   dirPerson;
    Name                        rearrangedName;
    DirNameSequence             dirNameSequence;
    DirPersonName               dirPersonName;
    while select userInfo
        join sysUserInfo
            where sysUserInfo.Id == userInfo.id
        notexists join dirPersonUser2
            where dirPersonUser2.User == userInfo.id
    {
        dirPerson.clear();
        if (sysUserInfo.Email) // 1st attempt
        {
            select firstonly hcmWorker
                join dirPerson
                    where dirPerson.RecId == hcmWorker.Person
                join electronicAddress
                    where electronicAddress.Locator == sysUserInfo.Email
                       &amp;&amp; electronicAddress.RecId == dirPerson.(DirPartyTable::electronicAddressType2primaryFieldId(LogisticsElectronicAddressMethodType::Email);
        }
        if (! dirPerson &amp;&amp; strAlpha(userInfo.name))
        {
            dirPersonName.clear(); 
            [dirPersonName.FirstName,
             dirPersonName.MiddleName,
             dirPersonName.LastName] = str2con(strReplace(userInfo.name, '.,', ' '), ' ');
            while select dirNameSequence // 2nd, 3rd etc. attempt
            {    
                rearrangedName = dirPerson.name(dirPersonName,  DirNameSequence.DisplayAs);         
                select firstonly hcmWorker
                    join dirPerson
                        where dirPerson.RecId == hcmWorker.Person
                           &amp;&amp; dirPerson.Name  == rearrangedName;
                if (dirPerson)
                    break;
            }
        }
        if (dirPerson &amp;&amp; hcmWorker::getMaxEmploymentEndDate(hcmWorker.RecId) &gt; DateTimeUtil::utcNow())
        {
            dirPersonUser.clear();
            dirPersonUser.initValue();
            dirPersonUser.PersonParty = dirPerson.RecId;
            dirPersonUser.User = userInfo.id;
            dirPersonUser.ValidFrom = hcmWorker::getMinEmploymentStartDate(hcmWorker.RecId);
            dirPersonUser.ValidTo = hcmWorker::getMaxEmploymentEndDate(hcmWorker.RecId);
            if (dirPersonUser.validateWrite())
            {
                dirPersonUser.insert();
            }
        }
    }
}</pre>
</blockquote>]]></content:encoded>
    </item>
    <item>
      <title>“Cost accounting” for multi-level process manufacturing</title>
      <link>https://docs.microsoft.com/archive/blogs/dynamics-coe/cost-accounting-for-multi-level-process-manufacturing</link>
      <pubDate>Thu, 11 Feb 2016 09:55:00 GMT</pubDate>
      <dc:creator><![CDATA[Eugen Glasow]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dynamics-coe/2016/02/11/cost-accounting-for-multi-level-process-manufacturing/</guid>
      <description><![CDATA[In the series &ldquo;Dynamics AX modules we rarely implement&rdquo;, imagine a dialogue between a...]]></description>
      <content:encoded><![CDATA[<p>In the series &ldquo;Dynamics AX modules we rarely implement&rdquo;, imagine a dialogue between a financial controller (C) and a Dynamics pre-sales consultant (S):<br />-&nbsp;C: I would like to see the contribution of raw materials (direct costs) separately from the energy, machine depreciation and wages (indirect costs) in the cost price of my finished goods.<br />-&nbsp;S: Nothing is easier: use Dynamics AX&rsquo; standard costing for products. It allows for a &ldquo;cost breakdown&rdquo; by user-defined cost groups in the <a title="BOM calculation sheet" href="https://www.microsoft.com/en-us/download/details.aspx?id=30128" target="_blank">BOM calculation sheet</a>.<br />-&nbsp;C: Fine. And how do my indirect costs propagate this calculation sheet?<br />-&nbsp;S: You enter them as a constant machine hour cost rate or as a surcharge in percent of the raw material costs.<br />-&nbsp;C: But my indirect costs vary by accounting periods, don&rsquo;t they?<br />-&nbsp;S: Yes, they do. You should verify and update the hour cost rates regularly.<br />-&nbsp;C: How can I do that?<br />-&nbsp;S: Hmm&hellip; You can use Excel&hellip; or unleash the power of BI!<br />-&nbsp;C: Can you suggest any systemic and automated approach?</p>
<p>In fact, we can: in the German-speaking countries (the so-called DACH area, Deutschland- Austria- Confoederatio Helvetica) there is a long established school of the formal cost accounting. It introduces the <strong>cost center (CC) accounting</strong> where the actual monthly costs of &lsquo;service&rsquo; cost centers (accounting, marketing) are iteratively allocated to the &lsquo;manufacturing&rsquo; cost centers (machine shops or single machines). By dividing this cost by the number of hours the machine has been running the past month you get the revised cost rate for the next month. In the <strong>cost purpose (CP) accounting</strong> direct material costs are recorded against cost purposes (e.g. finished products, groups of products, customers or market segments), where indirect costs booked on cost centers are periodically allocated to cost purposes by a certain basis, which gives the full cost per product on month average.</p>
<p>This scheme was first implemented in Axapta 3.0 for <a title="Columbus IT Austria" href="www.columbusglobal.com/en" target="_blank">Columbus IT Austria</a>&nbsp; by a Byelorussian near-shore company <a title="CS&amp;amp;IE" href="csie-data.com" target="_blank">CS&amp;IE</a> and then acquired by Microsoft. Later Microsoft recognized those &ldquo;Cost center accounting&rdquo; and &ldquo;Cost purpose accounting&rdquo; modules were a bit crude, and replaced them with the &ldquo;<a title="Cost accounting" href="https://technet.microsoft.com/EN-US/library/hh242782.aspx" target="_blank">Cost accounting</a>&rdquo; solution initially developed by the Swiss partner <a title="Circon Circle Consulting" href="www.circon.net/" target="_blank">Circon Circle Consulting</a>. The latter module has been in existence since Dynamics AX&nbsp;4.0 through Dynamics AX 2012 R3. In the forthcoming version &ldquo;AX7&rdquo; this module may re-appear in a later release.<br />In this blog I am going to show how to leverage the standard capabilities of this "Cost accounting" module.</p>
<h2>Setting the scene<br /><br /></h2>
<p>In chemical manufacturing or metalworking, it is not always possible to record even the direct material costs against the finished product order, let alone the indirect ones. The product &ldquo;individualization&rdquo; begins in the late production stages where for example an addition of a perfume to the basis makes a distinct hair shampoo SKU, or where the steel is alloyed with vanadium and molybdenum to reach the steel grade ordered by the customer. The &ldquo;semi-finished materials&rdquo; i.e. intermediate products are manufactured continuously, and immediately transported further in pipes or railway cars.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/1768.CA1.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/1768.CA1.png" alt="" border="0" /></a><br />&nbsp;<br />The smallest &ldquo;cost purpose&rdquo; for such an intermediate product may be a daily order or a team shift batch. The batches should preferably have the constant chemical composition, and they are barely distinguishable. The factory does not record which intermediate product (molten iron) batches are consumed by which individual order (steel grade). Only the quantity of the intermediate product is tracked, i.e. metric tons of the iron used, or liters or cubic meters of a gas or a fluid inflow, etc.<br />To make the things worse, by-products are collected and re-processed and fed to the earlier stages in the production. For example, the accumulating scale &ndash; the oxidized crust left from forging - may be collected and fed back to the blast furnace, building a loop in the cost flow.</p>
<h2><br />Sample case</h2>
<p>On a highly simplified example below I am going to show how to use the Cost accounting module in the first 2 stages of the steelmaking process (<a title="sintering" href="https://en.wikipedia.org/wiki/Sinter_plant" target="_blank">sintering</a> and smelting) to absorb the cost of the raw materials in sintering (coke, limestone flux, iron ore) into the cost of the smelting product <a title="pig iron" href="https://en.wikipedia.org/wiki/Pig_iron" target="_parent">pig iron</a>. For the simplification I do not take the fuel consumption in the sinter plant, or the highly energetic blast furnace gas into consideration.<br />The wages are allocated to the respective SP (sinter plant) and BF (blast furnace) cost centers. The intermediary product &ndash; the sinter - is produced continuously in daily batch orders, measured in metric tons and reported against the cost purpose &ldquo;Sint&rdquo;. The molten iron and the slag fraction are tapped and poured into <a title="torpedo cars" href="www.allpronix.com/wp-content/uploads/2014/07/allpronix-wadeco-mws-10rf.jpg">torpedo cars</a> at the blast furnace roughly every 6-8 hours, weighted in tons and reported against the cost purpose &ldquo;Iron&rdquo;. The by-product has the cost purpose &ldquo;Slag&rdquo;. Every tapping is represented by an individual batch production order in Dynamics AX.<br />The below table summarizes a very schematic material balance in ferrous sintering and smelting. The quantities have been reduced from the month to one day of production:</p>
<table border="1" align="left">
<tbody>
<tr>
<td><span lang="EN-US">Raw material</span></td>
<td>Product / by-product</td>
<td>Ref input, t&nbsp;</td>
<td>Ref output, t&nbsp;</td>
<td>CC</td>
<td>CP</td>
<td>Price, USD/t</td>
<td>Avg consumption per day, t</td>
<td>Avg yield per day, t</td>
<td>Total cost per day</td>
</tr>
<tr>
<td>&nbsp;65% Fe iron ore concentrate</td>
<td>&nbsp;</td>
<td>&nbsp;1.3</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;Sint</td>
<td>&nbsp;55</td>
<td>&nbsp;7800</td>
<td>&nbsp;</td>
<td>&nbsp;429000</td>
</tr>
<tr>
<td>&nbsp;Fuel (Coke)</td>
<td>&nbsp;</td>
<td>&nbsp;0.07</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;Sint</td>
<td>&nbsp;75</td>
<td>&nbsp;420</td>
<td>&nbsp;</td>
<td>&nbsp;31500</td>
</tr>
<tr>
<td>&nbsp;Limestone</td>
<td>&nbsp;</td>
<td>&nbsp;0.1</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;Sint</td>
<td>&nbsp;20</td>
<td>&nbsp;600</td>
<td>&nbsp;</td>
<td>&nbsp;12000</td>
</tr>
<tr>
<td>&nbsp;Labor</td>
<td>&nbsp;</td>
<td>80 workers in staff</td>
<td>&nbsp;</td>
<td>&nbsp;SP</td>
<td>&nbsp;</td>
<td>
<p>2000 per person per mth</p>
</td>
<td>&nbsp;</td>
<td>
<p>&nbsp;</p>
</td>
<td>&nbsp;5333</td>
</tr>
<tr>
<td>&nbsp;</td>
<td><strong>60% Fe sinter</strong></td>
<td>&nbsp;</td>
<td>&nbsp;1.4</td>
<td>&nbsp;</td>
<td>&nbsp;Sint</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>
<p>8400 per day, aligned with BF</p>
</td>
<td>&nbsp;477833</td>
</tr>
<tr>
<td>&nbsp;60% Fe sinter</td>
<td>&nbsp;</td>
<td>&nbsp;1.4</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;<span style="background-color: #ff0000">Iron</span></td>
<td>&nbsp;</td>
<td>&nbsp;8400</td>
<td>&nbsp;</td>
<td>&nbsp;477833</td>
</tr>
<tr>
<td>&nbsp;Coke</td>
<td>&nbsp;</td>
<td>&nbsp;0.4</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;Iron</td>
<td>&nbsp;75</td>
<td>&nbsp;2400</td>
<td>&nbsp;</td>
<td>&nbsp;180000</td>
</tr>
<tr>
<td>&nbsp;Skilled labor</td>
<td>&nbsp;</td>
<td>
<p>8 workers in shift, 100 in staff&nbsp;</p>
</td>
<td>&nbsp;</td>
<td>BF</td>
<td>&nbsp;</td>
<td>
<p><span lang="EN-US">3000 per person </span><span lang="EN-US">per mth</span></p>
</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;10000</td>
</tr>
<tr>
<td>&nbsp;</td>
<td><strong>Pig iron&nbsp;</strong></td>
<td>&nbsp;</td>
<td>&nbsp;1.0</td>
<td>&nbsp;</td>
<td>&nbsp;Iron</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>
<p>&nbsp;~2000 every 8h tap-to-tap, i.e. 6000 per day</p>
</td>
<td>&nbsp;667833</td>
</tr>
<tr>
<td>&nbsp;</td>
<td><strong>Slag</strong></td>
<td>&nbsp;</td>
<td>&nbsp;0.3</td>
<td>&nbsp;</td>
<td>&nbsp;Iron</td>
<td>&nbsp;15 (sales price)</td>
<td>&nbsp;</td>
<td>&nbsp;1800</td>
<td>
<p>&nbsp;</p>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<h2>Scenario in Dynamics AX</h2>
<p>In the standard demo company USPI, create 6 released products measured in tons as shown below, note the production type necessary to activate the Process manufacturing capabilities:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/2438.CA2.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/2438.CA2.png" alt="" border="0" /></a><br />&nbsp;<br />Set the standard cost price as shown in the table above.<br />Create the new financial dimension <em>CostPurpose</em>, enter 3 values &ldquo;Iron&rdquo;, &ldquo;Sint&rdquo; and &ldquo;Slag&rdquo;, and add this dimension to the P&amp;L accounting structure. Allow for blanks. Add 2 new <em>cost centers</em>: &ldquo;BF&rdquo;, &ldquo;SP&rdquo;.<br />Assign the dimension &ldquo;Iron&rdquo; to the product &ldquo;Iron&rdquo;, &ldquo;Sint&rdquo; to &ldquo;Sinter&rdquo; and &ldquo;Slag&rdquo; to &ldquo;Slag&rdquo;. Make sure that in the item groups the production issue offset and receipt offset posting types are bound to the new profit and loss accounts <em>500111 &ldquo;Change in inventory - Raw materials&rdquo;</em> and <em>500101 &ldquo;Change in inventory &ndash; Products&rdquo;</em>. The reason is that the Cost accounting module cannot acquire balance sheet GL transactions.<br />Procure sufficient stock (e.g. 10000 tons each) of the raw materials Coke, IronOre and Limestone. You may use the shortcut <strong>Manage inventory &gt; On-hand inventory &gt; Quantity adjustment</strong>.<br />For the products Sinter and Iron create 2 formulas (<strong>Engineer &gt; Formula &gt; Lines</strong>) using the above table with the reference input quantities. Beware the Formula size (1.4 tons for the sinter, 1 t for the pig iron).</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/3515.CA3.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/3515.CA3.png" alt="" border="0" /></a></p>
<p>For the pig iron add the by-product &ldquo;Slag&rdquo; (0,3 t per 1 t of iron) with the button <strong>Co-products</strong>. Set the <strong>Burden</strong>=None: the slug is not an additional cost but a product that can be sold profitably. Approve and activate the formulas.</p>
<p>The ERP orders in the&nbsp;first stages of steel production are not individually planned but entered after-the-fact with the recorded output quantity. In the production control module (<strong>Production control / All production orders</strong>) create a batch order for 8400 metric tons of Sinter. The Iron batch orders are likely to be&nbsp;entered on every blast furnace tapping, let&rsquo;s say for 1500 t, 2500 t, and 2000 t:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/3021.CA4.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/3021.CA4.png" alt="" border="0" /></a></p>
<p>The formula lines with raw materials are automatically provided with the product cost purposes &ldquo;Sint&rdquo; and &ldquo;Iron&rdquo;, respectively. In this scenario we do not absorb any planned labor into the production cost; inactivate any anticipated overheard in the costing sheet.<br />Produce 8400 t of Sinter with the <strong>Process &gt; Report as finished</strong> button. Use picking list back-flashing to automatically consume the appropriate quantity of the raw materials.<br />Now produce 1500 + 2500 + 2000 t of Iron along&nbsp;with 450 + 750 + 600 t of the Slag by-product, use back-flushing to quickly record the consumption of Sinter and Coke.</p>
<p>Sell 1000 t of Slag at 15 USD per ton with a sales order to some customer.</p>
<p>Now simulate the monthly salary allocation with a general ledger journal: post 5333 and 10000 USD to the account 600250 "Manufacturing Salaries"&nbsp;and the respective cost center:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/7585.CA5.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/7585.CA5.png" alt="" border="0" /></a></p>
<p>We have now collected data sufficient to start applying the Cost accounting module.</p>
<h2>Cost accounting setup</h2>
<p>Go to <strong>Cost accounting / Setup / Dimensions</strong> and make the <em>CostCenter</em> and <em>CostPurpose</em> dimensions available to the module. In <strong>Cost accounting parameters</strong>, choose <strong>Cost category identical with account number</strong>. Perform the periodic job <strong>Account reconciliation</strong>; this will synchronize all P&amp;L accounts in the company with the cost accounting primary <strong>Cost categories</strong>:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/6765.CA6.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/6765.CA6.png" alt="" border="0" /></a></p>
<p>You will later add the non-numeric &ldquo;local cost categories&rdquo; manually. On the General tab, <strong>Transaction control</strong> activate the dimensions <em>CostCenter</em> and <em>CostPurpose</em> for the cost categories 401100, 500101, 500111 and 600250. You are now ready to inject the GL transactions into the Cost accounting module: <strong>Periodic / Transactions / Process ledger transactions</strong>. The result can be verified in <strong>Inquires / Cost transactions</strong>:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/3125.CA7.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/3125.CA7.png" alt="" border="0" /></a></p>
<p>There will be some costs without a cost center or cost purpose, because the data does not exist at the GL source. You may use <strong>Cost accounting / Setup / Dimension posting control</strong> to selectively filter out the blank CostCenter on 401100, 500101, 500111 and the blank CostPurpose on 600250.<br />We may now start viewing and aggregating the direct raw material costs in the module. The necessary setup is the <strong>Line structure </strong>(<strong>Cost accounting / Setup / Grouping / Line structures</strong>). Ideally, this line structure should resemble the P&amp;L statement. Start with a basic structure with the cost category lines <em>1_RM, 2_WG, 4_CP, 5_SL</em> and the&nbsp;totals <em>3_TC</em> and <em>6_TS</em>, the remaining nodes you may add later:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/1145.CA8.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/1145.CA8.png" alt="" border="0" /></a></p>
<p>The effect of this aggregation can be observed in <strong>Inquires / Dimensions</strong>, <strong>Cost balances</strong>. Mark the Total cost and Quantity in <strong>Display setup</strong> and choose your <strong>Line structure</strong>. The result is an aggregation of the primary [material] costs posted against a financial dimension, here for the&nbsp;CostPurpose = Sinter:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/0777.CA9.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/0777.CA9.png" alt="" border="0" /></a></p>
<p>The indirect costs &ndash; the wages &ndash; are not yet displayed. They wages are absorbed into the product cost by means of a CC-CP allocation:</p>
<p style="padding-left: 30px">CC &ldquo;SP&rdquo;&nbsp;--&gt; CP "Sint"<br />CC &ldquo;BF&rdquo; --&gt; CP "Iron"</p>
<p>This kind of an allocation is usually performed in Dynamics AX Cost accounting by a variable basis with the so-called service transactions. They are taken from the production route hour data and allow for the CC-CP allocation of the machine cost (CC) over the product cost (CP) if the same machine have been used to make different products. In our case the &ldquo;SP&rdquo; staff only works for the &ldquo;Sint&rdquo; production, whereas &ldquo;BF&rdquo; people only make &ldquo;Iron&rdquo;. I.e. the allocation can be constantly 100%.</p>
<p>The Dynamics AX Cost accounting module knows <a title="distributions and allocations" href="https://msdn.microsoft.com/en-us/library/aa498366(v=ax.10).aspx" target="_blank">distributions and allocations</a> in a <strong>Calculation version</strong>. The &ldquo;distributions&rdquo; can re-arrange costs from one CC to another or from one CP to another while preserving the Cost category at the inception. The "allocations" move costs from one dimension (CC) to another (CP), but they require separate Secondary cost categories. Now you have to create CC-CP and CC-CPwg secondary categories as shown on one of the screenshots above. Create one calculation version (<strong>Setup / Calculation / Calculation version</strong>) for the <strong>Actual cost</strong>, and add first 2 allocations (you will add the remaining ones later):</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/1184.CA10.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/1184.CA10.png" alt="" border="0" /></a></p>
<p>Choose the &ldquo;debit&rdquo; cost category <strong>Allocation account</strong> = CC-CP, and the &ldquo;credit&rdquo; <strong>Offset account</strong> = CC-CPwg. Mark <strong>Calculate fixed costs</strong> and the <strong>Offset transaction dimension</strong> = Cost purpose. The <strong>Calculation value t</strong>ype=Total costs. On the tab page <strong>Dimension</strong>, you can&nbsp;choose the CP dimension value to distribute the CC cost over: &ldquo;Sint&rdquo; and &ldquo;Iron&rdquo;, respectively. Enter the <strong>Reference quantity</strong> = 100. The leftmost symbol in the grid must become green if everything has been set up properly.</p>
<p>Now perform the <strong>Periodic / Period calculation</strong>. The <strong>Inquires / Calculation transactions</strong> should start appearing, 4 of them, and in the dimension balance for the &ldquo;Sint&rdquo; the wages of 5333 should be displayed.<br />In the next iteration the resulting full cost of the sinter is spread over the iron batches: CP Sint&nbsp;--&gt; CP Iron. The raw material cost in Sinter may be&nbsp;processed with a <strong>distribution</strong>; here I may spread a whole Line structure node (1_RM)&nbsp;for CP=Sint over the Line structure node=1_RM of CP=Iron while preserving the original cost category 500111 inside:</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/6545.CA11.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/6545.CA11.png" alt="" border="0" /></a></p>
<p>Unfortunately, this trick is not going to work with the indirect wages allocated to the Sinter, because internally the &ldquo;distributions&rdquo; are executed before the &ldquo;allocations&rdquo;, i.e. there will be no allocated wages to distribute.</p>
<div>Moreover, note that the momentary average cost of intermediate product Sinter is already recorded as a raw material contribution into the Iron. This should be prevented to avoid the misclassification of the labor absorbed in the sinter cost price as a material price, and the double&nbsp;impact of the sinter raw materials. There are several possible solutions how to take it out:</div>
<ol>
<li>Remove the CP=Iron (the red one in the table)&nbsp;from the formula line &ldquo;Sinter&rdquo; in the iron production batches before the back-flushing. The intermediate product cost is now &ldquo;orphaned&rdquo; and doesn&rsquo;t show up under &ldquo;Iron&rdquo;. This would require a customization to automate.</li>
<li>Book the intermediate product Issue to a separate GL account&nbsp;i.e. cost category and exclude it from the line structure. This is not always possible because the classification of the product as &ldquo;intermediate&rdquo; or &ldquo;final&rdquo; may be vague: the intermediate products may also be sold to a customer.</li>
<li>Building on the fact that in a continuous production the intermediate products cannot accumulate, we may subtract the reported-as-finished &ldquo;revenue&rdquo; (line 4_CP) of Sinter from the direct costs of the Iron (line 1_RM): the whole 'change in inventory' of sinter will be spread over CP=Iron with an &ldquo;allocation&rdquo;.</li>
</ol>
<div><br />I used the latter approach. Create the remaining CP-CP* categories and allocate to the Iron both the wages and the &ldquo;change in inventory&rdquo; of Sinter as <em>CP-CPwg</em> and <em>CP-CPrm</em> secondary cost categories, respectively. Add&nbsp;<em>CP-CPwg</em> to the line structure node 1_RM,&nbsp;and <em>CP-CPwg</em> to&nbsp;2_WG.&nbsp;&nbsp;Execute the <strong>Period calculation</strong> again, it is going to&nbsp;delete and re-build&nbsp;the <strong>Calculation transactions</strong>:</div>
<div><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/7624.CA12.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/7624.CA12.png" alt="" border="0" /></a></div>
<div>Check the cost balance inquiry:<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/4370.CA13.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/4370.CA13.png" alt="" border="0" /></a><br />Now you know that the full cost of your daily pig iron batches was 667833 USD, where the raw material contribution over the whole material chain was <span style="background-color: #00ff00">652500 USD</span> and the salary was <span style="background-color: #00ff00">15333 USD</span>.</div>
<div><span style="background-color: #00ff00">You cannot obtain this information elsewhere in the Dynamics AX system.</span></div>
<div>In this example we spread the Sinter costs fully over the Pig iron, the allocation was 100%. Talking about the later stages in the production process, pig iron may be used for different steel grades. The exact consumption per batch is not necessary for the calculation of the average steel price, but can be approximated&nbsp;by the&nbsp;simple proportion</div>
<div style="padding-left: 30px"><em>Output(Stage X) * Consumption_for_A (Stage X+1) / Total_consumtion_A_to_Z (Stage X+1)</em> or just<br /><span style="background-color: #ffffff"><em>Output(Stage X) * Output_for_A (Stage X+1) / Total_output_A_to_Z (Stage X+1)</em></span>.</div>
<div>The allocation percentage becomes dynamic. Such a CP-CP allocation require the &ldquo;service transactions&rdquo; to represent the product output i.e. the quantity reported as finished on production orders. This is a customization (extension) of the class <em>COSMovements_Prod</em>, since the Cost accounting can only acquire <span style="text-decoration: underline">hour</span> route transactions from the production module, and not the <span style="text-decoration: underline">quantity</span> route transactions.<br />To have an understanding of service transactions in the Cost accounting module, let&rsquo;s book them manually as opposed to using the automatic function <strong>Process production transactions</strong>. Create a service cost category <em>Output_t</em> and record 2 service transaction against &ldquo;Sint&rdquo; and &ldquo;Iron&rdquo; with the daily production yield in a journal <strong>Cost accounting / Journals / Service transactions</strong>.</div>
<div><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/8741.CA14.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/8741.CA14.png" alt="" border="0" /></a></div>
<div>In your <strong>Line structure</strong> you may now refer to the service cost quantity (line <em>3_TO</em>), and divide the total cost <em>3_TC</em> by the operand <em>3_TO</em> in the &ldquo;calculation&rdquo; line <em>3_TT</em>. The resulting cost price per ton appears as <span style="background-color: #00ff00">111,31 USD/t</span>. Subtract the Slag sales price with the final CP-CP Slag-Iron allocation, and you get an even lower price of 108 USD per metric ton. Finally this can presented to a controller on a nice and configurable&nbsp;<strong>Dimension statement</strong> report.</div>
<div>With such a cost price we may successfully compete with the Chinese, but one substantial position is missing: the maintenance and the amortization of the sinter plant and the blast furnace ;) I leave it to the reader to simulate the monthly fixed assets depreciation run with a subsequent CC-CP allocation: there is not much difference to the wages allocation implemented above.</div>
<h2>Conclusion</h2>
<div>I imagine you may be slightly puzzled, asking yourself: &ldquo;What was it? I can achieve the same result with the route cost in production, can&rsquo;t I?&rdquo;<br />Yes, you can, but the route cost associated with the machine relies on the estimated cost rates and remains distinctive only in&nbsp;one production stage, while the Cost accounting module takes the full Profit and loss statement and breaks it down to the single product. Consider it a huge calculator to deduct the machine cost rate.</div>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>VISA VCF plain text credit card statement into Dynamics AX with XSLT</title>
      <link>https://docs.microsoft.com/archive/blogs/dynamics-coe/visa-vcf-plain-text-credit-card-statement-into-dynamics-ax-with-xslt</link>
      <pubDate>Tue, 08 Dec 2015 10:39:00 GMT</pubDate>
      <dc:creator><![CDATA[Eugen Glasow]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dynamics-coe/2015/12/08/visa-vcf-plain-text-credit-card-statement-into-dynamics-ax-with-xslt/</guid>
      <description><![CDATA[Introduction
A good level of travel expense automation in Microsoft Dynamics AX 2012 R3 requires...]]></description>
      <content:encoded><![CDATA[<h3>Introduction</h3>
<div>A good level of travel expense automation in Microsoft Dynamics AX 2012 R3 requires daily import of credit card files. The credit card number must be specified for the employee in the Human Resources module. The daily credit card statements with unbilled credit card transactions are picked up by the <strong>Travel and expense / Periodic / Credit cards / Credit card import from folder</strong> batch job. The data is stored in the <strong>TrvPBSMaindata</strong> table. Every time an employee enters a new expense report in the AX Enterprise Portal those unreconciled transactions appear on the screen. The employee enriches the transactions with missing data and necessary notes and takes them over into the expense report.</div>
<div>The three major credit card companies offer the following integration services:</div>
<ul>
<li><strong>AMEX</strong> - American Express &ndash; gives a plain text <a title="KR 1025" href="https://secure.cmax.americanexpress.com/Internet/International/AtWork/CA_en/Files/DataFileToolkit.doc" target="_blank">KR 1025</a> file, currently being replaced by the GL 1025 format</li>
<li><strong>Master Card</strong> uses the Common Data Format 3.0 (<a title="CDF3" href="smartdatasupport.mastercard.com/CDF3Overview.pdf" target="_blank">CDF3</a>), an XML file.</li>
<li><strong>VISA</strong> provides the Visa Commercial Format 4.0 (<a title="VCF4" href="ogs.ny.gov/purchase/biddocument/22712rfp_VCF40.pdf">VCF4</a>), a plain tab-separated text file</li>
</ul>
<div><br />None of the formats above are supported in Dynamics AX out-of-the box. Nevertheless, the credit card import routine uses an AIF (Application Integration Framework) <a title="SOAP service" href="https://msdn.microsoft.com/en-us/library/cc967370(v=ax.50).aspx" target="_blank">SOAP service</a> and as any other service in AX it can be fed with an <a title="XSLT" href="www.w3schools.com/xsl/xsl_transformation.asp" target="_blank">XSLT</a> transformation to map the external file to the&nbsp;AX data structures.<br />This approach will work with an&nbsp;CDF3 XML file, but not with the plain text KR1025 and VCF4 files, and here is why:</div>
<ul>
<li>The AIF framework is built upon the WCF and .NET libraries, but</li>
<li>NET does not support XSLT 2.0 specification with its unparsed-text() and <a title=" tokenize()" href="www.w3.org/TR/xpath-functions-30/#func-tokenize" target="_blank">tokenize()</a> functions and this is not expected to change in the near future, and</li>
<li>XSLT 1.0 transformations cannot take a plain text file, the input to an XSLT 1.0 transformation must be a well-formed XML. An attempt to convert a text file ends up in a &ldquo;Line 1, column 1&rdquo; error message, i.e. an XML header is expected by the XSLT processor.</li>
<li>Ergo, we are doomed.</li>
</ul>
<div>There are basically 2 solutions:</div>
<ul>
<li>Pre-process the text file and put it into a CDATA node of a well-formed XML document</li>
<li>Perform the transformation in an external&nbsp;.NET library.</li>
</ul>
<p>The latter approach is well illustrated in the blog <a title="importing-credit-card-statements-into-dynamics-ax-2012-using-aif-and-transformation-library" href="https://blogs.msdn.com/b/axsa/archive/2013/01/08/importing-credit-card-statements-into-dynamics-ax-2012-using-aif-and-transformation-library.aspx">importing-credit-card-statements-into-dynamics-ax-2012-using-aif-and-transformation-library</a>.&nbsp;However, this implementation is far from being an industry grade solution. Firstly, this implementation if not official and it uses hardcoded text constants. Without the DLL source code, itit &nbsp;impossible to maintain. Secondly, for every change the DLL must be recompiled and re-deployed, and the AOS service must be <a title="restarted" href="https://technet.microsoft.com/en-us/library/gg861992.aspx" target="_blank">restarted</a>. While you are developing your interface you might need to restart the AOS service 100-200 times; you must be really masochistic to bring it upon you.</p>
<p>In contrary, a XSLT transformation may be replaced on-the-fly without even restarting the Inbound port service (to do that, use <strong>Tools / Application Integration Framework / Manage transforms</strong>, button <strong>Load</strong>). The&nbsp;XSLT language is a complex but&nbsp;powerful functional language, and it is a well-recognized industry standard. An XSLT transformation can be nicely debugged in Visual Studio. It can be adjusted by the system administrator, and it can accommodate to future changes.<br />Inspired by the AX2012 R3 &ldquo;<a title="Advanced Bank Reconciliation" href="https://technet.microsoft.com/en-us/library/jj729753.aspx">Advanced Bank Reconciliation</a>&rdquo;, which is able to import BAI2 and MT940 plain text files through an AIF inbound port, I developed a VISA VCF4 interface to 99% with XLST transformations only.</p>
<p>The remaining 1% is a generic, very simple .NET DLL that takes any text file and wraps it into a CDATA section. In the Bank Reconciliation this is done not in a transformation pipeline but in the X++ code, see <strong>\Classes\BankStatementFileImport\getImportFileContainer</strong>.</p>
<p>The transformation pipeline consists of 3 transformations:</p>
<div><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/1121.VCF1.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/1121.VCF1.png" alt="" border="0" /></a></div>
<p>The target format must conform to the AIF <a title="batch message schema" href="https://technet.microsoft.com/en-us/library/hh397323.aspx" target="_blank">batch message schema</a>: aside of the typical AX &lt;Envelope&gt; with the &lt;MessageParts&gt; the whole message has to be additionally embedded into a &lt;Batch&gt; node.<br />Processing of such a message can take place in an AX batch job. Beware: an attempt to call the function synchronously <strong>Travel and expense / Periodic / Credit cards / Credit card import from file</strong> from the AX client may lead to a processing error &ldquo;Cannot logon to AX&hellip;&rdquo;, because different credentials may be expected by the service. Either way, the above function is very useful in testing the transformation itself and the XML schema: you first call it interactively to check if the message reaches AX (<strong>System administration / Services and Application Integration Framework / Queue manager</strong>), then launch it in the batch mode to test the final stages when the message is being de-serialized and written to the <strong>TrvPBSMaindata</strong> table.</p>
<h3>Visa Commercial Format 4.0 interface implementation</h3>
<p>A VCF file consists of one or more transaction sets, one set per company (i.e. legal entity in AX). A transaction set consists of one or more blocks of transaction records, it is delimited by a header transaction &ldquo;6&rdquo; at the beginning and a trailer transaction &ldquo;7&rdquo; at the end.</p>
<p>One transaction set may have up to 13 blocks of transactions. A transaction block is a group of transactions that belong to the same record type. Like transaction sets, each block requires a header record &ldquo;8&rdquo; at the beginning and a trailer record &ldquo;9&rdquo; at the end.</p>
<p>Hence, the 6-7 and 8-9&nbsp;lines&nbsp;always come in pairs, and this structure is very similar to an XML file with opening and closing tags:</p>
<p style="padding-left: 30px"><span style="font-size: x-small">6 Company Header Transaction Set</span></p>
<p style="padding-left: 60px"><span style="font-size: x-small">8 Header Block Transactions &ndash; Type &ldquo;01&rdquo;</span></p>
<p style="padding-left: 90px"><span style="font-size: x-small">Transaction 1</span><br /><span style="font-size: x-small">Transaction 2</span><br /><span style="font-size: x-small">Transaction n&nbsp;</span></p>
<p style="padding-left: 60px"><span style="font-size: x-small">9 Trailer Block Transactions &ndash; Type &ldquo;01&rdquo;</span><br /><span style="font-size: x-small">&hellip;</span></p>
<p style="padding-left: 60px"><span style="font-size: x-small">8 Header Block Transactions &ndash; Type &ldquo;05&rdquo;</span></p>
<p style="padding-left: 90px"><span style="font-size: x-small">Transaction 1</span><br /><span style="font-size: x-small">Transaction 2</span><br /><span style="font-size: x-small">Transaction n</span></p>
<p style="padding-left: 60px"><span style="font-size: x-small">9 Trailer Block Transactions &ndash; Type &ldquo;05&rdquo;</span><br /><span style="font-size: x-small">&hellip;</span></p>
<p style="padding-left: 30px"><span style="font-size: x-small">7 Company Trailer Transaction Set</span></p>
<p>The following record types are to be provided daily, e.g. transactions<br />- Car Rental Summary Type &ldquo;02&rdquo; (if available)<br />- Card Transaction Type &ldquo;05&rdquo; (if available)<br />- Line Item Detail Type &ldquo;07&rdquo; (if available)<br />- Line Item Summary Type &ldquo;08&rdquo; <br />- Lodging Summary Type &ldquo;09&rdquo; <br />- Period Type &ldquo;11&rdquo; <br />- Passenger Itinerary Type &ldquo;14&rdquo; (if available)<br />- Leg-Specific Information Type &ldquo;15&rdquo; (if available)</p>
<p>For the purpose of expense entry automation the Type 05 records are of most interest.</p>
<p>Potentially we may&nbsp;also&nbsp;import &ldquo;02&rdquo;s, &ldquo;14&rdquo;s and &ldquo;15&rdquo;s into an TrvEnhancedData record by sending a nested element such as<br /><span style="color: #339966;font-family: courier new,courier">&lt;TrvEnhancedData class="entity" type ="tns:AxdEntity_TrvEnhancedData_TrvEnhancedItineraryData"&gt;</span>, but the <strong>TrvEnhancedItineraryData</strong> inherits from <strong>TrvEnhancedData</strong>, while AX programmers forgot to provide any of the \Classes\TrvTrvPBSMaindata_TrvEnhancedData_XXX container classes. Standard Dynamics AX simply cannot uptake the TrvEnhancedData descendant tables.</p>
<p>The first stage of conversion is provided by a puristic C# assembly <strong>AX2012_TransformAnyTextToXML.DLL</strong>. It writes the text into an XML file with a large CDATA section.</p>
<div>
<pre class="scroll"><code class="cplusplus"> using System.Text;<br /> using System.IO;<br /> using System.Xml;<br /> using Microsoft.Dynamics.IntegrationFramework.Transform;<br /> <br /> namespace AX2012_TransformAnyTextToXML<br /> {<br /> public class TransformAnyTextToXML : ITransform<br /> {<br /> public void Transform(System.IO.Stream input, System.IO.Stream output, string config)<br /> {<br /> StreamReader sreader = new StreamReader(input);<br /> XmlTextWriter xwriter = new XmlTextWriter(output, Encoding.UTF8);<br /> <br /> xwriter.Formatting = Formatting.None;<br /> xwriter.WriteStartDocument();<br /> xwriter.WriteStartElement("root");<br /> xwriter.WriteCData(sreader.ReadToEnd());<br /> sreader.Close();<br /> xwriter.WriteEndElement();<br /> xwriter.Close();<br /> }<br /> }<br /> }</code></pre>
</div>
<div style="padding-left: 30px">&nbsp;</div>
<p>Build and deploy it as described here: <a href="https://technet.microsoft.com/en-us/library/gg863930.aspx">https://technet.microsoft.com/en-us/library/gg863930.aspx</a>.</p>
<p>The second stage is an XSLT transformation <strong>VCF4TXT_to_XML.xslt</strong> that recursively breaks down the long text string into records by the &ldquo;LF&rdquo; character, and into fields by the &ldquo;TAB&rdquo; character. The result is a pre-digested XML file with enumerated fields. Headers and footers are records of their own, but I elevated their fields up to the &lt;TransactionSet&gt;, &lt;TransactionBlock&gt; level to facilitate cross-record lookups and XPath axis addressing.</p>
<p>The third stage is an XSLT transformation <strong>VCF4XML_to_AX.xslt</strong> that applies business logic and converts the resulting XML file to the Dynamics AX AIF message format. It makes one &lt;Envelope&gt; per &lt;TransactionSet&gt; i.e. company.</p>
<div><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/0574.VCF2.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/0574.VCF2.png" alt="" border="0" /></a></div>
<p>The mapping from a long 10 digits &ldquo;Company Identification&rdquo; code to the 4 char AX legal entity code is hard-coded into the XSLT transformation.&nbsp;In an environment with just one company or there only one company issues VISA cards you may omit his section: the &lt;Company&gt; is not a mandatory element.</p>
<p>Another added&nbsp;&bdquo;sugar&ldquo; is a <strong>&lt;MessageId</strong>&gt; tag for idempotency. AX may not import the same file twice. This is enforced at later stages through the uniqness of the TrvPBSMaindata.CCTransUniqueID field, but also by the &lt;MessageId&gt; in the XML header. On an attempt to import a second file with the same &lt;MessageId&gt; AX is going to show an error message &bdquo;<em>Duplicate message. Message has already been processed.</em>&ldquo;</p>
<p>Logically the &lt;MessageId&gt; corresponds to the VCF download Sequence Number which is unique in every credit card statement file. However, AX expects a <span style="text-decoration: underline">GUID</span> in the &lt;MessageId&gt; element.&nbsp;In our case&nbsp;this GUID must be deterministic. For example, it&nbsp;must reproduceably return the same GUID <em>{feb9aab5-8853-9501-0381-3a7d6075d3d1}</em> for the same Sequence Number &bdquo;<em>02746</em>&ldquo; in the VCF4 file. This logic is implemented in an inline C# script <strong>stringToGuid()</strong> through a SHA1 hash, courtesy of a great guy called <a title="Ben Gripka" href="stackoverflow.com/users/530658/ben-gripka" target="_blank">Ben Gripka</a> (see <a href="stackoverflow.com/questions/2642141/how-to-create-deterministic-guids" target="_blank">stackoverflow.com/questions/2642141/how-to-create-deterministic-guids</a>).</p>
<p>The conversion tables from the&nbsp;ISO numeric codes for countries and currencies into the ISO symbolic codes are embedded directly into the VCF4XML_to_AX.xslt.</p>
<p>The mapping between <a title="merchant SIC codes" href="https://en.wikipedia.org/wiki/Standard_Industrial_Classification" target="_blank">merchant SIC codes</a> &lt;CatCode&gt; such as 5411 &ldquo;Retail-Grocery Stores&rdquo; and expense categories is configurable in Dynamics AX (<strong>Travel and expense / Setup / Credit cards / Credit card category codes</strong>). The credit card type &ldquo;VISA&rdquo; is hardcoded in the XSLT.</p>
<p>Here is a sample of the resulting XML file, ready to be consumed by the AX service:</p>
<div style="padding-left: 30px"><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&lt;Batch xmlns="schemas.microsoft.com/dynamics/2009/06/documents/Batch" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:tns="schemas.microsoft.com/dynamics/2008/01/documents/TrvPBSMaindata"&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp; &lt;Envelope xmlns="schemas.microsoft.com/dynamics/2011/01/documents/Message"&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp; &lt;Header&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;MessageId&gt;{feb9aab5-8853-9501-0381-3a7d6075d3d1}&lt;/MessageId&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Company&gt;USMF&lt;/Company&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Action&gt;schemas.microsoft.com/dynamics/2008/01/services/TrvPBSMaindataService/create&lt;/Action&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp; &lt;/Header&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp; &lt;Body&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;MessageParts&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TrvPBSMaindata xmlns="schemas.microsoft.com/dynamics/2008/01/documents/TrvPBSMaindata"&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;DocPurpose&gt;Original&lt;/DocPurpose&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TrvPBSMaindata class="entity"&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;AmountCurr&gt;257&lt;/AmountCurr&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;AmountLocal&gt;176.96&lt;/AmountLocal&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;BusinessName&gt;Airport Store&lt;/BusinessName&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;CardNumber&gt;################&lt;/CardNumber&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;CardType&gt;VISA&lt;/CardType&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;CatCode&gt;5309&lt;/CatCode&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;CCTransUniqueId&gt;###################604&lt;/CCTransUniqueId&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Country&gt;CHE&lt;/Country&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ExchCode&gt;CHF&lt;/ExchCode&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Name&gt;MARTHA S.&lt;/Name&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Town&gt;Lovely UK Countryside&lt;/Town&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TransDate&gt;2015-10-21&lt;/TransDate&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/TrvPBSMaindata&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TrvPBSMaindata class="entity"&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;AmountCurr&gt;19.47&lt;/AmountCurr&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;AmountLocal&gt;19.47&lt;/AmountLocal&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;BusinessName&gt;Amazon UK Marketplace&lt;/BusinessName&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;CardNumber&gt;################&lt;/CardNumber&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;CardType&gt;VISA&lt;/CardType&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;CatCode&gt;5999&lt;/CatCode&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;CCTransUniqueId&gt;####################984&lt;/CCTransUniqueId&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Country&gt;LUX&lt;/Country&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ExchCode&gt;GBP&lt;/ExchCode&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Name&gt;&lt;/Name&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Town&gt;Luxembourg&lt;/Town&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TransDate&gt;2015-10-19&lt;/TransDate&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/TrvPBSMaindata&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/TrvPBSMaindata&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/MessageParts&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp;&nbsp;&nbsp; &lt;/Body&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&nbsp; &lt;/Envelope&gt;</span><br /><span style="color: #339966;font-family: courier new,courier;font-size: xx-small">&lt;/Batch&gt;</span></div>
<h3>Conslusion</h3>
<p>A VISA credit card interface with virtually no customizations in Dynamics AX is feasible. The reference XSLT transformations are attached.</p>
<p>The situation with the support&nbsp;for the&nbsp;remaining credit card providers is still unsatisfactory. Please vote for my product suggestion on <a title="MSConnect" href="https://connect.microsoft.com/dynamicssuggestions/feedback/details/1057087/travel-expense-implement-amex-master-card-and-visa-credit-card-statements">MSConnect</a>.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/65/92/27/VCF4XML_to_AX_v2.zip">VCF4XML_to_AX_v2.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>One warehouse, 2 cost models</title>
      <link>https://docs.microsoft.com/archive/blogs/dynamics-coe/one-warehouse-2-cost-models</link>
      <pubDate>Tue, 28 Jul 2015 11:47:00 GMT</pubDate>
      <dc:creator><![CDATA[Eugen Glasow]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dynamics-coe/2015/07/28/one-warehouse-2-cost-models/</guid>
      <description><![CDATA[Around 14 years ago I designed a feature called the &ldquo;Dual warehouse&rdquo;. The feature is...]]></description>
      <content:encoded><![CDATA[<p><span style="font-family: Calibri;font-size: small">Around 14 years ago I designed a feature called the &ldquo;Dual warehouse&rdquo;. The feature is scarcely documented&nbsp;</span><span style="font-family: Calibri;font-size: small">(</span><a href="https://technet.microsoft.com/en-us/library/jj733298.aspx">https://technet.microsoft.com/en-us/library/jj733298.aspx</a><span style="font-family: Calibri;font-size: small">) and barely understood. It was intended to maintain 2 warehouse cost prices in parallel in countries suffering from hyperinflation. In 2002 I was even given a chance to present this feature to Erik Damgaard, at that time known not as a Danish TV celebrity but the Damgaard Data co-founder and the father of Dynamics AX. His verdict was &ldquo;he understood the benefit but the approach was a bit too radical&rdquo; to his taste. </span></p>
<p><span style="font-family: Calibri;font-size: small">Indeed, the feature was not only tracking inventory cost in 2 currencies (the local accounting one and in the reporting i.e. secondary currency) but also calculating it in accordance with 2 different cost calculation models and posting the financial impact into the general ledger in an isolated GL layer to make it visible on IFRS vs. local account statements. Every inventory transaction was given an additional set of fields CostAmountSecCur* to store the value in the secondary currency. The feature was blamed for bugs, but after a while it made it into the Dynamics AX core application. A decade later the bugs are gone and the feature is still there in Dynamics AX 2012 R3 for Russia and other Eastern European countries, it has been kept on a par with the latest developments at the AX logistics core.</span></p>
<p><span style="font-family: Calibri;font-size: small">What have been the reasons to keep it in the application?</span></p>
<ul>
<li>
<p>Initially it provided a stable inventory value in the &lsquo;hard&rsquo; currency USD, in a country where retail prices in rubles RUB were updated daily and sometimes grounded in a pseudo-currency tied to the dollar. The COGS in RUB was reflecting the past purchase price whereas the revenues were driven by the inflated sales price, resulting in a disproportionally huge profit in RUB. Only the COGS in USD was comparable with the&nbsp;revenues in USD and provided a more solid basis for a business decisions in an economy ravaged by <strong>hyperinflation</strong>. With the Russian economy &ldquo;in tatters&rdquo; my dual warehouse feature may gain back some popularity :)</p>
</li>
<li>
<p>Not that long time ago I was asked by a CEO: &ldquo;We buy in euros, we sell in euros, why on Earth would we track our stock and assets in the Polish zloty?!&rdquo; Indeed, <a href="www.iasplus.com/en/standards/ias/ias21">IAS 21</a> says &ldquo;an entity is required to determine a <strong>functional</strong> currency &hellip; based on the primary economic environment in which it operates&rdquo;, but auditors are generally less tolerant and expect the balance to the produced in the national currency.</p>
</li>
<li>
<p>Costing models in accounting and in the cost accounting sometimes differ. For example, on the <em>balance sheet</em> the average price may be applied to the product stock, whereas in the <em>cost accounting</em> the product may be recorded at a standard price. Here we may utilize the &ldquo;dual warehouse&rdquo; with the reporting currency same as the local one but with 2 different <strong>cost valuation models</strong>.</p>
</li>
</ul>
<p><span style="font-family: Calibri;font-size: small">The emphasis is put here on the last requirement as it seems to be pretty common across the globe.</span></p>
<h3>Example 1</h3>
<p><span style="font-family: Calibri;font-size: small">I am using the standard Dynamics AX 2012 R3 demo database, the RUMF company. &ldquo;RUB&rdquo; is both the local currency and the reporting currency there. The license configuration key </span><strong><span style="font-family: Calibri;font-size: small">Country regional specific features / Multiple countries regions / Russia / Dual warehousing</span></strong><span style="font-family: Calibri;font-size: small"> must be active. Contrary to AX2009, local compliance features in Dynamics AX 2012 cannot be re-used in a &ldquo;foreign&rdquo; legal entity by just turning the configuration key: the primary company address must be in Russia. I leave it to the reader to hack AX and to &lsquo;jailbreak&rsquo; this feature. Do not expect it to be very&nbsp;easy.</span></p>
<p><span style="font-family: Calibri;font-size: small">Let me first highlight the business case the feature was initially intended to support. Imagine a product valued at a monthly average price. It is delivered in 2 batches at the same effective price in USD but a different <span lang="EN-US">equivalent </span>in RUB:</span></p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="113">
<p><span style="font-family: Calibri;font-size: small">Date</span></p>
</td>
<td valign="top" width="163">
<p><span style="font-family: Calibri;font-size: small">Business case</span></p>
</td>
<td valign="top" width="118">
<p><span style="font-family: Calibri;font-size: small">Price USD</span></p>
</td>
<td valign="top" width="160">
<p><span style="font-family: Calibri;font-size: small">Rate USD/RUB</span></p>
</td>
<td valign="top" width="96">
<p><span style="font-family: Calibri;font-size: small">Primary </span><span style="font-family: Calibri;font-size: small">cost price RUB </span><span style="font-family: Calibri;font-size: small">(Weighted avg.)</span></p>
</td>
<td valign="top" width="105">
<p><span style="font-family: Calibri;font-size: small">Secondary cost price USD </span><span style="font-family: Calibri;font-size: small">(Weighted avg.)</span></p>
</td>
</tr>
<tr>
<td valign="top" width="113">
<p><span style="font-family: Calibri;font-size: small">15.01.2015</span></p>
</td>
<td valign="top" width="163">
<p><span style="font-family: Calibri;font-size: small">Purchase 100 kg</span></p>
</td>
<td valign="top" width="118">
<p><span style="font-family: Calibri;font-size: small">10,00</span></p>
</td>
<td valign="top" width="160">
<p><span style="font-family: Calibri;font-size: small">66,10</span></p>
</td>
<td valign="top" width="96">
<p><span style="font-family: Calibri;font-size: small">66,10</span></p>
</td>
<td valign="top" width="105">
<p><span style="font-family: Calibri;font-size: small">10</span></p>
</td>
</tr>
<tr>
<td valign="top" width="113">
<p><span style="font-family: Calibri;font-size: small">17.02.2015</span></p>
</td>
<td valign="top" width="163">
<p><span style="font-family: Calibri;font-size: small">Purchase 100 kg</span></p>
</td>
<td valign="top" width="118">
<p><span style="font-family: Calibri;font-size: small">10,00</span></p>
</td>
<td valign="top" width="160">
<p><span style="font-family: Calibri;font-size: small">62,66</span></p>
</td>
<td valign="top" width="96">
<p><span style="font-family: Calibri;font-size: small">64,38</span></p>
</td>
<td valign="top" width="105">
<p><span style="font-family: Calibri;font-size: small">10</span></p>
</td>
</tr>
<tr>
<td valign="top" width="113">
<p><span style="font-family: Calibri;font-size: small">16.05.2015</span></p>
</td>
<td valign="top" width="163">
<p><span style="font-family: Calibri;font-size: small">Sale 50 kg</span></p>
</td>
<td valign="top" width="118">
<p><span style="font-family: Calibri;font-size: small">15,00</span></p>
</td>
<td valign="top" width="160">
<p><span style="font-family: Calibri;font-size: small">50,01</span></p>
</td>
<td valign="top" width="96">
<p><span style="font-family: Calibri;font-size: small">64,38</span></p>
</td>
<td valign="top" width="105">
<p><span style="font-family: Calibri;font-size: small">10</span></p>
</td>
</tr>
</tbody>
</table>
<p><span style="font-family: Calibri;font-size: small">The contribution margin in the &lsquo;hard&rsquo; currency USD is 33.33%, while the contribution margin in RUB is just 14.17%. Which is the &ldquo;right&rdquo; one depends on the cost structure of the company. Technically, the one cannot be deducted from the other without knowing the full transaction history. In Dynamics AX a separate inventory closing run is required. This is exactly what the &ldquo;Dual warehouse&rdquo; feature does: it allows for 2 parallel closing runs, 2 settlement data pools and a secondary GL ledger.</span></p>
<h3>Example 2</h3>
<p><span style="font-family: Calibri;font-size: small">Now let us explore my major case with one currency but 2 models:</span></p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="113">
<p><span style="font-family: Calibri;font-size: small">Date</span></p>
</td>
<td valign="top" width="163">
<p><span style="font-family: Calibri;font-size: small">Business case</span></p>
</td>
<td valign="top" width="118">
<p><span style="font-family: Calibri;font-size: small">Price USD</span></p>
</td>
<td valign="top" width="96">
<p><span style="font-family: Calibri;font-size: small">Inventory cost price USD </span><span style="font-family: Calibri;font-size: small">(Weighted avg.)</span></p>
</td>
<td valign="top" width="105">
<p><span style="font-family: Calibri;font-size: small">Inventory cost price USD </span><span style="font-family: Calibri;font-size: small">(Standard)</span></p>
</td>
<td valign="top" width="105">
<p><span style="font-family: Calibri;font-size: small">Cost variation USD</span></p>
</td>
</tr>
<tr>
<td valign="top" width="113">
<p><span style="font-family: Calibri;font-size: small">15.01.2015</span></p>
</td>
<td valign="top" width="163">
<p><span style="font-family: Calibri;font-size: small">Purchase 100 kg</span></p>
</td>
<td valign="top" width="118">
<p><span style="font-family: Calibri;font-size: small">10,00</span></p>
</td>
<td valign="top" width="96">
<p><span style="font-family: Calibri;font-size: small">10</span></p>
</td>
<td valign="top" width="105">
<p><span style="font-family: Calibri;font-size: small">10</span></p>
</td>
<td valign="top" width="105">
<p><span style="font-family: Calibri;font-size: small">&nbsp;</span></p>
</td>
</tr>
<tr>
<td valign="top" width="113">
<p><span style="font-family: Calibri;font-size: small">17.02.2015</span></p>
</td>
<td valign="top" width="163">
<p><span style="font-family: Calibri;font-size: small">Purchase 100 kg</span></p>
</td>
<td valign="top" width="118">
<p><span style="font-family: Calibri;font-size: small">12,00</span></p>
</td>
<td valign="top" width="96">
<p><span style="font-family: Calibri;font-size: small">11</span></p>
</td>
<td valign="top" width="105">
<p><span style="font-family: Calibri;font-size: small">10</span></p>
</td>
<td valign="top" width="105">
<p><span style="font-family: Calibri;font-size: small">+2</span></p>
</td>
</tr>
<tr>
<td valign="top" width="113">
<p><span style="font-family: Calibri;font-size: small">16.05.2015</span></p>
</td>
<td valign="top" width="163">
<p><span style="font-family: Calibri;font-size: small">Sale 50 kg</span></p>
</td>
<td valign="top" width="118">
<p><span style="font-family: Calibri;font-size: small">15,00</span></p>
</td>
<td valign="top" width="96">
<p><span style="font-family: Calibri;font-size: small">11</span></p>
</td>
<td valign="top" width="105">
<p><span style="font-family: Calibri;font-size: small">10</span></p>
</td>
<td valign="top" width="105">
<p><span style="font-family: Calibri;font-size: small">&nbsp;</span></p>
</td>
</tr>
</tbody>
</table>
<p><span style="font-family: Calibri;font-size: small">To test it, set up a new item model group. Pay attention the secondary inventory model group and the </span><strong><span style="font-family: Calibri;font-size: small">Post secondary financial</span></strong><span style="font-family: Calibri;font-size: small"> parameters. The latter activates the &ldquo;dual&rdquo; GL posting layer.</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/6320.DW1.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/6320.DW1.png" alt="" border="0" /></a></p>
<p><span style="font-family: Calibri;font-size: small">Create a new product with the tracking groups None-None. Assign a default site and a warehouse. Use the button </span><strong><span style="font-family: Calibri;font-size: small">Manage costs / Item price</span></strong><span style="font-family: Calibri;font-size: small"> on the released product ribbon to assign a standard price to the item. Do not enter the price of 10.00 on the first tab page of the &ldquo;Pending price&rdquo; grid but on the second, in the field </span><strong><span style="font-family: Calibri;font-size: small">Secondary cost</span></strong><span style="font-family: Calibri;font-size: small">! Leave the primary standard cost to be zero. Activate the price. In the item group of the product, set an account for the &ldquo;Rounding variance&rdquo;.</span></p>
<p><span style="font-family: Calibri;font-size: small">Open a purchase order to the &ldquo;Vortex corporation&rdquo; and post 2 PO invoices with different prices as outlined above. Open a sales order and post an AR invoice with 50 kg.</span></p>
<p><span style="font-family: Calibri;font-size: small">Now check the inventory transactions and look at the awaited, but still stunning result, or as we say at Microsoft &ndash; awesome. Just awesome:</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/3252.DW2.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/3252.DW2.png" alt="" border="0" /></a></p>
<p><span style="font-family: Calibri;font-size: small">Note the column </span><strong><span style="font-family: Calibri;font-size: small">Cost amount (cur.)</span></strong><span style="font-family: Calibri;font-size: small"> meticulously tracking our standard cost as opposed to the average cost in the ordinary </span><strong><span style="font-family: Calibri;font-size: small">Cost amount</span></strong><span style="font-family: Calibri;font-size: small"> column. Now open the GL voucher for the second PO invoice:</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/4034.DW3.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/4034.DW3.png" alt="" border="0" /></a></p>
<p><span style="font-family: Calibri;font-size: small">Examine how the system recorded the cost variance in a separate posting layer.</span></p>
<p><span style="font-family: Calibri;font-size: small">You may also perform the </span><strong><span style="font-family: Calibri;font-size: small">Inventory management / Periodic / Closing and adjustment</span></strong><span style="font-family: Calibri;font-size: small"> vs. </span><strong><span style="font-family: Calibri;font-size: small">Closing and adjustment in currency</span></strong><span style="font-family: Calibri;font-size: small">. Here nether of the procedures is going to make any cost adjustments, since within the primary cost model the momentary cost price happens to be the same as the total average, while the secondary model should not produce any settlements at all for our product valuated at a standard cost.</span></p>
<h3>Conclusion</h3>
<p><span style="font-family: Calibri;font-size: small">The examples above have been deliberately kept simple; in reality different currencies and models lead to collisions where an inventory transaction may be settled in one model but remain &lsquo;open&rsquo; in the other; where manual adjustments and write-offs are only applied to one of the models; where the &lsquo;physical&rsquo; price affects the calculation. I still hope this short introduction has given you an idea what this feature can do if applied creatively.</span></p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Work item could not be created. Insufficient rights for user %1</title>
      <link>https://docs.microsoft.com/archive/blogs/dynamics-coe/work-item-could-not-be-created-insufficient-rights-for-user-1</link>
      <pubDate>Tue, 02 Jun 2015 23:50:00 GMT</pubDate>
      <dc:creator><![CDATA[Lars Bøgebjerg [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dynamics-coe/2015/06/02/work-item-could-not-be-created-insufficient-rights-for-user-1/</guid>
      <description><![CDATA[Have you ever encountered the issue that a workflow in Microsoft Dynamics AX stops with the...]]></description>
      <content:encoded><![CDATA[<p>Have you ever encountered the issue that a workflow in Microsoft Dynamics AX stops with the following error message?</p>
<p><em>Stopped (error): X++ Exception: Work item could<br />not be created. Insufficient rights for user %1.</em></p>
<p><em>at SysWorkflowWorkItem-create</em></p>
<p><em>SysWorkflowWorkItem-createWorkItems</em></p>
<p><em>SysWorkflow-save</em></p>
<p><em>SysWorkflowQueue-resume</em></p>
<p>&nbsp;</p>
<p>Moreover, the issue still occurs even after assigning the user to the <em>System Administrator</em> role?</p>
<p>The cause for this is most likely that you have disabled one or more configuration keys in the <em>License configuration</em> in Microsoft Dynamics AX.</p>
<p>As an example, the <em>Vendor invoice approval</em> workflow stops with the above error.</p>
<p>Let&rsquo;s in the AOT navigate to Workflows&nbsp;-&gt; VendInvoiceApproval&nbsp;-&gt; Outcomes -&gt; Approval</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/2476.VendInvoiceApproval_Outcomes_Approve.jpg" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-57-32/2476.VendInvoiceApproval_5F00_Outcomes_5F00_Approve.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/2476.VendInvoiceApproval_Outcomes_Approve.jpg" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-57-32/2476.VendInvoiceApproval_5F00_Outcomes_5F00_Approve.jpg" alt="" border="0" /></a></p>
<p>And have a look at the <em>Properties</em> for this node.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/2438.Approve_Properties.jpg" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-57-32/2438.Approve_5F00_Properties.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/2438.Approve_Properties.jpg" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-57-32/2438.Approve_5F00_Properties.jpg" alt="" border="0" /></a></p>
<p>ActionMenuItem = VendInvoiceApprovalApprove</p>
<p>Let&rsquo;s verify the <em>Configuration key</em> for this menu item by still in the AOT to navigate to Menu items&nbsp;-&gt; Action&nbsp;-&gt; VendInvoiceApprovalApprove and have a look at the <em>Properties</em> for this node.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/5383.VendInvoiceApprovalApprove_properties.jpg" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-57-32/5383.VendInvoiceApprovalApprove_5F00_properties.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/5383.VendInvoiceApprovalApprove_properties.jpg" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-57-32/5383.VendInvoiceApprovalApprove_5F00_properties.jpg" alt="" border="0" /></a></p>
<p>The <em>Configuration key</em> is LedgerBasic. This configuration key is most likely not disabled in the <em>License configuration</em> for Microsoft Dynamics AX.</p>
<p>So let&rsquo;s check the <em>Web menu item</em>.</p>
<p>WebActionMenuItem = EPVendInvoiceApprovalApprove</p>
<p>Let&rsquo;s verify the <em>Configuration key</em> for this menu item by still in the AOT to navigate to Web&nbsp;-&gt; Web Menu items&nbsp;-&gt; Actions&nbsp;-&gt; EPVendInvoiceApprovalApprove and have a look at the <em>Properties</em> for this node.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/6201.EPVendInvoiceApprovalApprove_Properties.jpg" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-57-32/6201.EPVendInvoiceApprovalApprove_5F00_Properties.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/6201.EPVendInvoiceApprovalApprove_Properties.jpg" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-57-32/6201.EPVendInvoiceApprovalApprove_5F00_Properties.jpg" alt="" border="0" /></a></p>
<p>The <em>Configuration key</em> is VSS. This is the configuration key for the <em>Vendor portal </em>and must be enabled for the <em>Vendor invoice approval</em> workflow to be successful. Enabling this <em>Configuration key</em> in the <em>License configuration</em> in Microsoft Dynamics AX solves the above problem. In Microsoft Dynamics AX navigate to System administration&nbsp;-&gt; Setup&nbsp;-&gt; Licensing&nbsp;-&gt; License configuration. Navigate to <em>Procurement I</em> and make sure that <em>Vendor portal</em> is checked.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/5344.LicenseConfiguration_VendorPortal.jpg" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-57-32/5344.LicenseConfiguration_5F00_VendorPortal.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/5344.LicenseConfiguration_VendorPortal.jpg" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-57-32/5344.LicenseConfiguration_5F00_VendorPortal.jpg" alt="" border="0" /></a></p>
<p>The conclusion is that the <em>Vendor Invoice Approval</em> workflow will not work in Microsoft Dynamics AX without the <em>Vendor portal</em> being enabled,&nbsp;even if the Vendor portal is not to be used.</p>]]></content:encoded>
    </item>
    <item>
      <title>German travel expenses in AX 2012 / Deutsche Reisekostenabrechnung 2015</title>
      <link>https://docs.microsoft.com/archive/blogs/dynamics-coe/german-travel-expenses-in-ax-2012-deutsche-reisekostenabrechnung-2015</link>
      <pubDate>Wed, 06 May 2015 16:10:00 GMT</pubDate>
      <dc:creator><![CDATA[Eugen Glasow]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dynamics-coe/2015/05/06/german-travel-expenses-in-ax-2012-deutsche-reisekostenabrechnung-2015/</guid>
      <description><![CDATA[Introduction
You want to implement travel expense reporting for Germany in Dynamics AX...]]></description>
      <content:encoded><![CDATA[<h2>Introduction</h2>
You want to implement travel expense reporting for Germany in Dynamics AX out-of-the-box? Congratulations! You are about to deploy an exotic module (“Travel and expense”) on an undoubtedly exotic AX implementation project in an exotic country. Luckily enough, the requirements of the federal income law with its painstaking per diem regulations may be implemented in Dynamics AX 2012 R3 without significant customizations, let’s say, to 95%.
Let me start with a short introduction to the state of the law in 2015. If an employee of a German company – let’s call him Otto - got reimbursed for hotel or meals above a certain level, the value of goods or services received would be a subject to his income tax. Instead, Otto is given a by the company a fixed statutory per diem amount per day. For domestic trips inside Germany he gets 24 Euro per day, yet this rate is only applied to the 2nd day on multi-day business trips. For the first and the last day Otto only becomes the half of the daily ration ½ = €12.
No per diems are paid for a one-day business trip if it lasts less than 8 hours. This restriction does not apply to the first and the last day on a longer trip: he can start from home (or office) at 23:00 and come back in 26 hours on the 2nd calendar day – this still classifies as a 3 day business travel with €12 + €24 + €12 = €48 of allowance in total.
There is an additional “midnight rule” but we are going to neglect that. The only thing important on a several day trip is the night stop in-between.
In general, per diem in Germany is an allowance for catering. Hotel bills are reimbursed in full (with some limitations, see below), an invoice provided. Every free meal sponsored by the employer or customer, Otto has to report and reduce the daily allowance in accordance with the “20-40-40” rule:
<ul>
 	<li>“Free” <strong>breakfast</strong> at the hotel = 20% reduction = -€4.80</li>
 	<li>Free <strong>lunch</strong> at work = 40% reduction = -€9.60</li>
 	<li><strong>Dinner</strong> sponsored by the boss = 40% reduction = -€9.60</li>
</ul>
The statutory per diem rates vary by country. The recent novelty in 2015 are rates specific to a city. Indeed, New York, London and Geneva are known to be notoriously expensive travel destinations, and the German state now accounts for that. The rates are usually yearly updated by the federal government and expressed in euro:
<a href="www.spesen-ratgeber.de/wp-content/uploads/2015/01/Verpflegungspauschalen-Ausland-2015.pdf">www.spesen-ratgeber.de/wp-content/uploads/2015/01/Verpflegungspauschalen-Ausland-2015.pdf</a>
Here is an example for Switzerland, note the different ratio between the full and reduced daily allowance:
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="189" valign="top">&nbsp;</td>
<td width="189" valign="top" style="text-align: center"><strong>Full 24h day</strong></td>
<td width="189" valign="top" style="text-align: center"><strong>“First/last day” or</strong>
<strong>  &lt;8 hours</strong></td>
<td width="189" valign="top" style="text-align: center"><strong>Hotel allowance</strong>
<strong>  “Pauschalbetrag”</strong></td>
</tr>
<tr>
<td width="189" valign="top">Switzerland</td>
<td width="189" valign="top">&nbsp;</td>
<td width="189" valign="top">&nbsp;</td>
<td width="189" valign="top">&nbsp;</td>
</tr>
<tr>
<td width="189" valign="top">- Geneva</td>
<td width="189" valign="top" style="text-align: center">€62</td>
<td width="189" valign="top" style="text-align: center">€41</td>
<td width="189" valign="top" style="text-align: center">€174</td>
</tr>
<tr>
<td width="189" valign="top">- the rest of Switzerland</td>
<td width="189" valign="top" style="text-align: center">€48</td>
<td width="189" valign="top" style="text-align: center">€32</td>
<td width="189" valign="top" style="text-align: center">€139</td>
</tr>
</tbody>
</table>
The "hotel allowance" is applicable to an overnight stay if the employee fails to bring a proper hotel bill, which must be a very rare occasion.

The “20-40-40” meal reduction rule is also applied to destinations abroad, based on the full 24h rate.
If the meal is offered to Otto at a discounted price, but Otto still has to pay a small contribution from his pocket, this meal contribution may theoretically be claimed, but no more than €4.80 for breakfast or €9.60 for lunch/dinner, respectively. This seems to be a true exception. To handle it properly, an own category (not taxable by VAT) has to be created and a special expense policy has to be established to limit the meal price entered from above. This case is not explored here any further.
Let’s take a realistic example and start setting up Dynamics AX 2012 R3 CU8 for German per diems:
<table style="width: 535px;height: 697px" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="106" valign="top">&nbsp;</td>
<td width="307" valign="top"><strong>Case</strong></td>
<td width="331" valign="top"><strong>Per diem calculation</strong></td>
</tr>
<tr>
<td width="106" valign="top">Case 1

“One-day training”</td>
<td width="307" valign="top">Otto attended a daily training and was absent from 9:00 till 19:00. One lunch was provided.</td>
<td width="331" valign="top">One day               €12.00

Reduction            €9.60

<strong>Grand total         €2.40</strong></td>
</tr>
<tr>
<td width="106" valign="top">Case 2

“3 days of training with hotel”</td>
<td width="307" valign="top">Same as before, but the business trip now takes 3 days in total:
<ul>
 	<li>from 18:00 on Monday</li>
 	<li>whole Tuesday</li>
 	<li>until 19:00 on Wednesday.</li>
</ul>
This includes 2 nights at a hotel without breakfast.

2 lunches were provided by the training center.</td>
<td width="331" valign="top">First day             €12.00

Day between      €24.00

Last day             €12.00

<strong>Total                  €48.00</strong>

2 nights                €107.00*2

Reduction            €19.20 (2*9.60)

<strong>Grand total         €242.80</strong></td>
</tr>
<tr>
<td width="106" valign="top">Case 3

“Fine Dining”</td>
<td width="307" valign="top">Same as before: 3 days in total, 2 nights at the hotel including 2 breakfasts.

The breakfasts are separately shown on the hotel bill: €8 inkl. VAT 19% each.

2 lunches are consumed for free at the training center.

In addition, Otto invited a potential customer to a fine restaurant.</td>
<td width="331" valign="top">First day             €12.00

Day between      €24.00

Last day             €12.00

<strong>Total                  €48.00</strong>

2 nights              €99.00*2

(2 breakfasts      €8.00)

1 dinner              €115.00

Reduction           €28.80 (3*9.60)

<strong>Grand total        €332.20</strong></td>
</tr>
<tr>
<td width="106" valign="top">Case 4

“Travelling abroad”</td>
<td width="307" valign="top">Otto goes to Switzerland.

On the same dates as above he flies to Geneva, resides for 2 nights at the “President Wilson” and slowly consumes 2 exquisite breakfasts served on the lakeshore.</td>
<td width="331" valign="top">First day             €41.00

Day between      €62.00

Last day             €41.00

<strong>Total                  €144.00</strong>

2 nights              770.00 CHF *2 +

(2 breakfasts      45.00 CHF*2)

2 city tax             4.75CHF *2

<strong>Hotel sub-total  1549.50 CHF</strong>

Reduction            €24.80 (2*62*20%)

<strong>Grand total         ~1527.84 EUR</strong>

<strong>(depending on the rate)</strong></td>
</tr>
</tbody>
</table>
<h2>Domestic business travel – case 1 “One-day training”</h2>
Let’s start setting up the system for the case 1.
First of all, we require a shared expense category ”ePerDiem” of the type “Allowance”. This expense category is then selected under local legal entity expense categories and “Activated in journals” to make is available for expense entry:

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/3513.TE1.png"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/3513.TE1.png" border="0" /></a>
This per diem category is not eligible value added tax recovery and given the tax group “tax free”.
The right per diem parameters for Germany can be read from the following screenshot:
<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/6472.TE2.png"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/6472.TE2.png" border="0" /></a>

Indeed, in our second case the allowance is paid for every of the 3 calendar days and the <strong>Base per diem calculation on</strong> must be <em>Calendar day</em> as opposed to an absolute trip duration in days. The <strong>Meal reductions</strong> are self-explaining. The <strong>First and last day defaults</strong> are used to model the reduced rate on the days of arrival and departure.
The <strong>Per diem rounding</strong> = <em>Normal rounding</em> is a must, because we don’t round up cents to whole euros.
The <strong>Calculate meal reduction by</strong> is a new field in CU8 (Cumulative Update 8 to AX2012 R3). Since breakfast weight less than lunch/dinner and the meal reduction amount stays the same for the first/last day, both the options <em>Meal type per day</em> and <em>Meal type per trip</em> work well. AX version prior to CU8 only supported the <em>Meal type per trip</em> option.
Per diems locations has to be created next, and the right rate has to be assigned to the German domestic location <em>DEU</em>. Every leg in on the business trip has to be given a “per diem location” to deduct the right allowance for that country or city.
<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/1803.TE3.png"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/1803.TE3.png" border="0" /></a>

The fist and the last day assume a reduced allowance, this can be modelled by means of the <strong>Per diem rate tiers</strong>. The reduction (€12/€24 = 50%) is the same for the day of arrival and the day of departure, therefore the right setting is <strong>Apply to</strong> = <em>Both</em>. A one day trip should be no less than 8 hours, but there is no such a restriction per calendar day on 3+ day trips, and the <strong>Minimum hours</strong> should be set here to zero in general. The 8 hours threshold can be enforced differently with an "Expense report policy", see below.
We now can test case 1, but first make sure that the <em>Meal reduction, Breakfast, Lunch</em>, Dinner, Location, Country fields are activated in the<strong> T&amp;E / Setup / Travel and expense entry / Display fields</strong>.

The sole user interface for expense report entry is the <span style="text-decoration: underline">Dynamics AX Enterprise Portal</span> (Employee profile). No expense entry is possible in the AX2012 rich client.
Create a new expense report, add a new line “ePerDiem”, enter the start and the end date/time of your trip and choose the location:

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/8156.TE4.png"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/8156.TE4.png" border="0" /></a>
The <strong>Per diems</strong> block below is new in CU8. The previous versions did not track meal reductions per day, but only in total in the <strong>Breakfast</strong>, etc. fields above. Enter the free lunch provided by the training institution. The reduction of €9.60 is shown as required.

Since the meal reduction amounts are not relative to the reduced daily allowance rate, by entering additionally Breakfast = 1 your reduction is going to exceed the maximum allowance: €12 - €4.80 - €9.60 = €12 – €14.40 = -€2.40.
According to the letter of the BMF, the German Federal Ministry of Finance (<a href="www.bundesfinanzministerium.de/Content/DE/Downloads/BMF_Schreiben/Steuerarten/Lohnsteuer/2014-10-24-ergaenztes-bmf-schreiben-reform-steuerliches-reisekostenrecht.pdf?__blob=publicationFile&amp;v=3">www.bundesfinanzministerium.de/Content/DE/Downloads/BMF_Schreiben/Steuerarten/Lohnsteuer/2014-10-24-ergaenztes-bmf-schreiben-reform-steuerliches-reisekostenrecht.pdf?__blob=publicationFile&amp;v=3</a>), a reduction may not exceed 100% and the daily allowance is just set to zero, but Dynamics AX gives here an error. This warning has to be removed by a small customization in the method
<strong>\Data Dictionary\Tables\TrvExpTrans\Methods\perDiem</strong> which will simply turn the per diem amount to 0.

Save the expense line and enjoy the expected result:
<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/2313.TE5.png"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/2313.TE5.png" border="0" /></a>

To finally approve and post the expense report an approval workflow has to be in place. This workflow most probably will be looking for an approver upwards in the managerial hierarchy under consideration of the proper signing limit:

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/5873.TE6.png"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/5873.TE6.png" border="0" /></a>

Beware of the bug 2746305 in all version prior to CU8: “The expense report workflow using managerial hierarchy cannot assign to a user beyond the first level in the hierarchy". A standalone hotfix KB 3009953 exists for this bug.

Remember, a one-day trip less than 8 hours does not count as business travel. The “Per diem rate tiers” cannot be used to enforce it, but here are 2 possible alternatives:
<ul>
 	<li>solve it organizationally, establish “human-driven” approval rules</li>
 	<li>make a small customization to enable the total trip duration, the start and the end date as parameters in the expense policy definition.</li>
</ul>
This expense policy will be applied to the expense category type “other”:

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/2620.TE7.png"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/2620.TE7.png" border="0" /></a>
to produce an error message if the user erroneously tries to enter a short 1-day trip (for example, just from 09:00 to 16:00). To support this scenario, the class <strong>TrvRuleExpressionSetup</strong> has to be extended by 3 parm-methods.
<h2>Domestic business travel – case 2 “3 days of training with hotel”</h2>
The 2nd case requires a receipt, a bill for the accommodation at a hotel. The VAT from domestic invoices may be recovered, and we need a country-specific setup for the VAT (<strong>T&amp;E / Setup / Taxes / Tax configurations</strong>) where the host country is associated with a tax group containing both full (19%) and reduced (7%) tax codes:

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/2480.TE8.png"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/2480.TE8.png" border="0" /></a>

There is also such thing as a city tax. A city tax is imposed by a commune and is not a subject to the VAT (no tax on tax). Currently it is only levied by the tax authority in Berlin, and does not apply to business travel. Therefore, we can neglect this and don’t have to enforce an itemization of the hotel bill by the “pure” room rate and the city tax.
Set up an additional category “eHotel” of the type “Hotel”, assign the reduced 7% tax group to this category. Let the user enter a line against his category as an amount including tax, and select the <strong>Country/region</strong> = <em>DEU</em>. The VAT is derived automatically by the system: €14.00:

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/1488.TE9.png"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/1488.TE9.png" border="0" /></a>
The per diems line is entered as follows:

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/1768.TE10.png"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/1768.TE10.png" border="0" /></a>

with the total reimbursable amount as intended:

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/0083.TE11.png"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/0083.TE11.png" border="0" /></a>
<h2>Domestic business travel – case 3 “Fine dining”</h2>
<p style="text-align: left">This time the hotel served breakfast to Otto. The breakfast must presented on the invoice separately, since any meal at the restaurant is taxed at the full rate of 19%, whereas the accommodation is subsidized through the reduced VAT of 7%.
One can hardly get a decent breakfast in Germany for 4.80 EUR, and in Switzerland breakfast would cost not 48 EUR * 20% = 9.60 EUR but probably around 20 CHF ~= 19 EUR. In practical terms, to get off with as little damage as possible, Otto has to strip the hotel bill of the breakfast and record no reduction for breakfast. There is still no need for the itemization of the hotel bill.
The fine dining with the customer is tolerated by the BMF, but it should be at a reasonable cost. The statutory definition of “reasonable” in 2015 is no more than €60 per person. This so-called “entertainment” may not reduce the corporate tax base, but the VAT may be recovered. Until recently the BMF used to only return 70% of the VAT, but after an intervention of the European Union the VAT amount may now be recovered in full.
We require a new expense category of the type “Meal” with the full VAT rate assigned. To enforce the “reasonable price” rule, an expense validation policy may be set up:
<em>Amount &lt; Number of guests * €60</em>
The policy screen in AX does not allow for complex formulas with multiplication, but we hope that Otto is not going to throw a wedding party for a hundred of guests, and we are able to set up an exhaustive list for any party with a number of guests between 2 and 10-20:
<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/5417.TE12.png"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/5417.TE12.png" border="0" /></a></p>
<p style="text-align: left">The first condition additionally enforces an obligatory entry of the invited guests. The system will show an error unless the button <strong>Guests…</strong> is clicked in the “eMeals” line:</p>
<p style="text-align: left"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/1234.TE13.png"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/1234.TE13.png" border="0" /></a></p>
<p style="text-align: left">Try and see what happens if bier costs 20 euros more.
Here is the total impact of the Otto’s activities, as expected:
<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/2728.TE14.png"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/2728.TE14.png" border="0" /></a></p>

<h2>Domestic business travel – case 4 "Travelling abroad"</h2>
<p style="text-align: left">As we have learned already, daily allowances are country-specific. The reduced domestic rate for Germany is 50%, but the reduced foreign rates are close to 66% (but not exactly):</p>

<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="189" valign="top">&nbsp;</td>
<td width="189" valign="top" style="text-align: center"><strong>Full 24h day</strong></td>
<td width="189" valign="top" style="text-align: center"><strong>“First/last day”</strong></td>
<td width="189" valign="top" style="text-align: center"><strong>Percentage</strong></td>
</tr>
<tr>
<td width="189" valign="top">Germany</td>
<td width="189" valign="top" style="text-align: center">€24</td>
<td width="189" valign="top" style="text-align: center">€12</td>
<td width="189" valign="top" style="text-align: center">50%</td>
</tr>
<tr>
<td width="189" valign="top">Switzerland, Geneva</td>
<td width="189" valign="top" style="text-align: center">€62</td>
<td width="189" valign="top" style="text-align: center">€41</td>
<td width="189" valign="top" style="text-align: center">66.13%</td>
</tr>
<tr>
<td width="189" valign="top">Rest of Switzerland</td>
<td width="189" valign="top" style="text-align: center">€48</td>
<td width="189" valign="top" style="text-align: center">€32</td>
<td width="189" valign="top" style="text-align: center">66.66%</td>
</tr>
</tbody>
</table>
<p style="text-align: left">The reduced rates are rounded by the government to whole euros. To match the reduced foreign rate, I use a tailored percentage. It should approximate the daily rate with a deviation less than €0.01:
41/62 = 0,66129… =&gt; 62.00 * 66.13% = 41.0006 ~= 41.00
32/48 = 0,66666… =&gt; 62.00 * 66.66% = 31.9968 ~= 32.00
The respective setup of per diems and tiers per location is shown on the following screenshot:</p>
<p style="text-align: left"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/5226.TE15.png"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/5226.TE15.png" border="0" /></a></p>
<p style="text-align: left"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/2577.TE16.png"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/2577.TE16.png" border="0" /></a></p>
<p style="text-align: left">Note that the rates are updated by the BMF every year and have to be regularly re-imported with validity dates. This is also true for the calculated percentage for first/last day.
The meals reduction in AX now takes the rates for the location “Switzerland-Geneva” into account:</p>
<p style="text-align: left"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/3365.TE17.png"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/3365.TE17.png" border="0" /></a>
The foreign VAT on the hotel bill is not recoverable, the selection of the right country code ensures no VAT is going to be deducted. The amount paid in Swiss francs is converted to euro at the intrinsic System exchange rate type the AX (see <strong>System administration / Setup / System parameters</strong>) on the given day. Again, breakfasts have to be subtracted from the total bill amount:</p>
<p style="text-align: left"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/4382.TE18.png"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/4382.TE18.png" border="0" /></a></p>
<p style="text-align: left">Newly in 2015, a special challenge is posed by roundtrips across foreign cities with different rates as explained here on a case of the USA: <a href="www.spesen-ratgeber.de/verpflegungsmehraufwand-ausland-2014-neue-ausloese-tabelle/">www.spesen-ratgeber.de/verpflegungsmehraufwand-ausland-2014-neue-ausloese-tabelle/</a>
The legs have to be entered in AX in separate expense report lines, because the only place to specify the location driving the rate is the line, there are no per diem sub-lines in AX. This makes erroneously the first day of the leg an “arrival” and the last – a “departure” day. This is not entirely correct, because the days “in the middle” are eligible to the full 24h-rate of the destination reached by 24:00 o’clock on the respective date.
Indeed, “2/3 Los Angeles rate” + “2/3 Miami rate” is not the same as “1 Miami rate”. This may be helped by dummy locations without any reduction for the first and last day.</p>
<p style="text-align: left">On per diems configuration in Dynamics 365 for Finance and Operations, read <a href="erconsult.eu/blog/configuring-austrian-and-norwegian-per-diems-in-d365/">Configuring Austrian and Norwegian per diems in Dynamics 365</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Override configuration ID in the constraint-based product configurator in AX2012</title>
      <link>https://docs.microsoft.com/archive/blogs/dynamics-coe/override-configuration-id-in-the-constraint-based-product-configurator-in-ax2012</link>
      <pubDate>Tue, 28 Apr 2015 12:21:00 GMT</pubDate>
      <dc:creator><![CDATA[Eugen Glasow]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dynamics-coe/2015/04/28/override-configuration-id-in-the-constraint-based-product-configurator-in-ax2012/</guid>
      <description><![CDATA[The new constraint-based product configurator was a huge leap forward compared to the old product...]]></description>
      <content:encoded><![CDATA[<p>The new constraint-based product configurator was a huge leap forward compared to the old product builder. In version AX2012 R3 we additionally got</p>
<ul>
<li>&ldquo;Calculations&rdquo; and a slight possibility to work with real numerical values</li>
<li>A feature to automatically re-use configurations instead of generating a new one every time</li>
</ul>
<p>Yet with regards to the integration with the rest of the Dynamics AX system both tools sometimes share similar weaknesses:</p>
<ol>
<li>The configurator cannot take main product attributes as parameters to build&nbsp;one complex re-usable model with forks for similar products with some slightly varying properties.</li>
<li>The used product configurator attributes are not stored in a human readable format on the generated configuration record. Needless to say, an AX configuration does not possess its own attributes at all, nor are the attributes searchable in the AX rich client.</li>
<li>Lookups from AX master tables (usually products, units, product groups) seem to only be leveraged in Retail attributes, while in the product configurator every value should be re-entered as a &ldquo;free text&rdquo; in a dedicated attribute type.</li>
<li>Process manufacturing formulas are not supported even if they are technically exactly the same as discrete BOMs.</li>
<li>New configuration IDs are taken from a number sequence (000147, 000148, 000149&hellip;) and together with the resulting configurations names bear no meaning to the user. Furthermore, a constraint-based product may not have a pre-configured set of initial configurations with distinct codes. One may only use configuration templates for that.</li>
</ol>
<p>While&nbsp;the ivory towers are high, thanks to customizable interfaces in AX we can help ourselves. Below is a solution to the last issue, a feature that allows the user to enter a voluntary free-text ID for the new product configuration record. The feature is looking for an attribute with the solver name <strong>ConfigID</strong> among the options chosen by the user:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/3426.Product_model_with_freetext_ID.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/3426.Product_model_with_freetext_ID.PNG" alt="" border="0" /></a></p>
<p>and takes it instead of drawing a new number from the number sequence. One screen of X++ code is attached to this blog. The issue with the dummy configuration name may also be solved following this pattern. A&nbsp;natural&nbsp;approach would be a name composed of the same unique attributes as in the "re-usable configuration cache".<br />Now, who is going to tackle the points 1-4?</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/61/04/88/SharedProject_PC_FreeText_ConfigID.zip">SharedProject_PC_FreeText_ConfigID.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>What we talk about when we talk about KITS in Dynamics AX</title>
      <link>https://docs.microsoft.com/archive/blogs/dynamics-coe/what-we-talk-about-when-we-talk-about-kits-in-dynamics-ax</link>
      <pubDate>Sun, 01 Mar 2015 14:06:00 GMT</pubDate>
      <dc:creator><![CDATA[Eugen Glasow]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dynamics-coe/2015/03/01/what-we-talk-about-when-we-talk-about-kits-in-dynamics-ax/</guid>
      <description><![CDATA[We often encounter the requirement for handling kits or product combinations, sets, bundles or packs...]]></description>
      <content:encoded><![CDATA[<p>We often encounter the requirement for handling <strong>kits </strong>or product<strong> combinations</strong>, <strong>sets</strong>, <strong>bundles</strong> or <strong>packs</strong> in the sales module in Dynamics AX. They all have in common a fixed (or partially variable) set of components (&lsquo;A&rsquo;, &lsquo;B&rsquo;, &lsquo;C&rsquo;&hellip;) offered to the client as a single package &lsquo;K&rsquo;.</p>
<p>Here the common part ends. The users may follow very different kit handling processes:</p>
<ul>
<li>The kits may be pre-assembled and assume some work at the picking workplace</li>
<li>Or the kit just requires a joint shipment</li>
<li>On the invoice the kit may be represented by a single line or it may expose its components</li>
<li>The sales price for the kit may be less than the sum of the component&rsquo;s prices, or it may be the same</li>
</ul>
<p>For example, an epoxy resin may be sold in a combination with a hardener; the ratio between the resin and hardener is pre-defined. This assumes a Bill of Materials for the Epoxy kit:</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="126">
<p><strong>Product ID</strong></p>
</td>
<td valign="top" width="275">
<p><strong>Name</strong></p>
</td>
<td valign="top" width="83">
<p><strong>Quantity</strong></p>
</td>
<td valign="top" width="126">
<p><strong>Unit of measure</strong></p>
</td>
<td valign="top" width="126">
<p><strong>Regular sales price per unit</strong></p>
</td>
</tr>
<tr>
<td valign="top" width="126">
<p>EXY-6001</p>
</td>
<td valign="top" width="275">
<p>Epoxy SET Bisphenol&nbsp;A</p>
</td>
<td valign="top" width="83">
<p>100</p>
</td>
<td valign="top" width="126">
<p>Pcs</p>
</td>
<td valign="top" width="126">
<p>&euro;1.00</p>
</td>
</tr>
<tr>
<td valign="top" width="126">
<p>EXY-7001</p>
</td>
<td valign="top" width="275">
<p>Epoxy Resin base&nbsp;Bisphenol A</p>
</td>
<td valign="top" width="83">
<p>-50</p>
</td>
<td valign="top" width="126">
<p>Liter</p>
</td>
<td valign="top" width="126">
<p>&euro;1.00</p>
</td>
</tr>
<tr>
<td valign="top" width="126">
<p>EXY-7002</p>
</td>
<td valign="top" width="275">
<p>Epoxy Hardener&nbsp;Phenalkamine</p>
</td>
<td valign="top" width="83">
<p>-50</p>
</td>
<td valign="top" width="126">
<p>Liter</p>
</td>
<td valign="top" width="126">
<p>&euro;2.00</p>
</td>
</tr>
</tbody>
</table>
<p>In this example, the &ldquo;Epoxy set&rdquo; costs less than the total sales price of the components (150) it entails.</p>
<p>A related problem may arise in the high-tech industry when selling software-hardware bundles. Shown to the customer as one line on the sales confirmation and the invoice, the revenue from this bundle broken down by the revenue stream:</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="126">
<p><strong>Product ID</strong></p>
</td>
<td valign="top" width="240">
<p><strong>Name</strong></p>
</td>
<td valign="top" width="95">
<p><strong>Quantity</strong></p>
</td>
<td valign="top" width="154">
<p><strong>Unit of measure</strong></p>
</td>
<td valign="top" width="126">
<p><strong>Revenue</strong></p>
</td>
</tr>
<tr>
<td valign="top" width="126">
<p>HW-0284</p>
</td>
<td valign="top" width="240">
<p>HP Server + 1&nbsp;y guarantee</p>
</td>
<td valign="top" width="95">
<p>1</p>
</td>
<td valign="top" width="154">
<p>Pcs</p>
</td>
<td valign="top" width="126">
<p>&euro;1500.00</p>
</td>
</tr>
<tr>
<td valign="top" width="126">
<p>&nbsp;HW-0284-01</p>
</td>
<td valign="top" width="240">
<p>HP Proliant Server</p>
</td>
<td valign="top" width="95">
<p>-1</p>
</td>
<td valign="top" width="154">
<p>Pcs</p>
</td>
<td valign="top" width="126">
<p>85%</p>
</td>
</tr>
<tr>
<td valign="top" width="126">
<p>&nbsp;SRV-3934</p>
</td>
<td valign="top" width="240">
<p>1 year guarantee</p>
</td>
<td valign="top" width="95">
<p>-1</p>
</td>
<td valign="top" width="154">
<p>Pcs</p>
</td>
<td valign="top" width="126">
<p>15%</p>
</td>
</tr>
</tbody>
</table>
<p>The guarantee may be managed as a non-stockable item or even as a stockable one, should it be provided by a 3<sup>rd</sup> party.</p>
<p>&nbsp;</p>
<p>Depending on the requirements above the preferrable solution in Dynamics AX 2012 R3 may differ:</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="252">
<p><strong>Invoice:</strong></p>
</td>
<td valign="top" width="252">
<p><strong>Price(K) = Price A + Price B + &hellip;</strong></p>
</td>
<td valign="top" width="252">
<p><strong>Price(K) &lt; Price A + Price B + &hellip;</strong></p>
</td>
</tr>
<tr>
<td valign="top" width="252">
<p><strong>The lines A, B, C, &hellip; are printed</strong></p>
</td>
<td valign="top" width="252">
<p style="text-align: center"><a href="https://technet.microsoft.com/en-us/library/aa496944.aspx">(1) Sales BOM&nbsp;explosion</a></p>
<p style="text-align: center"><a href="https://msdn.microsoft.com/en-us/library/aa550326(v=ax.10).aspx">(2) Supplementary&nbsp;items</a></p>
</td>
<td valign="top" width="252">
<p style="text-align: center"><a href="https://technet.microsoft.com/en-us/library/hh597304.aspx">(4) Retail&nbsp;mix-and-match discount</a></p>
<p>&nbsp;</p>
</td>
</tr>
<tr>
<td valign="top" width="252">
<p><strong>Only the kit line K is printed</strong></p>
</td>
<td valign="top" width="252">
<p style="text-align: center">(3) Sales BOM explosion (customized)</p>
<p style="text-align: center"><a href="https://technet.microsoft.com/en-us/library/dn497846.aspx">(5) Retail product&nbsp;kits</a></p>
</td>
<td style="text-align: center" valign="top" width="252">
<p>(3) Sales BOM explosion (customized)</p>
<p><a href="https://technet.microsoft.com/en-us/library/dn497846.aspx">(5) Retail product&nbsp;kits</a></p>
</td>
</tr>
</tbody>
</table>
<p>Let us explore the options in more detail, with its benefits and shortcomings.</p>
<h2>(1)&nbsp;Sales BOM explosion</h2>
<p>Imagine one &ldquo;Epoxy SET Bisphenol A&rdquo; would cost exactly &euro;150 and will be shown to the customer as 2 separate lines. We just know that the epoxy resin is useless without the hardener and we are happy to offer the hardener as an option. Create a simple bill of materials of 2 lines for the set EXY-6001, approve and activate it:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/4505.Kit1.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/4505.Kit1.png" alt="" border="0" /></a></p>
<p>In this example, one set requires 500 ml of the resin and 500 ml of the hardener.</p>
<p>Now create a sales order, enter a new line with the set and apply the <strong>Sales order line / Explode BOM lines</strong> function:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/8206.Kit2.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/8206.Kit2.png" alt="" border="0" /></a></p>
<p>Choose <strong>Select all, OK</strong>. The sales order quantity for the original goes to zero, the line is effectively replaced by its 2 components, each with an individual price set in the released product master:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/1031.Kit3.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/1031.Kit3.png" alt="" border="0" /></a></p>
<p><em>Note the need for the user to press the button. What if the operator does not know there is a BOM behind the set? Use distinctive product names or implement a customization to apply the BOM explosion automatically.</em></p>
<p>Make sure there is enough stock for <em>EXY-7001 </em>and <em>EXY-7002</em>, produce a delivery note and an invoice for the order. As expected, the invoice shows 2 lines with a total amount of &euro;150. There is no reference to the original set.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/3527.Kit4.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/3527.Kit4.png" alt="" border="0" /></a></p>
<h2>(2) Supplementary items</h2>
<p>Imagine the buyer of an EXY-7002 &ldquo;Epoxy hardener&rdquo; lot is offered a promotional &ldquo;Mixing bowl&rdquo;, 1 piece at a discounted price.</p>
<p>Navigate to the EXY-7002 released product record records, use <strong>Sell / Supplementary sales items</strong> on the ribbon to enter the information as shown below:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/3060.Kit5.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/3060.Kit5.png" alt="" border="0" /></a></p>
<p>Note the sales price for the EXY-7010 &ldquo;Mixing bowl&rdquo; is again taken from its own product settings, unless the option <strong>Free of charge</strong> is chosen. I.e. the level of control of the sales price is very low.</p>
<p>Return to your sales orders, create a new one 50 liters of the hardener EXY-7002. Note that nothing happens when you save the sales line for the main product. Again, the operator MUST know there is a potential supplementary item and press the&nbsp;<strong>Sales order line / Supplementary items </strong>button:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/8400.Kit6.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/8400.Kit6.png" alt="" border="0" /></a></p>
<p>The <strong>Once only</strong> option chosen above allows for just one supplementary item line instead of 50 (per liter).</p>
<p><em>Note: similarly to the BOM explosion and standard multi-line discounts, the supplementary item calculation requires an thoughtful action (clicking the button, approving with OK) from the user. You may think of programming an automatic notification of a supplementary item applicable.</em></p>
<p>The resulting invoice printout is from the functional perspective&nbsp;equivalent to the previous solution (1) with 2 lines and individual prices:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/4135.Kit7.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/4135.Kit7.png" alt="" border="0" /></a></p>
<h2>(3)&nbsp;Sales BOM explosion (customized)</h2>
<p>Having the limitations of the solution (1) and (2) in mind, I may recommend developing a customized BOM explosion routine which replaces the components&rsquo; sales prices with the (lesser) set sales price. The calculated sales prices follow the ratio of components&rsquo; sales amounts. The invoice printout is customized to replace the 2 set component lines with the kit sales line.</p>
<p>You may find the source code of the customization attached to this blog entry. It is kept very minimalistic and non-intrusive, more like a proof of concept. The core of the customization is a change in <strong>SalesLine.expandBOM </strong>method as well as a hook in the &nbsp;<strong>SalesInvoiceDP.insertIntoSalesInvoiceTmp </strong>invoice printout data provider:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/4722.Kit8.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/4722.Kit8.png" alt="" border="0" /></a></p>
<p>Here is what happens when you apply the modified BOM explosion routine to your sales order line:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/3542.Kit9.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/3542.Kit9.png" alt="" border="0" /></a><br />The sales prices of the components now accommodate the set sales price.</p>
<p>The invoice printout obscures the components as if it was just the set alone, while the kit components are still picked, shipped and posted to the General Ledger at the back office:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/2425.Kit10.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/2425.Kit10.png" alt="" border="0" /></a></p>
<h2>(4) Retail mix-and-match discount</h2>
<p>Note the difference in the sales price allocation between the solutions (1-2) and (3): the presence of the second line (hardener) have an influence on the first sales line (resin). A similar effect may be achieved with the retail mix-and-match discounts: &ldquo;take a pillow to your blanket and have a 10% discount on both&rdquo;.</p>
<p>This may also be applicable to wholesale or manufacturing: we anticipate the demand for the hardener to correlate with the resin and procure / produce both in a constant ratio. The customer is motivated to buy both products together. Should he only buy the resin, the hardener accumulates in our stock and we suffer.</p>
<p>In the previous versions of AX the retail pricing engine was only used on hardware points of sales (POS) and not in the rich client sales order. In AX 2012, the both worlds are united in the <strong>Call center </strong>extension to the sales orders. The configuration is not quite easy, though. First of all, we need a new &ldquo;Call center&rdquo; retail channel to be established in <strong>Retail/Common/Retail channels/Call centers</strong>:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/6404.Kit11.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/6404.Kit11.png" alt="" border="0" /></a></p>
<p>The <strong>Channel user</strong> must be associated with the new call center to take advantage of the retail sales orders. In fact, this user &ndash; the call center operator - &nbsp;is given a very limited, workflow-driven access to the sales order form.</p>
<p>Additionally, a <strong>Price group</strong> of the retail type must assigned to the call center. You may also find it useful to associate your products with a retail category in the retail hierarchy, and the call center should normally be grounded in your Retail assortment hierarchy:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/0027.Kit12.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/0027.Kit12.png" alt="" border="0" /></a></p>
<p>Our mix-and-match agreement must be activated if the 2 products &ndash; 50 liters of resin and the 50 liters of hardener &ndash; meet each other in the same sales order. This requires a <strong>Mix and match group setup </strong>of 2 lines there the <strong>Number of products needed</strong> = 50+50 = 100. Yes, this calculation is kind of weird. My understanding is that in the retail business the stuff is normally sold in small numbers (1+1=2).</p>
<p>In the<strong> Retail/Common/Pricing and discount/Mix and match discounts</strong> form you must be able to configure the following:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/2021.Kit13.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/2021.Kit13.png" alt="" border="0" /></a><br />Here the two components together are granted a discount of 10% for both. The link to the call center is established though the <strong>Price group</strong> (see the button above). Set the status of the discount to <strong>Enabled</strong>. The discount becomes effective immediately.</p>
<p>Having all the necessary setup in place, proceed to the sales order and enter a new one. With the right AX user every new sales order is associated with the call center and marked as a <strong>Retail sale</strong> in the order Header view. This activates the retail price and discount engine in the lines.</p>
<p>Enter the first sales line for the 50 liters of EXY-7001. Nothing happens at first, but when you are about to leave the second one (50 l of EXY-7002) a notification appears:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/8787.Kit14.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/8787.Kit14.png" alt="" border="0" /></a></p>
<p>The result is as follows: the 10% discount is applied to the both the resin and the hardener:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/1351.Kit15.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/1351.Kit15.png" alt="" border="0" /></a></p>
<p><em>Beware: this interactive discount calculation runs amok when you enter a sales quantity more than the <strong>Number of products needed</strong> = 100.</em></p>
<p><em>Moreover, this discount agreement is applied to ANY customer: the call center and retail modules are made to implement a uniform sales process to a large group of mass customers.</em></p>
<p>As a call center operator, you must <strong>Complete</strong> the order, providing payment info before shipping and billing. The invoice printout is as follows, individual lines with combination prices; a percentage discount is always converted into an amount by the retail price engine:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/8765.Kit16.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/8765.Kit16.png" alt="" border="0" /></a></p>
<h2>(5) Retail product kits</h2>
<p>A solution alternative to the BOM explosion is offered by the new retail kit functionality in AX2012 R3. Retail kits are better understood as tangible ones, put into one box: &ldquo;Canon EOS 100 + 40mm lens kit, boxed&rdquo;. The retail kits are therefore stored at the warehouse and assembled explicitly. The assembling procedure is managed with a kit assembly order. It silently posts a BOM inventory journal, an approach well known to an experienced Dynamics AX consultant.</p>
<p>The kit requires a configurable product master to be set up (<strong>Retail/Common/Kits/Product kits</strong>). By clicking <strong>Configure</strong> you are able to enter the components. Every set of components results in a new Configuration of the kit product:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/5141.Kit17.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/5141.Kit17.png" alt="" border="0" /></a></p>
<p>A retail-enabled &ldquo;call center sales order" checks for kits on-hand and may raise a kit assembly order automatically when you &ldquo;Complete&rdquo; the sales order. Posting the assembly order consumes the components and increases the stock of the kit item. This kit may now be shipped and billed with a trivial invoice layout:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/8130.Kit18.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/57/32/8130.Kit18.png" alt="" border="0" /></a></p>
<p><em>Note: the retail product kit functionality does not use BOMs. The retail &lsquo;flavor&rsquo; enforces strict rules for the sales order entry, its modification and fulfillment. The retail kit is normally a stockable one, its shipping requires an explicit confirmation of the assembly order by the warehouse operator.</em></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/59/68/96/PrivateProject_SalesBOM_Explode_Kit.zip">PrivateProject_SalesBOM_Explode_Kit.zip</a></p>]]></content:encoded>
    </item>
  </channel>
</rss>