Create outbound delivery with different shipping address - abap

I've searched for days and found nothing. My problem is, that I have to create a return delivery out of an QM-Report. Everything works fine.
However, the customer wants to change the delivery address manually.
Flow:
QM02 (QM-Report) => Return order with BAPI_PO_CREATE1 (different address works fine) => Delivery with BAPI_OUTB_DELIVERY_CREATE_STO (different address from PO not working)
My question:
Is there a possibility to change the delivery address of the outbound delivery? Do I have to implement a BADI or is there a simple solution?
If anything is missing, I will update the question.

Function BAPI_OUTB_DELIVERY_CREATE_STO allows you to create deliveries from PO but you can't handle many of the delivery fields.
After you have created the deliveries, you should use WS_DELIVERY_UPDATE_2 function to update any field.
This is not a BAPI, and consequently it is not well documented, but is widely used for these changes.
Best regards
UPDATE
Here's a snippet:
ls_vbkok-vbeln_vl = <delivery number>.
ls_partners-vbeln_vl = ls_vbkok-vbeln_vl.
ls_partners-parvw = 'WE'.
ls_partners-parnr = <partner number>.
ls_partners-updkz_par = 'U'.
ls_partners-stras = <new street address>.
append ls_partners to lt_partners.
call function 'WS_DELIVERY_UPDATE_2'
exporting
vbkok_wa = ls_vbkok
synchron = 'X'
commit = 'X'
delivery = ls_vbkok-vbeln_vl
tables
vbpok_tab = lt_vbpok
it_partner_update = lt_partners
prot = lt_prot.
if lt_prot[] is not initial.
" handle error message here
endif.

if you need to make a commit and you can do it after the 'WS_DELIVERY_UPDATE_2' , try to call it in a new task.
for exemple :
call function 'WS_DELIVERY_UPDATE_2' STARTING NEW TASK task
PERFORMING return_fm ON END OF TASK
exporting
vbkok_wa = ls_vbkok
synchron = 'X'
commit = ' '
delivery = ls_vbkok-vbeln_vl
tables
vbpok_tab = lt_vbpok
it_partner_update = lt_partners
prot = lt_prot.
*your code
WAIT UNTIL get_executed <> space.
FORM return_fm USING i_taskname.
*your code
get_executed = 'X'.
ENDFORM.

Related

How to reverse POD status and PGI status?

Can anyone suggest function module to reverse POD status and PGI status?
I used WS_DELIVERY_UPDATE_2 to update POD status and PGI from A or B to C, but how to reverse it?
Is it possible to reverse POD status from C to A just like a VLPOD and reverse PGI status from C to A just like a VL09.
This code updates POD status but I don't know how to reverse it
*** updating PGI status ***
ls_vbkok-wabuc = 'X'.
ls_vbkok-wadat_ist = sy-datum.
ls_vbkok-wauhr = sy-uzeit.
ls_vbkok-wadat = plandate.
ls_vbkok-kzwad = 'X'.
CLEAR: ls_vbkok-kzpod, ls_vbkok-podat, ls_vbkok-potim.
CALL FUNCTION 'WS_DELIVERY_UPDATE_2'
EXPORTING
vbkok_wa = ls_vbkok
synchron = 'X'
commit = 'X'
delivery = ls_likp-vbeln
update_picking = 'X'
TABLES
prot = lt_prot.
*** updating POD status ***
ls_vbkok-kzpod = 'D'.
ls_vbkok-podat = sy-datum.
ls_vbkok-potim = sy-uzeit.
CALL FUNCTION 'WS_DELIVERY_UPDATE_2'
EXPORTING
vbkok_wa = ls_vbkok
synchron = 'X'
* NO_MESSAGES_UPDATE_1 = ' '
commit = 'X'
delivery = ls_likp-vbeln
* update_picking = 'X' "test stock
* nicht_sperren_1 = 'Y'
TABLES
vbpok_tab = lt_vbpok
prot = lt_prot.
CLEAR: lt_vbpok, ls_vbpok, lt_prot, ls_likp.
Best regards
I recently had an issue where I used the module function WS_DELIVERY_UPDATE_2 and I had to reverse the delivery to status 'A' for my tests.
To reverse the status I executed transaction VL09.
After I read your issue I checked the code of that transaction, which is RVV50L09, and I found the module function WS_REVERSE_GOODS_ISSUE.
Hope it helps.
Check POD_STATUS_MAINTAIN subroutine in FV50XFPD include.
It uses the following FM for reverting the POD status:
lips-kzpod = 'B'.
CALL FUNCTION 'LIPS_STATUS_MAINTAIN'
EXPORTING
f_likp = likp
f_posnr = lips-posnr
land1_we = kuwev-land1
TABLES
fxlips = xlips
fxvbapf = xvbapf
fxvbup = xvbup
fyvbup = yvbup
fxvbfa = xvbfa.
Regarding PGI, ask the separate question.

