4 Replies Latest reply: Nov 23, 2013 8:08 AM by Aadish Yadav RSS

BAPI_PO_CHANGE change price of service

Wil V
Currently Being Moderated

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

  • Re: BAPI_PO_CHANGE change price of service
    ANIRUT WORAKITRUNGRUANG
    Currently Being Moderated

    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.

    • Re: BAPI_PO_CHANGE change price of service
      Wil V
      Currently Being Moderated

      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.

      • Re: BAPI_PO_CHANGE change price of service
        Wil V
        Currently Being Moderated

        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.

         

  • Re: BAPI_PO_CHANGE change price of service
    Aadish Yadav
    Currently Being Moderated

    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.

Actions