Dear community, enhancements (SD user exits, customer exits, Business Add-ins, source code enhancements and more), are a great way to customize own processes.
However, how you implement the enhancements is important. You can get real process advantages and at the same time you can get design (technical) problems that will accompany you for a long time, perhaps forever. According to the sentence “once programmed, maintained a thousand times“, something like this can make life difficult … a thousand times.
Unfortunately, I encounter some negative examples of enhancement implementations in practice from time to time. I’m not innocent of some of them 😉 So I share my experiences and thoughts so that others can do better enhancement implementations in the future.
I also apologize for the exceptionally long blog. Please drink two cups of coffee or tea while reading.
Here’s a very classic example: Enhancement “MM06E005” (customer fields in purchasing document). You can check it with transaction SMOD.
It can be used for enhancements of purchase order at header and item level (see transaction ME23N for example). But not only for purchase orders. Also agreement and request for quotation is included.
It’s a fine detail, but in the description of the enhancement the term “purchase document” is used. That means three different things (business object types): purchase order, agreement and request for quotation.
You can already guess what happens in practice. Developers implement an enhancement of purchase order (or they think they do so), but also influence agreements and requests for quotation at the same time 🙁
The screens for enhancing the different business object types are separated (different dynpros). The application logic isn’t. If you define for example a global variable in Include ZXM06TOP, it’s visible in the application logic for all three business object types. If you aren’t careful, this will result in a “polluted” memory and misunderstandings.
Have a look at function module “EXIT_SAPMM06E_006” (export data to customer subscreen for purchasing document header (PBO)). This function module has an IMPORT parameter “I_BSTYP”. It exists to differentiate between purchase order, agreement and request for quotation. You can design your application logic depending on the business object type. As I said: “you can” …
In addition, you will often find a lot of application logic in such enhancements. So much application logic that processes can no longer be distinguished. Global and local variables together with constants, IMPORTING, EXPORTING, CHANGING and TABLES parameters form a colorful mix – anyone who changes something here is either very experienced, brave, desperate or was forced 😉
The situation becomes even worse when two enhancements offer same or similar options. For example enhancement “MM06E005” and the Business Add-in (BAdI) ME_PROCESS_PO_CUST. However, it can also happen that a BAdI can be used for enhancing transaction logic (dialog) and Business Application Programming Interfaces (BAPIs, dialog/background).
The possibilities here are as numerous as the flowers on a meadow. Unfortunately, the problems resulting from this situation too.
Fortunately, people are able to develop answers to complex questions. Here are some of my approaches. Some have already been tried, others are still considerations. Gladly comment and discuss.
In the chinese classic text “Tao Te Ching” there’s a passage that reads “organize what is not yet in mess” (sorry for my bad translation). I’ve often experienced that problems haven’t been adequately considered. It was often said that something has to be developed. The decision was made surprisingly quickly.
That isn’t right. At least not in my opinion. Programming is not a panacea. Sometimes there are very good standard solutions or a reorganization of the process is necessary. But no development.
Of course it’s a “serious/intense” discussion, perhaps a conflict. But it has to be resolved. The aftermath of an enhancement implementation can be more expensive than resolving the conflict and opting for a different, non-programmed solution.
The isle of happiness
I heard this term for the first time in the openSAP course “Writing Testable Code for ABAP“. In our polluted seas, sorry, enhancements, these are little life rafts (isles). You branch out of the enhancement into your own source code by calling the method of a class. Not more. This class and other classes (composition) implement the required application logic. No further application logic in the enhancement.
There are many positive aspects to this. The parameters when calling the method already clarify what is important. The name of the class and the method is helpful in order to make a conclusion about the meaning and purpose. Local variables can be reduced. Testability can be guaranteed (don’t forget to write an interface). Debugging is more comfortable.
An on/off switch for the enhancement implementation can save lives. For example, there may be a central framework that manages the on/off state of all enhancement implementations. Or you have individual switches because they depend on certain organizational data such as the company code and the purchasing organization.
In any case, you should be able to react to unforeseen situations by switching off. By the way, for me, “emergency shutdown systems” are not a sign that you haven’t understood a problem in all its facets. They are much more a sign of respect for real life (see Murphy’s law)!
Reduce global variables, types and constants
Global variables, types and constants should be reduced to a minimum in an enhancement implementation. Otherwise, they will pollute the memory. Constants and types can be outsourced to a class or interface. Be sure to use suitable names.
Dialog vs. background
Where does enhacements really have an impact? You should carefully check and test to avoid any negative surprises. As described above, BAPIs can be affected while they are called via Remote Function Call (RFC). This may trigger problems (error logs) in systems other than the SAP ERP system.
Output of messages (MESSAGE statement) is sometimes not allowed or permitted in a special way. Some enhancements aren’t designed to output messages. Others have EXPORT parameters or special mechanisms to return a message to the standard application logic. You should take a close look at that.
Returning error status
Some enhancements allow you to report an error to the standard application logic. You should ask yourself how the user recognizes the error situation and what options to clear the situation are (still) there.
Please no implicit or explicit database commit
In my experience, some enhancements offer opportunities to register with update function modules for the standard update process. This is triggered by the standard application logic. Implicit or explicit commits triggered by your own code is not a good idea.
An enhancement should be done in the right context. This can be client-wide or client-specific or even depending on organizational elements such as the company code. In any case, it should only be for the right process and don’t bother anyone else.
If an enhancement implementation is so complex that no one is able to maintain it (even the bravest and most experienced), there’s a big problem. At this point, you lose the ability to safely enhance a standard process. This limits a company in its possibilities. In my view, all that’s left is extensive refcatoring. Step by step. That’s expensive and time consuming.
Not active code
For me there is hardly no place where commented-out source code is more disturbing than in a complex enhancement. Better delete than comment (trust version control). This helps to keep track during design time. During runtime debugging is easier and not like jumping over huge chasms of inactive statements.
During upgrades, I had to check various enhancements again and again. I remember a case where the user exits for processing sales documents were suddenly empty (include MV45A…). For whatever reason. Therefore, I check them after every upgrade such as installing an Enhancement Package. It’s not always easy for testers to determine whether the enhancements has been run through during test 🙁
There is also a saying in Chinese: “If you really want to know something, ask an experienced person and not a wise man” (sorry again for my bad translation). Experience counts a lot, especially with enhancements. Because they are run through standard application logic. A mistake in such a place can have an incredibly quick impact.
Let’s say that a company generates approximately 2,000 purchase orders a day. An error in the BAdI “ME_PROCESS_PO_CUST” could mean 2,000 purchase orders with bad transaction data or simply no 2,000 purchase orders. Explain that to your boss 😉
Please share your experiences and knowledge! We may all face the same chaos 😉 Or I’m the only one and have to go through it alone. Thanks in advance.
Best regards, thanks for reading and please stay healthy