Skip to Content
Author's profile photo Sankara Bhatta

Update PO using BBP_PD_PO_UPDATE and trigger Process controlled workflow

In this blog I am going to talk about how to change an existing PO using function modules and also trigger process controlled workflow that is set up for purchase order. The reason why I am specifically mentioning the workflow is the FMs that we are going to use to update POs do not trigger process controlled workflow. they only work for application controlled workflow. For process controlled workflow, we need to explicitly trigger the workflow by mimicking the ORDER process from WebUI.

Below is the code snippet for changing / adding new items to an existing PO

– First get the PO details using BBP_PD_PO_GETDETAIL

DATA: ls_header_p TYPE bbp_pds_header,

          ls_header_new_p TYPE bbp_pds_header.

<code>

CALL FUNCTION ‘BBP_PD_PO_GETDETAIL’

    EXPORTING

      i_guid            = lv_h_guid

      i_attach_with_doc = ‘ ‘

      i_with_itemdata  = ‘X’

      i_read_be_data    = ‘ ‘

    IMPORTING

      e_header          = ls_header_d

    TABLES

      e_item            = lt_item_d

      e_account        = lt_account_d

      e_partner        = lt_partner_d

      e_longtext        = lt_longtext_d

      e_limit          = lt_limit_d

      e_pridoc          = lt_pridoc_d

      e_orgdata        = lt_orgdata_d.


</code>

If we are changing an active version then we have to first create a change version guid. This guid will be used as ‘parent guid’ for all the items that we are going to change or new items that we are going to add


IF ls_header_dversion_type NE ‘C’.


*Create a change version


    MOVE-CORRESPONDING ls_header_d TO ls_header_p.


    ls_header_pobject_type = ‘BUS2201’.


    CALL FUNCTION ‘BBP_PROCDOC_UPDATE’

      EXPORTING

        iv_create_change_version = ‘X’

        i_header                = ls_header_p

      IMPORTING

        es_header                = ls_header_new_p

      TABLES

        e_messages              = lt_pd_messages

      CHANGING

        e_changed                = lv_changed.


*Move the new change version guid to header data

    ls_header_uguid = ls_header_new_pguid.

endif.


Now for changing an existing item we will first move the data from PD_PO_GETDETAIL to corresponding update structures

MOVE-CORRESPONDING ls_item_d TO ls_item_c.


Then we change the data that we want to change. for example quantity


  ls_item_dquantity  =  ’40’.


After that we will replace the parent guid with the new change version guid. Please note we have to do this if we are changing an active version. If we are changing an existing change version, we don’t have to do this.


      IF ls_header_dversion_type NE ‘C’.

        ls_item_cparent = ls_header_uguid.

      ENDIF.

For adding a new item we will populate the item structure will all the required data like below

ls_new_itemnumber_int            = ls_po_item_additem_number  .

    ls_new_itemdescription          = ls_po_item_adddescription .

    ls_new_itemprice                = ls_po_item_addprice.

    ls_new_itemquantity              = ls_po_item_addquantity.

    …………                                      = ………………………..


The GUID field should be populated with number_int like below

ls_new_itemguid                  = lv_item_number.   “ Pass new item number into GUID field

If we are adding new items in active version then parent field should be populated with new change version guid created above using BBP_PD_PO_UPDATE

    IF ls_header_dversion_type NE ‘C’.

      ls_new_itemparent  = ls_header_uguid.

    ENDIF.


for populating accounting data, partner data, pricing data and org data fro the new item, fill in number_int in P_GUID field and DO NOT fill anything in GUID field.


Example :


LOOP AT lt_account_d  INTO ls_account_d .

      MOVE-CORRESPONDING ls_account_d TO ls_account_c.

      CLEAR ls_account_cguid.

      MOVE ls_new_itemguid TO ls_account_cp_guid.   ” ls_new_item-guid contains new item number here

      APPEND ls_account_c TO lt_account_c.

    ENDLOOP.


After you have everything ready, call BBP_PD_PO_UPDTATE as shown below


call with i_park and i_save as space


CALL FUNCTION ‘BBP_PD_PO_UPDATE’

      EXPORTING

        i_park    = ‘ ‘

        i_save    = ‘ ‘

        i_header  = ls_header_u

      IMPORTING

        e_changed  = lv_changed

      TABLES

        i_item    = lt_item_c

        i_account  = lt_account_c

        i_partner  = lt_partner_c

        i_longtext = lt_longtext_c

        i_orgdata  = lt_orgdata_c

        i_limit    = lt_limit_c

        i_pridoc  = lt_pridoc_c

        e_messages = lt_pd_messages.


in general, after this we call BBP_PD_PO_SAVE FM and do COMMIT WORK, but we don’t use BBP_PD_PO_SAVE here as it does not trigger process controlled workflow. So from this point on wards we have to follow SRM7 approach of ordering the PO.


*Now order the PO in display mode by using OO based concept.

   TRY.

