Most of Dynamics AX specialists (especially from support) heard about inventSumLogTTS table. Everyone knows that this table somehow is related to MRP; Everyone knows that if you do not run MRP, your inventSumLogTTS table grows bigger and bigger and eventually you need to clean it somehow. But since detailed documentation on static/dynamic plan update algorithms is absent, not many people understand how Axapta actually use this table for plan updates; what are advantages and caveats of dynamic vs static plan use;how order explosion differs from regeneration planning and so on…
I wrote this text mostly from my experience with Dynamics AX 2009. In the new version (DAX2012) approach remained the same from functional point of view, only technical details changed, so this information can be useful also for people using DAX2012.
A bit of history
As I wrote in my blog before, inventSumLogTTS table began its life (somewhere in late releases Axapta 2.5) only as a tool to track a list of changes which was applied to inventSum table in independent DB transaction. Should the main transaction be rolled back, the system was to iterate over related records in inventSumLogTTS and programmatically rollback changes to inventSum. Starting from Axapta 3.0, inventSumLogTTS table started to be also used to support dynamic update to MRP plan. In version Dynamics AX 4.0, the whole Inventory MultiTransaction System was dropped from Axapta and replaced with a new approach. Nevertheless inventSumLogTTS table still exists in the system, but nowadays it is used only to support dynamic MRP plan update. Today, name of the table is misleading, because now it is not used to log InventSum updates. As of versions 4-2012, it is used only to keep track of inventTrans changes, which have not been applied to dynamic plan yet.
How data gets into inventSumLogTTS
The mechanism which now (in versions 4.0/2009/2012) creates new records in inventSumLogTTS is the very same mechanism which is used to update inventSum. (I described this mechanism in details in the article I mentioned). When inventTrans is inserted/updated/deleted the system calls inventUpdateOnHand.addInventSumLogTTS() method to register deletion or insertion of inventTrans record. (An update goes as a delete and insert). InventSumLogTTS records are kept in cache till the end of the transaction and are actually written to the database at the same time when the system updates the inventSum records, related to inventory transactions updated in the database transaction.
To link two records of inventSumLogTTS related to the same update of an inventory transaction, the system uses the sequenceNumber field of the inventSumLogTTS table. The system registers changes of inventTrans record, till it become physically/financially updated (Deducted/Sold or Received/Purchased statuses). Only the very first change of the transaction to physical/financial status is registered to inventSumLogTTS. Later this change is to be applied to Net Requirement of On-Hand type by dynamic plan update mechanism. Subsequent changes to the same inventory transaction are not recorded, since they are not anymore relevant for MRP; Now the transaction is a part of OnHand Stock which is represented in Net Requirements as a one on-hand net requirement per item and coverage dimension.
Working Set of MRP and a bit of terminology
To simplify further discussion I want to introduce a new term – Working Set. I will use this term to describe a list of net requirements which are participating in the current MRP session. In different stages of an MRP session, content of that list is different. In the beginning of an update stage, it contains the issue net requirements to be covered, during a coverage phase it contain mixture of covered issue net requirements, covering receipt net requirements and uncovered issue net requirements to be covered. After coverage phase, working set contains only covered/covering net requirements.
But the point is: Working set of MRP session is the most fundamental thing for understanding of MRP process and it is always defined by adding the uncovered issue net requirements to it. Everything else is implementation details.
Generally, there are two ways to start MRP: One is to start MRP from Master Planning->Periodic->Master planning; Another – to click Master Planning->Periodic->Master planning in Requirement Profile form. These menu items point to the different classes. From implementation point of view, both classes use different algorithms. First class is optimized for a multi-threaded scheduling of large number of net requirements. Second is optimized for a scheduling of only 1 item, but it has good caching mechanisms, so it might work much faster sometimes. I will use term Full MRP for MRP from Periodic menu and term Item MRP for MRP from Requirement Profile form. From functional point of view, two kinds of MRP differ a lot. Item MRP runs on the level of the set of specific net requirements; Full MRP works on the level of item+coverage dimension combination. When net requirement is added to Working Set of Full MRP, it implicitly adds a whole set of net requirements with a given item and coverage dimension combination into Working Set. Technically speaking, Item MRP is implemented by combination of classes ReqCalcScheduleItem (Responsible for the planning process itself) and ReqTransCache_Daily(Responsible for Working Set support). ReqTransCache_daily class holds a set of itemIds in a Working Set, a set of coverage dimension combinations for every item in a Working Set and a map with Net Requirements of Working Set itself. Full MRP is implemented by combination of classes ReqCalcScheduleItemTable (responsible for planning process) and ReqTransCache_Periodic (Responsible for Working Set support).ReqTransCache_Periodic class holds only a set of items and set of coverage dimensions for items in a Working Set. (Technically these sets are stored as ReqProcessItemListLine and ReqProcessItemDim list tables).
As we will see later, working set is created on Update phase of MRP session (I will use term Initial Working Set for it), but can grow as a result of the Coverage phase of MRP Session (I will use term Extended Working Set for working set after extension by the coverage planning).
I will also occasionally use term Items in working set, to refer to the list of items which have net requirements in the given Working Set; Sometimes, I will also use term Session Item Set to designate the set of items defined before MRP start. In case of Item MRP, this item is defined by current content of Requirements Profile form; In case of Full MRP, these items are defined by query parameters in dialog box which is popping up in beginning of MRP process
Simplest scenario: Regeneration of static plan
Before we proceed with our discussion any further, I want to discuss the simplest scenario of MRP: Regeneration of static plan. If we are running MRP in regeneration mode, here is what happens:
- The system deletes all net requirements and all coverage information for the Session Item Set of MRP session (actually, approved planned orders can be spared from deletion, but we are not going into such a deep discussion).
- If some of the deleted net requirements were planned orders, the system also deletes derived demand for them (say, demand for sub-components of planned production order). If some of deleted derived net requirements was covered by another planned orders, these planned orders are deleted recursively and so on. The main point is: If we are running MRP for a limited working set , after an update stage, we won’t have net requirements for all items in Session Item Set;Also some of receipt net requirements items outside of the Session Item Set will become available. Say, we are running MRP for Item A, which consists from items B,C and D. Update stage will delete all item requirements for item A, including planned production order. It leads also to deletion of the issue item requirements (not all of them, just this PO) for item B,C and D. We also delete coverage for these issue net requirements and some other receipt net requirements (say – from invent on-hand) become unused and available to cover something else.
- The system creates new issue net requirements for all items from Session Item Set. It imports info from all necessary sources – on-hand data, inventory transactions, forecast data, Min/Max data from Item Coverage setup and so on… Created uncovered issue net requirement are added to Working Set, thus forming Initial Working Set.
- Coverage phase begins for the working set items, having lowest BOM Level. The system fetches from working set all uncovered issue net requirements for an item (all our newly created net requirements from previous step are uncovered) creates coverage info (if appropriate receipt net requirements were found) or creates a new planned order and create coverage info for it. Covering net requirement is added to working set. If new planned orders were planed production orders, then the system adds derived issue net requirements for sub-components for the planned production orders into initial working set. (Thus is making it to be an Extended Working Set) .
- Then the system proceed to build coverage for the working set items with next lowest BOM level; Again new planned orders are created; Again it leads to creation of planned orders and to further extension of working set. So, with every new BOM level, the working set contains more and more net requirements.
- Finally, after processing of working set items with highest BOM Level, the system finish coverage phase and proceed to subsequent phases.
- Futures and action planning are executed over net requirements in working set. Since this stages are more receipt-oriented, behavior of Item MRP and Full MRP differs a lot. In case of Item MRP, the system calculates action/futures only for receipt net requirements which were actually used in current MRP session(at least one record in coverage was created for these receipt net requirements). In case of Full MRP, the system calculates action/futures for all net requirements which has the same itemid+coverage dimensions combination as any the requirement used in the current planning session.
The main conclusion of this section is that the Session Item Set in Regeneration mode MRP have two purposes:
- It show the system, net requirements for which items must be regenerated and included into Initial Working Set.
- It implicitly define extended working set of planning session, by providing root items for implicit BOM explosion. Every net requirements of this explosion is included into extended working set.
I also want to mention that ONLY full regeneration for all items (MRP Item Set have all items in the system) can result in perfect plan. Even in regeneration mode (which brings much more up-to-the-rules planning results then Net Change/Net Change Minimized mode), the system can create a bit inconsistent planned orders. Say, if we created new sales line and ran regeneration mode MRP for the item used in this salesLine, it can create new planned production order to cover it and then new planned purchase order to cover the demand requirement for one of its sub-components. If this sub-component has Requirement coverage model – it is Okey. If the sub-components has ‘period’ coverage model – it is a minor problem in the plan. (Since we would probably have two planned orders for a period, instead of one).
More complex case: Regeneration of dynamic plan
Regeneration of dynamic plan generally work the same way as regeneration of static plan only with few extra steps added:
- Before importing an item’s inventTrans/inventSum data into net requirements (step 4 of the previous case), the system cleans all records of inventSumLogTTS table for the item.
- On coverage phase, before processing of an item (even if it was not in Session Item Set) the system runs special class (reqTransUpdate) which updates net requirements for the item with relevant information from the inventSumLogTTS table and then drop this information from aforementioned table. I will call this process a Dynamic Update Stage.
So, here what’s the data propagation chain is: When user changes a logistics document, changed data are propagated to inventTrans; Then in the end of transaction changed data are propagated to inventSumLogTTS; Then, finally, recorded changes are propagated to Net Requirements data (reqTrans). After the records from inventSumLogTTS are applied to Net Requirements, they are dropped from inventSumLogTTS, since they have fulfilled the purpose of their existence and are not needed anymore.
I want to mention specially that net requirements updated on Dynamic Update Stage, are not automatically included into the Working Set. Dynamic Update process is not very fine-grained; It runs on level of an item;It might be that Dynamic Update has updated net requirements with configurations, sizes or colors that have nothing in common with the current Session Item Set.
Thus, inclusion of all updated net requirement for an item into a Working Set, would cause unnecessary increase in a Working Set size and increase complexity of planning.
Interesting side effect of Dynamic Update Stage is that the MRP session can adapt to latest changes to inventTrans made by users during planning session. Say, if we have item with BOM Level 4 in our Session Item Set, it might happen that between initial net requirements creation (during update phase) and coverage planning for BOM Level 4, a user will make a set of changes to inventTrans for the item. Since coverage planning for item starts from application of recent inventTrans changes to net requirements, results of MRP will be consistent with inventTrans state in the beginning of coverage process for given item. In case of regeneration of static plan, reqTrans state is consistent with the state of inventTrans during initial net requirement update phase; All subsequent changes to inventTrans are not reflected in net requirements.
Net change update of dynamic plan
In Net Change/Net Change minimized mode,update phase of MRP is executed in entirely different way. It is simply a sequence of Dynamic Updates for the items in a Session Item Set. The system iterates over the Session Item Set and for every item it calls usual net requirement update mechanism (reqTransUpdate class), so that relevant net requirements will be updated with recent information from inventSumLogTTS. As a result of this update, some of the net requirements are dropped, some are created, for some requirements quantity and other relevant information is changed and so on.
Next, during coverage phase, coverage process the uncovered issue net requirements in Working Set. Again, before running coverage process for an item, the system run regular net requirements update mechanism as usual, so even items not in Session Item Set have their net requirements updated during coverage phase.
Regarding requirement update phase, Net Change and Net Change minimized modes differs in the following two points:
- In Net Change Minimized mode, the system includes into Initial Working Set only those net requirements, which are marked as uncovered. Since after regeneration planning, the plan can not have uncovered net requirements, technically, the Initial Working Set consists only from the uncovered issue net requirements which were updated on net requirements update stage. Since no receipt net requirements are included into Initial Working Set by update stage, subsequent futures and action calculation stages will work only with the net requirements which were actually used in the planning session (in case of Item MRP) or with the net requirements which has the same itemId and coverage dimensions as any of the net requirements used in coverage phase of planning session (in case of Full MRP).
- In Net Change, the system includes into Initial Working Set all net requirements for all items in Session Item Set. Also, the system drops action information (action quantity and action days in net requirements and coverage table) for all net requirements in Initial Working Set (even already covered). As a result, action phase works for all net requirement with items in Session Item Set. (Coverage phase of MRP session cannot be influenced by inclusion of all net requirements, since MRP simply ignores all issue net requirements which are already covered).
Shortly speaking, Net Change/Net Change Minimized plan update mode is the fastest way to update your plan with actual data. But as usual, update speed comes at a price. Often, usage Net Change update mode results in non-optimal plan. (I mean – even more non-optimal than results of partial MRP Regeneration).
Say, you have a 80 pieces of an item in stock and a sales order for exactly 50 pieces of the item with the delivery date in distant future. (Say – in 6 month). Regular nightly planning in regeneration mode, has created coverage record between these two net requirements. SalesLine is fully covered with invent on-hand, while the invent on-hand net requirement has 30 free pieces left; This 30 pieces can be used to cover something else. Suppose that on the next morning a customer came and placed an urgent order for 70 pieces of the item with delivery date of tomorrow. Common sense tells us that we can use our current on-hand to cover this new urgent sales order; While for remaining uncovered 40 pieces of non-urgent sales order, we can create appropriate planned order with execution date in distant future (in a few days before non-urgent order’s delivery date).
Instead of this, Net Change planning will use remaining 30 pieced of on-hand to cover urgent sales order; Then planning algorithm will create extra urgent planned order for remaining 40 pieces with execution date of today.
It happens, because planning in net change/net change minimized modes never touches net requirements which had not had related inventTrans changed. During update phase, the system creates new net requirement for 70 pieces for tomorrow’s order. Planning algorithm cannot ‘release’ on-hand net requirement for more urgent order, because it cannot touch it! During coverage phase it creates coverage record for 30 pieces between the existing (not touched by Dynamic Update) on-hand net requirement and the new sales net requirement. For remaining 40 pieces, the system creates a new planned order.
The only way to solve this issue is to run regeneration mode scheduling for an item and all nested sub-components. If we run regeneration mode scheduling only for the item from the new urgent sales order, we won’t have the phenomena for the net requirements of item itself. But if this item is a BOM with sub-components, it means that for sub-component items, the same problem can arise on next BOM Levels.
I am a bit surprised, that standard Dynamics AX does not have some special ‘Explosion regen MRP’ which would take item or item mask as an input and then build INITIAL working set from all sub-components of the item entered. I made this functionality for a couple of projects. It works much faster then full regeneration scheduling and it works somewhat slower then explosion. (Which in a completely different way, being just a special case of Net Change Minimized planning). This MRP extension also happens to fix the issue of incorrect planned orders for items with Period coverage code, which I mentioned in the section before previous.
Explosion is a special kind of Net Change dynamic plan update. By definition, explosion only can be run for the current dynamic plan. The most fundamental difference between explosion and regular MRP is that explosion includes into Initial Working Set ONLY net requirements belonging to the specific order or line of the order. It also means that it is the most fine-grained MRP kind. Since it is the most fine-grained kind of planning, it also uses the same approach for working set update as Item MRP do:Working Set for explosion also stores working set as a set of particular net requirements, not as a set of item and coverage dimensions combinations. During requirement update stage, the system simply runs Dynamic Update for the item of the net requirement being exploded and then create Initial Working Set from this net requirement and derived demand net requirements (sub-components for the planned production order or production order; derived net requirements on refill warehouse in case of planned transfer order and so on). The subsequent stages goes more or less in the same way as for Net Change Minimized dynamic plan update.
There are three different kinds of explosion:
- Sales line explosion. Implemented by the class ReqCalcExplodeSO. This class runs when you click ‘Update’ button on top of the Explosion form, called from sales orders form by clicking on Inquiries->Explosion. It also automatically run on salesLine creation or update if salesLine has reservation mode Explosion;Also, It runs when a user has changed marking for inventory transaction. The last point looks a unclear at a first sight, but purpose of this behavior is very simple: Whenever a user is changing inventory marking (which is mirrored in coverage info), the system must drop existing coverage info and rebuild it from new marking information. (We will talk later about extra marking-related functions of explosion, which are not supported by regular MRP)
- Production order explosion. Implemented by the class ReqCalcExplodeProd. This class runs when you click ‘Update’ button on top of the Explosion form, called from production orders form by clicking on Inquiries->Explosion. It also can be automatically run during Operation/Job Scheduling in of production order. Automatic explosion of production order happen in two cases: First of all, it happens when at least one of the ProdBOM lines have a ‘On Schedule’ automatic reservation mode and the product order is being scheduled for the first time in its life cycle. Second, it happens when production order does not have related Net Requirements in current dynamic plan (probably – because the order was entered manually and never was scheduled before) and user is running order scheduling with checked ‘Finite material’ checkbox in scheduling parameters. It might look surprising on a first look, but ‘Finite material’ mode asumes compulsory integration of production order scheduling into MRP. There is no other way for Axapta to find availability of a material for a production order, but the usage of MRP. So, if you are going to use production orders without setting up master planning module and implementing master planning business process , do not hope to have reasonable results of production scheduling with ‘Finite materials’ checkbox. If you have not specified current dynamic plan in Master Planning parameters, the system will use current static plan. If both static and dynamic plans have not been specified, the system will create new plan with reasonable defaults and set it in Master planning parameters as both current static and current dynamic plans.
- Planned order explosion. Implemented by the class ReqCalcExplodePO. This class starts when you click ‘Update’ button on top of the Explosion form, called from planned orders form by clicking on Inquiries->Explosion. It is also called automatically when user creates/modify planned order or when planned production order is firmed.
In the most general case, there are three additional parameters which enable/disable certain additional explosion functions, absent in regular MRP:
- Current Explosion. This checkbox enables so to say, selective regeneration for explosion.All coverage information for the net requirement is being exploded. If covering net requirement was planned order and it does not cover another net requirements, it is also deleted, leading to recursive deletion of derived net requirements and so on. I want to warn you that this mode does not prevent incorrect planing phenomena, which we discussed in previous section. Since this mode only deletes coverage information for demand and derived demand of given net requirement, it won’t help if we have non-urgent net requirement, independent from net requirement being exploded and our on-hand data is covering this non-urgent net requirement.
- Marking and Reservation. This checkbox is available only for salesLine explosion and production order explosion. It instructs the system to delete marking information and drop reservations from underlying inventory transactions. As you probably knew, marking and reservation have impact on coverage planning. If two inventory transactions are marked, their net requirements will be connected by coverage. If inventory transaction is Reserved Physically, it always covered from on-hand net requirement. So, if you checked Current Explosion, you would probably need to check this checkbox as well, otherwise most of dropped coverage information,would be recreated from inventTrans data.
- Autoreservation. This checkbox is available only for salesLine explosion and production order explosion. If you enabled this checkbox, after explosion, the system will duplicate coverage information into inventory transactions. Coverage info will be transferred into marking; If the requirement was covered by an on-hand net requirement, related inventory transaction will be reserved. This checkbox is especially useful if you want to handle the situation of manual production order entry. In ideal world, users never enter production orders manually. They run regeneration MRP for all items, firm resulting planned production orders and the firming process creates inventory markings from coverage info. But what if a user have manually created new production order? How can we create marking from coverage info in a quick way ? Just try to check this checkbox and run explosion.
I do not understand, why autoreservation functionality in the system is limited only to sales orders and production orders. From time to time users manually create purchase orders, transfer orders and inventory journals. All these orders/journals participate in coverage planning, but system do not have direct means to transfer created coverage information into inventory transaction. I once developed a class, which can make something like ‘autoreservation’ for sales orders in a batch mode (I mean – for all sales orders in current company). I am wondering, why Microsoft have not developed some functionality for flexible massive update of inventory transactions from current dynamic plan? Something which would allow you to select type of net requirements, date range and so on, and then run over suitable net requirements and transfer coverage info into inventory marking data…
Two plans scheme
Standard MRP tutorials describes the idea of two plans schema in details. Shortly speaking, we have two plans – static and dynamic. Static plan is fully regenerated every night (or maybe every second night, every Saturday and so on…) and copied into dynamic plan. During daytime (between two static plan regenerations), production, purchase and logistics departments works with static plan. (Since it is stable and kept in ‘up-to-the-rules’ state), while sales managers use the dynamic plan to run explosions for newly created sales orders. In this case, sales managers have a tool to make reasonable estimation for a sales order delivery time, while all other departments work with stable plan without irregularities caused by last moment change. To support this scheme of work, if Full MRP is being run,Session Item Set contains all items and automatic copy of static to dynamic plan is enabled in the plan parameter, update phase for static plan also dropps all info from inventSumLogTTS table. The logic behind is clear: Since we are running full regeneration of the static plan and we are going to copy its results to dynamic plan anyway, there is no much point in keeping our old update log. In the beginning, we will drop inventSumLogTTS; We will create static plan from the scratch; Then, after MRP finish, we will copy static plan to dynamic. InventSumLogTTS at this moment will contain the list of updates to inventTrans made after initial net requirements regeneration. If user try to run explosion or dynamic plan update in Net Change/Net Change Minimized mode, the system will handle it in the same way as usual dynamic update of dynamic plan.
Change of current dynamic plan
If you try to change Current Dynamic Plan setting in master planning parameters, you witness very strange behavior. On attempt to change, the system pops-up a dialog box with the message “Update and move transactions to new dynamic master plan?”. If you agree, on attempt to save changes, the system will hang for a while. After that you will be surprised a lot: Your new dynamic plan contains exactly the same information as old dynamic plan. The system was hanging during parameters update just because it was copying old dynamic plan content into the new dynamic plan…
On a first sight it looks totally weird and counter-intuitive. We are deliberately changing dynamic plan and yet, as a result, we have the same plan under a different name. But if we think more about it, it is not so weird as t seems. Say, we just changed current dynamic plan without copying. What should the next explosion do ? We have a lot of recorded changes in inventSumLogTTS; Which of them should be applied to the new dynamic plan and which – should not ? The system does not have information to make this decision at all. We have only one dynamic plan which is synchronized with inventTrans/InventSumLogTTS state. So, if we are changing current dynamic plan settings, there is only one relatively fast way to bring it to synchronous state – to copy the old dynamic plan (which is kept in sync by definition) to the new one. An alternative approach would be to run Full MRP in regeneration mode, but it would require much more time and DB/AOS server capacity. That’s why designers of MRP module in Dynamics AX decided to always copy dynamic plan on change of current dynamic plan setting.
Dynamic Update process
Dynamic update algorithm is pretty straightforward. The system runs over the inventSumLogTTS records for the specified item sorted by sequence number and applies every change to underlying net requirement record (reqTrans). There are few points to be made though:
- InventSumLogTTS table uses pessimistic locking. If two users are trying to run planning or explosion for the same item, one of them will be suspended. If we have a lot of changes for the given item, this user can spend 20-30 seconds waiting. In version 2012, developers has changed this approach and now the system uses optimistic locking for the table.
- Dynamic Update process starts not only during MRP or Explosion, but also when a user opens Requirement Profile or Explosion forms. If your inventSumLogTTS has a lot of records for the given item, do not be surprised that on attempt to open any of these forms for the item, Axapta client can hang for a while (up to several minutes, if you have not run regeneration planning for a long time and your database server is weak). Another interesting effect of this mechanism is that even if you just created new order line (say – Sales Order line) and have not run MRP/Explosion afterwards, in the Requirements Profile form, you can see requirement for this line. The call to Dynamic Update class in the init() method of the forms mentioned, caused it to create new net requirement even before any MRP/Explosion runs.
- When the system is running Dynamic Update process, it keeps list of changed dimensions and changed quantities. After the update, it tries to find paired Net requirements with changed dimensions and ‘re-wire’ coverage information for them. Say, if you changed warehouse in purchase line and the system automatically changed warehouse in marked inventory transaction for sales order, next dynamic update will first drop and then re-create coverage information even before real MRP coverage stage is run. (You can check it if you open Requirements Profile form after changing warehouse, but before running MRP/Explosion).
- I never saw the following situation, but I still believe that it can happen sometimes: Since Axapta does not use serializable transaction isolation level, it might happen that after the system red inventTrans data (used to regenerate net requirements) but before the deletion of inventSumLogTTS data, another user might update inventTrans. As a result: Information about change is deleted from inventSumLogTTS (since we deleted all info for the item) and is not present in Net Requirements (because query which is reading inventTrans to build net requirements was started before the change). Probability of this situation is very low, but it still can cause minor inconsistency in planning results. I believe that the only way to fix it is to implement a support for snapshot transaction isolation level in Axapta and then use this new isolation level in code of MRP Update phase.