Skip to Content
Author's profile photo Aditya Manideep Gunda

Addition & Deletion of Component in a Production Order

We are all well familiarize with creation of Production order and doing the modification of the existing operation and components. But what if we have a case where we need to delete the existing components and add a component into the given Production.

Generally we do addition or deletion of components by going to CO02 transaction and then to component overview and do the operation. But what if we need to do it from program level.

The below code snippets can be used to create order, delete the existing components and add a new component and later release the production order.

Creation of Order:

For creating a Production order BAPI_PRODORD_CREATE can be used. And it can be used as shown by below code snippet.

*** Production Order Creation
DATA: ls_orderdata    TYPE bapi_pp_order_create,
      ls_return       TYPE bapiret2,
      lv_order_number TYPE bapi_order_key-order_number,
      lv_order_type   TYPE bapi_order_copy-order_type.

* Assign data to BAPI Header to create Production order
ls_orderdata-material = '000000000000000001'.
ls_orderdata-plant = '0001'.
ls_orderdata-order_type = 'PP01'.

ls_orderdata-basic_start_date = sy-datum.
ls_orderdata-basic_start_time = sy-uzeit.
ls_orderdata-basic_end_date = sy-datum.
ls_orderdata-basic_end_time = sy-uzeit.
ls_orderdata-quantity = 1.
CALL FUNCTION 'UNIT_OF_MEASURE_ISO_TO_SAP'
  EXPORTING
    iso_code  = 'PCE'
  IMPORTING
    sap_code  = ls_orderdata-quantity_uom
  EXCEPTIONS
    not_found = 1
    OTHERS    = 2.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.

IF NOT ls_orderdata IS INITIAL.
* BAPI Create Production Order
  CALL FUNCTION 'BAPI_PRODORD_CREATE'
    EXPORTING
      orderdata    = ls_orderdata
    IMPORTING
      return       = ls_return
      order_number = lv_order_number
      order_type   = lv_order_type.
  IF ( ls_return-type = 'S' OR
       ls_return-type = 'I' OR
       ls_return-type = 'W' ) OR
       ls_return IS INITIAL.
* Commit data
    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'.
  ELSE.
* Data Rollback
    CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
  ENDIF.
ENDIF.

 

Deletion of components from Production order:

After creation of production order, the components are fetched from the BOM of the order material. And if we want to delete the particular component or all the components, then it can be done by use of CO_XT_COMPONENT_DELETE function module as shown in the below code snippet. The above mentioned function module is followed by two other function modules to commit the changes and to initialize all other tables required during processing which are CO_XT_ORDER_PREPARE_COMMIT and CO_XT_ORDER_INITIALIZE.

*** Deleting Components from Production Order

DATA: lt_resbkeys TYPE coxt_t_resbdel,
      lt_return   TYPE STANDARD TABLE OF bapiret2,
      lv_error    TYPE flag.

* Fetch existing components of given Production Order
SELECT rsnum, rspos INTO TABLE @DATA(lt_resb)
                    FROM resb
                    WHERE aufnr = @lv_order_number.  " Previously created order
IF sy-subrc EQ 0.
  lt_resbkeys = CORRESPONDING #( lt_resb ).
ENDIF.

IF NOT lt_resbkeys[] IS INITIAL.
* BAPI to delete the components of Production Order
  CALL FUNCTION 'CO_XT_COMPONENTS_DELETE'
    EXPORTING
      it_resbkeys_to_delete = lt_resbkeys
    IMPORTING
      e_error_occurred      = lv_error
    TABLES
      ct_bapireturn         = lt_return
    EXCEPTIONS
      delete_failed         = 1
      OTHERS                = 2.
  IF lv_error = space.
    CALL FUNCTION 'CO_XT_ORDER_PREPARE_COMMIT'
      IMPORTING
        es_bapireturn    = ls_return
        e_error_occurred = lv_error.
    IF ( ls_return-type = 'S' OR
         ls_return-type = 'W' OR
         ls_return-type = 'I' ) OR
         ls_return IS INITIAL.
      CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'.
      CALL FUNCTION 'CO_XT_ORDER_INITIALIZE'.
    ELSE.
      CLEAR: lv_error,
             ls_return.
      CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
    ENDIF.
  ELSE.
    CLEAR lv_error.
    CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
  ENDIF.
ENDIF.

 

Addition of components to Production Order:

In case we need to add components to a production order, it can be done by use of CO_XT_COMPONENT_ADD function module. And it can be used as shown in the below code snippet. The above mentioned function module is followed by two other function modules to commit the changes and to initialize all other tables required during processing which are CO_XT_ORDER_PREPARE_COMMIT and CO_XT_ORDER_INITIALIZE.

But by using the above function module, we have a small issue viz. the item number will be missing in the added component. This is due to incompatible types of I_POSNO (parameter in the function moduleI) and RESB-POSNR.

So in order to solve the issue we shall be modifying the POSNR via assigning it to the internal table before DB update so as to correct the blank item number in components.

*** Adding components to Production Order

DATA: ls_storage_location  TYPE coxt_s_storage_location,
      ls_storage_locationx TYPE coxt_s_storage_locationx,
      ls_requ_quan         TYPE coxt_s_quantity,
      lv_operation         TYPE co_aplzl,
      lv_batch             TYPE coxt_batch,
      lv_batchx            TYPE coxt_batchx,
      lv_postp             TYPE postp,
      lv_sequence          TYPE plnfolge,
      lv_material          TYPE matnr,
      lv_positionno        TYPE positionno,
      lv_numc              TYPE numc4.

TYPES: BEGIN OF ty_resb_bt.
    INCLUDE TYPE resbb.
TYPES: indold     TYPE syst_tabix.
TYPES: no_req_upd TYPE syst_datar.
TYPES: END OF ty_resb_bt.

TYPES tt_resb_bt TYPE TABLE OF ty_resb_bt.

FIELD-SYMBOLS: <ft_resb_bt> TYPE tt_resb_bt,
               <fs_resb_bt> TYPE ty_resb_bt.

ls_storage_location-werks = '0001'.
ls_storage_locationx-werks = 'X'.

ls_storage_location-lgort = 'LGOT'.
ls_storage_locationx-lgort = 'X'.

lv_batch = '0000000001'.
lv_batchx = 'X'.

ls_requ_quan-quantity = 1.
CALL FUNCTION 'UNIT_OF_MEASURE_ISO_TO_SAP'
  EXPORTING
    iso_code  = 'PCE'
  IMPORTING
    sap_code  = ls_requ_quan-uom
  EXCEPTIONS
    not_found = 1
    OTHERS    = 2.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.

lv_positionno = '0010'.
lv_postp = 'L'.
lv_material = '000000000000000002'.

SELECT SINGLE aufnr, aufpl INTO @DATA(ls_afko)
                               FROM afko
                               WHERE aufnr = @lv_order_number.
IF sy-subrc EQ 0.
* Fetch operation to which it has to be assigned
  SELECT SINGLE aufpl, aplzl, plnfl INTO @DATA(ls_afvc)
                                    FROM afvc
                                    WHERE aufpl = @ls_afko-aufpl.
  IF sy-subrc EQ 0.
    lv_operation = ls_afvc-aplzl.
    lv_sequence = ls_afvc-plnfl.
  ENDIF.
ENDIF.

* BAPI to add components to Production Order
CALL FUNCTION 'CO_XT_COMPONENT_ADD'
  EXPORTING
    is_order_key         = lv_order_number
    i_material           = lv_material
    is_requ_quan         = ls_requ_quan
    i_operation          = lv_operation
    i_sequence           = lv_sequence
    is_storage_location  = ls_storage_location
    is_storage_locationx = ls_storage_locationx
    i_batch              = lv_batch
    i_batchx             = lv_batchx
    i_postp              = lv_postp
    i_posno              = lv_positionno
  IMPORTING
    es_bapireturn        = ls_return
    e_error_occurred     = lv_error.
IF lv_error = space.
  CLEAR: lv_numc,
         ls_return.

* Modify POSNR via ASSIGN before DB update to correct the blank
* item number in Components due to incompatible types of I_POSNO
* (type CIF_R3RES-POSITIONNO) and RESB-POSNR
  ASSIGN ('(SAPLCOBC)RESB_BT[]') TO <ft_resb_bt>.
  LOOP AT <ft_resb_bt> ASSIGNING <fs_resb_bt>.
    lv_numc = sy-tabix * 10.
    <fs_resb_bt>-posnr = lv_numc.
    CLEAR lv_numc.
  ENDLOOP.

* Commit transaction
  CALL FUNCTION 'CO_XT_ORDER_PREPARE_COMMIT'
    IMPORTING
      es_bapireturn    = ls_return
      e_error_occurred = lv_error.

  IF ( ls_return-type = 'S' OR
     ls_return-type = 'W' OR
     ls_return-type = 'I' ) OR
     ls_return IS INITIAL.
* Commit data
    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'.
    CALL FUNCTION 'CO_XT_ORDER_INITIALIZE'.
  ELSE.
    CLEAR: lv_error,
           ls_return.
* Data Rollback
    CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
  ENDIF.
ELSE.
  CLEAR: lv_error,
         ls_return.