BAPI or FM for Promise to pay creation?

I'm working with Promises to pay in UDM_SUPERVISOR transaction and I need to upload Promise to pay data using BAPI/FM from an excel file.
There is a data migration template which will include all the required fields for the creation of a Customer Promise To Pay in the system.
The migration will happen using LTMC migration cockpit tool. Is there any BAPI/FM I can use for uploading Promise To Pay?
Try function modules from FDM_P2P_SERVICES group which is Promise to Pay API.
For example UDM dashboard calls FDM_P2P_CREATE FM under the hood
ls_p2p_partner-obj_type = 'KNB1'.
ls_p2p_partner-obj_key = '0030000001CA09'.
ls_p2p_attr-fin_comp_code = "CA09".
ls_p2p_attr-fin_customer = '0030000001".
ls_p2p_attr-fin_p2p_curr = 'CAD".
ls_p2p_attr-fin_p2p_date = ls_p2p_attr-fin_p2p_due_date = "20220530".
ls_p2p_attr-fin_promised_by = 'Sandeep Phogat".
ls_p2p_attr-fin_contact_tel = "9058262323".
ls_p2p_attr-fin_contact_key = "0000000003".
APPEND ls_p2p_attr TO lt_p2p_attr.
ls_gen_inv_for_partner-obj_type = "BSEG".
ls_gen_inv_for_partner-obj_key = "CA0901000001752017001".
ls_gen_inv_for_partner-open_amount = "0.75".
ls_gen_inv_for_partner-max_p2p_amount = "0.75".
ls_gen_inv_for_partner-assigned_p2p_amount = "0.75".
ls_gen_inv_for_partner-p2p_curr = "CAD".
ls_gen_inv_for_partner-due_date = "20170515".
ls_gen_inv_for_partner-overdue_by = "1841".
ls_gen_inv_for_partner-case_type = "CAPP".
APPEND ls_gen_inv_for_partner TO lt_gen_inv_for_partner.
CALL FUNCTION 'FDM_P2P_CREATE'
EXPORTING
is_p2p_partner = ls_p2p_partner
it_p2p_attr = lt_p2p_attr
it_p2p_invoice = lt_gen_inv_for_partner
IMPORTING
et_p2p_created = lt_p2p_crea_for_partner
EXCEPTIONS
get_number_failure = 1
case_interface_failure = 2.
If you want to upload promises from file, please check /HEX/UPLOAD_P2P standard report.

Changes don't commit after RFC of ME_INFORECORD_MAINTAIN_MULTI

