cancel
Showing results for 
Search instead for 
Did you mean: 

What are best practices to allow multiple developers to change the SAPMV45A enhancement?

BaerbelWinkler
Active Contributor

Hi All,

I'm aware that this question has already been asked more than once but none of the responses I found seem to be a good fit for our particular (?) situation as far as I can tell:

  • we are on SAP_BASIS 740/SP11 with EHP 7 (but haven't activated (m)any of them)
  • (almost) all of the custom-code for SAPMV45A is in one big enhancement
  • special logic has been added over the years for various org-units, countries or other groupings of which we have a lot (>50)
  • many changes are surrounded by an additional check to see if the code-snippet is currently active or not (done via a select on a Z-table which contains relevant entries)
  • the code and comments in the enhancement totals >30,000 lines
  • most of the code is kept right within the enhancement includes (MV45FZ*) with some special cases also having their own country-specific include (e.g. ZRU1_MOVE_FIELD_TO_VBAK)
  • the enhancement needs to be changed often as new requirements come in, be it for longer term projects or quick fixes due to other requests (we sometimes have 2 to 3 changes per week)
  • several developers routinely work on these changes at any given time
  • In order to avoid tripping over each other, we've been documenting currently happening and upcoming changes in a collaborative workspace, so that the developers involved with this enhancement are aware of what's happening and don't overtake each others' changes.

As more concurrently running projects are currently being planned, we are trying to find a way to make parallel development possible, ideally without losing the one advantage we have with just having "everything" in one enhancement: comparing versions for just one entity via SE84 and version compare.

While searching here and elsewhere, I saw suggestions for both using dedicated Z-includes as well as BADI-implementations, but I'm not really sure what's the best approach, esp. to ease this in as a major rework of what we already have in the enhancement is not planned.

What I'm especially interested in is to learn about the respective pros and cons of the different options.

Thanks much!

matt
Active Contributor

I have edit the wiki entry that promotes the use of includes for modularisation as it is a bad idea - not good practice at all.

Accepted Solutions (1)

Accepted Solutions (1)

matt
Active Contributor

BADI is much better approach than Z includes. It decouples the coding from SAPMV45A. It also allows you to properly modularise your code. This modularisation alone will enable multiple developers to work without interfering with each other - if combined with multiple BADI instances, it gets even easier.

While being able to use version management on just one entity is nice, the Total Cost of Ownership of a single program 30000+ lines long almost certainly outweighs the cost of having to compare individual methods.

Includes should not be used, since a single syntax error in one include kills the entire program. Includes are not a modularisation technique. Includes are solely for managing source code.

BaerbelWinkler
Active Contributor
0 Kudos

Thanks for your reply, Matthew! I understand the reasons why includes should not be used, but I'll also admit that it's nonetheless tempting to go down that route anyway as it's an option I can at least picture actually implementing within the time and resource constraints we have (not to mention about 28 to 50 entities - countries or sales-orgs - we'd need to take into account).

As I - unfortunately - know next to nothing about BADIs in general I don't have much of a clue how we'd be able to actually move from what we have now in SAPMV45A to BADI(s) in a timely manner. I think what I'm looking for is some kind of layman's explanation or "BADI-101 for MV45A" for how this would actually need to be done and how it would eventually look like. As mentioned above, I did read through Andrea Olivieri's helpful Best Practice blog post, but the screenshots of the code snippets - the things I'm most interested in - are very difficult to read even zoomed in.

What I can make out is, that instead of calling different form-routines in a case-statement in the USEREXIT-forms in SAPMV45A as we'd do with includes, we'd have a case-statement to set the relevant filter-value followed by calling the BADI. But, what would the "grouping" for these implementations need to be? Would there be one implementation per e.g. sales-org which then has logic for each of the user-exits? Or would it be vice-versa? Or, perhaps even one implementation per sales-org and userexit? I'm showing my general ignorance about BADIs here ....

As most change-requests we get for the enhancement are based on country or sales-org, I guess that this would be the relevant denominator of what should go into one BADI implementation (assuming that this is the smallest entity within a transport?) - esp. as our goal is to allow multiple developers to work on this in parallel.

So, I'm not really asking for much, am I?

Cheers

Baerbel

matt
Active Contributor

You create a BADI, you add the relevant code to initiate the BADI implementations. If you create a BADI that has, for example, a company code filter, you can have an implementation per company code. You initiate the BADI implementations sending the company code as a parameter. The BADI framework then handles which implementations it should run - no need for a case statement.

