Wednesday, 23 May 2018

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.

SAP ABAP Development, SAP ABAP Learning, SAP ABAP Tutorials and Materials

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.

1 comment: