Skip to Content
Author's profile photo Luís Pérez Grau

Redetermine conditions in sales orders massively using BOL

Component Suuport Pachage
BBPCRM SAPKU70204
SAP_ABA SAPKA73105
SAP_BASIS SAPKB73105
WEBCUIF SAPK-73105INWEBCUIF

The scnenario

We want to redetermine all the conditions of sales orders without modifying any data which forces the pricing redetermination (PRICE_DATE, STATUS, etc.)

Should we use BOL to perform mass changes?

Well, IMHO you shouldn’t use the BOL to manage large amount of data, why? Well, that’s a good question, in theory less amount of software layers, better performance, but one reason why I would choose an API instead of BOL is using aRFC to improve the performance via parallelization, as you already know you must initialize the BOL core and load the specific sets for each aRFC, so I don’t believe this is the right path, but if don’t agree with my view I will be more than happy to discuss even change this lines 🙂

Then, Why we should use BOL?

BOL has numerous advantages, modern/uniform layer to access data, tools for modelling, etc. my intention is not enter in detail why we should or not using BOL, but I think a very brief overview will situate you for what comes next.

We should use BOL, some times, because there’s no other option, and my example is one of those cases, there’s no complete API to redetermine conditions. If you want to develop this functionality you should trace all the FM involved in during the process and put all the pieces together (for more  detail, I would suggest to trace the stack until  the FM PRC_PD_ITEM_UPDATE_MULTI or PRC_PD_ITEM_UPDATE is triggered), the problem is you are decoupling the logic in the GENIL layer or in the controller of the CRMD_ORDER into a custom spot, like a report, the logic decoupled is how the standard works right here, right now, but guess what, SP and ehp will come, and new FM can be included/excluded bugs fixed, etc. and your code will remind the same, so you must take an eye every time you apply a note, sp or ehp, from my point of view this is a huge waste of time.

/wp-content/uploads/2014/07/cookie_monster_wtf_is_this_497091.jpg

The small reward

Here is the sample of the code as reward to bear all my “philosophical” stuff, keep in mind this is just a sample use it with care.


DATA: lt_param TYPE crmt_name_value_pair_tab.
DATA: lv_error_w TYPE string,
        lv_object_id_w  TYPE string.
DATA: lo_bol_core  TYPE REF TO cl_crm_bol_core,
        lo_query     TYPE REF TO cl_crm_bol_query_service,
        lo_result    TYPE REF TO if_bol_entity_col,
        lo_entity    TYPE REF TO cl_crm_bol_entity,
        lo_col       TYPE REF TO if_bol_entity_col,
        lo_bol_trans TYPE REF TO if_bol_transaction_context.
DATA: lv_bpath_query TYPE string.
FIELD-SYMBOLS: <ls_param>  LIKE LINE OF lt_param.
lo_bol_core = cl_crm_bol_core=>get_instance( ).
lo_bol_core->start_up( iv_appl_name = 'ONEORDER' ).
lo_query = cl_crm_bol_query_service=>get_instance( 'BTQuery1O' ).
lo_query->set_property( EXPORTING iv_attr_name =   'OBJECT_ID'
                                    iv_value     = lv_object_id_w  ).
lo_result = lo_query->get_query_result( ).
TRY.
      IF lo_result->size( ) EQ 0.
*     Error handling
      ENDIF.
      lo_entity  = lo_result->get_first( ).
      IF lo_entity->lock( ) EQ abap_false.
*     Error handling
      ENDIF.
    CATCH cx_sy_move_cast_error.