How you'd actually do this with your system depends very much on what's been done already and the business requirments - not exactly the kind of thing that can be worked out on this forum. I strongly suggest you get someone who does know about BADIs (they're hardly new technologies - first introduce over 15 years ago) for a few days consultancy at your site. The good news is that you shouldn't be too hard pressed to find someone who's done this kind of stuff before - it's a common solution to a common problem.

The problem you have is that your current handling is effectively broken. The risk every time there's a change that you'll kill something will only increase over time. Take the opportunity to decouple the code, remove the risk. Spending a week now properly planning will save you a world of pain later on.

raghug
Active Contributor

Bärbel, to take the fear out of calling a BADI... here is a code snippet where I am sorting transfer orders in a warehouse for a picklist. Each warehouse had its own preference to how the sort went. This is the call from the picklist program.

   DATA obadi_to_sort     TYPE REF TO  zbadi_rf_pick_sort.

    TRY.
        GET BADI obadi_to_sort FILTERS warehouse = lgnum.
        CALL BADI obadi_to_sort->get_sorted_to_lines
          EXPORTING
            i_ltak           = ob_to->ltak    " WM transfer order header
            it_ltap          = ob_to->i_ltap    " TO Items
          IMPORTING
            et_ltap          = sorted_to_lines. 

      CATCH: cx_badi_not_implemented.
        "Error handling
    ENDTRY.

Basic Fallback BADI...

class Z_PICK_TO_SORT definition
  public
  final
  create public .

public section.
  interfaces IF_BADI_INTERFACE .
  include structure ZIF_RF_PICK_TO_SORT .
endclass.

class Z_PICK_TO_SORT implementation.
METHOD zif_rf_pick_to_sort~get_sorted_display.
  et_ltap[] = it_ltap[].
  SORT et_ltap BY vltyp vlpla. 
ENDMETHOD.

Specific BADI for warehouse 123

class Z_PICK_TO_SORT_123 definition
  public
  final
  create public .

public section.
  interfaces IF_BADI_INTERFACE .
  include structure ZIF_RF_PICK_TO_SORT .
endclass.

class Z_PICK_TO_SORT implementation.
METHOD zif_rf_pick_to_sort~get_sorted_display.
  et_ltap[] = it_ltap[].

  IF i_ltak-trart = 'E'.
    SORT et_ltap BY nltyp nlpla. 
  ELSE.
    SORT et_ltap BY tapos.
  ENDIF.

ENDMETHOD.

As, Matthew said, the BADI infrastructure takes care of calling the appropriate class/method and there is IF or CASE statements to manage. The main programmer can be responsible for the fallback class and then hand the rest to local organizational unit based developers to do as they please 🙂

raghug
Active Contributor

Forgot to mention, for your initial refactoring, you could just move the existing implementation into your Fallback class.

BaerbelWinkler
Active Contributor

Thanks for your responses Matthew, and for your example Raghu!

I scheduled a meeting with our inhouse consultants to discuss our options going forward and this thread will be very helpful to shape it. Can we leave this thread open for more comments until after the meeting which will happen on March 15?

Cheers

Baerbel

matt
Active Contributor

I see no reason to not leave it open. But when done, it would be helpful for you to close it.

BaerbelWinkler
Active Contributor
0 Kudos

Here is a quick update:

We discussed this today and were in agreement that we'll need to analyse the existing code in a lot more detail before we can start looking into how to "improve our luck" with this enhancement.

As this will take quite some time, I'm going to close this thread now.

Thanks again everybody, for all the feedback which gave us quite a lot of food for thought.

Cheers

Baerbel

Answers (5)

Answers (5)

horst_keller
Product and Topic Expert
Product and Topic Expert
nomssi
Active Contributor

Modularization based on abstractions is the way things are done (Barbara Liskov)

=> extract logic to other modularization units (FORMS, function module, methods of separate local class, global class, BAdI) and only keep a PERFORM / function call / method call in the user exit include. For object oriented code, check. refactoring best practice.

After the initial refactoring, changes should only be made in the new modules.

Hope this helps,

JNN

Former Member

Hello Bärbel,

in fact that you have a lot of developments and changes over the time, I suggest to use BADI with filters in combination with Switch Framework (SFW5).

What is the benefit ?

1.

Values of an filter can be maintained by a good keyuser . So if you have code running depending on organisational data e.g. sales organisation, and you want to add oder change this, you only need to maintain the filter values --- No Programm changes neede, no Z-Tables needed ---

2.

Code at Userexits with a lot of developments, will be much more easier to maintain.

3.

By using the Switch-Framework you can use a standard tool for activation/deactivation of your developments (useful at system upgrades for example to test sap standard and after that, the different developments you have made.

4.

A very big point is : If you organize you development projects a little bit at SWF, you see at ONE look, that there are dependencies to other developments. For example : You will code something what gives you values for use in another module, where another developer does an development. In Switch-Framework you define a hierarchie if you want. All depending developments can be simply seen. And more less you get a warning if you try to deactivate a switch, witch is base for another part. So you will never deactive something which is part of an later development. Doesn't matter at days, months or years.

-----

-Extensions will be switchable

-Dependencies will be shown

-No big thinkover about the structure of any Z-Tables to stear the development

- Less of research time

- Less of coding time

- Standard functionality - let SAP do the job for you.

- you can integrate it step by step to remove an older not really working solution

----

I had the same issue, with an existing z-table-concept and a lot of changes, and exits, and all should be switchable. A horror to debug, and to see through for new developers at this system.

Ryan-Crosby
Active Contributor
0 Kudos

Hi Bärbel,

I would echo what Matt has said in that the situation will not change if you don't explore alternatives that give way to a new approach. We have utilized Z BADIs in a handful of locations where it has helped immensely and although it takes a little time up front it will help on the back end. The one other alternative that I would mention is BRF Plus (FDT_WORKBENCH) which can be called via the ABAP runtime to execute rules based on business needs. I have not had a chance to use it yet because we are not on a high enough BASIS release but we have implemented a larger custom application using the precursor in our current environment. Here is a link to a PDF with some pages included from an SAP Press book on the subject: BRF Plus

Regards,

Ryan Crosby

Tomas_Buryanek
Active Contributor
0 Kudos

Good question!

I was also searching for best approach. And custom Z* BADI is good one.

Only problem with these USEREXIT_SAVE_DOCUMENT_PREPARE etc blocks is, that there is no clearly stated interface. I mean importing, exporting, changing parameters 😞 But you will collect them all (used ones) if you do a refactoring of current code.