The blog talks about handling old / Pos which may no longer be needed and have to be Transaction Completed .
This is a step before actually archiving the POs and contracts. So basically the business should first be Transaction completing them if there is no more GR and Invoice expected and letter archiving them as needed. The details mentioned here are related to mass transaction complete and change the status of the PO/ Contracts from backend via an ABAP report .
This however is possible to do via front-end by just clicking on the complete button.
The reason for doing transaction completed can be many from an operational perspective
- You need to ensure no one is using those POs as they are already Gr’d and invoiced
- Lets consider an example where these POs are linked to the contract. The contract value was 10000 USD and PO value was of 1000 USD. The remaining contract amount available after the PO is ordered is 9000 USD. However if the PO was actually on Gr’d for 500 USD it should return back the 500 USD balance amount. This happens when we transaction complete the PO. So the amount left to use in contract after the PO is transaction completed would be 9500 USD. This is a best practice to ensure you make use of contracts efficiently.
- The program I created can be made as a batch job to see if a PO has not been updated for last 1 year or the requester/recipient is no longer available and no one else has been identified to take its ownership and is lying with the admin team it should just be transaction completed.
- It helps a lot in reporting making the reports look better as well as ensure you are able to forecast the expected invoice and balance amount in a much better way
- The reason for doing this via a program code is also the reason that these are Old Pos and if you try to transaction complete them from the backend they will have errors in terms of WBS being locked, users who have left the org and these checks needs to be fixed before you can actually ‘Transaction complete’ it from the portal. If however we do as a batch program it skips those checks and is easier to close off these POs without wasting time on trying to fix the data errors
Now that we discussed transaction completed there may be a case where you need to make changes in a PO which was either manually transaction completed incorrectly or was incorrectly updated by the batch job or was put on hold for sometime but is needed again. So to handle such a case I also created another program to update the table entries to change the status of the PO from being transaction completed to change back to ordered status.
Pl find details about how the solution was implemented.
Transaction completed status is ‘I1023’
Call Function Module ‘BBP_PD_PO_GETDETAIL’ ” To read the details of the PO
Ensure you read the version correctly if the PO has been ordered multiple times there will be change version of the. Check if a change version exists if yes then use GUID for change version of PO
IF SY-SUBRC EQ 0. p_guid = ls_version-guid. ELSe. p_guid = ls_header-GUID . ENDIF.
Call the below function module again with the p_guid of the latest version you found above
'BBP_PROCDOC_GETDETAIL' IF sy-subrc eq 0 . " lv_object_type EQ /sapsrm/if_pdo_obj_types_c=>GC_PDO_PO. READ TABLE lt_status1 TRANSPORTING NO FIELDS WITH KEY stat = /sapsrm/if_pdo_status_c=>GC_PDO_ORDERED inact = ' '. IF sy-subrc NE 0. lv_not_ordered = 'X' . ENDIF. READ TABLE lt_status1 TRANSPORTING NO FIELDS WITH KEY stat = /sapsrm/if_pdo_status_c=>GC_PDO_CLOSED inact = ' '. IF sy-subrc EQ 0. lv_tc = 'X' . ENDIF. ENDIF.
Ensure the Po is not Awaiting approval or transaction completed already
if lv_not_ordered is not initial or lv_tc is not INITIAL. * MESSAGE i047(bbp_pd) WITH text-001. "Transaction completed only for status ordered ls_po_error = ls_po. APPEND ls_po_error to lt_po_error. CONTINUE. ENDIF.
If the PO is in the right status of Ordered proceed with the change of status and Don’t forget to call Commit FM. Also note in SRM you need to update the Final_entry and Final_inv indicator which will update the delivery completion indicator in the ECC system
'BBP_PROCDOC_STATUS_CHANGE_DIRE' select * from bbp_pdigp INTO table lt_pdigp for ALL ENTRIES IN lt_guid_pdigp where guid = lt_guid_pdigp-guid. UPDATE bbp_pdigp SET Final_inv = 'X' final_entry = 'X' WHERE guid = ls_pdigp-guid. CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
You may also want to use the class /sapsrm/cl_pdo_bo_po and method /sapsrm/if_pdo_bo_po~complete_po to be able to complete the PO
This is the same class and method which is called when you click on Complete PO from the portal side. There is however a lot of buffer data it calls from the portal execution and hence you may need to copy the actual code and the FM instead of calling the class directly.
Somewhere inside the class it also checks for Value and Qty of invoice. This was not part of my business requirement so I haven’t really used this logic.
->/sapsrm/if_pdo_bo_po~get_flwondoc_totval ** if sy-subrc = 0. ** lv_conf_val = ls_actval-val_cf_e. ** lv_conf_qty = ls_actval-quan_cf_e. ** lv_inv_val = ls_actval-val_iv_e. ** lv_inv_qty = ls_actval-quan_iv_e.
When you do transaction complete it will be nice to do a check to ensure
- Delivery completed Flag has been ticked for the PO
- User is not able to do any more GR for the PO
- Status on the portal has changed to Transaction completed
Reverse transaction Complete
Now , coming to the next part is to make changes to reverse the already existing Transaction completed POs and make its status as Ordered again. Pass GUID to get the status
CALL FUNCTION ‘CRM_STATUS_READ_MULTI’
objnr_tab = lt_obj
status = lt_status.
* remove status which are not in scope based on Global parameter values
DELETE lt_status WHERE stat NOT IN lr_stat. “i,e check transaction completed status exists and delete all the others
CALL FUNCTION ‘CRM_STATUS_UPDATE’
no_workflows = ‘X’
jest_ins = lt_jest_ins “not filled
jest_upd = lt_jest_upd “filled with the status you need
jsto_ins = lt_jsto_ins “not filled
jsto_upd = lt_jsto_upd “not filled
obj_del = lt_obj_del. “not filled
COMMIT WORK AND WAIT.
Ensure you get the updated status again to ensure that the work has been completed successfully/.
CALL FUNCTION ‘CRM_STATUS_BUFFER_REFRESH’.
* get updated status of all objects AFTER the reset
REFRESH: lt_jcds, lt_status.
CALL FUNCTION ‘CRM_STATUS_READ_MULTI’
only_active = ‘X’
get_change_documents = ‘X’
objnr_tab = pt_obj
status = lt_status
jcds_tab = lt_jcds.
With this now the PO would again open up and you can place an order and create a change version or be able to do GR for the PO.
That’s it on this blog.
Hope I have been able to help those using SRM and trying to handle the transaction completion status of the POs.
I also took some help from the below links
Thanks for taking time to read my blog and please let me know if you have some comments or other ways on how you have handled a similar scenario