* Data Rollback
  CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
ENDIF.

 

Release Production Order:

Once the order is created it can be released by the below code snippet.

*** Release Created Production Order
DATA: lt_order TYPE STANDARD TABLE OF bapi_order_key,
      ls_order TYPE bapi_order_key.

SELECT SINGLE a~aufnr, a~objnr, b~stat INTO @DATA(ls_aufk)
                                       FROM aufk AS a
                                       INNER JOIN jest AS b
                                       ON a~objnr = b~objnr
                                       WHERE a~aufnr = @lv_order_number
                                         AND b~stat = 'I0002'
                                         AND b~inact = @space.
IF sy-subrc NE 0.
  ls_order-order_number = lv_order_number.
* If production order is not released then append the order to table
* LT_ORDER to release the order
  APPEND ls_order TO lt_order.
  CLEAR ls_order.
ENDIF.

IF NOT lt_order[] IS INITIAL.
  CLEAR ls_return.
* Release Production order
  CALL FUNCTION 'BAPI_PRODORD_RELEASE'
    IMPORTING
      return = ls_return
    TABLES
      orders = lt_order.
  IF ( ls_return-type = 'S' OR
       ls_return-type = 'W' OR
       ls_return-type = 'I' ) OR
       ls_return IS INITIAL.
    CLEAR ls_return.
* Commit Data
    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'.
  ELSE.
* Data Rollback
    CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
    CLEAR ls_return.
  ENDIF.
ENDIF.

 

And for changing the existing components, we can use CO_XT_COMPONENT_CHANGE function module followed by two other function module to commit the changes and to initialize all other tables required during processing which are CO_XT_ORDER_PREPARE_COMMIT and CO_XT_ORDER_INITIALIZE.

Assigned Tags

      11 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Dominik Ritter
      Dominik Ritter

      Hello,

      thanks for sharing your apporach.

      One comment: CO_XT_COMPONENT_CHANGE / CO_XT_COMPONENT_ADD is not a BAPI. These are regular function modules which are not released by SAP.

      Author's profile photo Aditya Manideep Gunda
      Aditya Manideep Gunda
      Blog Post Author

      Thanks Dominik for pointing it out. Yes you are right!!

       

      Author's profile photo Gokul RADHAKRISHNAN
      Gokul RADHAKRISHNAN

      Good blog Aditya. Very informative & useful.

      Author's profile photo Anoop S E
      Anoop S E

      Thanks for sharing Aditya..:)

       

      Author's profile photo Christophe CAPARROS
      Christophe CAPARROS

      Thanks for sharing Aditya.

      Until now we are using a Call Transaction 'CO02' to change or delete the production order components which is not always robust solution. Next time we'll use your approach 🙂

       

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva

      Thanks for sharing! I think it'll be helpful to many. Not sure why but PP seems to be not very rich with APIs. Really sad that we have to resort to non-released FMs that SAP tells us not to use but provides no better alternatives.

      Of course, changing components in PO should be rather an exception and perhaps SAP is thinking it'd happen so seldom that CO02 would suffice. Maybe this works in a vacuum somewhere. 🙂

      Just a small note: instead of multiple OR... like this:

          IF ( ls_return-type = 'S' OR
               ls_return-type = 'W' OR
               ls_return-type = 'I' ) 

      we can just do

      IF ls_return-type CA 'SWI'.

      or even something more advanced.

      Author's profile photo Aditya Manideep Gunda
      Aditya Manideep Gunda
      Blog Post Author

      Thanks Jelena for your feedback. And the note will be useful as mentioned.

      Author's profile photo Manuel Rodríguez
      Manuel Rodríguez

      Thanks for the info!

      Just a question about storage location determination: as per SAP note 137225, there is a standard logic for that. That means SAP in its deeps have a logic to determine the storage location suggestion for production order components. Do you know if this logic is available in a FM/BAPI?

       

      Author's profile photo Anil Kumar Aleti
      Anil Kumar Aleti

      We are dealing with a situation where non-stock item category materials need to be added. For example, a DIEN material type component needs to be added with item category "N". That gives us troubles for getting the item number (POSNR) right...we are sorting it out. For regular items of item cat "L" there is no issue. This FM works just fine.

      Author's profile photo Neil Cao
      Neil Cao

      An exception occurred to CO_XT_COMPONENTS_DELETE, but directly testing the CO_XT_COMPONENTS_DELETE function in SE37 will jump to an order settlement rule interface, and then publish as a remote call function will report a Web service exception error. How should I deal with this

      Author's profile photo Patrick Weber
      Patrick Weber

      Thank you so much, exactly what I was looking for. Still valid under S/4