I'm calling ME_INFORECORD_MAINTAIN_MULTI with an RFC. The purchase info records get a new number, but the changes aren't commited to the db.
The commit is supposed to be implicit after a RFC, but it isn't. I've tried adding an explicit COMMIT WORK after the function call, but this didn't help.
The changes are commited properly if I use a regular function call (not remote), however performance is very slow.
Please help.
FORM CALL_BAPI_PIR.
lv_taskname = |PIR-{ lv_sentjobs WIDTH = 3 ALIGN = RIGHT PAD = '0' }|.
CALL FUNCTION 'ME_INFORECORD_MAINTAIN_MULTI'
STARTING NEW TASK lv_taskname
DESTINATION IN GROUP DEFAULT
PERFORMING RETURN_BAPI_PIR ON END OF TASK
EXPORTING
testrun = p_test
TABLES
t_eina = GT_ME_EINA
t_einax = GT_ME_EINAX
t_eine = GT_ME_EINE
t_einex = GT_ME_EINEX
return = GT_ME_INFORECORD_RETURN
EXCEPTIONS
system_failure = 1 MESSAGE lv_exceptionmsg
communication_failure = 2 MESSAGE lv_exceptionmsg
resource_failure = 3
.
CASE sy-subrc.
WHEN 0.
lv_sentjobs = lv_sentjobs + 1.
COMMIT WORK.
WHEN 1 OR 2.
MESSAGE lv_exceptionmsg TYPE 'I'.
WRITE: / lv_taskname, ':', lv_exceptionmsg.
ENDCASE.
ENDFORM.
FORM RETURN_BAPI_PIR USING TASKNAME.
DATA INFO LIKE RFCSI.
RECEIVE RESULTS FROM FUNCTION 'ME_INFORECORD_MAINTAIN_MULTI'
IMPORTING
RFCSI_EXPORT = INFO
RETURN = GT_ME_INFORECORD_RETURN.
lv_recvjobs = lv_recvjobs + 1.
ENDFORM.
I've solved this by making a wrapper function that ends with a commit, and calling the wrapper function instead of the standard function.
FUNCTION z_inforecord_maintain_mult2
IMPORTING
VALUE(testrun) TYPE bapiflag-bapiflag OPTIONAL
EXPORTING
VALUE(et_eina) TYPE mewieina_mig_t
VALUE(et_eine) TYPE mewieine_t
TABLES
t_eina TYPE mewieina_mig_t OPTIONAL
t_einax TYPE mewieinax_t OPTIONAL
t_eine TYPE mewieine_t OPTIONAL
t_einex TYPE mewieinex_t OPTIONAL
txt_lines TYPE mewipirtext_tt OPTIONAL
cond_validity TYPE mewivalidity_tt OPTIONAL
condition TYPE mewicondition_tt OPTIONAL
cond_scale_value TYPE mewiscaleval_tt OPTIONAL
cond_scale_quan TYPE mewiscalequan_tt OPTIONAL
return TYPE fs4mig_t_bapiret2 OPTIONAL.
CALL FUNCTION 'ME_INFORECORD_MAINTAIN_MULTI'
EXPORTING
testrun = testrun
IMPORTING
et_eina = et_eina
et_eine = et_eine
TABLES
t_eina = t_eina
t_einax = t_einax
t_eine = t_eine
t_einex = t_einex
txt_lines = txt_lines
cond_validity = cond_validity
condition = condition
cond_scale_value = cond_scale_value
cond_scale_quan = cond_scale_quan
return = return
.
IF SY-subrc = 0.
COMMIT WORK.
ENDIF.
ENDFUNCTION.
With RFC, there's an implicit database commit at some point of time in the calling program, but not in the RFC session, like there's no implicit database commit after SUBMIT.
You may chain several function module calls in the same RFC session, and to chain a SAP LUW commit in the RFC session you may call the function module BAPI_TRANSACTION_COMMIT to do a COMMIT WORK. The solution then depends on the type of RFC you use.
In your case, you use asynchronous RFC with a callback i.e. with wait, so the solution will be to
indicate KEEPING TASK at RECEIVE RESULTS so that to keep the RFC session open after calling ME_INFORECORD_MAINTAIN_MULTI
use WAIT FOR ASYNCHRONOUS TASKS so that BAPI_TRANSACTION_COMMIT is called sequentially after ME_INFORECORD_MAINTAIN_MULTI has ended.
CALL FUNCTION 'ME_INFORECORD_MAINTAIN_MULTI'
STARTING NEW TASK lv_taskname
DESTINATION IN GROUP DEFAULT
PERFORMING RETURN_BAPI_PIR ON END OF TASK
...
EXCEPTIONS
system_failure = 1 MESSAGE lv_exceptionmsg
communication_failure = 2 MESSAGE lv_exceptionmsg
resource_failure = 3.
IF sy-subrc = 0.
WAIT FOR ASYNCHRONOUS TASKS UNTIL lv_recvjobs = lv_sentjobs.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
STARTING NEW TASK lv_taskname " <====== reuse existing RFC session/closed implicitly right after
DESTINATION IN GROUP DEFAULT
EXCEPTIONS
system_failure = 1 MESSAGE lv_exceptionmsg
communication_failure = 2 MESSAGE lv_exceptionmsg
resource_failure = 3.
...
FORM RETURN_BAPI_PIR USING TASKNAME.
DATA INFO LIKE RFCSI.
RECEIVE RESULTS FROM FUNCTION 'ME_INFORECORD_MAINTAIN_MULTI'
KEEPING TASK " <============== add this to not close the RFC session
IMPORTING
RFCSI_EXPORT = INFO
RETURN = GT_ME_INFORECORD_RETURN.
lv_recvjobs = lv_recvjobs + 1.
ENDFORM.
NB:
I did not handle the exceptions to simplify the demonstration.
If you run the RFC under several task names, several RFC sessions are started, so you must call BAPI_TRANSACTION_COMMIT in each of these RFC sesssions.

Send multiple files in HTTP response

