Monday, 16 October 2017

SAP HANA MRP Live BADI Usage

SAP continues to improve its ERP products to HANA technology gradually. One of the most critical product is that instead of the classic MRP, it now becomes a new product as “MRP Live“. For the benefit of HANA’s speed and efficiency, MRP Live is available.

Such changes and innovations have always had advantages and disadvantages as well. These changes are especially important for backend developers. The biggest advantage of MRP Live is speed and performance, the biggest disadvantage is the length of development time. Even for a simple customer demand, we may need to write dozens of lines of code. This situation will change according to needs, of course, but it seems that we will spend much more time for according to the previous development environment and language as known SAP GUI and ABAP. MRP live is fully developed with ABAP managed database procedure(AMDP) and also for enhancements AMDP BADIs is used for MRP Live HANA development with top-down approach.

AMDP is a feature that we can use for our developments as well as SAP, for ERP on HANA because it is such a fast process but a slow working methodology when we compare with core ABAP developments.


AMDP (ABAP Managed Database Procedure) is a stored prodecure that enables us to write queries at database level and perform database operations. HANA and ABAP 740, this feature gives us incredible speed while we are trying to develop codes on database layer without ABAP language and we are not able to use the strengths of ABAP because we pass completely to SQLScript on HANA. I think, not being able to use ABAP is time-consuming for us. However it comes with a great speed and performance. This is a superb thing for the customers, and it will not be a pleasure for consultants and ABAPers because it not easy to develop based on native SQL level. ABAPers have to think and control much more case on their programs and developments. Until today, ABAP can handle lots of things for ABAP developers but after SQLScript and HANA, developers also have to change their minds and algorithms. I think, it is a good reason to improve yourself and quality of your projects.

MRP Live transaction code MD01N. The classic MRP BADIs does not work well when this t-code is runs, because SAP has completely used AMDP at the backend. Many database operations such as logging, message management and creating, updating or deleting records on database tables. SAP has also made BADI adaptations for customer needs, but these BADIs are working as AMDP BADI. It may appear as a classical ABAP class, but it does not mean that the ABAP can be written in any way.

Enhancement spot: ES_PPH_MRP_BADI

SAP HANA MRP Live BADI Usage

As you can see above, AMDP BADI is selected in BADI properties. The same applies for all BADI definitions below. If you implement BADI with t-code SE18, SAP automatically creates a class and adds related methods into it. But it creates as a normal class. AMDP methods does not specify itself in the class. So if you try to activate without any changes after creating the implementation, you will get an error. At this point you have to change the relevant BADI methods to AMDP method. You can only do this using ECLIPSE. We can not create an AMDP method on the SAP GUI. Because it is completely new feature, it has been developed for new platforms and we do not want to develop these features by SAP GUI anymore.

Once you have identified your need, find the relevant BADI and perform the implementation as you have done so far, and then just save it.

Open the class that you created on Eclipse, and there are a few definitions at the beginning of the methods that we must set as a AMDP definition below. These definitions vary according to the situation, but I tried to use most common usage. If you do further research on AMDP, you can also learn about other options.

class zpp_001_mrp_live_run_badi definition
  public
  final
  create public .

  public section.

    interfaces if_badi_interface .
    interfaces if_pph_mrp_run_badi .
    interfaces if_amdp_marker_hdb .
  protected section.
  private section.
endclass.

class zpp_001_mrp_live_run_badi implementation.
  method if_pph_mrp_run_badi~mdps_adjust
      by database procedure for hdb language sqlscript options read-only.
    -- Our excellent codes
    begin sequential execution
    end;
  endmethod.

  method if_pph_mrp_run_badi~planord_before_update_adjust
        by database procedure for hdb language sqlscript options read-only.
    -- Our excellent codes
    begin sequential execution
    end;
  endmethod.

  method if_pph_mrp_run_badi~purreq_before_update_adjust
        by database procedure for hdb language sqlscript options read-only.
    -- Our excellent codes
    begin sequential execution
    end;
  endmethod.
endclass.

We have added an additional interface IF_AMDP_MARKER_HDB in the class, and after defining the names of the methods, we made the definitions as above. We then make changes to the relevant parameters and write down our codes. I wrote a comment and a command because AMDP methods could not be implemented without any code lines. “The Begin sequential execution” command is not something that should be mandatory, so I wrote it in terms of being an example.

After we write our code with SQLScript, we activate the BADI implementation and we have done later.

Below I share a sample codes for the AMDP method. You can learn HANA SQLScript and write your code as you like in these places, use both HANA’s performance and optimize your standard processes. The codes are independent of each other. It does not mean a certain whole. It is only some code snippets.

