You may have heard the following idiom before:
Too many cooks spoil the broth
The common meaning extracted from this saying is that too many people working on a single task tend to make a mess of it. But, what happens when you have too many developers working in a single piece of ABAP code? That’s right, you get a big mess. This issue is especially difficult to deal with when there are multiple functional requirements leveraging the same custom code object, form-based user-exit, or function-based user-exit.
While current releases of SAP (those built on SAP NetWeaver 2004s and later) have good built-in handling of enhancements and customizations via implicit and explicit enhancement points and BADIs, there still exists many old-school user-exits.
Multiple Developers; One Code Object
I recently worked on a project where three separate developers were creating three separate interfaces based on the outbound delivery IDOC. While the development for all three interfaces was occurring at the same time, the go-live date for each of the interfaces were different (we’ll discuss that project management glitch at another time). Each interface required a separate set of custom fields and, therefore, it’s own IDOC extension. The problem is there is only one appropriate user-exit in IDOC_OUTPUT_DELVRY and three developers needed to be developing in it at the same time!
How did we solve this problem?
An Object To Call One’s Own
To allow each developer his own development object and transport timeline, I decided to implement a custom multiple-use, filtered BADI inside the SAP user-exit function EXIT_SAPLV56K_002. Actually, you can implement your own BADI almost anywhere you need alternate logic execution–even custom code!
So you might be saying, “Create my own multi-use, filtered BADI definition? Sounds complicated.” Well, it’s easier than you think!
NOTE: This solution was done on an ECC6 system based on SAP NetWeaver 2004s. The steps to implement this type of solution in ECC5 (SAP NetWeaver 2004) are very similar.
Create A Custom BADI Definition
-
To create a new enhancement spot definition, use transaction SE18. I named my enhancement spot Z_EXIT_SAPLV56K_002 because the enhancement spot will be used in user-exit function EXIT_SAPLV56K_002.
-
In the ensuing dialog box, enter a description and choose BAdi Definition for the Technology
-
Next, create a new BADI definition.
-
Specify that the new BADI definition will be multiple use and limited to filtered use.
Making the BADI definition multiple use means that each developer can create his or her own BADI implementation. Each BADI is implemented in its own class. This promotes code separation and the proper reuse of shared development objects.Making the BADI definition limited to filter use ensures that the BADI implementations are separate and cannot affect every interface using the user-exit.
-
Now, create a new filter.
BADI filtering in SAP NetWeaver 2004s is much more powerful than in previous versions of SAP. Read more about BADI filtering here.
-
The BADI we are defining will be used to populate IDOC extensions. Each IDOC extension has its own message type (e.g. ZMHL_DESADV, ZQTC_DESADV, ZMHL_SHPORD), therefore the message type of the IDOC being processed is a good value to filter on. I named my BADI filter EDI_MESTYP.
SAP allows for the automatic checking of BADI implementation filter values. The standard domain EDI_MESTYP has a value range of table EDMSG attached to it. This is exactly the range of values I want as allowable values, so I configure the BADI filter to automatically check the filter values against dictionary object EDI_MESTYP.
-
Next, create the BADI interface that will be inherited by each implementing class
-
The original user-exti function EXIT_SAPLV56K_002 is executed after each segment is added. Our BADI will do the same. Create a new public interface method SEGMENT_ADDED.
-
The BADI we are creating is replicating user-exit function EXIT_SAPLV56K_002. Here is the function interface for EXIT_SAPLV56K_002:
Here is the same data being passed via the interface method.
-
Lastly, the BADI has to be called from the existing user-exit. I will not cover the steps required for implementing user-exit function EXIT_SAPLV56K_002 here, but once you have the user-exit implemented, add the following code. This code should be the only logic directly inside the user-exit. Any data processing logic should be implemented via a BADI implementation:
DATA: GO_BADI TYPE REF TO Z_EXIT_SAPLV56K_002. DATA: L_STR TYPE STRING. L_STR = MESSAGE_TYPE. * Get BADI class based on IDOC message type GET BADI GO_BADI FILTERS EDI_MESTYP = L_STR. * Execute SEGMENT_ADDED BADI method CALL BADI GO_BADI->SEGMENT_ADDED EXPORTING MESSAGE_TYPE = MESSAGE_TYPE SEGMENT_NAME = SEGMENT_NAME DATA = DATA TAB_IDOC_REDUCTION = TAB_IDOC_REDUCTION FLT_VAL = MESSAGE_TYPE CHANGING CONTROL_RECORD_OUT = CONTROL_RECORD_OUT IDOC_DATA = IDOC_DATA[].
We’re done with creating the BADI definition! Save and activate your work. I bet you’re saying to yourself, “Wow, that was easy!”
BADI Implementation
Implementing the BADI you just created in the steps above is just like implementing any other BADI in SAP, so here are the Cliff Notes version of implementation instructions.
-
Using transaction SE19, create a new enhancement spot implementation for Z_EXIT_SAPLV56K_002.
-
Enter the BADI implementation details. This particular BADI implementation is for RICEF ID MHL-IO-007, so I added that identification to the BADI implementation name and implementing class name.
-
In the BADI definition, we required each BADI implementation to be filtered on message type. This particular BADI implementation is for message type ZMHL_SHPORD. Create the filter combination for the BADI implementation.
-
This ensures that the other interfaces using this BADI (ZMHL_DESADV, ZQTC_DESADV) will not execute the code implemented with this BADI.
-
The final steps are to add the code to the SEGMENT_ADDED method just like you would in user-exit function EXIT_SAPLV56K_002. Once you are done, save and activate your changes!
Summary
As you can see, with a few extra steps, it is possible to have your cake and eat it, too, by create a custom BADI definition that can be used by other developers. All this talk of food is making me hungry. Is it lunchtime yet?
Hello Sir,
I have created my own BADI and also implemented the same. But the code throws an error stating that the method is from the Interface ‘Z_IF_ZMYBADI1’. Can you please throw some light on this ?
======================================
DATA : BADIREF TYPE REF TO ZMYBADI1.
GET BADI BADIREF.
CALL BADI BADIREF->Methodname.
======================================
Hi Craig,
Excellent though process. However the Filter Type should be Character type and not String. Using String, the calls fails.
Regards,
Kevin Dass