I have created an ICF handler class which sends files to the sender. The thing is, it works fine with single file where i am reading the data in binary format and attaching the same in body part using set_data.
But when I try to add more than 1 file, I am unable to add 2 files separately. i am using IF_HTTP_EXTENSION and do not have NTW GATEWAY component yet.
I am also using MULTIPART feature, but dont konw exactly on how to add 2 files separately. Can you please help me ?
//file1
server->response->set_header_field( name = 'Content-Type' value = 'multipart/mixed').
CONCATENATE 'form-data;name="file"; filename="' filename+5(9) '"' INTO lv_header_value.
server->response->set_header_field( name = 'content-disposition' value = lv_header_value ).
server->response->set_data( data = attach_xstring ).
//file2
server->response->add_multipart( ).
CONCATENATE 'form-data;name="file"; filename="' filename+5(9) '"' INTO lv_header_value.
server->response->set_header_field( name = 'content-disposition' value = lv_header_value ).
server->response->set_data( data = attach_xstring ).
You need to use add_multipart() method. Try like this:
cl_http_client=>create( EXPORTING host = host service = port scheme = scheme
IMPORTING client = lo_http_client ).
lo_http_client->request->set_header_field( name = 'Content-Type' value = 'multipart/form-data' ). "#EC NOTEXT
lo_request_part = lo_http_client->request->add_multipart( ).
lo_request_part->set_content_type( 'application/xml' ).
lv_content_disposition = |form-data; name="item"; filename="item_data.xml" |.
lo_request_part->set_header_field( name = `Content-Disposition` value = lv_content_disposition ).
lo_request_part->set_data( data = lv_create_item_xml ).
LOOP AT mt_files ASSIGNING <attachment>.
lo_request_part = lo_http_client->request->add_multipart( ).
lo_request_part->set_content_type( <attachment>-content_type ). "#EC NOTEXT
lv_content_disposition = |form-data; name="{ <attachment>-part_name }"; filename="{ <attachment>-filename }" |.
lo_request_part->set_header_field( name = `Content-Disposition` value = lv_content_disposition ).
lo_request_part->set_data( <attachment>-file ).
ENDLOOP.
It is sample for request, but for response the scheme should be the same. Here initially xml-file added to request and them multiple attachments are processed in loop.

Add new emails Customer at XD02 from CALL METHOD cmd_ei_api=>maintain_bapi

I need to add a new email address on customers in XD02 from an xls.
That's all ok, but, when I CALL METHOD cmd_ei_api=>maintain_bapi
this really change the email but delete all the emails on XD02, and it's not what I want, I want to add a new email put this one default, but I want to keep the old ones.
My code :
FORM data_to_bapi.
DATA: gs_correct TYPE cmds_ei_main,
gt_customers TYPE cmds_ei_main,
gs_address TYPE bapiad1vl,
gs_addressx TYPE bapiad1vlx,
gs_company_code_st TYPE cmds_ei_company,
gs_company_code TYPE cmds_ei_cmd_company,
gt_smtp TYPE cvis_ei_smtp_t,
gs_smtp LIKE LINE OF gt_smtp,
gs_comm TYPE cvis_ei_cvi_communication,
gs_customers TYPE cmds_ei_extern,
gs_defective TYPE cmds_ei_main,
gs_msg_correct TYPE cvis_message,
gs_msg_error TYPE cvis_message,
iv_test_run TYPE c.
LOOP AT lt_data INTO wa_data.
"Controlo
gs_customers-header-object_instance-kunnr = wa_data-kunnr. "kunnr
gs_customers-header-object_task = 'U'. "Update this kunnr
gs_smtp-contact-task = 'I'. " Insert New Email
gs_smtp-contact-data-e_mail = wa_data-email. " New email
gs_smtp-contact-datax-e_mail = 'X'.
APPEND gs_smtp TO gt_smtp.
gs_comm-smtp-smtp = gt_smtp[].
gs_customers-central_data-address-communication = gs_comm.
gs_customers-central_data-address-task = 'I'. " Insert new communication
APPEND gs_customers TO gt_customers-customers.
**********************************************************************
* CALL BAPI *
**********************************************************************
CHECK gt_customers-customers IS NOT INITIAL.
gv_collect_messages = abap_true.
cmd_ei_api=>initialize( ).
iv_test_run = ' '.
CALL METHOD cmd_ei_api=>maintain_bapi
EXPORTING
iv_test_run = iv_test_run
iv_collect_messages = gv_collect_messages
is_master_data = gt_customer
" Master Data
IMPORTING
es_master_data_correct = gs_correct
es_message_correct = gs_msg_correct
es_master_data_defective = gs_defective
es_message_defective = gs_msg_error.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'.
CLEAR wa_data.
ENDLOOP.
ENDFORM. "data_to_bapi
Thanks !