for pilot_index in 1 .. cardinality(:pilot_mng01) do                                                           
   miktar_tam = 0;                                                                                             
   miktar_kalan = 0;                                                                                           
   i = 0;                                                                                                      
                                                                                                               
   if :pilot_disls[:pilot_index] = 'FX' then                                                                   
       if :pilot_bstfe[:pilot_index] > 0 then                                                                  
         miktar_tam = :pilot_mng01[:pilot_index] / :pilot_bstfe[:pilot_index];                                 
         miktar_kalan = mod( :pilot_mng01[:pilot_index], :pilot_bstfe[:pilot_index] );                         
                                                                                                               
         for i in 1 .. miktar_tam do                                                                           
            yeni_kayit_new_mng01 = cardinality(:pilot_mng01_new) + 1;                                          
            pilot_mng01_new[:yeni_kayit_new_mng01] = :pilot_bstfe[:pilot_index];                               
         end for;                                                                                              
         if :miktar_kalan > 0 then                                                                             
            if ( :pilot_bstfe[:pilot_index] * ( yuzde / 100 ) ) <= miktar_kalan then                           
              yeni_kayit_new_mng01 = cardinality(:pilot_mng01_new) + 1;                                        
              pilot_mng01_new[:yeni_kayit_new_mng01] = :pilot_bstfe[:pilot_index];                             
            end if;                                                                                            
         end if;                                                                                               
       else                                                                                                    
         yeni_kayit_new_mng01 = cardinality(:pilot_mng01_new) + 1;                                             
         pilot_mng01_new[:yeni_kayit_new_mng01] = 0;                                                           
       end if;                                                                                                 
   elseif :pilot_disls[:pilot_index] = 'EX' then                                                               
       if :pilot_bstma[:pilot_index] > 0 then                                                                  
         miktar_tam = :pilot_mng01[:pilot_index] / :pilot_bstma[:pilot_index];                                 
         miktar_kalan = mod( :pilot_mng01[:pilot_index], :pilot_bstma[:pilot_index] );                         
                                                                                                               
         for i in 1 .. miktar_tam do                                                                           
            yeni_kayit_new_mng01 = cardinality(:pilot_mng01_new) + 1;                                          
            pilot_mng01_new[:yeni_kayit_new_mng01] = :pilot_bstma[:pilot_index];                               
         end for;                                                                                              
         if :miktar_kalan > 0 then                                                                             
            if :miktar_kalan >= :pilot_bstmi[:pilot_index] and :miktar_kalan <= :pilot_bstma[:pilot_index] then
              yeni_kayit_new_mng01 = cardinality(:pilot_mng01_new) + 1;                                        
              pilot_mng01_new[:yeni_kayit_new_mng01] = :miktar_kalan;                                          
            elseif ( :pilot_bstmi[:pilot_index] * ( yuzde / 100 ) ) < miktar_kalan then                        
              yeni_kayit_new_mng01 = cardinality(:pilot_mng01_new) + 1;                                        
              pilot_mng01_new[:yeni_kayit_new_mng01] = :pilot_bstmi[:pilot_index];                             
            end if;                                                                                            
         end if;                                                                                               
       else                                                                                                    
         yeni_kayit_new_mng01 = cardinality(:pilot_mng01_new) + 1;                                             
         pilot_mng01_new[:yeni_kayit_new_mng01] = 0;                                                           
       end if;                                                                                                 
   end if;                                                                                                     
end for;                                                                                                       


lt_matb_ctrl_del = select ct_matb_ctrl.*                           
                     from :lt_out as lt_out                        
                     inner join :ct_matb_ctrl as ct_matb_ctrl      
                             on ct_matb_ctrl.matnr <> lt_out.matnr;
                                                                   
lt_out = select * from :lt_out where mng01 <> 0;                   
                                                                   
found = 0;                                                         
select count(*) into found from :lt_out;                           
if :found > 0 then                                                 
   ct_result = select * from :lt_out;                              
end if;                                                            
                                                                   
count = 0;                                                         
select count(*) into count from :ct_result;                        
select count(*) into count from :lt_matb_ctrl_del;                 
if :found > 0 or :count > 0 then                                   
   ct_matb_ctrl = select * from :lt_matb_ctrl_del;                 
end if;                                                            

Unfortunately there is no so much technical documentation on MRP Live at SAP inserted English comments while writing the codes. Quite useful is the interpretation of the codes, especially those for which why they use the parameters. You can look inside the BADI and see where it is called from the stack and you will get the information you need. You need to debug on ECLIPSE and check what you need to be aware of when debugging AMDP. If you have specific questions about MRP Live or AMDP, you can also ask below. I will try to respond as soon as I can.

No comments:

Post a Comment