Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Overcome limitation of multiple use in BAdI ME_PROCESS_PO_CUST

kenzo
Participant
0 Kudos

Hi Experts,

I have a number of requests from users that came up at the same time to enhance ME21/2/3N.

They are related to different subjects and need to be saved in different transports.

I am very use to BAdIs, so I would like to use only ME_PROCESS_PO_CUST and NOT use CMOD to enhance MM06E005.

Does anyone know how to overcome the limitation of not having the "Multiple Use" flag checked to enable multiple ative implementations at the same time?

Has anyone been through this and came with a solution that doesn't require changing the standard configuration of ME_PROCESS_PO_CUST, like checking this flag?

1 ACCEPTED SOLUTION

former_member400468
Active Participant

Hi!

You can implement something like BTE, create class-implementations for each development with the interface from BAdi and call them according come lists (for example table with names of the classes or STVARV select-options). Also as noticed Deepak you can implement filters on which you can call only necessary classes

Hope it's helpful

Evgeny

24 REPLIES 24

pokrakam
Active Contributor

Is there any reason you can't just include all your requirements in one implementation?

If it's that important to keep coding separate, just build each requirement as a private method in your implementing class and call them all in your BADI implementation.

0 Kudos

Hi Mike,

Thanks for your reply!

Yes, as a requirement, I do need separate implementations.

But I have to make a "dynamic" call to each implementation, as I must save each implementation in a separate transport.

These changes come from different Functional Spec and have the same Go Live date.

And I also think is more organized to keep them in separate places...

pokrakam
Active Contributor

If it's the same go-live date then you can have each method in it's own transport. One will be the master, suggest that is your main implementation that calls all the others.

You can make the whole process generic in a couple of ways. For complete separation I would personally go the route that Sandra suggested. Creating your own BADI is not that difficult, and you can define that one as multi-use and just pass on all the SAP BADI's parameters.

0 Kudos

Can I use that "Z" BAdI to change values item values passed on ME_PROCESS_PO_CUST~PROCESS_ITEM ?

There's a parameter called IM_ITEM which allows you to do so...

Where do I create that BAdI? Inside methods of ME_PROCESS_PO_CUST?

pokrakam
Active Contributor

Yes, you just need to pass it on. Effectively you will turn the SAP BAdI into a wrapper for your own BAdI.

The doco is very helpful, over here.

0 Kudos

Do I need to create a BAdI for each method of ME_PROCESS_PO_CUST or

can I have only one BAdI and create methods for each method of ME_PROCESS_PO_CUST?

pokrakam
Active Contributor

That's a design question entirely up to you. It's a bit of effort so if every requirement just involves this SAP enhancement point, then I'd probably keep it in one for simplicity.

The only reason I would create multiple BAdIs is if one solution involves something where the BAdI provides enhancement points that are also inserted into completely different pieces of code (e.g. Z-reports). But that's a pretty extensive design.

Sandra_Rossi
Active Contributor

Anyway, there will always be one common-master-initial transport request, to contain the driver, and it can't be avoided (even the modification of the "multiple use" flag, if possible, will have to be transported first; --but-- even if it would be possible I wouldn't recommend to changing it).

Note: if one of the BAdI methods has an EXPORTING parameter, then you can't make it "multiple use" (the parameters can be only IMPORTING or CHANGING for such BAdIs)

Do as Mike suggests: keep the BAdI, and build a "driver" in it so that the developers can create distinct implementations. The driver could be done in various technologies. I would recommend an enhancement point, and the developers will create completely independent implementations (which is not the case of several methods in the same class, as they will share the same visibility section which contains all method definitions -- only the implementation is strictly separate).

0 Kudos

Hi Sandra,

I liked your proposal to create a "driver", but how is that achieve within ABAP?

Do you mean to create a "Z" BAdI inside a method of ME_PROCESS_PO_CUST, say PROCESS_ITEM?

Could you please give further details?

Thanks!

The 'driver' is just an abstract concept, could also call it a controller if it makes more sense to you. Basically any means to call a bunch of <whatever you design> implementations.

Enhancement point = new style BAdI, so yes a Z-BAdI is exactly what Sandra suggested and is what we've been talking about in the other comments subthread (@Sandra, that's why I hijacked your answer comment thread, sorry 🙂 )

My first and simples idea of just hard-coded calling a bunch of private methods on the SAP-BAdI implementation class is the same concept, only a quick and simple version. If there are only two or three bits of functionality I'd still stick with that.

Another alternative:

Create an interface with your required method, and instantiate and execute all classes that implement it. It's a slightly simpler "DIY BAdI" without the SAP framework around it.

0 Kudos

Mike, I think the Z-BAdI "driver" is a good way to go.

But the suggestion of creating private methods, to me sounds the same thing as using only one BAdI-method for all implementations. I don't see much difference since you would still need to edit the main method to call private methods implementations. Also very similar to what Deepak's proposed below...

(any people is welcome hijacking my comments with interesting comments 😉 )

Not quite the same as doing it all in one method. Private methods lets each developer do their own thing and the controller has to know nothing about what's being done by each pseudo-implementation. The only common bit is the piece of code that calls all the methods. One can't get much less complex than a method which does nothing else than call a bunch of other methods, so maintainability is easy.

