Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
adityamani369
Explorer
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.
13 Comments
dominik_ritter
Explorer
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.
adityamani369
Explorer
0 Kudos
Thanks Dominik for pointing it out. Yes you are right!!

 
gokul_radhakrishnan3
Active Participant
Good blog Aditya. Very informative & useful.
Thanks for sharing Aditya..:)

 
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 🙂

 
Jelena
Active Contributor
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.
adityamani369
Explorer
0 Kudos
Thanks Jelena for your feedback. And the note will be useful as mentioned.
Former Member
0 Kudos
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?

 
former_member412
Participant
0 Kudos
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.
0 Kudos
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
patrick_weber11
Participant
0 Kudos
Thank you so much, exactly what I was looking for. Still valid under S/4
5352119c
Employee
Employee
0 Kudos
hello,

thanks for the blog, it helps a lot, but here is a question.

when I use the function CO_XT_COMPONENT_ADD insert a component which is set as 'phantom assembly',  why just added itself ,not bring other related components automatically, actually, those related components will be added by T-code 'CO02' . The function is not supported?

thanks

jiaxin
Pritam
Explorer
0 Kudos

Hi All,

I am using the above function module to add components to production order in co02. We have a custom tab to extract components from a custom table, when click on the extract button then multiple components is added to production order(we are not deleting any components, just adding couple of additional components). Sometime it is working fine but I am getting a dump error regularly.

Category ABAP Programming Error
Runtime Errors DBSQL_DUPLICATE_KEY_ERROR
Except. CX_SY_OPEN_SQL_DB
ABAP Program SAPLCOVB
Application Component PP-SFC

Error analysis
An exception has occurred which is explained in more detail below. The
exception is assigned to class 'CX_SY_OPEN_SQL_DB' and was not caught in
procedure
"RESB_POST" "(FORM)", nor was it propagated by a RAISING clause.
Since the caller of the procedure could not have anticipated this
exception, the current program was terminated.
The reason for the exception is:
When an Open SQL array insert is performed, trying to insert a record
into the database table "RESB" causes the function to terminate if a
record with the same key already exists.

(When an Open SQL individual record insert is performed, this situation
does not cause the function to terminate. SY-SUBRC is set to 4 instead.)

kindly let me know if you have any solution for this.

Labels in this area