The great thing about being technical developers is that “ours is not to reason why, ours is just to do or die” (just like the Light Brigade, come to think of it.) And having the new-found power of implicit enhancement makes this even more true – a functional objective can be well-conceived, mis-conceived, or ill-conceived – it doesn’t matter – it can still be accomplished by implicit enhancement, so long as you’re willing to read SAP code long enough and carefully enough.
And therefore, it is quite possible that sometimes, instead of being successful Bengal Lancers, implicit enhancers can wind up more like the cavalrymen of the Light Brigade, forced into the valley of “depth” because a particular functional goal cannot be achieved without setting hooks into SAP code that are perhaps, set way to deep to be really “safe”.
As a possible case in point, I want to outline a particular functional objective that was recently achieved at a ECC 6.0 client and the implicit enhancements that were required to achieve this goal. As a technical developer, I am not and can not pass any judgment on whether the functional objective was“good” or “bad”, but I can say that the implicit enhancements needed to accomplish this objective were extremely interesting, in the sense that they taught me more about the internals of SAP MRP (MD01/2/3) than I ever thought I’d haveto know or need to know.
So I leave it entirely up to you as readers to decide what you think – did this project bring further glory to the Implicit Enhancers, or was it an ill-conceived charge into the “Valley of Depth” – into those deeply buried nooks and crannies of SAP code where none should dare to go?
At first glance, the functional objective seems quite simple – when SAP generates new Schedule Lines and PurchReqs during an MRP run, decide whether these are already “pegged” properly to the right “projects” (think POSKI’s), and if not, do the following: 1) if a newly-generated purchase req is not properly pegged, figure out how it should have been pegged and call a BAPI to change the bednr; 2) if a newly generated SchedLine has not been properly pegged (i.e. is attached to a SchedAgreement referencing a different project), then try to find a SchedAgreement that the line can be properly attached to – if you find one, reassign the line to that Agreement, and if you don’t, recreate the SchedLine as a PR (in either case, remove the SchedLine from the origina Agreement), 3) make sure that the create_indicator (estkz)in the new PR or re-assigned SchedLine is set to “B” and the new “fixed” indicator (fixkz) is not “on”;4) only do all of (1-3) when SAP has marked the PR or SchedLine “new” (aussl or oldsl = N1-N4.)
To accomplish these goals, it was necessary to examine MRP code in order to determine where to to three kinds of implicit enhancements:
First, during the SAP run itself, where to collect the MDPS lines that SAP has marked new (Call this the Collection Point.)
Second, where to call the custom code at the end of the SAP MRP run after SAP has “dequeued” the run (this is not as simple as it first sounds, because the flows of MD01, MD02, and MD03 are different, and within MD02 and MD03, there are subflows depending on various “simulation” or “display before save” selection screen options. (Call these points the Invocation Points.)
Third, when the custom code calls the relevant BAPIs to reassign schedlines (i.e. create new schedlines within different agreements) or create new PRs, where to circumvent the SAP code that wants to make the create-indicator “R” and the fixed indicator “X” . (Call these the “FakeOutSAP Points”.)
Here is where we put the Collection Point, Invocation Points, and FakeOutSAP Points. And as I said earlier, readers can decide for themselves how wise these choices were, i.e. whether we perhaps charged a little too far into the “Valley of Depth”.
We put this at the end of the SAP function HINZUFUEGEN_NEW_DISPOSITION, which is always invoked in the course of MD01/2/3 invocation, and in fact, is one of the last “common” places these transactions visit.
To cover all bases in MD01/MD02/MD03, we had to put our invocation points at the end of four different SAPMM61X forms:
( And of course, we had to make sure that no two of these four were ever both hit in the course of any MD01/2/3 run of any “flavor”.)
A bunch of these proved to be necessary in the MEOUT and MEREQ function groups:
Include LMEOUTP14, class lcl_instance_factory, beginning of post method
Include LMEREQF32, class lcl_r_estkz, beginning of Is_valid method
Include LMEREQF51, class lcl_r_fixkz, beginning of is_valid method
Include LMEREQF56, class lcl_r_hd_extkz, beginning of is_valid method
(So many of these were necessary, because SAP code seems to have been understandably written to enforce the following rule: “if SAP didn’t create this object, make extkx “R” (manual) and turn on “fixkz” (fixed.))