There will always be common code. Someone has to build the BAdI or whatever framework for any of the strategies discussed here. So you will always have one master (or "driver") transport that all others depend on. Therefore it should not be terribly complex to communicate and get that person to insert all the method calls into the main method.

There's no right or wrong here, it's a matter of weighing up simplicity against the importance to have absolute separation. If there are 2 or 3 implementations and people communicate then it should not be a major issue to fix a few method calls and the main caller method and sub-implementation framework can be written in a few minutes (copy-paste an empty BAdI method for each implementation). Of course if absolute separation is a must then one of the other alternatives can be done, but with more effort.

0 Kudos

I understand your ideas Mike.

Very interesting, thank you very much!

Will definitely considere them in my developments.

For now, I had to leave it all implementations in one method for simplicity, and the first request is Live already.

In future, we will implement something like more flexible and independent.

Cheers!

Former Member

Hi Carlo,

You can do as follows:

There would be many a times the BADi is Single use and not multiple use but the business requirements and logic can be more than one.

What you can do is You can create an Include for each of the Business Requirements and put in the entire business logic in that Include.

All Your Data and types Declaration and the Logic Should be in that Include. Most important is that You also need to put in the Conditions that this Include should be Executed for Your Business logic ONLY. Example you want the BAdi to trigger only for Certain Material type or some Article / MAterial number or any such Conditions.

The Other guy will use his Buisness Logic, Data types Declaration and Conditions in his Include. and so on and so forth.

Mind you only one person should work with the BAdi at One Particlar time and should be under only one TR and not multiple.

Let me know if you like this Solution.

Reward Points if helpful.

Regards,

Deepak.

0 Kudos

Hi Deepak,

Thanks for your answer, but as mentioned I have concurrent requirements and they all have same Go Live dates.

If only there were a way of dynamically including the includes in the method of BAdI...

former_member400468
Active Participant

Hi!

You can implement something like BTE, create class-implementations for each development with the interface from BAdi and call them according come lists (for example table with names of the classes or STVARV select-options). Also as noticed Deepak you can implement filters on which you can call only necessary classes

Hope it's helpful

Evgeny

0 Kudos

Hi Evgeny, could you give more details on implementation of BTE?

0 Kudos

So you will have a main class which is implementing the BAdi, and inside of this class you will get a list of sub-class names for example from database table ZMEPOCLASS in Constructor method and then create a list of objects which methods you will call. The sub-class should have the same interface as main class, so you will call method PROCESS_HEADER of sub-class inside the same method of main class in the loop by sub-classes list.

0 Kudos

Sorry Evgeny, but I couldn't really understand the proposed solution.

Could you please point out some examples in practice?

So first of all you need to create BAdi implementation as usual. The class implementing the BAdi will be the driver class. Then you can from it for each separate development. Then you should create a constructor method which will get class names (Select from Z-table) and then generates objects. And the processing in each method of your class will look like this:

TYPES:
  BEGIN OF ty_subclass,
    classname TYPE zmepoclass-classname,
    oref      TYPE REF TO if_ex_me_process_po_cust, "reference to the class with BAdi interface
  END OF ty_subclass.

METHOD constructor.
  SELECT classname
    FROM ZMEPOCLASS
    INTO TABLE mt_subclass.
  IF sy-subrc = 0.
    LOOP AT mt_subclass ASSIGNING FIELD-SYMBOL(<ls_subclass>).
      TRY.
        CREATE OBJECT <ls_subclass>-oref TYPE (<ls_subclass>-classname). "create instances of your classes
      CATCH cx_root.
      ENDTRY.
    ENDLOOP.
  ENDIF.
ENDMETHOD.



* Example of processing in the method
METHOD if_ex_me_process_po_cust~check .
  LOOP AT mt_subclass ASSIGNING FIELD-SYMBOL(<ls_subclass>).
* call corresponding subclass method
    IF <ls_subclass>-oref IS BOUND.
      TRY.
        <ls_subclass>-oref->if_ex_me_process_po_cust~check( EXPORTING IM_HEADER = IM_HEADER
                                                                      IM_HOLD = IM_HOLD
                                                                      IM_PARK = IM_PARK
                                                             CHANGING CH_FAILED = CH_FAILED ).
      CATCH cx_root.
      "catch if the method is not implemented in the subclass
      ENDTRY.
    ENDIF.
  ENDLOOP.
ENDMETHOD.                    "IF_EX_ME_PROCESS_PO_CUST~CHECK

0 Kudos

Hi Evgeny!

- Is the constructor method created in the BAdI implementation class? Can I even do that in this class?

- Is mt_subclass an attribute of BAdI implementation class?

- The classes of each implementation (on table ZMEPOCLASS) are created on SE24, right? Are they all type if_ex_me_process_po_cust?

Thanks!

Hi!

- yes, you can rule the BAdi implementation class as simple SE24 class

- yes, I propose to set it like class attribute

- yes, you should create each class in SE24, and the set if_ex_me_process_po_cust on the tab Interfaces

0 Kudos

Thanks Evgeny!!! Your solution was most appropriate to my case and I have implemented it in DEV and already working!!!

You also demonstrated a practical solution, which was key for my implementation.

Thanks to you and all guys that helped me here!!!