
Dynamics 365 Intercompany Cost+ pricing
As highlighted 10 years ago by M. Aamer in his article Inter-company goods trading (sales price equal to cost price) – Microsoft Dynamics AX 2012 – Microsoft Dynamics 365 Blog, there is a parameter Unit price equal to cost price in the intercompany settings in Dynamics 365 for SCM, which enforces the intercompany purchase price at the cost price in the intercompany selling company.
The system tries to update the Sales order – Purchase order pair on 3 occasions:
- ICO sales order line creation;
- reservation of the goods in the supplier company;
- release (!) to the warehouse in that company i.e., just before picking.
The resulting sales price is the current moving average stock price. D365 traverses the inventory transactions, and if no price is known at the given inventory dimensions, it defaults to the price at the item master (this may be relevant in the engineer-to-order scenario, where the ultimate cost price becomes known just shortly before the shipping).
As noted many years ago by my humble self 😉 , the pure cost price is normally not allowed by accounting standards: the “arm’s length” principle must be respected in transfer pricing between companies within a group i.e., there must be a markup on top. The Intercompany percent charge was developed recently by Microsoft to comply: Set up charges on intercompany orders – Supply Chain Management | Dynamics 365 | Microsoft Learn.
At some locations, the misc. charge is not good enough, as the auditors favour an “opaque” sales price with an embedded markup percentage. This may in principle be achieved with a negative line discount to the sales price = cost price. Normally, negative discounts are frowned upon by D365: “Field 'Discount percentage 1'(= -15,00) can only contain positive numbers.
“, but the trick described in the blog “Overwrite a read-only configuration in D365FO” will let you import such a trade agreement.
At the recipient’s side, at the ICO Purchase order, the accounting distribution will be split into the base price (= ICO cost) and the [negative] discount. To satisfy the request for one single SO revenue GL transaction and one single PO change-in-stocks GL transaction, a customization was made out of pure desperation. The markup percentage is stored in a custom field Intercompany percent at the seller’s Item group, and quietly added to the net sales price in the following routine (you may download the source code here: ICOCostPlus.axpp):
[ExtensionOf(classStr(SalesLineType))]
final class SalesLineType_ICOCostPlus_Extension
{
public CostPrice interCompanyCalcSalesPrice()
{
SalesPrice salesPrice = next interCompanyCalcSalesPrice();
if (! salesLine.InterCompanyInventTransId ||
salesLine.SalesQty < 0 ||
! salesLine.isStocked())
{
return salesPrice;
}
if (! salesTable.interCompanyEndpointActionPolicy().UnitPriceEqualsCostPrice)
{
return salesPrice;
}
InventItemGroup itemGroup = InventItemGroupItem::findByItemIdLegalEntity(salesLine.ItemId, salesLine.DataAreaId).itemGroup();
if (itemGroup.ICOSalesPercentMarkup != 0)
{
salesPrice += CurrencyExchangeHelper::price(salesPrice * itemGroup.ICOSalesPercentMarkup/100, salesLine.CurrencyCode);
}
return salesPrice;
}
}
Revenue recognition and deferred cost blog series
Further reading:
Revenue recognition with project budget shadow forecasts
Bundles (Revenue recognition)
Accrued revenue (Revenue recognition)
On provisions, accruals and deferrals