
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_d-version_type NE 'C'.
*Create a change version
MOVE-CORRESPONDING ls_header_d TO ls_header_p.
ls_header_p-object_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_u-guid = ls_header_new_p-guid.
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_d-quantity = '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_d-version_type NE 'C'.
ls_item_c-parent = ls_header_u-guid.
ENDIF.
For adding a new item we will populate the item structure will all the required data like below
ls_new_item-number_int = ls_po_item_add-item_number .
ls_new_item-description = ls_po_item_add-description .
ls_new_item-price = ls_po_item_add-price.
ls_new_item-quantity = ls_po_item_add-quantity.
............ = .............................
The GUID field should be populated with number_int like below
ls_new_item-guid = 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_d-version_type NE 'C'.
ls_new_item-parent = ls_header_u-guid.
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_c-guid.
MOVE ls_new_item-guid TO ls_account_c-p_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_u-guid
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 :smile: :smile:
Thanks,
sankar.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.