*   Error handling
ENDTRY.
lv_bpath_query  = `./BTOrderHeader/BTHeaderPridoc/CondHSetRel/*$`.
lo_col = lo_entity->get_related_entities_by_bpath( iv_bpath_statement =  lv_bpath_query ).
IF lo_col->size( ) EQ 0.
*  Error handling
ENDIF.
lo_entity ?= lo_col->get_first( ).
CLEAR lt_param.
APPEND INITIAL LINE TO lt_param ASSIGNING <ls_param>.
<ls_param>-name  = 'RETAIN_MANUAL_CONDITIONS'.
<ls_param>-value = abap_true.
TRY.
      lo_entity->execute( iv_method_name = 'Update' it_param = lt_param ).
      lo_bol_core->modify( ).
      lo_bol_trans = lo_bol_core->get_transaction( ).
      lo_bol_trans->save( ).
      lo_bol_trans->commit( ).
      lo_bol_core->reset( EXPORTING iv_include_bal_reset = abap_true ).
    CATCH: cx_crm_genil_model_error cx_crm_bol_meth_exec_failed.
*   Error handling
ENDTRY.





If you want to redetermine the conditions at item level you can use the following BPath: ./BTOrderHeader/BTHeaderPridoc/CondItemSetRel/*$ and loop at the collection executing the method for each entity (CondISet), one nice thing to considerer is the entity CondISet has the attribute ITEM_NO, well don’t let the name confuse you, that’s the item GUID (CRMD_ORDERADM_I-GUID) 😉


Cheers!


Luis

Assigned Tags

      13 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Kavindra Joshi
      Kavindra Joshi

      Luiz ,

      Essentially this code does the same as the "Retain Manual Conditions" . Can we pass other parameters which there in ECC using the BOL relations ? Didn't check but it would be interesting to see if we can or not.

      ~Kavindra

      Author's profile photo Luís Pérez Grau
      Luís Pérez Grau
      Blog Post Author

      Basically you have the options to retain or not. I'm afraid is not so complex as the one you have in ECC 🙁

      Author's profile photo Former Member
      Former Member

      Hello  Luis,

      I  copied and pasted your code.

      I tried to run it in a abap report.

      Each time I got the exception  cx_crm_genil_model_error cx_crm_bol_meth_exec_failed generated. when the following line executes :

      lo_entity->execute( iv_method_name = 'Update' it_param = lt_param ). 


      Have you came across the same issue ?

      Best Regards

      Abdou

      Author's profile photo Luís Pérez Grau
      Luís Pérez Grau
      Blog Post Author

      Nope, did you check if your CRM release matches with mine? I did a copy paste of the code in a local report and worked fine for me 😕

      Author's profile photo Former Member
      Former Member

      Hello Luis,

      many thanks for your fast answer.

      I just check and it seems to nearly match :

      BBPCRM   702    0005    SAPKU70205   BBPCRM
      SAP_ABA   731    0005    SAPKA73105   Cross-Application Component
      SAP_BASIS   731    0005    SAPKB73105  SAP Basis Component
      WEBCUIF   731    0005    SAPK-73105INWEBCUIF SAP Web UI Framework

      It should be ok ?

      Author's profile photo Luís Pérez Grau
      Luís Pérez Grau
      Blog Post Author

      That's weird, the code is exactly the same? did you try it in a local report with just the code?

      Author's profile photo Former Member
      Former Member

      Hello Luis,

      That's what I tried. I created a report Y_ABO_TEST_BOL_004.

      It is always the same line with the execute.

      I looked in the slg1. There was no log. I tried to refresh the price on webui, so I assume it is not authorisation issue.

      REPORT Y_ABO_TEST_BOL_004.
       
      DATA: lt_param TYPE crmt_name_value_pair_tab.
      DATA: lv_error_w TYPE string,
               lv_object_id_w  TYPE string.
      DATA: lo_bol_core  TYPE REF TO cl_crm_bol_core,
               lo_query     TYPE REF TO cl_crm_bol_query_service,
               lo_result    TYPE REF TO if_bol_entity_col,
               lo_entity    TYPE REF TO cl_crm_bol_entity,
               lo_col       TYPE REF TO if_bol_entity_col,
               lo_bol_trans TYPE REF TO if_bol_transaction_context.
      DATA: lv_bpath_query TYPE string.
      FIELD-SYMBOLS: <ls_param>  LIKE LINE OF lt_param.

      lv_object_id_w = '0005018681'.

      lo_bol_core = cl_crm_bol_core=>get_instance( ).
      lo_bol_core->start_up( iv_appl_name = 'ONEORDER' ).
      lo_query = cl_crm_bol_query_service=>get_instance( 'BTQuery1O' ).
      lo_query->set_property( EXPORTING iv_attr_name =   'OBJECT_ID'
                                           iv_value     = lv_object_id_w  ).
      lo_result = lo_query->get_query_result( ).
      TRY.
             IF lo_result->size( ) EQ 0.
      *     Error handling
             ENDIF.
             lo_entity  = lo_result->get_first( ).
             IF lo_entity->lock( ) EQ abap_false.
      *     Error handling
             ENDIF.
           CATCH cx_sy_move_cast_error.
      *   Error handling
      ENDTRY.
      lv_bpath_query  = './BTOrderHeader/BTHeaderPridoc/CondHSetRel/*$'.
      lo_col = lo_entity->get_related_entities_by_bpath( iv_bpath_statement lv_bpath_query ).
      IF lo_col->size( ) EQ 0.
      *  Error handling
      ENDIF.
      lo_entity ?= lo_col->get_first( ).
      CLEAR lt_param.
      APPEND INITIAL LINE TO lt_param ASSIGNING <ls_param>.
      <ls_param>-name  = 'RETAIN_MANUAL_CONDITIONS'.
      <ls_param>-value = abap_true.
      TRY.
             lo_entity->execute( iv_method_name = 'Update' it_param = lt_param ).
             lo_bol_core->modify( ).
             lo_bol_trans = lo_bol_core->get_transaction( ).
             lo_bol_trans->save( ).
             lo_bol_trans->commit( ).
             lo_bol_core->reset( EXPORTING iv_include_bal_reset = abap_true ).
           CATCH: cx_crm_genil_model_error cx_crm_bol_meth_exec_failed.
      *   Error handling
      ENDTRY.

      Author's profile photo Luís Pérez Grau
      Luís Pérez Grau
      Blog Post Author

      Really really weird, I checked your code, it works 🙁 can you put a break point on the class/mehod CL_CRM_CNDSET_GENIL_API_IF->IF_GENIL_APPL_INTLAY~EXECUTE_OBJECT_METHOD  and debugg from there, also I would check SU53 just to be sure there's no authority check issue (it would surprise me, but who knows...)

      I also would try redetermine the condition by the standard application, log on on the WebUI go to one sales order detail and from there on the conditions assignment block push the redetermine conditions retaining manual ones, it's very important you perform those steps on the WebUI, if you do it on SAP GUI the standard code executed won't be the "same" as mine.

      Author's profile photo Former Member
      Former Member

      Hello Luis,

      I don't know this reason why but today the same code is working 😆

      Thank you so much !!!!

      Best Regards

      Abdou

      Author's profile photo Former Member
      Former Member

      Hello Luis,

      It's indeed very interesting way of using BOL for this and I wish I could have come across this blog before. I had similar requirement for mass price re determination and I used CRM_ORDER_MAINTAIN to achieve this.

      Author's profile photo Luís Pérez Grau
      Luís Pérez Grau
      Blog Post Author

      Thanks for you feedback, maybe you can write a blog about how to archieve the same using the CRM_ORDER_MAINAIN, I believe another approach is allways welcome 🙂

      Author's profile photo Former Member
      Former Member

      Sure Luiz!! I would love to do that. 🙂

      Author's profile photo Former Member
      Former Member

      Hi,

      I am trying to change the pricing condition of an item, from a custom button on header overview page.

      With the help your blog I could get the item CONDSET, could you help me with the bol query for CONDLINE.