Microsoft Dynamics AX 2012 ® Import forecasts Implementation Considerations This paper highlights some considerations when supply and/or demand forecasts need to be imported from external systems. August 2011 CCAX2012IC0060 Table of Contents Overview..................................................................................................... 3 Forecast ...................................................................................................... 3 Data model.................................................................................................. 3 ForecastPurch....................................................................................................................... 3 Definition .......................................................................................................................... 3 Explosion .......................................................................................................................... 3 ForecastSales ....................................................................................................................... 5 Definition .......................................................................................................................... 5 Explosion .......................................................................................................................... 6 ForecastInvent ..................................................................................................................... 9 Forecasts created by the application ........................................................... 9 Importing forecast data ............................................................................ 10 Example .............................................................................................................................11 2 IMPORT FORECASTS Overview Microsoft Dynamics® AX 2012 does not include a standard forecast import feature. The wide variety of source systems and customer requirements makes it impractical to provide a standard way for importing supply and/or demand forecasts. This paper details some considerations for implementing a custom solution. Forecast Microsoft Dynamics AX 2012 supports forecasts on both the supply side and the demand side. All forecasts belong to user-defined forecast models. Forecasts can be specified at the item level or the item group level. Demand forecasts can be customer specific or customer group specific. Supply forecasts can be vendor specific or vendor group specific. Exploded forecasts can be allocated in weekly, monthly, or yearly periods, or according to userdefined allocation categories. Forecasts can be linked to a set of financial dimensions. Data model ForecastPurch Supply forecast data is stored in the ForecastPurch table. There are two types of records: forecast definition records and exploded forecast records. Definition The definition is entered in the upper grid (the Overview tab) of the ForecastPurch form. Explosion Exploded or allocated forecast records are created by the system when a definition record is saved with an allocation method other than None. Group Field Description See also Identification ItemId (Optional) The item that the forecast is for. This field may be left blank when you import an item group–specific forecast. initFromInventTable() Foreign key to InventTable. ItemGroupId The item group that the forecast is for. This field should be set, even when you import an item-specific forecast. initFromItemGroup() Foreign key to InventItemGroup. VendAccountId (Optional) The vendor that the forecast is for. initFromVendTable() Foreign key to VendTable. 3 IMPORT FORECASTS Group Field Description See also VendGroupId (Optional) The vendor group that the forecast is for. initFromVendGroup() Foreign key to VendGroup. ModelId (Mandatory) The forecast model that the forecast is for. initFromForecastModel() Foreign key to ForecastModel (model type Heading). Report Set to NoYes::No when importing forecasts with an allocation method other than None. A system field that indicates whether the record is used in planning. InventDimId Set the mandatory, product, and coverage planned dimensions. Foreign key to InventDim. Allocation AllocateMethod Set the allocation method to None, Period, or Key. Freq Set the frequency when using the Period allocation method; otherwise, set to 0 (zero). FreqCode Set the frequency code when using the Period allocation method. Possible values are Days, Months, and Years. BudgetMap. setReport() setInventDimId FromInventDim() BudgetMap. setAfterAllocateMethod() Set to Days when using the Key allocation method. StartDate The start date. BudgetMap. initValue() EndDate The end date. BudgetMap. setEndDate() KeyId Set the period key when using the Key allocation method. Foreign key to LedgerAllocateKey. ItemAllocateId Set the item allocation key when importing an item group–specific forecast. initFromItemGroup() Foreign key to ForecastItemAllocation. BOM, Route ItemBOMId Optionally set the Bill of Materials (BOM) ID. The active BOM is used if no value is specified. Foreign key to BOMTable. ItemRouteId Optionally set the route ID. The active route is used if no value is specified. Foreign key to RouteTable. Inventory Quantity InventQty The forecast quantity, in the inventory unit. Set to the same value as PurchQty when importing an item group–specific forecast. Purchase Quantity PurchQty The forecast quantity, in the purchase unit. The value cannot be negative. PurchUnitId The purchase unit ID. Foreign key to UnitOfMeasure. 4 IMPORT FORECASTS calcQtyOrdered() initFromInventTable() Group Field Description See also Purchase Forecast Comment A free text comment. initFromInventTable() initFromItemGroup() initFromVendTable() initFromVendGroup() Active A NoYes enumeration value that indicates whether the forecast is active. Cov A NoYes enumeration value that indicates whether the forecast must be forecast planned in the ledger module. CovStatus A system field. Set to 0 (zero). BudgetMap. initValue() BudgetMap. Insert() Amount Amount The line amount. calcPrice2LineAmount() Currency The line amount currency. initFromVendTable() Foreign key to Currency. BudgetMap. initValue() Price Discount Tax PurchPrice The purchase price per unit. PriceUnit The number of purchase units that the price is specified for. PurchMarkup Fixed charges independent of the quantity. DiscAmount The discount amount per purchase unit. DisPercent The discount percentage. TaxGroupId (Optional) The sales tax group. initFromVendTable() Foreign key to TaxGroupHeading. TaxItemGroupId (Optional) The item sales tax group. initFromInventTable() Foreign key to TaxItemGroupHeading. Dimension System DefaultDimension ExpandId (Optional) The financial dimensions. initFromInventTable() Foreign key to DimensionAttributeValueSet. initFromVendTable() For exploded forecast records, the record ID of the source; otherwise, 0 (zero). Set this field to 0 when importing forecasts. Foreign key to ForecastPurch. ForecastSales Demand forecast data is stored in the ForecastSales table. Just as on the supply side, there are two types of records: forecast definition records and exploded forecast records. Definition The definition is entered in the upper grid (the Overview tab) of the ForecastSales form. 5 IMPORT FORECASTS Explosion Exploded or allocated forecast records are created by the system when a definition record is saved with an allocation method other than None. Group Field Description See also Identification ItemId (Optional) The item that the forecast is for. This field may be left blank when you import an item group– specific forecast. initFromInventTable() Foreign key to InventTable. ItemGroupId The item group that the forecast is for. This field should be set, even when you import an item-specific forecast. initFromItemGroup() Foreign key to InventItemGroup. CustAccountId (Optional) The customer that the forecast is for. initFromCustTable() Foreign key to CustTable. CustGroupId (Optional) The customer group that the forecast is for. initFromCustGroup() Foreign key to CustGroup. ModelId (Mandatory) The forecast model that the forecast is for. initFromForecastModel() Foreign key to ForecastModel (model type Heading). Report Set to NoYes::No when importing a forecast with an allocation method other than None. BudgetMap. setReport() A system field that indicates whether the record is used in planning. InventDimId Set the mandatory, product, and coverage planned dimensions. Foreign key to InventDim. Allocation AllocateMethod Set the allocation method to None, Period, or Key. Freq Set the frequency when using the Period allocation method; otherwise, set to 0 (zero). FreqCode Set the frequency code when using the Period allocation method. Possible values are Days, Months, and Years. setInventDimId FromInventDim() BudgetMap. setAfterAllocateMethod() Set to Days when using the Key allocation method. StartDate The start date. BudgetMap. initValue() EndDate The end date. BudgetMap. setEndDate() 6 IMPORT FORECASTS Group Field Description KeyId Set the period key when using the Key allocation method. See also Foreign key to LedgerAllocateKey. ItemAllocateId Set the item allocation key when importing an item group–specific forecast. initFromItemGroup() Foreign key to ForecastItemAllocation. BOM, Route ItemBOMId Optionally set the BOM ID. The active BOM is used if no value is specified. Foreign key to BOMTable. ItemRouteId Optionally set the route ID. The active route is used if no value is specified. Foreign key to RouteTable. Inventory Quantity InventQty The forecast quantity, in the inventory unit. Set to the same value as SalesQty when importing an item group–specific forecast. Sales Quantity SalesQty The forecast quantity, in the sales unit. The value cannot be negative. SalesUnitId The purchase unit ID. calcQtyOrdered() initFromInventTable() Foreign key to UnitOfMeasure. Sales Forecast Comment A free text comment. initFromInventTable() initFromItemGroup() initFromCustTable() initFromCustGroup() initFromSalesQuotationLine() initFromProjTable() Active A NoYes enumeration value that indicates whether the forecast is active. Cov A NoYes enumeration value that indicates whether the forecast must be forecast planned in the ledger module. CovStatus A system field. Set to 0 (zero). BudgetMap. initValue() BudgetMap. Insert() Amount Amount The line amount. calcPrice2LineAmount() Currency The line amount currency. initFromCustTable() Foreign key to Currency. initFromSalesQuotationLine() initFromProjTable() BudgetMap. initValue() Price SalesPrice The sales price per unit. 7 IMPORT FORECASTS Group Field Description See also CostPrice The cost price of the item. InventTable. costPcsPrice() Discount Tax PriceUnit The number of sales units that the price is specified for. SalesMarkup Fixed charges independent of the quantity. DiscAmount The discount amount per purchase unit. DiscPercent The discount percentage. TaxGroupId (Optional) The sales tax group. initFromCustTable() Foreign key to TaxGroupHeading. initFromSalesQuotationLine() initFromProjTable() TaxItemGroupId Dimension DefaultDimension (Optional) The item sales tax group. initFromInventTable() Foreign key to TaxItemGroupHeading. initFromSalesQuotationLine() (Optional) The financial dimensions. initFromInventTable() Foreign key to DimensionAttributeValueSet. initFromCustTable() initFromSalesQuotationLine() initFromProjTable() System ExpandId For exploded forecast records, the record ID of the source; otherwise, 0 (zero). Set this field to 0 when importing forecasts. Foreign key to ForecastPurch. Project Identification ProjId (Optional) The project ID. initFromProjTable() Foreign key to ProjTable. ProjFundingSource (Optional) The project funding source. initFromProjInvoiceDate() Foreign key to ProjFundingSource. ActivityNumber (Optional) The project activity. Foreign key to SMMActivities. ProjCategoryId ProjLinePropertyId Project Dates ProjForecast (Optional) The project category. initFromSalesQuotationLine() Foreign key to ProjCategory. initFromProjTable() The project line property. initFromSalesQuotationLine() Foreign key to ProjLineProperty. initFromProjTable() The invoice date. InvoiceDate ProjForecast The elimination date. EliminationDate ProjForecast The cost payment date. CostPaymDate ProjForecast SalesPaymDate 8 IMPORT FORECASTS The sales payment date. Group Field Description Project Budget ProjForecast The budget type. See also BudgetType Project Transaction ProjTransId The project transaction. insert() ForecastInvent The inventory forecast table is maintained by the system. It holds supply and demand forecast information that is relevant to forecast scheduling and master scheduling. The information can be viewed by using the ForecastInvent form that can be opened from both the supply (ForecastPurch) form and the demand (ForecastSales) form. Group Field Description Identification ItemId (Optional) The item that the forecast is for. This field may be left blank when you import an item group–specific forecast. Foreign key to InventTable. TableType The forecast type, a ForecastTableType enumeration value. ModelId The forecast model. Foreign key to ForecastModel. DateBudget The budget date. InventDimId The inventory dimensions. Foreign key to InventDim. BOM, Route ItemBOMId Optionally set the BOM ID. The active BOM is used if no value is specified. Foreign key to BOMTable. ItemRouteId Optionally set the route ID. The active route is used if no value is specified. Foreign key to RouteTable. Inventory Quantity QtyInvent The inventory quantity. System TransTableId The source table ID. This is the table ID of the ForecastPurch or ForecastSales table. TransRecId The source table record ID. Forecasts created by the application In the application, a forecast is created by using the supply and demand forecast forms. These can be opened from the Planning tab on the Released products list page, or from the Inventory menu (Inventory and warehouse management > Periodic > Forecast > Entry). 9 IMPORT FORECASTS When a new forecast is saved, the forecast is exploded into periodic forecasts, as shown in the lower grid of the forecast form. Figure 1 Inserting a forecast As Figure 1 illustrates, the ForecastPurch and ForecastSales tables are members of the BudgetMap table map. The table insert() methods delegate their job to the BudgetMap.insert() method. This method instantiates the correct BudgetTrans instance and calls insert() on it. The derived BudgetTrans_Forecast class in turn delegates the task to the ForecastAllocate hierarchy, where create() breaks down the forecasts according to their periods and inserts records into the ForecastPurch, ForecastSales, and ForecastInvent tables. The ForecastInvent table holds the supply and demand forecast data that is relevant to master scheduling. All of this happens behind the scenes when a forecast record is saved or the user clicks the Create lines button. The table insert() methods then trigger the required business logic. Importing forecast data As explained in the previous section, no special business logic needs to be invoked to create the exploded forecast data. Provided that all relevant data is populated and consistent in the ForecastPurch or ForecastSales table, the exploded forecast data is created simply by calling insert(). When implementing a custom import solution, consider the following: Create a new class. We recommend that the class extend RunbaseBatch or implement the new SysOperation framework, so that it can be scheduled as a recurring batch job. Use the existing initialization code wherever possible (for example, in table initValue() methods). Look at the field in the ForecastPurch or ForecastSales form, record the validation/modification logic, and apply it to your custom import code as applicable. Some mechanism is likely to be required to enable the import of updated forecasts. One option is to import forecasts by ModelID, and then delete the entire model each time before you import a new version. Validate all data from the external data source against entities in Microsoft Dynamics AX, such as items, allocation groups, customers, and vendors. Throw verbose errors when validation fails. Decide on the transaction granularity (ttsbegin/ttscommit): record by record, or one transaction for the entire import. 10 IMPORT FORECASTS Call insert() on the table buffer. Implement try/catch blocks to handle update conflicts and deadlocks. Do not import data directly into the ForecastInvent table. Records in this table are created by the system when records are created in the ForecastPurch and ForecastSales tables. Example Previous versions of Microsoft Dynamics AX supported an external demand planning tool. Although this tool is no longer present in the user interface, because the menu item has been marked with the SysDeletedObjects60 configuration key, the ForecastDMPImport business class can still be found in the Application Object Tree (AOT). 11 IMPORT FORECASTS Microsoft Dynamics is a line of integrated, adaptable business management solutions that enables you and your people to make business decisions with greater confidence. Microsoft Dynamics works like and with familiar Microsoft software, automating and streamlining financial, customer relationship and supply chain processes in a way that helps you drive business success. U.S. and Canada Toll Free 1-888-477-7989 Worldwide +1-701-281-6500 www.microsoft.com/dynamics This document is provided “as-is.” Information and views expressed in this document, including URL and other Internet Web site references, may change without notice. You bear the risk of using it. Some examples depicted herein are provided for illustration only and are fictitious. No real association or connection is intended or should be inferred. This document does not provide you with any legal rights to any intellectual property in any Microsoft product. You may copy and use this document for your internal, reference purposes. You may modify this document for your internal, reference purposes. © 2012 Microsoft Corporation. All rights reserved. Microsoft, Microsoft Dynamics, and the Microsoft Dynamics logo are trademarks of the Microsoft group of companies. All other trademarks are property of their respective owners. 12 IMPORT FORECASTS