04-15-2011 4:35 PM
Hi,
I am trying to update the price of a service irem using BAPI_PO_CHANGE and BAPI_PO_GETDETAIL1. The issue im having is for multiple PO's for the first PO the price updates as expected but on the next loop pass for the second PO the BAPI_PO_CHANGE is returning error message ''Instance 4330000362 of object type purchase order could not be changed" and "Please specify a valid account assignment". If I run the program with this same PO ONLY, the same one that is failing on the second loop pass it updates the price as expected.
I compared the contents of the internal tables poitem, poitemx and i_services just before te call of bapi_po_change when I run the program with 1 PO (Result as expected) and when I run the program with 2 PO's. The contents of the internal tables for the same PO is the same its just returning errors on the second loop pass.
In other words. The input for the bapi is the same but the bapi returns errors when I run the program with more than one PO.
All the internal tables get cleared after the first loop pass so I dont think is a clear refresh issue. Below is my code, te issue is happening in the call of bapi below comment "* Call bapi to change the gross price." Please advice me on this.
FIELD-SYMBOLS: <fs_po> LIKE LINE OF i_poitem,
<fs_k_serv> LIKE LINE OF i_services.
* Get PO details
CALL FUNCTION 'BAPI_PO_GETDETAIL1'
EXPORTING
purchaseorder = pk_po-ebeln
services = c_x
TABLES
return = i_return
poitem = i_poitem
poservices = i_services.
SORT i_return BY type.
READ TABLE i_return INTO k_return WITH KEY type = c_e BINARY SEARCH.
IF sy-subrc <> 0.
LOOP AT i_poitem ASSIGNING <fs_po>.
* If PO is locked clear deletion indicator to unlock it.
IF <fs_po>-delete_ind = c_l.
CLEAR <fs_po>-delete_ind.
ENDIF.
k_poitemx-po_item = <fs_po>-po_item.
k_poitemx-delete_ind = c_x.
APPEND k_poitemx TO i_poitemx.
CLEAR k_poitemx.
ENDLOOP.
UNASSIGN <fs_po>.
CLEAR i_return.
* Unlock PO
CALL FUNCTION 'BAPI_PO_CHANGE'
EXPORTING
purchaseorder = pk_po-ebeln
TABLES
return = i_return
poitem = i_poitem
poitemx = i_poitemx.
SORT i_return BY type.
READ TABLE i_return INTO k_return WITH KEY type = c_e BINARY SEARCH.
IF sy-subrc <> 0.
* Commit changes to DB.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = c_x.
* No sy-subrc check required.
* Modify the gross price of the services
LOOP AT i_services ASSIGNING <fs_k_serv>.
<fs_k_serv>-gr_price = pk_po-ucost.
* In order to set the price the deletion indicator must be cleared.
CLEAR <fs_k_serv>-delete_ind.
ENDLOOP.
UNASSIGN <fs_k_serv>.
CLEAR i_return.
* Call bapi to change the gross price.
CALL FUNCTION 'BAPI_PO_CHANGE'
EXPORTING
purchaseorder = pk_po-ebeln
TABLES
return = i_return1 "<----------- Error
poitem = i_poitem
poitemx = i_poitemx
poservices = i_services.
SORT i_return1 BY type.
READ TABLE i_return1 INTO k_return1 WITH KEY type = c_s
BINARY SEARCH TRANSPORTING type message.
IF sy-subrc = 0.
* Commit changes to the DB.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = c_x.
* No sy-subrc check required
.
Edited by: bodyboarder1 on Apr 15, 2011 9:48 PM
04-18-2011 5:16 AM
Is 4330000362 the PO/Service number of the first or second loop pass?
I guess it's likely that the service number is locked.
If that's the case, you'll need to make sure you unlock the service number before you call FM 'BAPI_PO_CHANGE' to change the gross price.
Also, make sure the account assignment number is really valid for that 2nd loop pass.
When you say you checked the contents of the itab for when you run it on its own and when you run it as a second loop pass, did you use the tool in debugger as human eyes may mistakenly work. It's the last tab in debugger named "Diff.". You supply the name of 2 itab variables and press Enter.
How about you hardcode in your program to append 2 records of the same PO to an itab and loop at it to call this logic 2 times. Let's see how it works out.
Good luck.
04-19-2011 8:20 PM
Thanks for your reply.
4330000362 is the PO number for the second loop pass. The same one that updates the price fine if I run the program with this PO only. In the code logic the PO is first gets unlocked before the call of the bapi.
I checked the contents of the data by exporting the files to excell and comparing side by side since the data gets cleared after the end of each loop pass. I will try and compare like you suggested using dif tab.
I think the error might be bad data because the bapi clearly says "Please specify a valid account assignment" although is strange that if I run this PO by its self I don't get any error messages.
I noticed similar behavior when I run transaction ME22N and perform the same steps of BAPI_PO_CHANGE. After I unlock the PO, click on services tab, change the gross price and hit enter I get a new winwow asking for the account asignment info but the fields are not editable, this again only happens after I edit the price in ME22N for any PO after the first one. If I edit the PO on its own I get an iformation message "Please specify a valid account assignment" but I can update the price.
04-26-2011 6:06 PM
I resolved the problem by looping the same table twice. The first loop unlocks the PO item and the second loop changes the price. If I put all the logic into one loop it does not work, I have done some reading and I think it has something to do with the Logical Unit of Work. If anyone has any suggestions please share them.
PARAMETERS: p_grprc TYPE bapigrprice OBLIGATORY.
FIELD-SYMBOLS: <fs_k_po> LIKE LINE OF i_po_items,
<fs_k_serv> LIKE LINE OF i_po_item_services.
k_po-ebeln = '4330000456'.
APPEND k_po TO i_po.
CLEAR k_po.
k_po-ebeln = '4330000369'.
APPEND k_po TO i_po.
CLEAR k_po.
LOOP AT i_po INTO k_po.
CLEAR: i_po_items,
i_po_itemsx,
i_po_item_services,
i_return,
i_poaccount,
i_poaccountx.
REFRESH: i_po_items,
i_po_itemsx,
i_po_item_services,
i_return.
CALL FUNCTION 'BAPI_PO_GETDETAIL1'
EXPORTING
purchaseorder = k_po-ebeln
services = 'X'
TABLES
return = i_return
poitem = i_po_items
poservices = i_po_item_services.
SORT i_return BY type.
READ TABLE i_return INTO k_return WITH KEY type = 'E' BINARY SEARCH.
IF sy-subrc <> 0.
LOOP AT i_po_items ASSIGNING <fs_k_po>.
IF <fs_k_po>-delete_ind = 'L'.
CLEAR <fs_k_po>-delete_ind.
ENDIF.
k_po_itemsx-po_item = <fs_k_po>-po_item.
k_po_itemsx-delete_ind = 'X'.
k_po_itemsx-po_itemx = 'X'.
APPEND k_po_itemsx TO i_po_itemsx.
CLEAR k_po_itemsx.
ENDLOOP.
UNASSIGN <fs_k_po>.
CLEAR i_return.
* Unlock PO item
CALL FUNCTION 'BAPI_PO_CHANGE'
EXPORTING
purchaseorder = k_po-ebeln
TABLES
return = i_return
poitem = i_po_items
poitemx = i_po_itemsx.
SORT i_return BY type.
READ TABLE i_return INTO k_return WITH KEY type = 'E' BINARY SEARCH.
IF sy-subrc <> 0.
* Commit changes to DB.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'.
ENDIF.
ENDIF.
ENDLOOP.
LOOP AT i_po INTO k_po.
CLEAR: i_return, i_po_items, i_po_item_services.
CALL FUNCTION 'BAPI_PO_GETDETAIL1'
EXPORTING
purchaseorder = k_po-ebeln
services = 'X'
TABLES
return = i_return
poitem = i_po_items
poservices = i_po_item_services.
SORT i_return BY type.
READ TABLE i_return INTO k_return WITH KEY type = 'E' BINARY SEARCH.
IF sy-subrc <> 0.
* Change price of item
LOOP AT i_po_item_services ASSIGNING <fs_k_serv>.
<fs_k_serv>-gr_price = p_grprc.
CLEAR <fs_k_serv>-delete_ind.
ENDLOOP.
UNASSIGN <fs_k_serv>.
CLEAR i_return.
* Change price of item
CALL FUNCTION 'BAPI_PO_CHANGE'
EXPORTING
purchaseorder = k_po-ebeln
TABLES
return = i_return
poitem = i_po_items
poitemx = i_po_itemsx
poservices = i_po_item_services.
SORT i_return BY type.
READ TABLE i_return INTO k_return WITH KEY type = 'S'
BINARY SEARCH TRANSPORTING type message.
IF sy-subrc = 0.
* Commit changes to the DB.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'.
* No sy-subrc check required.
LOOP AT i_po_items ASSIGNING <fs_k_po>.
* Set deletion indicator if not set.
IF <fs_k_po>-delete_ind NE 'L'.
<fs_k_po>-delete_ind = 'L'.
ENDIF.
k_po_itemsx-po_item = <fs_k_po>-po_item.
k_po_itemsx-delete_ind = 'X'.
APPEND k_po_itemsx TO i_po_itemsx.
CLEAR k_po_itemsx.
ENDLOOP.
UNASSIGN <fs_k_po>.
CLEAR i_return.
* Set deletion indicator.
CALL FUNCTION 'BAPI_PO_CHANGE'
EXPORTING
purchaseorder = k_po-ebeln
TABLES
return = i_return
poitem = i_po_items
poitemx = i_po_itemsx.
SORT i_return BY type.
READ TABLE i_return INTO k_return WITH KEY type = 'E' BINARY SEARCH.
IF sy-subrc <> 0.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'.
* No sy-subrc check required.
ENDIF.
ENDIF.
ENDIF.
ENDLOOP.
11-23-2013 7:08 AM
BAPI_PO_CHANGE if you want to change something through POSERVICES better get the POSERVICES data through function module
CALL FUNCTION 'BAPI_PO_GETDETAIL1'
EXPORTING
purchaseorder = gs_ebeln-ebeln"pk_po-ebeln
services = c_x
TABLES
return = gt_return
poitem = gt_poitem
poservices = gt_services.
do the manupulations in POSERVICES table and
pass it to
CALL FUNCTION 'BAPI_PO_CHANGE'
EXPORTING
purchaseorder = gs_ebeln-ebeln"pk_po-ebeln
TABLES
return = gt_return1 "<----------- Error
poitem = gt_poitem
poitemx = gt_poitemx
poservices = gt_services.