*Get instance of change version PO

       CALL METHOD /sapsrm/cl_pdo_bo_po_adv=>get_po_adv_instance

         EXPORTING

           iv_header_guid  = ls_header_uguid

           iv_mode         = ‘DISPLAY’

           iv_wiid         = lv_wiid

           iv_process_type = ‘ECPO’

           iv_user_id      = lv_user_id

         RECEIVING

           ro_instance     = lo_po_instance.

*Do a check

       CALL METHOD lo_po_instance->/sapsrm/if_pdo_base~check

         CHANGING

           co_message_handler = lo_message_handler.

*Order the PO which is in HELD status

       CALL METHOD lo_po_instance->/sapsrm/if_pdo_bo_po~order

         CHANGING

           co_message_handler = lo_message_handler.

*read the messages

       CALL METHOD lo_message_handler->get_messages

         IMPORTING

           et_messages = lt_messages_class.

       COMMIT WORK.

     CATCH /sapsrm/cx_pdo_wf_mode_ban

      /sapsrm/cx_pdo_wrong_bus_type

      /sapsrm/cx_pdo_pd_read_error

      /sapsrm/cx_pdo_lock_failed

      /sapsrm/cx_pdo_no_authorizatio

      /sapsrm/cx_pdo_parameter_error

      /sapsrm/cx_pdo_status_error

      /sapsrm/cx_pdo_incons_user

     /sapsrm/cx_pdo_error

      /sapsrm/cx_pdo_unlock_error

      /sapsrm/cx_pdo_abort

      /sapsrm/cx_wf_abort

      /sapsrm/cx_wf_error INTO lo_root.

* read the exception message

       lv_msg = lo_root->get_text( ).

   ENDTRY.

Have a nice day and keep blogging 🙂 🙂

Thanks,

sankar.

Assigned Tags

      11 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Flavio Machado Barbosa Neto
      Flavio Machado Barbosa Neto

      Also works for PO with hierarchy?

      Author's profile photo Sankara Bhatta
      Sankara Bhatta
      Blog Post Author

      Not 100% sure.. but most probably should work with some changes.

      Author's profile photo Mohit Kumar
      Mohit Kumar

      Hi Sankara,

      When you are fetching an instance of change version, which user ID is passed to the factory class? (iv_user_id      = lv_user_id) and what is its relevance?

      I am unable to get the instance of a PO change version , it throws an exception and the text says "The attributes for user <my user ID> could not be determined" ( /sapsrm/cx_pdo_abort is the exception class).

      I am passing iv_header_guid = HEADER GUID of changed PO

      iv_mode                        = 'DISPLAY'  and iv_process_type                = 'ECPO'

      Please help.

      Mohit

      Author's profile photo Sankara Bhatta
      Sankara Bhatta
      Blog Post Author

      I don't remember exactly. just pass a blank value. it is a obligatory parameter that we need to pass

      Author's profile photo Mohit Kumar
      Mohit Kumar

      Thanks for your reply, I passed user ID of PO creator hence I am able to access the instance now. This issue might have happened due to my user ID authorization (PO access).

      Author's profile photo Former Member
      Former Member

      Hi Sankara,

      I'm new to SRM. I have a requirement that when a PO is modified, specifically a new line item is added, I should provide checking for its account details. Can you tell me, during runtime, how do I know that a new line item is added to an existing PO?

      Author's profile photo Mohit Kumar
      Mohit Kumar

      Hi Melanie,

      When you make any changes to the SRM doc, BBP_DOC_CHANGE_BADI badi gets triggered, in your case the filter would be BUS2201 (business object for purchase order). Please check if the said BADI is implemented in your system for your business object. Please check BBP_PO_CHANGE method which will have parameter IT_ITEM filled in with the newly added line items, also, you will get account assignment details too in IT_ACC table. Now you will need to have another class for which you can have static attributes as item data and account data which you need to set in BBP_DOC_CHANGE_BADI  badi implementation with the IT_ITEM AND IT_ACC values. You may use these set static attributes in BBP_DOC_CHECK_BADI to do validations as per your requirements.

      I hope this helps.

      Author's profile photo Former Member
      Former Member

      Hi Mohit Kumar,

      Thank you for your help. I'm beginning to understand it better now.

      Author's profile photo Former Member
      Former Member

      Hi Sankara,

      When I am using update FM, change version is getting created without item for limit PO, its working fine for material and service PO. I am new to ABAP, you can ask for details if my question is not clear.

      Author's profile photo Former Member
      Former Member

      Hi Sankara,

      When I am using update FM, change version is getting created without item for limit PO, its working fine for material and service PO. I am new to ABAP, you can ask for details if my question is not clear.

      Author's profile photo Dayal Roy
      Dayal Roy

      Hi Sankara,

       

      How are you ?

       

      thanks for the blogs. do you remember  during calling

       CALL METHOD /sapsrm/cl_pdo_bo_po_adv=>get_po_adv_instance

      iv_wiid         = lv_wiid

       

      how to get value lv_wiid ?

       

      regards

       

      dayal

       

       

       

       

       

       

       

       

       

       

      how you pass