Thursday, February 14, 2013

How to Implement a BAdI

In the previous post (Building Your First BAdI) you defined a BAdI, provided a fallback class, instantiated the BAdI and called a BAdI method. You also provided an enhancement spot to serve as a container for the BAdI.
As you already know, the fallback class is chosen in case no BAdI implementation is available. As you have not created a BAdI implementation so far, the method implementation of the fallback class is used in your example code.
In this section you will learn how to create a BAdI implementation. As soon as there is a suitable BAdI implementation, the methods of the fallback class are not used any longer.
The entries you have so far are:
      Enhancement spot z_es_calc_tax, in which the BAdI z_badi_calc_vat lives.
      Interface z_if_calc_vat with one method get_vat().
The BAdI interface defines an important part of the BAdI identity. It defines the BAdI methods that can be used.

Create a Container for the Implementation

The definition and the implementation of BAdIs have one similarity – just as you need an enhancement spot to act as a container for the BAdI, you cannot build a BAdI implementation unless you have the relevant container first.
The relevant container type for BAdI implementations is called a (simple) enhancement implementation. A simple enhancement implementation can keep many different BAdI implementations, but with one restriction: a simple enhancement implementation is uniquely assigned to an enhancement spot. That is, a (simple) enhancement implementation can keep only BAdI implementations of BAdIs that belong to the spot the simple enhancement implementation is assigned to. Therefore, a (simple) enhancement implementation cannot keep BAdI implementations that implement BAdIs belonging to different spots.
That is why you have to create a container that is uniquely assigned to the enhancement spot to which your BAdI belongs. The respective tool in the SE80 has paved a smooth way to do this:
...
       1.      In the Object Navigator (transaction SE80), open the enhancement spot you have already created and choose the Create Enhancement Implementation pushbutton.
This graphic is explained in the accompanying text
       2.      In the new dialog that appears, create a (simple) enhancement implementation:
       3.      This graphic is explained in the accompanying text
This graphic is explained in the accompanying text
The following new window opens:
This graphic is explained in the accompanying text
What are you asked to enter here?
So far you have created a container for BAdI implementations- an enhancement implementation. This container is uniquely assigned to your enhancement spot. Once this connection is established, you can create a BAdI implementation for the BAdI within the enhancement spot. Since you have defined only one BAdI within the enhancement spot, you have no choice. If you had more BAdIs in your enhancement spot, this will be the point where you would select which BAdI you want to implement.
       4.      Enter z_bdi_calc_vat_us as the name of the BAdI implementation, confirm and save the enhancement spot in the next figure, which shows a (simple) enhancement implementation that contains the BAdI implementation z_bdi_calc_vat_us:
This graphic is explained in the accompanying text
The appearance of a (simple) enhancement implementation in the tool is pretty much like the one of an enhancement spot. Under the Enh. Implementation Elements tab there is a tree with the BAdI implementation(s) contained on the right-hand side. On the left, you see the properties of the marked BAdI implementation.


Select the property Implementation is active in the Runtime Behavior pane in the figure above. If you do this, the text below changes to Implementation is called. This is intended to help you understand what the selection you have just made is for. Further below, there is a list that shows the properties of the BAdI definition your BAdI implementation is assigned to.

The Implementing Class

Now that you have a BAdI implementation, you need an implementing class.
...
       1.      Choose the triangle in front of the name of the BAdI implementation in the tree.
       2.      In the Implementing Class field, enter z_cl_calc_vat_us and choose the Change pushbutton.
This graphic is explained in the accompanying text
The Class Builder opens. The relevant interface methods are already defined there. In your case it is only the method get_vat().
       3.      Implement the method using the following source snippet:
DATA: percent type p value 4 .
ex_amount_vat = im_amount * percent / 100 .
ex_percent_vat = percent .
       4.      Save and activate the class.
       5.      Return to the program and enter the following code:
DATA: handle TYPE REF TO z_badi_calc_vat,
sum TYPE p,
vat TYPE p,
percent TYPE p.
sum = 50.
GET BADI handle.
CALL BADI handle->get_vat
EXPORTING im_amount = sum
IMPORTING ex_amount_vat = vat
         ex_percent_vat = percent.
WRITE: 'percentage:', percent, 'VAT:', vat.
       6.      Run the program.
The result is a percentage of four percent. This is because the fallback class is not selected when there is an active BAdI implementation.

Creating a Second BAdI Implementation

...
       1.      Create another BAdI implementation, this time with the VAT rate of Great Britain.
To make your example more like real world programming, you create another enhancement implementation, that is, another container. This is because implementing the taxes for different countries most probably belongs to different projects and because the structure of the (simple) enhancement implementations must mirror the project structure.
       2.      Navigate to your enhancement spot and use the same button as you have done above. Name the BAdI implementation z_bdi_calc_vat_gb, and the implementing class Z_CL_CALC_VAT_GB. The implementation of the method get_vat is the same as for USA except for the VAT rate, which you assume to be 17.5%.
       3.      After saving and activating the enhancement implementation and the class, return to the program and run it again.
This time you get a short dump with the exception cx_badi_multiply_implemented.


You have defined a single-use BAdI by deselecting the Multiple Use option. When instantiating a single-use BAdI, you have to make sure that there is only one active non-default implementation. Otherwise, you get the respective exceptions at runtime.

No comments:

Post a Comment